CodableGeoJSON

CocoaPods Compatible SPM compatible

这个 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"
}

您可以使用 structtypealias 来定义模型。

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)
}

安装

CocoaPods

要使用 CocoaPods 将 CodableGeoJSON 集成到您的 Xcode 项目中,请在您的 Podfile 中指定它

pod 'CodableGeoJSON'
Swift Package Manager

您可以使用 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 文件。