Ios 在创建Mapbox MGLShape之前验证geojson
我正在使用iOS Mapbox SDK从来自第三方API的goejsonIos 在创建Mapbox MGLShape之前验证geojson,ios,swift,mapbox,mapbox-ios,Ios,Swift,Mapbox,Mapbox Ios,我正在使用iOS Mapbox SDK从来自第三方API的goejsonFeatureCollection数据创建一个MGLShapeCollectionFeature guard let feature = try? MGLShape(data: jsonData, encoding: String.Encoding.utf8.rawValue) as? MGLShapeCollectionFeature else { print("Could not cast to specifie
FeatureCollection
数据创建一个MGLShapeCollectionFeature
guard let feature = try? MGLShape(data: jsonData, encoding: String.Encoding.utf8.rawValue) as? MGLShapeCollectionFeature else {
print("Could not cast to specified MGLShapeCollectionFeature")
return
}
问题是,API有时返回无效的geojson,其中单个功能不包含有效坐标(见下文),初始化MGLShape
失败,原因是“NSInvalidArgumentException”,原因是:“多点必须至少有一个顶点。”
,这是正确的
除了手动解析和修复geojson外,是否有其他方法可以过滤掉功能集合中的无效功能
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"icaoId": "KBOS",
"airSigmetType": "AIRMET",
"hazard": "IFR"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
]
]
}
},
{
"type": "Feature",
"properties": {
"icaoId": "KSLC",
"airSigmetType": "AIRMET",
"hazard": "IFR"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-106.63,
49.06
],
[
-104.12,
48.95
],
[
-104.17,
44.8
],
[
-106.91,
46.38
],
[
-106.63,
49.06
]
]
]
}
}
]
}
一种可能的解决方案是使用Codable
将JSON解码为结构,过滤空项并将对象编码回:
struct FeatureCollection : Codable {
let type : String
var features : [Feature]
}
struct Feature : Codable {
let type : String
let properties : Properties
let geometry : Geometry
}
struct Properties : Codable {
let icaoId, airSigmetType, hazard : String
}
struct Geometry : Codable {
let type : String
let coordinates : [[[Double]]]
}
do {
var result = try JSONDecoder().decode(FeatureCollection.self, from: jsonData)
let filteredFeatures = result.features.filter{$0.geometry.coordinates != [[]]}
result.features = filteredFeatures
let filteredData = try JSONEncoder().encode(result)
guard let feature = try? MGLShape(data: filteredData, encoding: String.Encoding.utf8.rawValue) as? MGLShapeCollectionFeature else {
print("Could not cast to specified MGLShapeCollectionFeature")
return
}
} catch {
print(error)
}
正如您所建议的,我自己进行了筛选,并在数据上编写了此扩展
extension Data {
func removeEmptyCoordinates() throws -> Data {
guard var geojson = try JSONSerialization.jsonObject(with: self, options: []) as? [String: Any] else {
return self
}
fix(geojson: &geojson,
processFeatureIf: NSPredicate(format: "geometry.type == 'Polygon'"),
keepFeatureIf: NSPredicate(format: "%K[0][SIZE] >= 2", "geometry.coordinates"))
return try JSONSerialization.data(withJSONObject: geojson, options: [])
}
private func fix(geojson: inout [String: Any], processFeatureIf: NSPredicate, keepFeatureIf: NSPredicate) {
guard let type = geojson["type"] as? String, type == "FeatureCollection" else {
// "Not a FeatureCollection"
return
}
// "No features to fix"
guard let features = geojson["features"] as? [[String: Any]] else { return }
let filtered = features.filter { feature in
if !processFeatureIf.evaluate(with: feature) {
// not processing
return true
}
return keepFeatureIf.evaluate(with: feature)
}
geojson["features"] = filtered
}
}
MGLShape
似乎没有这样做。你可能需要自己做。将JSON数据转换为Struct/Swift对象,执行过滤器以删除空坐标特性,然后将其重新转换为数据。这可能会起作用,但问题是形状有许多属性,我不想将它们解码为类型安全模型,但我希望它们可以通过MapboxMGLFeature
属性
访问。使用Codable