Wil*_*ill 3 mapbox mapbox-marker mapbox-ios
我的应用程序将数据(包括坐标和其他信息)存储在本地数据库中。由于数据点的数量,该应用程序使用聚类在 iOS 上使用 Mapbox 显示数据。一些标记样式基于数据,这些数据可能会在运行时发生变化。地图设置为:
// fetch data from DB
let dataArray: [MyData] = fetchData()
// build features from data array
var features = [MGLPointFeature]()
dataArray.forEach({ (data) in
let feature = MGLPointFeature()
feature.identifier = data.id
feature.coordinate = CLLocationCoordinate2D(latitude: data.lat, longitude: data.lng)
// our attributes
feature.attributes = [
"amount": data.amount
"marked": false
]
features.append(feature)
})
// make and add source
let source = MGLShapeSource(identifier: "MySourceId", features: features, options: [
.clustered: true
])
style.addSource(source)
// regular marker layer
let layer = MGLSymbolStyleLayer(identifier: "unclustered", source: source)
layer.iconImageName = NSExpression(forConstantValue: "MyIcon")
layer.text = NSExpression(forKeyPath: "amount")
layer.iconScale = NSExpression(forMGLConditional: NSPredicate(format: "%@ == true", NSExpression(forKeyPath: "marked")), trueExpression: NSExpression(forConstantValue: 2.0), falseExpression: NSExpression(forConstantValue: 1.0))
layer.predicate = NSPredicate(format: "cluster != YES")
style.addLayer(layer)
// point_count layers
...
Run Code Online (Sandbox Code Playgroud)
上面的代码被简化,以帮助更清楚地说明这个概念。使用 MGLPoint 数组是因为数据存储在 DB 中,所以我们没有 GeoJSON 文件或 URL。使用 MGLShapeSource 是因为需要聚类,这就是我在示例中发现的。使用以“功能”作为参数的 MGLShapeSource 构造函数,因为它与我拥有的数据相匹配。常规标记层设置为根据 iconScale 中“marked”属性的值显示不同大小的图标。
在运行时,“marked”属性的值可能会发生变化(例如,当标记被点击时),并且需要更新相应图标的大小以反映“marker”值的变化。但是,我无法弄清楚如何更改标记属性值。MGPShapeSource 只显示对形状和 URL 的访问,这两个都不是我用来初始化源的 features 数组。我需要访问构建源的 features 数组,更改标记值,并更新标记图标。
我曾考虑过在每次数据更改时重新制作源。但是由于涉及的标记数量众多,这将表现不佳。另外,我相信我还需要重新制作所有样式层,因为它们是用实际的源对象构建的,这会使性能变得更糟。
我需要帮助弄清楚如何在运行时更改 MGLShapeSource 中 MGLPointFeature 的属性值并更新地图。
我没有找到接近我所希望的解决方案,但我确实找到了比每次都重新制作所有东西更好的方法。
在要素属性值更改时,我没有重新制作所有内容,包括源和所有图层,而是使用 MGLPointFeature 数组更新源的形状。我确实必须重新制作 MGLPointFeature 数组,但随后我可以使用此数组制作 MGLShapeCollectionFeature 并将其设置为现有源的形状。这样,现有层也不需要更改。就像是:
// build features from data array
...same as in original question, but with updated feature.attributes values as needed.
// look for existing source and update it if found; otherwise, make a new source
if let existingSource = style.source(withIdentifier: "MySourceId") {
// update data
guard let shapeSource = existingSource as? MGLShapeSource else {
throw <some_error>
}
shapeSource.shape = MGLShapeCollectionFeature(shapes: features)
} else {
// make new (same as original post)
let source = MGLShapeSource(identifier: "MySourceId", features: features, options: [.clustered: true])
style.addSource(source)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
344 次 |
| 最近记录: |