tangram-es icon indicating copy to clipboard operation
tangram-es copied to clipboard

Marker ids are invalidated after changing map scene

Open dgngulcan opened this issue 6 years ago • 2 comments

After changing map scene, previously added marker ids are invalidated and I'm getting the exception below when I try to hide markers.

I see that in MapController, loadSceneFile() is calling removeAllMarkers(), however, markers are still visible.

Steps to reproduce 1- load scene 2- add marker 3- load another scene 4- hide the marker

Exception:

java.lang.RuntimeException: Tried to perform an operation on an invalid id! This means you may have used an object that has been disposed and is no longer valid.
                                                                           at com.mapzen.tangram.MapController.checkId(MapController.java:1078)
                                                                           at com.mapzen.tangram.MapController.setMarkerVisible(MapController.java:1143)
                                                                           at com.mapzen.tangram.Marker.setVisible(Marker.java:185)

Expected behavior: Marker id to be consistent after loading a new scene.

Environment: Android

dgngulcan avatar Dec 28 '17 16:12 dgngulcan

So if this can not be solved in C++ code for one or the other technical reason, the way this could be solved in the Java Code would be to have the Marker class keep all properties that can be set on it (drawOrder, drawable, bitmap etc. pp.) in private fields additionally to calling through to the MapController. When the scene is reloaded and the marker (id) has been invalidated, it won't call through to the MapController anymore but just set the info into the private field. Then, when the scene has successfully reloaded, the marker class will be "revalidated" and can then call through its properties to the MapController.

This is the solution I am implementing right now in a wrapper class around the MapController. The downside of this approach as opposed to a solution in the core (C++) is that the marker IDs are not stable.

westnordost avatar Jan 11 '20 17:01 westnordost

So I am not sure if this is a bug or not. But since data layers are not invalidated, it would make a lot of sense if markers were also not invalidated. Right now, it is necessary for every user of the marker interface to keep track of all the markers and all the information put into markers to be able to recreate the markers after a scene update / load scene.

So for the time being, I created a convenience wrapper around the marker interface to take care of exactly that: https://github.com/westnordost/StreetComplete/blob/new_tangram/app/src/main/java/de/westnordost/streetcomplete/map/tangram/MarkerManager.kt

It seems like a lot of code, but most of it is wrapping the Tangram Marker into another Marker class that keeps all the properties that can be set on a Tangram Marker in private fields. Then once the Tangram markers are invalidated, setting properties on the wrapped marker will not call through to Tangram anymore but will catch up on it when the scene is available again.

Nevermind the pickMarker and suspend stuff in the linked file, these are just Kotlin-specific things that I also included in the convenience wrapper (uses coroutines instead of callbacks).

westnordost avatar Jan 17 '20 12:01 westnordost