Skip to content

Commit 0a2beff

Browse files
authored
Add Codable support for geometry collections (#6)
1 parent f396975 commit 0a2beff

6 files changed

Lines changed: 120 additions & 31 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>classNames</key>
6+
<dict>
7+
<key>GeoJSONSerializationTest</key>
8+
<dict>
9+
<key>testPerformanceNSWFires()</key>
10+
<dict>
11+
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
12+
<dict>
13+
<key>baselineAverage</key>
14+
<real>0.024924</real>
15+
<key>baselineIntegrationDisplayName</key>
16+
<string>Local Baseline</string>
17+
</dict>
18+
</dict>
19+
<key>testPerformanceWorld()</key>
20+
<dict>
21+
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
22+
<dict>
23+
<key>baselineAverage</key>
24+
<real>0.041320</real>
25+
<key>baselineIntegrationDisplayName</key>
26+
<string>Local Baseline</string>
27+
</dict>
28+
</dict>
29+
</dict>
30+
</dict>
31+
</dict>
32+
</plist>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>runDestinationsByUUID</key>
6+
<dict>
7+
<key>F6E2813B-6D38-41C4-979F-7ED86A869DD4</key>
8+
<dict>
9+
<key>localComputer</key>
10+
<dict>
11+
<key>busSpeedInMHz</key>
12+
<integer>0</integer>
13+
<key>cpuCount</key>
14+
<integer>1</integer>
15+
<key>cpuKind</key>
16+
<string>Apple M1</string>
17+
<key>cpuSpeedInMHz</key>
18+
<integer>0</integer>
19+
<key>logicalCPUCoresPerPackage</key>
20+
<integer>8</integer>
21+
<key>modelCode</key>
22+
<string>MacBookAir10,1</string>
23+
<key>physicalCPUCoresPerPackage</key>
24+
<integer>8</integer>
25+
<key>platformIdentifier</key>
26+
<string>com.apple.platform.macosx</string>
27+
</dict>
28+
<key>targetArchitecture</key>
29+
<string>arm64</string>
30+
</dict>
31+
</dict>
32+
</dict>
33+
</plist>

Sources/GeoJSONKit/GeoJSON+Codable.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ extension GeoJSON.GeometryObject: Codable {
1212
enum CodingKeys: String, CodingKey {
1313
case type
1414
case coordinates
15+
case geometries
1516
}
1617

1718
public enum CodingError: Error {
1819
case featuresNotSupported
19-
case geometryCollectionNotSupported
2020
case unsupportedCoordinateCount
2121
}
2222

@@ -27,8 +27,10 @@ extension GeoJSON.GeometryObject: Codable {
2727
switch type {
2828
case .feature, .featureCollection:
2929
throw CodingError.featuresNotSupported
30+
3031
case .geometryCollection:
31-
throw CodingError.geometryCollectionNotSupported
32+
let geometries = try container.decode([GeoJSON.GeometryObject].self, forKey: .geometries)
33+
self = .collection(geometries)
3234

3335
case .point:
3436
let coordinates = try container.decode([Double].self, forKey: .coordinates)
@@ -92,8 +94,8 @@ extension GeoJSON.GeometryObject: Codable {
9294
}
9395

9496
switch self {
95-
case .collection:
96-
throw CodingError.geometryCollectionNotSupported
97+
case .collection(let geometries):
98+
try container.encode(geometries, forKey: .geometries)
9799

98100
case .single(let geometry):
99101
try addCoordinates(geometry.coordinatesJSON())
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// GeoJSON+Serialization.swift
3+
//
4+
//
5+
// Created by Adrian Schönig on 29/9/21.
6+
//
7+
8+
import Foundation
9+
10+
extension GeoJSON {
11+
12+
public init(deserializing data: Data) throws {
13+
try self.init(data: data)
14+
}
15+
16+
public func serialize() throws -> Data {
17+
return try toData()
18+
}
19+
20+
}

Tests/GeoJSONKitTests/GeoJSONCodableTest.swift

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ final class GeoJSONCodableTest: XCTestCase {
1717
XCTAssertNotNil(parsed)
1818

1919
guard
20-
case let .single(geometry) = parsed,
21-
case let .point(position) = geometry
20+
case let .single(.point(position)) = parsed
2221
else { return XCTFail("Unexpected structure") }
2322

2423
XCTAssertEqual(0.0, position.latitude)
@@ -54,8 +53,7 @@ final class GeoJSONCodableTest: XCTestCase {
5453
XCTAssertNotNil(parsed)
5554

5655
guard
57-
case let .single(geometry) = parsed,
58-
case let .lineString(lineString) = geometry
56+
case let .single(.lineString(lineString)) = parsed
5957
else { return XCTFail("Unexpected structure") }
6058

6159
let positions = lineString.positions
@@ -68,7 +66,6 @@ final class GeoJSONCodableTest: XCTestCase {
6866
XCTAssertEqual(1.0, positions[1].latitude)
6967
XCTAssertEqual(101.0, positions[1].longitude)
7068
XCTAssertNil(positions[1].altitude)
71-
7269
}
7370

7471
func testMultiLineString() throws {
@@ -112,8 +109,7 @@ final class GeoJSONCodableTest: XCTestCase {
112109
XCTAssertNotNil(parsed)
113110

114111
guard
115-
case let .single(geometry) = parsed,
116-
case let .polygon(polygon) = geometry
112+
case let .single(.polygon(polygon)) = parsed
117113
else { return XCTFail("Unexpected structure") }
118114

119115
let external = polygon.exterior
@@ -136,8 +132,7 @@ final class GeoJSONCodableTest: XCTestCase {
136132
XCTAssertNotNil(parsed)
137133

138134
guard
139-
case let .single(geometry) = parsed,
140-
case let .polygon(polygon) = geometry,
135+
case let .single(.polygon(polygon)) = parsed,
141136
let hole = polygon.interiors.first
142137
else { return XCTFail("Unexpected structure") }
143138

@@ -169,27 +164,35 @@ final class GeoJSONCodableTest: XCTestCase {
169164
let parsed = try JSONDecoder().decode(GeoJSON.GeometryObject.self, from: data)
170165
XCTAssertNotNil(parsed)
171166
}
172-
173-
func testFeatureCollection() throws {
174-
let data = try XCTestCase.loadData(filename: "featurecollection")
175-
XCTAssertThrowsError(try JSONDecoder().decode(GeoJSON.GeometryObject.self, from: data))
176-
}
177167

178168
func testGeometryCollection() throws {
179169
let data = try XCTestCase.loadData(filename: "geometrycollection")
170+
let parsed = try JSONDecoder().decode(GeoJSON.GeometryObject.self, from: data)
171+
XCTAssertNotNil(parsed)
172+
173+
guard
174+
case let .collection(geometries) = parsed,
175+
geometries.count == 2,
176+
case let .single(.point(position)) = geometries.first,
177+
case let .single(.lineString(lineString)) = geometries.last
178+
else { return XCTFail("Unexpected structure") }
179+
180+
XCTAssertEqual(0.0, position.latitude)
181+
XCTAssertEqual(100.0, position.longitude)
182+
XCTAssertNil(position.altitude)
183+
184+
XCTAssertEqual(0.0, lineString.positions[0].latitude)
185+
XCTAssertEqual(101.0, lineString.positions[0].longitude)
186+
XCTAssertNil(lineString.positions[0].altitude)
187+
188+
XCTAssertEqual(1.0, lineString.positions[1].latitude)
189+
XCTAssertEqual(102.0, lineString.positions[1].longitude)
190+
XCTAssertNil(lineString.positions[1].altitude)
191+
}
192+
193+
func testFeatureCollection() throws {
194+
let data = try XCTestCase.loadData(filename: "featurecollection")
180195
XCTAssertThrowsError(try JSONDecoder().decode(GeoJSON.GeometryObject.self, from: data))
181196
}
182-
183-
static var allTests = [
184-
("testPoint", testPoint),
185-
("testMultiPoint", testMultiPoint),
186-
("testLineString", testLineString),
187-
("testMultiLineString", testMultiLineString),
188-
("testPolygon", testPolygon),
189-
("testPolygonWithHole", testPolygonWithHole),
190-
("testMultiPolygon", testMultiPolygon),
191-
("testFeatureCollection", testFeatureCollection),
192-
("testGeometryCollection", testGeometryCollection),
193-
]
194197

195198
}

Tests/GeoJSONKitTests/XCTestCase+Load.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ extension XCTestCase {
2020
.appendingPathExtension(fileType)
2121
return resourceURL
2222
}
23-
2423

2524
static func loadData(filename: String, ofType fileType: String = "geojson") throws -> Data {
2625
return try Data(contentsOf: url(filename: filename, ofType: fileType))

0 commit comments

Comments
 (0)