deck.gl icon indicating copy to clipboard operation
deck.gl copied to clipboard

Mapbox/Maplibre elevation compatibility

Open Baseform opened this issue 3 years ago • 22 comments

Description

We're using interleaved terrain rendering with Deck and Mapbox/Maplibre. There is a mismatch of elevation on renders - probably due to camera positioning between Deck and the others

Expected Behavior

I'd expect to see an overlap. WebMercatorViewport docs mention compatibility of default parameters

Steps to Reproduce

This codepen allows for toggling between both deck and the new Maplibre Terrain 3D versions. We've also tested with Mapbox with the same results.

[https://codepen.io/diogovit/full/wvyNjwW]

Environment

Baseform avatar Jun 20 '22 13:06 Baseform

Can you help me understand how this is going to be used? deck.gl does not support offseting/overlaying layers over a base terrain (it's something we are exploring, but not yet implemented), so even if the camera movement matches that of mapbox/maplibre, the data positions may not be very useful.

With that said, the mapbox module (MapboxLayer, MapboxOverlay) should definitely make an effort to match the camera matrices. I do not think they support terrain in the base map right now.

On a high level, deck.gl's TerrainLayer works just like other layers - it renders in a self-contained context and does not affect the camera control or any other layers. I agree that this is something we should address, probably by introducing a new operation. Whether deck's default behavior should be identical to that of Mapbox's is open for discussion.

@kylebarron @chrisgervang

Pessimistress avatar Jun 20 '22 21:06 Pessimistress

@Pessimistress

We have developed a rich visualization solution for water utility network at baseform.com. This includes mapping geojson/mvt infrastructure (pipes, buildings, valves and others), as well as visualizations of hydraulics (similar to trips layer) and aggregation analytic quantities, from population, to consumer usage, to water quality and water flows. The non-deck based solution is presented here: https://baseform.com/np4/papps0.html or https://baseform.com/np4/papps1.html OSM based vector maps as an alternative to satellite imagery are available as background.

For quite a while now we've been migrating from OL (and from our own threejs 3D viz) to deck and it's finally production ready. Besides being faster, more elegant, scalable and precise in drawing, deck.gl allows for near seamless transition from 2D to 3D. 99% of the code is deck.gl; the exception being vector streets for which we're using maplibre. The new terrain 3D feature of maplibre https://github.com/maplibre/maplibre-gl-js/pull/165would allow us to have that as a 3D backdrop to our maps.

Note: 3D is particularly interesting for water and wastewater networks as gravity and pressure drive hydraulics, meaning that it's not just a nice visualization but actually useful in interacting with how water flows and networks work.

In the codepen I chose to use terrain layers for both deck.gl and maplibre to demo the difference in rendering/camera position/elevation/? this disconnect is the same using any other type of layers - my guess is that it is more related to the WebMercatorViewport. I noted that in the docs, a reference to map box is made: "altitude has a default value that matches assumptions in mapbox-gl".

I'm available to share what we have on a web call if that makes sense to you - we'd also be open to present, reference or showcase as a commercial application of the technology.

Baseform avatar Jun 21 '22 07:06 Baseform

As far as I can tell, Mapbox does not expose the center elevation with any public API. Map has a queryTerrainElevation method but is not the same as the altitude it uses to target the camera. I just glanced at the Maplibre implementation and it does not seem to expose any API for this purpose either.

If deck.gl is to support Mapbox/Maplibre terrains, feature requests need to be submitted to both libraries to properly expose all the parameters that they use to calculate the viewport matrices. deck.gl does sometimes employ hacks in order to work better with a base map provider. However, considering the Mapbox/Maplibre code bases have diverged significantly, any usage of private API would be too many moving targets for us to chase.

Pessimistress avatar Jun 23 '22 06:06 Pessimistress

Feel free to submit a pull request to MapLibre GL JS if you need some more public API...

wipfli avatar Jun 23 '22 12:06 wipfli

Tracking the mapbox-gl request here, though it's much more complicated than maplibre. https://github.com/mapbox/mapbox-gl-js/issues/12040

Pessimistress avatar Jun 24 '22 23:06 Pessimistress

Can you help me understand how this is going to be used? deck.gl does not support offseting/overlaying layers over a base terrain (it's something we are exploring, but not yet implemented), so even if the camera movement matches that of mapbox/maplibre, the data positions may not be very useful.

@Pessimistress If I read your comment well, it is likely that deck.gl will support presenting multiple layers at different heights (e.g. a GridLayer on surface level and another one at an underground level). Is there any PR or issue that you could track for this feature.

harisbal avatar Jun 29 '22 09:06 harisbal

@harisbal This issue is about the @deck.gl/mapbox module. My comment said that we don't automatically snap data to the terrain surface. You can already render layers at any elevation of your choice.

Pessimistress avatar Jul 01 '22 16:07 Pessimistress

@Pessimistress There seems to be a bug in the deck.gl terrain layer that should be fixed before synchronization is attempted. When you zoom in and out there is around zoom level 12.1 a sudden jump in elevation.

Here is an example only with deck.gl (try zooming out a bit and see the terrain get more flat): https://stackblitz.com/edit/typescript-sguv1u?file=index.ts

In comparison, it can be seen that zoom in/out doesn't give the same jump in MapLibre with the exact same terrain data (not synching camera here): https://stackblitz.com/edit/typescript-bgbhil?file=index.ts

The zoom issue in deck.gl terrain persist if it i.e. is added as a MapboxOverlay from @deck.gl/mapbox in MapLibre, which might hint to where the bug doesn't come from: https://stackblitz.com/edit/typescript-hxvo9j?file=index.ts

birkskyum avatar Aug 31 '22 11:08 birkskyum

Many deps were getting a bit old - Here is an updated version where it's possible to swap between maplibre / deckgl terrain: https://stackblitz.com/edit/vitejs-vite-qgwfna?file=index.html

birkskyum avatar May 27 '23 18:05 birkskyum

Any progress on this?

I came to ask for this feature too. We are using MapboxOverlay and it would be great if the deck layers would automatically match the terrain elevation.

I thought the terrain extension would work but apparently it doesn't either.

I prepared a code sandbox with the use of MapboxOverlay and TerrainExtension if you are curious about it. https://codesandbox.io/s/deck-layers-with-3d-927gh8?file=/src/App.tsx

ssaornil avatar Aug 03 '23 10:08 ssaornil

@ssaornil If you change interleaved to false you can see that the layer does show up. When using interleaved mode there are often issues regarding GL context state handoff. Feel free to open a bug.

Pessimistress avatar Aug 03 '23 19:08 Pessimistress

The TerrainExtension is only supported within deck.gl since there isn't a public api in Maplibre/Mapbox to access the elevation in a performant way, afaik (there is a function to perform one-off lookups, but this could only work for offset and performance is a big question mark).

So, maplibre terrain layer won't work as a target for draping or offsetting, so you'll continue to need to use a deck.gl TerrainLayer or Tiles3DLayer as the target.

chrisgervang avatar Aug 03 '23 21:08 chrisgervang

There is a terrain bug in Deck.gl. Solving that might help on this issue. In this example, the terrain "jumps"/changes the elevation when zooming out just a bit (at exactly zoom 12): https://deck.gl/examples/terrain-layer . Increasing the rScaler will exaggerate it further.

birkskyum avatar Oct 24 '23 23:10 birkskyum

I can reproduce the "jump"

I wonder if this jump could have anything to do with #1937, our mixed 32/64 bit mode. If I recall, that changes between modes at a particular zoom level.

What zoom level is it jumping?

chrisgervang avatar Oct 24 '23 23:10 chrisgervang

@chrisgervang consistently at zoom = 12 for that data, and the stackblitz example i shared above. Both utilize RGB DEM tiles.

It doesn't happen in this black/white png example though : https://deck.gl/docs/api-reference/geo-layers/terrain-layer

birkskyum avatar Oct 25 '23 00:10 birkskyum

https://github.com/visgl/deck.gl/blob/0c8e2163039354581f55fada92bd4cbe5526d44e/modules/core/src/viewports/viewport.ts#L223

Edit: So it looks like zoom +/-12 behaves differently, but I'd have to familiarize myself more with this code before understanding if this is the cause and what could fix it.

chrisgervang avatar Oct 25 '23 00:10 chrisgervang

When terrain was initially introduced in MapLibre there was also an 'elevationOffset', which was set to a large value lifting everything above sea-level, but it kept producing new issues. It's since been completely removed, which as a bonus allows for querying a point and getting the correct altitude. I noticed the offset is set to -10000 in the terrain example, and it looks a bit like a similar workaround.

birkskyum avatar Oct 25 '23 00:10 birkskyum

The offset is user editable already, right? That offset was provided by Mapbox. Do you have a link to the Maplibre change?

chrisgervang avatar Oct 25 '23 01:10 chrisgervang

It's here

  • https://github.com/maplibre/maplibre-gl-js/pull/1578

I won't rule out that a simple offset setting might appear again, but it's not something anyone has requested yet - and it should preferably be for the use case that someone is interested in offsetting the altitude of the DEM rather than fighting a near/far plane clipping or tile loading

birkskyum avatar Oct 25 '23 01:10 birkskyum

In deck.gl the WEB_MERCATOR_AUTO_OFFSET projection mode appear to be used at high zoom level for increased performance and precision. I still don't know if the jump at zoom 12 is caused by WEB_MERCATOR being imprecise compared to WEB_MERCATOR_AUTO_OFFSET at that zoom level, or if WEB_MERCATOR_AUTO_OFFSET isn't correct.

birkskyum avatar Nov 21 '23 16:11 birkskyum