Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Interleaving Data and Basemap Layers #442

Answered by kylebarron
diehl asked this question in Q&A
Discussion options

One of the downsides of most, if not all, Python-based geospatial visualization libraries is that it is impossible to insert one or more data layers into the basemap such that place names are on top of the data layers. This is critical in my view for maintaining geospatial context. Is it possible in lonboard to perform this interleaving? I sure hope so! Scanning through the documentation, it is not clear to me how this would be done. Rather it seems like all data layers are stacked on top of the basemap, forcing one to rely on opacity to maintain some level of geospatial context.

You must be logged in to vote

It's not possible today, though it could be an option in the future. It depends on some architectural decisions that haven't been set in stone yet. The following is a braindump on the options here:

Most JS mapping libraries focus primarily either on the basemap or on the data visualization. Mapbox, Maplibre, Google Maps JS, Leaflet, OpenLayers... I'd say that all of these have a primary focus on the basemap. Sure, it's possible to render small amounts of data or tiled layers in these tools, but they don't aim for performant large-scale data visualization. Deck.gl is the opposite; it focuses exclusively on the data visualization but doesn't attempt to render a basemap at all.

The default a...

Replies: 1 comment 10 replies

Comment options

It's not possible today, though it could be an option in the future. It depends on some architectural decisions that haven't been set in stone yet. The following is a braindump on the options here:

Most JS mapping libraries focus primarily either on the basemap or on the data visualization. Mapbox, Maplibre, Google Maps JS, Leaflet, OpenLayers... I'd say that all of these have a primary focus on the basemap. Sure, it's possible to render small amounts of data or tiled layers in these tools, but they don't aim for performant large-scale data visualization. Deck.gl is the opposite; it focuses exclusively on the data visualization but doesn't attempt to render a basemap at all.

The default approach is to render Maplibre on the bottom with Deck above it, using two separate WebGL contexts. This suffers from the problem that the entire basemap is hidden behind whatever Deck renders. I'd say there are three main options to solve this, outlined below

Render Deck and Maplibre into the same WebGL context

Mapbox/Maplibre expose a "custom style layer" where a user can write WebGL that gets added to the same context as Maplibre is already using. Deck.gl implements this with MapboxOverlay, so you can render some deck layers in the same context as Maplibre.

However this suffers from having "two cooks in the kitchen", where each tries to render in the same canvas but neither is truly aware of the other. So for example in this demo you can see poor polygon rendering when panning as the buildings drawn by Mapbox and the radius drawn by Deck z-fight.

Another downside here is that Maplibre needs to be the parent and that Deck needs to be the child. This means that Deck is forced into all of Maplibre's constructs. It can only support Web Mercator. It can't use WebGPU. Deck can't manage view state itself. More discussion in #437.

Render multiple copies of Maplibre

Another option, which I believe kepler.gl uses, is to render a Maplibre sandwich, where you render Maplibre above and below Deck: maplibre - deck - maplibre. So you render most of the basemap below the Deck context and the text/label layers above the deck context.

This is pretty resource intensive because now you have three WebGL/WebGPU contexts! Additionally you always have to keep all three map views in sync. This is less tied to Maplibre because deck is drawing into its own canvas, so you won't get z-fighting like with MapboxOverlay. But it still can't use alternate projections.

Additionally, this requires intricate knowledge of the Maplibre style being used for the basemap because you have to know which layer ids to render in the lower basemap and which in the upper basemap.

Render some basemap context in deck

A third option is to render some basemap context in deck.gl. Deck.gl has a TileLayer and an MVTLayer, which can render things like text as part of the Deck canvas. This would also be necessary if/when we try to support alternate projections, as we couldn't use Maplibre for alternate projections.

But this has the downside of having to re-implement basemap properties in deck.gl, which may not be trivial. But if it's just light basemap context like admin boundaries and text labels, maybe that's a good approach.


Overall, interleaving data with the basemap is a really hard problem, which is why not many tools have tried to solve it.

You must be logged in to vote
10 replies
Comment options

@giswqs Can Leafmap be integrated into Shiny for Python? I need the capability to embed a map into a Shiny application for interactive analysis which makes lonboard and the Python bindings to MapLibre very attractive to me.

Comment options

I am not an R user, but I did make a simple shiny-maplibre app. Leafmap builds upon MapLibre, so I guess it should work as well. However, I am not quite sure if some leafmap dependencies may cause troubles.
https://huggingface.co/spaces/giswqs/shiny-maplibre

Comment options

@giswqs I thought Shiny was exclusively for R until I ran across this: https://shiny.posit.co/py/ And it was precisely because of lonboard's compatibility with Shiny for Python that I discovered it.

Comment options

Back to the original comment:

@kylebarron FYI - Turns out the Python bindings to MapLibre developed by Stefan Kuethe support this interleaving that we discussed. eodagmbh.github.io/py-maplibregl/examples/layer_order

I will note that this is different than the topic of this discussion thread because those layers are rendered by Maplibre. Mapbox/Maplibre have a small selection of layers that they can render directly, and since data and basemap are rendered by the same application, it's much easier for them to interleave into the basemap. But Maplibre doesn't have the breadth of visualization layers offered by deck.gl, nor does it have a binary data API, which is what gives Lonboard its performance.

If you look at the deck.gl example of that library the deck.gl layer is still rendered strictly on top of the basemap and the entire basemap is occluded.

I'm starting to have more time available to work on Lonboard again, so this functionality might able to be on the roadmap. But we have to figure out a good API for users who don't want to think about the names of the basemap layers (such as that example you linked, which uses before_id as an argument).

Comment options

@kylebarron If you have a look here, the library supports interleaving DeckGL layers into the basemap with the beforeId property.

Answer selected by diehl
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /