这个 GeoJSON 的实现遵循 rfc7946 规范,并被设计用于 Codable
对象。
这个库包含 GeoJSON 模型的动态和静态两种变体。静态变体在处理预定义的 GeoJSON 响应时非常有用。
当您的项目被设置为加载您知道其结构的数据时,建议使用静态模型。
例如,如果您知道您正在加载一个包含位置列表的 "FeatureCollection",如下所示
{
"features": [
{
"geometry": {
"coordinates": [
-0.452207,
51.471403
],
"type": "Point"
},
"properties": {
"address": "Longford, Hounslow TW6 1DB, UK",
"name": "Heathrow Airport"
},
"type": "Feature"
}
],
"type": "FeatureCollection"
}
您可以使用 struct
和 typealias
来定义模型。
struct LocationProperties: Codable {
let address: String
let name: String
}
typealias LocationFeatureCollection = GeoJSONFeatureCollection<PointGeometry, LocationProperties>
这样做的好处是您可以直接访问特定的几何形状和所有属性,而无需执行任何内省。 例如:
let locationFeatures = try JSONDecoder().decode(LocationFeatureCollection.self, from: data)
let firstFeature = locationFeatures.features.first
firstFeature?.geometry.longitude // -0.452207
firstFeature?.properties?.name // "Heathrow Airport"
根据定义,几何图形集合不是静态类型的,因为它可能包含不同 GeoJSON 几何图形类型的混合数组。 因此,您需要手动检查每个数组。 (如果有人有简化此过程的方法,请随时发布 PR 😉)
let geometryColection = try JSONDecoder().decode(GeometryCollection.self, from: data)
if geometryColection.geometries.count > 0,
case GeoJSON.Geometry.point(let pointCoordinates) = geometryColection.geometries[0] {
let point = PointGeometry(coordinates: pointCoordinates)
} else {
// Failed to get expected geometry
}
如果您不想要或不需要要素的任何属性,您可以定义一个空的 struct
并将其设置为 Properties
模板参数。
struct EmptyProperties: Codable {}
typealias PointFeature = GeoJSONFeature<PointGeometry, EmptyProperties>
这将导致 "Feature" 对象仅包含一个点坐标。
仅当预期结构未定义或可能更改时,才应使用动态模型。
首先,假设您有一个 GeoJSON 数据对象。 第一步是解码它。
do {
switch try JSONDecoder().decode(GeoJSON.self, from: data) {
case .feature(let feature, _):
handleGeometry(feature.geometry)
case .featureCollection(let featureCollection, _):
for feature in featureCollection.features {
handleGeometry(feature.geometry)
}
case .geometry(let geometry, _):
handleGeometry(geometry)
}
} catch {
// Handle decoding error
}
然后,您可以探索提供的不同几何形状。
func handleGeometry(_ geometry: GeoJSONGeometry?) {
guard let geometry = geometry else { return }
switch geometry {
case .point(let coordinates):
break
case .multiPoint(let coordinates):
break
case .lineString(let coordinates):
break
case .multiLineString(let coordinates):
break
case .polygon(let coordinates):
break
case .multiPolygon(let coordinates):
break
case .geometryCollection(let geometries):
for geometry in geometries {
handleGeometry(geometry)
}
}
}
如果您知道您要查找的几何图形类型,您可以尝试直接获取它。
func handleGeometry(_ geometry: GeoJSONGeometry?) {
guard case GeoJSONGeometry.polygon(let coordinates)? = geometry else { return }
displayPolygon(linearRings: coordinates)
}
您可以使用 Swift Package Manager 通过将适当的描述添加到您的 Package.swift
文件来安装 CodableGeoJSON
import PackageDescription
let package = Package(
name: "YOUR_PROJECT_NAME",
targets: [],
dependencies: [
.package(url: "https://github.com/guykogus/CodableGeoJSON.git", from: "1.2.0")
]
)
接下来,将 CodableGeoJSON
添加到您的 target 依赖项,如下所示
.target(
name: "YOUR_TARGET_NAME",
dependencies: [
"CodableGeoJSON",
]
),
然后运行 swift package update
。
CodableGeoJSON 在 MIT 许可证下可用。 有关更多信息,请参见 LICENSE 文件。