2

There are different type markers on a Mapbox SDK Android map. I'm using clustering for the source of the markers with custom filters that show the count of the different types.

      let geoJsonOptions = new this.mapboxSdk.style.sources.GeoJsonOptions()
        .withCluster(true)
        .withClusterMaxZoom(13)
        .withClusterRadius(51);

      for(let type in this.ChecklistAttributes){
        geoJsonOptions.withClusterProperty(type,
          this.mapboxSdk.style.expressions.Expression.literal("+"),
          this.mapboxSdk.style.expressions.Expression.raw('["case",["==",["get","type"],"'+type+'"],1,0]')
        )
      }

      //Add GeoJson Source
      this.ChecklistMarkersSource = new this.mapboxSdk.style.sources.GeoJsonSource("checklist-markers-source",
        JSON.stringify(this.ChecklistsGeoJson),
        geoJsonOptions
      );
      style.addSource(this.ChecklistMarkersSource);

This works as expected when I query the source features I'm getting the cluster data with the different counts.

I would like to show a donut chart based on the number of different types, but I can't find the way how to draw custom clusters and add to the map.

Here's a ready to use example for mapbox gl-js, but this uses HTML/SVG which is not supported by the Mapbox Android SDK or I don't find the way how to do it:

https://docs.mapbox.com/mapbox-gl-js/example/cluster-html/

I've tried to generate raster images and add them as an Image source layer, but this feels extremely resource taking and bad approach. Also, I don't know how to handle the size of the images during zooming in-out.

Peter
  • 748
  • 6
  • 20

1 Answers1

0

I also had issues with clusters and specifically with Mapbox Android's withClusterProperty field. This is what worked for me.

To create a cluster property named myClusterProperty - which adds 1 if a feature property myFeatureProperty equals "red" and 0 otherwise:

GeoJsonOptions()
    .withClusterProperty("myClusterProperty",
        sum(accumulated(), get("myClusterProperty")),
            switchCase(eq(get("myFeatureProperty"), "red"),
                       literal(1), literal(0)))

And for creating the cluster circle layer:

  1. Add the cluster source data
  2. Add the circle layer that points to the source data
  3. Filter the circle layer to only show for clusters

To add the source data:

val mySourceData = GeoJsonSource("mySourceData",
            FeatureCollection.fromFeatures(emptyList()),
    GeoJsonOptions().withCluster(true).withClusterProperty(...)

To add the circles for the cluster:

// "point_count" is the Mapbox built-in property that only clusters have 
val isInCluster = has("point_count") 

val circleLayer = CircleLayer("myClusterLayerId", "mySourceData")
circleLayer.setProperties()
circleLayer.setFilter(isInCluster)

addLayer(circleLayer)

To filter this cluster by your newly created cluster property myClusterProperty, replace circleLayer.setFilter(isInCluster) with:

val hasCountAtLeastOne = gte(toNumber("myClusterProperty"), literal(1))
circleLayer.setFilter(all(isInCluster, hasCountAtLeastOne))
zetatlas
  • 320
  • 2
  • 8