@@ -4,15 +4,15 @@ import Foundation
4
4
public struct GeometryCollection : GeoJsonGeometry {
5
5
6
6
public var type : GeoJsonType {
7
- return . geometryCollection
7
+ . geometryCollection
8
8
}
9
9
10
10
public var projection : Projection {
11
11
geometries. first? . projection ?? . noSRID
12
12
}
13
13
14
14
/// The GeometryCollection's geometry objects.
15
- public let geometries : [ GeoJsonGeometry ]
15
+ public private ( set ) var geometries : [ GeoJsonGeometry ]
16
16
17
17
public var allCoordinates : [ Coordinate3D ] {
18
18
geometries. flatMap ( \. allCoordinates)
@@ -32,7 +32,7 @@ public struct GeometryCollection: GeoJsonGeometry {
32
32
self . geometries = geometries
33
33
34
34
if calculateBoundingBox {
35
- self . boundingBox = self . calculateBoundingBox ( )
35
+ self . updateBoundingBox ( )
36
36
}
37
37
}
38
38
@@ -49,8 +49,8 @@ public struct GeometryCollection: GeoJsonGeometry {
49
49
self . geometries = geometries
50
50
self . boundingBox = GeometryCollection . tryCreate ( json: geoJson [ " bbox " ] )
51
51
52
- if calculateBoundingBox, self . boundingBox == nil {
53
- self . boundingBox = self . calculateBoundingBox ( )
52
+ if calculateBoundingBox {
53
+ self . updateBoundingBox ( )
54
54
}
55
55
56
56
if geoJson. count > 2 {
@@ -80,6 +80,20 @@ public struct GeometryCollection: GeoJsonGeometry {
80
80
81
81
extension GeometryCollection {
82
82
83
+ @discardableResult
84
+ public mutating func updateBoundingBox( onlyIfNecessary ifNecessary: Bool = true ) -> BoundingBox ? {
85
+ mapGeometries { geometry in
86
+ var geometry = geometry
87
+ geometry. updateBoundingBox ( onlyIfNecessary: ifNecessary)
88
+ return geometry
89
+ }
90
+
91
+ if boundingBox != nil && ifNecessary { return boundingBox }
92
+
93
+ boundingBox = calculateBoundingBox ( )
94
+ return boundingBox
95
+ }
96
+
83
97
public func calculateBoundingBox( ) -> BoundingBox ? {
84
98
let geometryBoundingBoxes : [ BoundingBox ] = geometries. compactMap ( { $0. boundingBox ?? $0. calculateBoundingBox ( ) } )
85
99
guard !geometryBoundingBoxes. isEmpty else { return nil }
@@ -130,3 +144,70 @@ extension GeometryCollection {
130
144
}
131
145
132
146
}
147
+
148
+ // MARK: - Geometries
149
+
150
+ extension GeometryCollection {
151
+
152
+ /// Insert a GeoJsonGeometry into the receiver.
153
+ ///
154
+ /// - note: `geometry` must be in the same projection as the receiver.
155
+ public mutating func insertGeometry( _ geometry: GeoJsonGeometry , atIndex index: Int ) {
156
+ guard geometries. count == 0 || projection == geometry. projection else { return }
157
+
158
+ if index < geometries. count {
159
+ geometries. insert ( geometry, at: index)
160
+ }
161
+ else {
162
+ geometries. append ( geometry)
163
+ }
164
+
165
+ if boundingBox != nil {
166
+ updateBoundingBox ( onlyIfNecessary: false )
167
+ }
168
+ }
169
+
170
+ /// Append a GeoJsonGeometry to the receiver.
171
+ ///
172
+ /// - note: `geometry` must be in the same projection as the receiver.
173
+ public mutating func appendGeometry( _ geometry: GeoJsonGeometry ) {
174
+ guard geometries. count == 0 || projection == geometry. projection else { return }
175
+
176
+ geometries. append ( geometry)
177
+
178
+ if boundingBox != nil {
179
+ updateBoundingBox ( onlyIfNecessary: false )
180
+ }
181
+ }
182
+
183
+ /// Remove a GeoJsonGeometry from the receiver.
184
+ @discardableResult
185
+ public mutating func removeGeometry( at index: Int ) -> GeoJsonGeometry ? {
186
+ guard index >= 0 , index < geometries. count else { return nil }
187
+
188
+ let removedGeometry = geometries. remove ( at: index)
189
+
190
+ if boundingBox != nil {
191
+ updateBoundingBox ( onlyIfNecessary: false )
192
+ }
193
+
194
+ return removedGeometry
195
+ }
196
+
197
+ /// Map Geometries in-place.
198
+ public mutating func mapGeometries( _ transform: ( GeoJsonGeometry ) -> GeoJsonGeometry ) {
199
+ geometries = geometries. map ( transform)
200
+ }
201
+
202
+ /// Map Geometries in-place, removing *nil* values.
203
+ public mutating func compactMapGeometries( _ transform: ( GeoJsonGeometry ) -> GeoJsonGeometry ? ) {
204
+ geometries = geometries. compactMap ( transform)
205
+ }
206
+
207
+ /// Filter Geometries in-place.
208
+ public mutating func filterGeometries( _ isIncluded: ( GeoJsonGeometry ) -> Bool ) {
209
+ geometries = geometries. filter ( isIncluded)
210
+ }
211
+
212
+
213
+ }
0 commit comments