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
478 stars 134 forks source link

Update existing features in a GeoJSON style source not working #2517

Open SigmaAppdevelopment opened 1 week ago

SigmaAppdevelopment commented 1 week ago

Environment

Observed behavior and steps to reproduce

Hi, we have a symbollayer with geoJsonSource. We want to update position (geometry) of this layer every second. So we add geometry-feature with addGeoJsonSourceFeatures and update with updateGeoJsonSourceFeatures. See code below.

fun initMarker() {
    val markerSource = geoJsonSource("currentMarkerSource")
    markerSource.addGeoJSONSourceFeatures(
        listOf(
             Feature.fromGeometry(
                Point.fromLngLat(0.0, 0.0),
                null,
                "geoId"
             ),
        )
    )
    style.addSource(markerSource)
}
fun updateMarker(point: Point) {
    val feature = Feature.fromGeometry(point, null, "geoId")
    val locationSource = style.getSource("currentMarkerSource") as? GeoJsonSource
    locationSource?.updateGeoJSONSourceFeatures(features)
}

Mapbox returns error: Error: [maps-core]: {}[Style]: Failed to load source currentMarkerSource: Cannot create new geojson impl for Update/Remove feature operations

What are we missing? Also tried to set dataId on addGeoJsonSourceFeature and updateGeoJsonSourceFeature, but didn't help. Couldn't find an example.

iolandarosavoid commented 2 days ago

Hello.

I also don't understand why your code does not work, but maybe an alternative solution might be helpful. It is very similar to what you have implemented but using the FeatureCollection instead of the feature array directly.

fun addOrUpdateSource(style: Style, collection: FeatureCollection, sourceId: String) {
        val source = style.getSource(sourceId) as? GeoJsonSource?
        if (source == null) {
            style.addSource(
                geoJsonSource(sourceId).apply {
                    featureCollection(collection)
                },
            )
        } else {
            source.featureCollection(collection)
        }
    }

To get the FeatureCollection you just use the method FeatureCollection.fromFeatures(<your_features_array>) and this way it should be fine.

Anyway I am finding some weird bugs on source data update specially using the compose version of mapbox. I always have to use old methods because updates of GeoJSONData in compose source are very buggy if they are frequent. I am unsure how can I improve this and the fact that there are little documentation and examples for compose is really bad for the ones trying to use this library

SigmaAppdevelopment commented 1 day ago

Hello,

yes, what you suggest works. But we wanted to use new api because it should be much more performant...

iolandarosavoid commented 1 day ago

Probably you are already doing this but you can always check for the error in mapLoadingError event