@@ -24,7 +24,7 @@ public struct GeoJSON: Hashable {
2424 case unexpectedRoot
2525 case missingOrInvalidRequiredField( String )
2626 case wrongNumberOfCoordinates( String )
27- case wrongTypeOfSimpleGeometry
27+ case wrongTypeOfSimpleGeometry( String )
2828 }
2929
3030 /// A GeoJSON object may represent a region of space (a Geometry), a
@@ -84,8 +84,10 @@ public struct GeoJSON: Hashable {
8484 }
8585 self = . collection( geometries)
8686
87- default :
88- throw SerializationError . wrongTypeOfSimpleGeometry
87+ case . feature:
88+ throw SerializationError . wrongTypeOfSimpleGeometry ( " Can't turn Feature into GeometryObject " )
89+ case . featureCollection:
90+ throw SerializationError . wrongTypeOfSimpleGeometry ( " Can't turn FeatureCollection into GeometryObject " )
8991 }
9092 }
9193
@@ -152,13 +154,21 @@ public struct GeoJSON: Hashable {
152154 self . altitude = altitude
153155 }
154156
155- fileprivate init ( coordinates: [ Degrees ] ) throws {
157+ fileprivate init ( coordinates: [ Any ] ) throws {
156158 guard coordinates. count >= 2 else {
157159 throw SerializationError . wrongNumberOfCoordinates ( " At least 2 per position " )
158160 }
159- latitude = coordinates [ 1 ]
160- longitude = coordinates [ 0 ]
161- altitude = coordinates. count >= 3 ? coordinates [ 2 ] : nil
161+
162+ if let lat = coordinates [ 1 ] as? Degrees , let lng = coordinates [ 0 ] as? Degrees {
163+ latitude = lat
164+ longitude = lng
165+ } else if let lat = coordinates [ 1 ] as? Decimal , let lng = coordinates [ 0 ] as? Decimal {
166+ latitude = GeoJSON . Degrees ( ( lat as NSDecimalNumber ) . doubleValue)
167+ longitude = GeoJSON . Degrees ( ( lng as NSDecimalNumber ) . doubleValue)
168+ } else {
169+ throw SerializationError . wrongTypeOfSimpleGeometry ( " Expected \( Degrees . self) for coordinates but got \( Swift . type ( of: coordinates [ 0 ] ) ) ( \( coordinates [ 0 ] ) ) and \( Swift . type ( of: coordinates [ 1 ] ) ) ( \( coordinates [ 1 ] ) ) " )
170+ }
171+ altitude = coordinates. count >= 3 ? coordinates [ 2 ] as? Degrees : nil
162172 }
163173
164174 fileprivate func toJSON( ) -> [ Degrees ] {
@@ -248,17 +258,15 @@ public struct GeoJSON: Hashable {
248258 case polygon( Polygon )
249259
250260 fileprivate init ( coordinates: [ Any ] ) throws {
251- if let coordinates = coordinates as? [ [ [ Degrees ] ] ] {
261+ if let coordinates = coordinates as? [ [ [ Any ] ] ] {
252262 let positions = try coordinates. map { try $0. map { try Position ( coordinates: $0) } }
253263 self = . polygon( Polygon ( positions) )
254- } else if let coordinates = coordinates as? [ [ Degrees ] ] {
264+ } else if let coordinates = coordinates as? [ [ Any ] ] {
255265 let positions = try coordinates. map { try Position ( coordinates: $0) }
256266 self = . lineString( LineString ( positions: positions) )
257- } else if let coordinates = coordinates as? [ Degrees ] {
267+ } else {
258268 let position = try Position ( coordinates: coordinates)
259269 self = . point( position)
260- } else {
261- throw SerializationError . wrongTypeOfSimpleGeometry
262270 }
263271 }
264272
@@ -537,11 +545,11 @@ fileprivate enum Adjuster {
537545 return dict. mapValues ( prune ( _: ) )
538546 } else if value is Int || value is [ Int ] || value is [ [ Int ] ] || value is Bool || value is [ Bool ] || value is [ [ Bool ] ] {
539547 return value
540- } else if let doubles = value as? [ Double ] {
548+ } else if let doubles = value as? [ GeoJSON . Degrees ] {
541549 return doubles. prune
542- } else if let doubless = value as? [ [ Double ] ] {
550+ } else if let doubless = value as? [ [ GeoJSON . Degrees ] ] {
543551 return doubless. map ( \. prune)
544- } else if let double = value as? Double {
552+ } else if let double = value as? GeoJSON . Degrees {
545553 return Decimal ( double)
546554 } else if let array = value as? [ Any ] {
547555 return array. map ( prune ( _: ) )
@@ -552,9 +560,9 @@ fileprivate enum Adjuster {
552560
553561 static func hashable( _ value: Any ) -> AnyHashable ? {
554562 if let dict = value as? [ String : Any ] {
555- return dict. mapValues ( hashable ( _: ) )
563+ return dict. compactMapValues ( hashable ( _: ) )
556564 } else if let array = value as? [ Any ] {
557- return array. map ( hashable ( _: ) )
565+ return array. compactMap ( hashable ( _: ) )
558566 } else if let hashable = value as? AnyHashable {
559567 return hashable
560568 } else {
0 commit comments