@@ -346,27 +346,45 @@ extension Coordinate3D: Projectable {
346346
347347extension Coordinate3D : GeoJsonReadable {
348348
349- /// Create a coordinate from a JSON object.
349+ /// Create a coordinate from a JSON object, which can either be
350+ /// - GeoJSON,
351+ /// - or a dictionary with `x`, `y` and `z` values.
350352 ///
351353 /// - Note: The [GeoJSON spec](https://datatracker.ietf.org/doc/html/rfc7946)
352354 /// uses CRS:84 that specifies coordinates in longitude/latitude order.
353- /// - Important: The third value will always be ``altitude``, the fourth value
355+ /// - Important: The third value in GeoJSON coordinates will always be ``altitude``, the fourth value
354356 /// will be ``m`` if it exists. ``altitude`` can be a JSON `null` value.
355357 /// - important: The source is expected to be in EPSG:4326.
356358 public init ? ( json: Any ? ) {
357- guard let pointArray = json as? [ Double ? ] ,
358- pointArray. count >= 2 ,
359- let pLongitude = pointArray [ 0 ] ,
360- let pLatitude = pointArray [ 1 ]
361- else { return nil }
359+ var pLongitude : Double ?
360+ var pLatitude : Double ?
361+ var pAltitude : CLLocationDistance ?
362+ var pM : Double ?
363+
364+ if let pointArray = json as? [ Double ? ] ,
365+ pointArray. count >= 2
366+ {
367+ pLongitude = pointArray [ 0 ]
368+ pLatitude = pointArray [ 1 ]
369+ pAltitude = if pointArray. count >= 3 { pointArray [ 2 ] } else { nil }
370+ pM = if pointArray. count >= 4 { pointArray [ 3 ] } else { nil }
371+ }
372+ else if let pointDictionary = json as? [ String : Any ] {
373+ pLongitude = pointDictionary [ " x " ] as? Double
374+ pLatitude = pointDictionary [ " y " ] as? Double
375+ pAltitude = pointDictionary [ " z " ] as? CLLocationDistance
376+ pM = pointDictionary [ " m " ] as? Double
377+ }
378+ else {
379+ return nil
380+ }
362381
363- let pAltitude : CLLocationDistance ? = if pointArray. count >= 3 { pointArray [ 2 ] } else { nil }
364- let pM : Double ? = if pointArray. count >= 4 { pointArray [ 3 ] } else { nil }
382+ guard let pLongitude, let pLatitude else { return nil }
365383
366384 self . init ( latitude: pLatitude, longitude: pLongitude, altitude: pAltitude, m: pM)
367385 }
368386
369- /// Dump the coordinate as a JSON object .
387+ /// Dump the coordinate as a GeoJSON coordinate .
370388 ///
371389 /// - Important: The result JSON object will have a `null` value for the altitude
372390 /// if the ``altitude`` is `nil` and ``m`` exists.
0 commit comments