composable maps based on `ipywidgets`
In xarray-contrib/xdggs#183 I'm trying to find a way to compose maps, either by taking all layers and adding them to a new map (this does not yet take data transfer into account), or by arranging multiple maps into a ipywidgets.GridBox.
This works pretty well already, but I'm wondering if it would make sense to upstream this into lonboard? If not, I'd be willing to open a PR to add this to the "ecosystem" page (if that's the right place).
What are you trying to achieve here? Can you expand on what you mean by "compose maps"? Do you just mean a side-by-side view?
side-by-side is the second use-case (which I'm implementing using GridBox) but the most important one is combining two maps such that the layers are displayed in the same map.
Ideally, I'd have a separate container that delays data transfers until the map is displayed (so that data transfer is lazy), but I have not yet figured out how the protocol used by ipywidgets / anywidget to interact with jupyterlab works.
side-by-side is the second use-case
I think side-by-side might become in scope for handling on the JS side natively
the most important one is combining two maps such that the layers are displayed in the same map
Sorry I still don't understand. How is this different from Map([*existing_map1.layers, *existing_map2.layers])?
I have a wrapper in xdggs that returns one Map instance per dataset containing one or more layers. If I have multiple datasets, I get multiple Map instances that I may want to overlay (which happens by adding all layers from the other maps to the first):
map1 = ds1["var1"].dggs.explore()
map2 = ds2["var2"].dggs.explore()
# overlay map1 with layers from map2
This may be the due to the abstraction of returning map objects, and so an API like:
map = lonboard.Map()
ds1["var1"].dggs.explore(map=map) # calls map.add_layer
ds2["var2"].dggs.explore(map=map)
may be better, but what I came up with is hvplot-style combinations:
ds1["var1"].dggs.explore() & ds2["var2"].dggs.explore()
What I was wondering is whether this is something that could live within lonboard.Map (whatever the API), or whether I should continue using a wrapper object.
I think side-by-side might become in scope for handling on the JS side natively
That could be neat (especially if we can do the linking of maps client-side and avoid the client-server roundtrip delay), but also would mean that we'd need to have a python container that allows addressing the individual map objects / layers.
need to have a python container that allows addressing the individual map objects / layers
That'll probably be a View, which corresponds to an underlying deck.gl view. A Map is made of one or more views, while layers are associated to one or more views.
I have a wrapper in
xdggsthat returns oneMapinstance per dataset containing one or more layers.
I think this is the wrong abstraction. A Map is something that is explicitly viewable and rendered. If you're returning data, not an end visualization, you should be returning layer objects, which the user can compose into a Map.
there's two different needs here:
- visualizing one or more layers returned by
explore. This we want to directly view / render - returning a collection of layers that can be combined with other collections of layers to form a map
I'm not sure how to best combine the two without making the API more verbose, or creating an additional layer that abstracts away the difference.
This may be the due to the abstraction of returning map objects, and so an API like:
map = lonboard.Map() ds1["var1"].dggs.explore(map=map) # calls map.add_layer ds2["var2"].dggs.explore(map=map)may be better
FWIW, the geopandas explore method allows you to pass in a map object, where layers get added onto the map.
ds1["var1"].dggs.explore() & ds2["var2"].dggs.explore()
I don't think supporting and or & are obvious enough for what should happen on a Map.
We already have Map.add_layer, and you can pass in a Map to that API.