opensciencemap / vtm

a vector-tile map library written in java - running on android, desktop and within the browser
GNU Lesser General Public License v3.0
238 stars 176 forks source link

Dynamic layering ideas #135

Open AAverin opened 9 years ago

AAverin commented 9 years ago

This is probably pretty far from being any kind of priority, but still. Trying to make some dynamic layering, I stumbled upon a problem that you have to know the layer index to remove it, and 'add' method by convention returns boolean, not index. So. Layers class being already a custom implementation of AbstractList, it would be good to have some kind of access to the layer index. My idea would be to have 'Layer' class for every new instance generate a unique identifier, and 'Layers' class store a HashMap<Long, Integer> mapping identifiers to index. That way for every new Layer there will be a way to say, which layer that is - I can have multiple building layers for every map, multiple map layers and so on. And for dynamic layering, we will always be able to modify Layers array by getting index via unique layer identifier.

Now, I'll most likely have to extend Layers, extend Map, extend Layer classes to implement this in my project. At least I'll try, but looks like some classes are final in the library. And there can also be some protected properties unaccessible outside of package. But I think this can be a neat feature for the library.

hjanetzek commented 9 years ago

For unique identifiers: Why not just keep a reference to the added Layer and use layers().remove(myLayer) ?

One thing that it is cumbersome with the current implementation is to keep the ordering when adding and removing layers. I think a good approach would be to change Layers to be a LayerGroup and let it itself be a Layer. This way one could define groups for: BaseLayer; PathLayers; BuildingLayer; LabelLayer; PoiLayers, so that one could add a PathLayer without caring where to insert it relative to other layers.

On the other hand layers are problematic for drawing 3D (or 2.5D) elements. E.g. the z-order of markers is wrong when using more than one MarkerLayer. So either one needs to wrap all elements in one layer or have layers share a common scenegraph.

AAverin commented 9 years ago

Yes, in the end I used the approach of storing references and adding/removing layers from the map, but it will be still difficult to determine which layer where (unless I do a wrapper with unique id) when, for example, you have, as you describe, multiple layer of markers by POI type and you want to enable/disable them. That's the most common thing that comes to mind, but I'm sure there can be more examples where you would want to know which layer you are removing.

I didn't yet play with multiple marker layers, but as I remember the implementation, SymbolBucket just draws a list of Bitmaps in appropriate parts of the screen, so yea, z-ordering will be a problem. I think Marker/POI is the most common thing one would want to use with the map, so it would be good to have some well-thought POILayer implementation that will deal with z-order and 3D-like display of markers (so they wouldn't remain flat when you tilt the map). That means that there can be a single scenegraph holding all markers, but implementation would allow to still have multiple marker layers on top of it. And library users would extend not just ItemizedLayer+MarkerItem+MarkerRenderer(which I had to extend for my markers already to support selected state), but some smarty POI layer.