Skip to content

Commit 990a409

Browse files
committed
✨ Encode bounding boxes in GeoJSON
Also fix bounding boxes computation
1 parent da78ab2 commit 990a409

File tree

6 files changed

+31
-14
lines changed

6 files changed

+31
-14
lines changed

Sources/GeoJSON/GeoJSON+Codable.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ extension LinearRingCoordinates {
145145

146146
fileprivate enum SingleGeometryCodingKeys: String, CodingKey {
147147
case geoJSONType = "type"
148-
case coordinates
148+
case coordinates, bbox
149149
}
150150

151151
extension SingleGeometry {
@@ -171,6 +171,7 @@ extension SingleGeometry {
171171

172172
try container.encode(Self.geoJSONType, forKey: .geoJSONType)
173173
try container.encode(self.coordinates, forKey: .coordinates)
174+
try container.encode(self.bbox, forKey: .bbox)
174175
}
175176

176177
}

Sources/GeoJSON/Helpers/GeoJSON+Boundable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Turf
1212
extension NonEmpty: Boundable where Collection: Hashable, Element: Boundable {
1313

1414
public var _bbox: Element.BoundingBox {
15-
self.reduce(.zero, { $0.union($1.bbox) })
15+
self.reduce(nil, { $0.union($1.bbox) }) ?? .zero
1616
}
1717

1818
}

Sources/GeoModels/BoundingBox.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,11 @@ public protocol BoundingBox: Hashable {
1313
func union(_ other: Self) -> Self
1414

1515
}
16+
17+
extension Optional where Wrapped: BoundingBox {
18+
19+
public func union(_ bbox: Wrapped) -> Wrapped {
20+
self?.union(bbox) ?? bbox
21+
}
22+
23+
}

Sources/Turf/Boundable.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,23 +76,23 @@ extension BoundingBox3D: Boundable {
7676
//extension Collection: Boundable where Element: Boundable {
7777
//
7878
// public var _bbox: Element.BoundingBox {
79-
// self.reduce(.zero, { $0.union($1.bbox) })
79+
// self.reduce(nil, { $0.union($1.bbox) }) ?? .zero
8080
// }
8181
//
8282
//}
8383

8484
extension Array: Boundable where Element: Boundable {
8585

8686
public var _bbox: Element.BoundingBox {
87-
self.reduce(.zero, { $0.union($1.bbox) })
87+
self.reduce(nil, { $0.union($1.bbox) }) ?? .zero
8888
}
8989

9090
}
9191

9292
extension Set: Boundable where Element: Boundable {
9393

9494
public var _bbox: Element.BoundingBox {
95-
self.reduce(.zero, { $0.union($1.bbox) })
95+
self.reduce(nil, { $0.union($1.bbox) }) ?? .zero
9696
}
9797

9898
}

Sources/Turf/Turf.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public func bbox<C: Collection>(for coords: C) -> BoundingBox3D? where C.Element
6868
public func bbox<T: Boundable, C: Collection>(for boundables: C) -> T.BoundingBox? where C.Element == T {
6969
guard !boundables.isEmpty else { return nil }
7070

71-
return boundables.reduce(.zero, { $0.union($1.bbox) })
71+
return boundables.reduce(nil, { $0.union($1.bbox) }) ?? .zero
7272
}
7373

7474
/// Returns the absolute center of a polygon.

Tests/GeoJSONTests/GeoJSON+EncodableTests.swift

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ final class GeoJSONEncodableTests: XCTestCase {
2626
XCTAssertEqual(string, [
2727
"{",
2828
"\"type\":\"Point\",",
29-
"\"coordinates\":[-1.55366,47.21881]",
29+
"\"coordinates\":[-1.55366,47.21881],",
30+
"\"bbox\":[-1.55366,47.21881,-1.55366,47.21881]",
3031
"}",
3132
].joined())
3233
}
@@ -41,7 +42,8 @@ final class GeoJSONEncodableTests: XCTestCase {
4142
"\"type\":\"MultiPoint\",",
4243
"\"coordinates\":[",
4344
"[-1.55366,47.21881]",
44-
"]",
45+
"],",
46+
"\"bbox\":[-1.55366,47.21881,-1.55366,47.21881]",
4547
"}",
4648
].joined())
4749
}
@@ -57,7 +59,8 @@ final class GeoJSONEncodableTests: XCTestCase {
5759
"\"coordinates\":[",
5860
"[-1.55366,47.21881],",
5961
"[2.3529,48.85719]",
60-
"]",
62+
"],",
63+
"\"bbox\":[-1.55366,47.21881,2.3529,48.85719]",
6164
"}",
6265
].joined())
6366
}
@@ -79,7 +82,8 @@ final class GeoJSONEncodableTests: XCTestCase {
7982
"[2.3529,48.85719],",
8083
"[5.36468,43.29868]",
8184
"]",
82-
"]",
85+
"],",
86+
"\"bbox\":[-1.55366,43.29868,5.36468,48.85719]",
8387
"}",
8488
].joined())
8589
}
@@ -102,7 +106,8 @@ final class GeoJSONEncodableTests: XCTestCase {
102106
"[2.3529,48.85719],",
103107
"[-1.55366,47.21881]",
104108
"]",
105-
"]",
109+
"],",
110+
"\"bbox\":[-1.55366,43.29868,5.36468,48.85719]",
106111
"}",
107112
].joined())
108113
}
@@ -133,7 +138,8 @@ final class GeoJSONEncodableTests: XCTestCase {
133138
"[-1.55366,47.21881]",
134139
"]",
135140
"]",
136-
"]",
141+
"],",
142+
"\"bbox\":[-1.55366,43.29868,5.36468,48.85719]",
137143
"}",
138144
].joined())
139145
}
@@ -155,7 +161,8 @@ final class GeoJSONEncodableTests: XCTestCase {
155161
"\"type\":\"Feature\",",
156162
"\"geometry\":{",
157163
"\"type\":\"Point\",",
158-
"\"coordinates\":[-1.55366,47.21881]",
164+
"\"coordinates\":[-1.55366,47.21881],",
165+
"\"bbox\":[-1.55366,47.21881,-1.55366,47.21881]",
159166
"},",
160167
"\"bbox\":[-1.55366,47.21881,-1.55366,47.21881]",
161168
"}",
@@ -183,7 +190,8 @@ final class GeoJSONEncodableTests: XCTestCase {
183190
"\"type\":\"Feature\",",
184191
"\"geometry\":{",
185192
"\"type\":\"Point\",",
186-
"\"coordinates\":[-1.55366,47.21881]",
193+
"\"coordinates\":[-1.55366,47.21881],",
194+
"\"bbox\":[-1.55366,47.21881,-1.55366,47.21881]",
187195
"},",
188196
"\"bbox\":[-1.55366,47.21881,-1.55366,47.21881]",
189197
"}",

0 commit comments

Comments
 (0)