mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.06k stars 2.21k forks source link

Switch off camera height change with terrain #11300

Open crnismrk opened 2 years ago

crnismrk commented 2 years ago

Motivation

I am writing geospatial app with deck.gl and react-map-gl. The problem when in 3D mode ( mapbox terrain feature ) is that mapbox changes camera height depending on terrain height. Because deck.gl doesn't know about this camera height change, objects rendered by deck.gl are not aligned with terrain despite having correct z coordinate (height). This is even more obvious while camera is moving ( rotating, panning, changing pitch) it look like deck.gl object are moving in space. Is there a way to switch off this camera behaviour.

Design

I would like to to be able to configure mapbox-gl camera not to change height with terrain bellow it.

Mock-Up

Concepts

Implementation

ryanhamley commented 2 years ago

Hi @crnismrk are you able to provide a minimal (as far as possible) reproduction of what you're seeing? There's several different options we could recommend depending on what exactly is happening. If you can use a site like JSBin or CodePen, that would be ideal.

crnismrk commented 2 years ago

Here is one solution for this problem:

https://github.com/geomatico/mapbox-gl-js/compare/v2.2.0...geomatico:2.2.0-deck?expand=1

But I don't wont to use mabox-gl fork. I would like to use official library.

If you still need an online example I will create one but it will take some time.

ryanhamley commented 2 years ago

I don't believe that's a solution we'll be able to adopt in the library. An example would be the clearest way for us to help provide a solution.

crnismrk commented 2 years ago

Here is a CodePen example: https://codepen.io/sinisa-malinovic/full/KKvjymN

If you pan (zoom, rotate..) left and right you will notice how red line changes its height. I believe the cause is mapbox camera height change with terain.

chunlampang commented 2 years ago

I hacked the code without fork.

map.on("idle", () => {
  // Switch off camera height change
  const Terrain = map.painter._terrain.constructor;
  map.painter.updateTerrain = function (style, cameraChanging) {
    const enabled = !!style && !!style.terrain;
    if (!enabled && (!this._terrain || !this._terrain.enabled)) return;
    if (!this._terrain) {
      this._terrain = new Terrain(this, style);
    }
    const terrain = this._terrain;
    this.transform.elevation = false; //enabled ? terrain : null;
    terrain.update(style, this.transform, cameraChanging);
  };
});
crnismrk commented 2 years ago

@chunlampang This does't work for me. It switches mapbox 3D terrain feature off.

chunlampang commented 2 years ago

@chunlampang This does't work for me. It switches mapbox 3D terrain feature off.

Oh, my solution is working on mapbox 2.2.0+. But in your codepen, the mapbox version is v2.1.1.