mapbox / mapbox-maps-android

Interactive, thoroughly customizable maps in native Android powered by vector tiles and OpenGL.
https://www.mapbox.com/mobile-maps-sdk
Other
466 stars 131 forks source link

setFeatureState not updating SymbolLayer #1642

Closed BryanJonesRichardson closed 1 year ago

BryanJonesRichardson commented 2 years ago

I'm trying to have map icons that change color when they are clicked. When I use setFeatureState and subsequently call getFeatureState the output in my log shows that the state map for the Feature has been updated correctly. However, the map icons on SymbolLayer never get updated. However, circles on CircleLayer respond to featureState changes and update as expected. I followed this code example: https://github.com/mapbox/mapbox-maps-android/blob/main/app/src/main/java/com/mapbox/maps/testapp/examples/featurestate/FeatureStateActivity.kt

My call to setFeatureState

featureId?.let { id ->
                        map?.setFeatureState(
                            SOURCE_ID, UNCLUSTERED_LAYER_ID, id,
                            Value(hashMapOf(ICON_SELECTED to Value(!assetSelected)))
                        )

                        map?.getFeatureState(SOURCE_ID, UNCLUSTERED_LAYER_ID, id) { stateMap ->
                            Timber.d("getFeatureState: ${stateMap.value!!}")
                        }

                        lastFeatureId = id
                    }

How i add icon to SymbolLayer. This is not responding to featureState updates.

val unclustered = SymbolLayer(UNCLUSTERED_LAYER_ID, SOURCE_ID)
        unclustered.iconImage(
         switchCase {
                boolean {
                    featureState {
                        literal(ICON_SELECTED)
                    }
                    literal(false)
                }
                get(ICON_IMAGE_SELECTED) //true
                get(ICON_IMAGE) // false
            }
        )
        loadedMapStyle.addLayer(unclustered)

How i add circle to CircleLayer. This is responding to featureState updates.

val unclustered2 = CircleLayer(UNCLUSTERED_LAYER_ID, SOURCE_ID)
        unclustered2.circleRadius(
         switchCase {
                boolean {
                    featureState {
                        literal(ICON_SELECTED)
                    }
                    literal(false)
                }
                literal(2.0) //true
                literal(1.0) // false
            }
        )
        loadedMapStyle.addLayer(unclustered2)

What am i missing?

ank27 commented 2 years ago

@BryanJonesRichardson , the symbol layer icon-image does not support feature state, but circle-radius of circleLayer does supports feature state property, and that's why you can see the result with circle-radius but not with icon-image. In order to achieve the result, the property needs to support feature-state.

Please see the documentation icon-image : https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#layout-symbol-icon-image and circle-radius : https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#paint-circle-circle-radius.

iadcialim commented 1 year ago

@BryanJonesRichardson , the symbol layer icon-image does not support feature state, but circle-radius of circleLayer does supports feature state property, and that's why you can see the result with circle-radius but not with icon-image. In order to achieve the result, the property needs to support feature-state.

Please see the documentation icon-image : https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#layout-symbol-icon-image and circle-radius : https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#paint-circle-circle-radius.

In order to achieve the result, the property needs to support feature-state. @ank27 How to do this in Android code? Can you share an example? The link you provided does not tell what to do next. Thanks