From 53910de2d29796d298c9ae642c022d0a2dcd5771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Wed, 29 Sep 2021 23:43:16 -0700 Subject: [PATCH] Convert between enumerations and associated values --- Sources/Turf/Feature.swift | 11 +++++++- Sources/Turf/GeoJSON.swift | 25 +++++++++++++++++ Sources/Turf/Geometry.swift | 45 ++++++++++++++++++++++++++++++ Tests/TurfTests/GeoJSONTests.swift | 23 +++++++++++++++ 4 files changed, 103 insertions(+), 1 deletion(-) diff --git a/Sources/Turf/Feature.swift b/Sources/Turf/Feature.swift index 0af1dd80..4a09a784 100644 --- a/Sources/Turf/Feature.swift +++ b/Sources/Turf/Feature.swift @@ -25,9 +25,18 @@ public struct Feature: Equatable { - parameter geometry: The geometry at which the feature is located. */ - public init(geometry: Geometry?) { + public init(geometry: Geometry) { self.geometry = geometry } + + /** + Initializes a feature defined by the given geometry-convertible instance. + + - parameter geometry: The geometry-convertible instance that bounds the feature. + */ + public init(geometry: GeometryConvertible?) { + self.geometry = geometry?.geometry + } } extension Feature: Codable { diff --git a/Sources/Turf/GeoJSON.swift b/Sources/Turf/GeoJSON.swift index 1aecb7c5..0c40d31c 100644 --- a/Sources/Turf/GeoJSON.swift +++ b/Sources/Turf/GeoJSON.swift @@ -28,6 +28,11 @@ public enum GeoJSONObject: Equatable { - parameter featureCollection: The GeoJSON object as a FeatureCollection object. */ case featureCollection(_ featureCollection: FeatureCollection) + + /// Initializes a GeoJSON object representing the given GeoJSON object–convertible instance. + public init(_ object: GeoJSONObjectConvertible) { + self = object.geoJSONObject + } } extension GeoJSONObject: Codable { @@ -60,3 +65,23 @@ extension GeoJSONObject: Codable { } } } + +/** + A type that can be represented as a `GeoJSONObject` instance. + */ +public protocol GeoJSONObjectConvertible { + /// The instance wrapped in a `GeoJSONObject` instance. + var geoJSONObject: GeoJSONObject { get } +} + +extension Geometry: GeoJSONObjectConvertible { + public var geoJSONObject: GeoJSONObject { return .geometry(self) } +} + +extension Feature: GeoJSONObjectConvertible { + public var geoJSONObject: GeoJSONObject { return .feature(self) } +} + +extension FeatureCollection: GeoJSONObjectConvertible { + public var geoJSONObject: GeoJSONObject { return .featureCollection(self) } +} diff --git a/Sources/Turf/Geometry.swift b/Sources/Turf/Geometry.swift index caaf5520..f5e3c2aa 100644 --- a/Sources/Turf/Geometry.swift +++ b/Sources/Turf/Geometry.swift @@ -27,6 +27,11 @@ public enum Geometry: Equatable { /// A heterogeneous collection of geometries that are related. case geometryCollection(_ geometry: GeometryCollection) + + /// Initializes a geometry representing the given geometry–convertible instance. + public init(_ geometry: GeometryConvertible) { + self = geometry.geometry + } } extension Geometry: Codable { @@ -85,3 +90,43 @@ extension Geometry: Codable { } } } + +/** + A type that can be represented as a `Geometry` instance. + */ +public protocol GeometryConvertible { + /// The instance wrapped in a `Geometry` instance. + var geometry: Geometry { get } +} + +extension Geometry: GeometryConvertible { + public var geometry: Geometry { return self } +} + +extension Point: GeometryConvertible { + public var geometry: Geometry { return .point(self) } +} + +extension LineString: GeometryConvertible { + public var geometry: Geometry { return .lineString(self) } +} + +extension Polygon: GeometryConvertible { + public var geometry: Geometry { return .polygon(self) } +} + +extension MultiPoint: GeometryConvertible { + public var geometry: Geometry { return .multiPoint(self) } +} + +extension MultiLineString: GeometryConvertible { + public var geometry: Geometry { return .multiLineString(self) } +} + +extension MultiPolygon: GeometryConvertible { + public var geometry: Geometry { return .multiPolygon(self) } +} + +extension GeometryCollection: GeometryConvertible { + public var geometry: Geometry { return .geometryCollection(self) } +} diff --git a/Tests/TurfTests/GeoJSONTests.swift b/Tests/TurfTests/GeoJSONTests.swift index af0269c6..e65be3f1 100644 --- a/Tests/TurfTests/GeoJSONTests.swift +++ b/Tests/TurfTests/GeoJSONTests.swift @@ -6,6 +6,29 @@ import struct Turf.Polygon import CoreLocation class GeoJSONTests: XCTestCase { + func testConversion() { + let nullIsland = LocationCoordinate2D(latitude: 0, longitude: 0) + XCTAssertEqual(Geometry(Point(nullIsland)), + .point(Point(nullIsland))) + XCTAssertEqual(Geometry(LineString([nullIsland, nullIsland])), + .lineString(LineString([nullIsland, nullIsland]))) + XCTAssertEqual(Geometry(Polygon([[nullIsland, nullIsland, nullIsland]])), + .polygon(Polygon([[nullIsland, nullIsland, nullIsland]]))) + XCTAssertEqual(Geometry(MultiPoint([nullIsland, nullIsland, nullIsland])), + .multiPoint(MultiPoint([nullIsland, nullIsland, nullIsland]))) + XCTAssertEqual(Geometry(MultiLineString([[nullIsland, nullIsland, nullIsland]])), + .multiLineString(MultiLineString([[nullIsland, nullIsland, nullIsland]]))) + XCTAssertEqual(Geometry(MultiPolygon([[[nullIsland, nullIsland, nullIsland]]])), + .multiPolygon(MultiPolygon([[[nullIsland, nullIsland, nullIsland]]]))) + XCTAssertEqual(Geometry(GeometryCollection(geometries: [])), + .geometryCollection(GeometryCollection(geometries: []))) + + XCTAssertEqual(GeoJSONObject(Geometry(Point(nullIsland))), .geometry(.point(.init(nullIsland)))) + XCTAssertEqual(GeoJSONObject(Feature(geometry: nil)), .feature(.init(geometry: nil))) + let nullGeometry: Geometry? = nil + XCTAssertEqual(GeoJSONObject(Feature(geometry: nullGeometry)), .feature(.init(geometry: nil))) + XCTAssertEqual(GeoJSONObject(FeatureCollection(features: [])), .featureCollection(.init(features: []))) + } func testPoint() { let coordinate = LocationCoordinate2D(latitude: 10, longitude: 30)