Clustering annotations with Mapbox

I did some research on this not too long ago and it didn't seem to be possible on iOS. Here is the suggestion on github that is still open. Here is another issue about how it wasn't mentioned in the documentation but has since been added.


Does anyone have a working example of Mapbox clustering with MGLAnnotations rather than geoJSON source file?

Given a Style

let style: MGLStyle

1) Build/Get your [MGLPointFeature]

2) Build a MGLShapeSource

let source = MGLShapeSource(identifier: "YOUR_IDENTIFIER_A", features: YOUR_ MGLPointFeature_ARRAY, options: [.clustered: true, .clusterRadius: YOUR_WIDTH])
style.addSource(source)

3) Build a style for the marker when it's not clustered

let markerLayer = MGLSymbolStyleLayer(identifier: "YOUR_IDENTIFIER_B", source: source)
    markerLayer.iconImageName = NSExpression(forConstantValue: "MARKER_IDENTIFIER")
    markerLayer.predicate = NSPredicate(format: "cluster != YES")
style.setImage(UIImage(named: "MARKER_IMAGE")!, forName: "MARKER_IDENTIFIER")

4) Build a style for the cluster

let clusterLayer = MGLSymbolStyleLayer(identifier: "YOUR_IDENTIFIER_C", source: source)
    clusterLayer.textColor = NSExpression(forConstantValue: UIColor.white)
    clusterLayer.textFontSize = NSExpression(forConstantValue: NSNumber(value: Double(YOUR_WIDTH) / 2.5))
    clusterLayer.iconAllowsOverlap = NSExpression(forConstantValue: true)
    clusterLayer.textOffset = NSExpression(forConstantValue: CGVector(dx: 0, dy: -0.2))
    clusterLayer.predicate = NSPredicate(format: "cluster == YES")
    style.setImage(UIImage(named: "CLUSTER_IMAGE")!, forName: "CLUSTER_IDENTIFIER")

5) You can use Stops features. This will let you change cluster image based on clustering count change.

let stops = [
        10: NSExpression(forConstantValue: "CLUSTER_IMAGE"),
        50: NSExpression(forConstantValue: "ANOTHER_CLUSTER_IMAGE")
    ]

6) Use expressions to set each cluster's image based on defined stops and display the point count over the corresponding image

let defaultShape = NSExpression(forConstantValue: "CLUSTER_IDENTIFIER")
    clusterLayer.iconImageName = NSExpression(format: "mgl_step:from:stops:(point_count, %@, %@)", defaultShape, stops)
    clusterLayer.text = NSExpression(format: "CAST(point_count, 'NSString')")

7) Add layers to the Style

style.addLayer(markerLayer)
style.addLayer(clusterLayer)

Tags:

Ios

Swift

Mapbox