@@ -105,3 +105,34 @@ extension GeoJSON.GeometryObject: Codable {
105105 }
106106 }
107107}
108+
109+ extension GeoJSON . Feature {
110+
111+ /// Create a feature with the provided `Encodable` as the properties
112+ /// - Parameters:
113+ /// - geometry: Geometry
114+ /// - properties: Known structure to use for the properties
115+ /// - id: GeoJSON-compatible ID, i.e., an Integer or a String
116+ /// - configure: Optional handler to configure how to encode the `Encodable`
117+ public init < P: Encodable > ( geometry: GeoJSON . GeometryObject , properties: P , id: AnyHashable ? = nil , configure: ( inout JSONEncoder ) -> Void = { _ in } ) throws {
118+ var encoder = JSONEncoder ( )
119+ configure ( & encoder)
120+ let data = try encoder. encode ( properties)
121+ let asDict = try JSONSerialization . jsonObject ( with: data) as? [ String : AnyHashable ]
122+ self . init ( geometry: geometry, properties: asDict, id: id)
123+ }
124+
125+
126+ /// Parses the properties as the provided `Decodable`
127+ /// - Parameters:
128+ /// - type: Known structure to decode the feature's properties again
129+ /// - configure: Optional handler to configure how to decode the `Decodable`
130+ /// - Returns: Properties decoded as the provided `Decodable`
131+ public func properties< P: Decodable > ( as type: P . Type , configure: ( inout JSONDecoder ) -> Void = { _ in } ) throws -> P {
132+ let asData = try JSONSerialization . data ( withJSONObject: properties ?? [ : ] )
133+ var decoder = JSONDecoder ( )
134+ configure ( & decoder)
135+ return try decoder. decode ( P . self, from: asData)
136+ }
137+
138+ }
0 commit comments