Search code examples
mapboxmapbox-android

How to show/hide icon for a SymbolLayer when clustering is triggered


I have two icon sets for a symbol-layer. I want one icon to be visible when a layer is not clustered and when cluster is triggered I want to show a different icon for the same layer. The problem I have is that the single icon is still visible beneath the cluster icon, I want the single icon to be hidden when clustered. How do I add this flag?

To show a new icon for clusters I use:

// Add Source
val options = GeoJsonOptions().withCluster(true).withClusterRadius(30)
val stopSource = GeoJsonSource(sourceId, collection, options)
style.addSource(stopSource)

// Add single layer
val singleLayer = SymbolLayer(singleLayerId, sourceId).apply {
                       withProperties(
                           PropertyFactory.iconImage(singleLayerId),
                           PropertyFactory.iconAllowOverlap(true)
                       )
                   }

style.addImage(singleLayerId, singleIcon)
style.addLayer(singleLayer)


// Add cluster layer
val clusterLayer = SymbolLayer(clusterLayerId, sourceId).apply {

                       setFilter(eq(get("cluster"), true))

                       withProperties(
                           PropertyFactory.iconImage(clusterLayerId),
                           PropertyFactory.iconAllowOverlap(true)
                       )
                   }

style.addImage(clusterLayerId, clusterIcon)
style.addLayer(clusterLayer)

This is working but only for clusters. The single icon is still visible.

I use the flag setFilter(eq(get("cluster"), true)) by pure guess since I looked at a iOS implementation that has the same requirement, and it seems to be working as intended.

If I use setFilter(eq(get("cluster"), false)) for the single layer, the icon is not visible at all.

iOS uses a flag, like so:

Single layer icon: layer.predicate = NSPredicate(format: "%K != YES", "cluster")

Cluster layer icon: layer.predicate = NSPredicate(format: "%K == YES", "cluster")

My hopes where setFilterwould be the equivalent, but its not working.


Solution

  • I found the issue, which was related to the overlapping property.

    PropertyFactory.iconAllowOverlap(true)

    Setting this to false for my single-layer fixed it.