我的应用程序将数据(包括坐标和其他信息)存储在本地数据库中。由于数据点的数量,该应用程序使用集群在 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
...
上面的代码被简化以帮助更清楚地说明这个概念。使用 MGLPoint 数组是因为数据存储在 DB 中,因此我们没有 GeoJSON 文件或 URL。使用 MGLShapeSource 是因为需要集群,这就是我在示例中找到的。使用将“特征”作为参数的 MGLShapeSource 构造函数,因为这是与我拥有的数据匹配的构造函数。常规标记层设置为根据 iconScale 中“标记”属性的值显示不同大小的图标。
在运行期间,“marked”属性的值会发生变化(例如,当一个标记被点击时),相应的图标的大小需要更新以反映“marker”值的变化。但是,我无法弄清楚如何更改标记属性值。MGPShapeSource 仅显示对形状和 URL 的访问,这两者都不是我初始化源的特征数组。我需要访问构建源的特征数组,更改标记值,并更新标记图标。
我考虑过在每次数据更改时重新制作源。但是由于涉及的标记数量,这将表现不佳。另外,我相信我还需要重新制作所有样式层,因为它们是用实际的源对象构建的,这会使性能变得更糟。
我需要帮助弄清楚如何在运行时更改 MGLShapeSource 中 MGLPointFeature 的属性值并更新地图。