Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return above-sea-level elevation from queryTerrainElevation + Pass lowered mercator matrix to custom layer #3854

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/geo/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,11 @@ export class Transform {
}

customLayerMatrix(): mat4 {
return this.mercatorMatrix.slice() as any;
// Mercator matrix is translated by -transform.elevation to match the elevation of projMatrix
// This allows to use above-sea-level elevation when positioning custom layer objects
const zTranslation = -((this.elevation * this._pixelPerMeter) / this.worldSize);
const loweredMercatorMatrix = mat4.translate([] as any, this.mercatorMatrix, [0, 0, zTranslation]);
return loweredMercatorMatrix;
}

/**
Expand Down
37 changes: 10 additions & 27 deletions src/ui/camera.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import {setMatchMedia} from '../util/test/util';
import {mercatorZfromAltitude} from '../geo/mercator_coordinate';
import {Terrain} from '../render/terrain';
import {LngLat, LngLatLike} from '../geo/lng_lat';

Check warning on line 9 in src/ui/camera.test.ts

View workflow job for this annotation

GitHub Actions / Code Hygiene

'LngLatLike' is defined but never used
import {Event} from '../util/evented';
import {LngLatBounds} from '../geo/lng_lat_bounds';

Expand Down Expand Up @@ -2136,34 +2136,17 @@
expect(result).toBeNull();
});

test('should return the correct elevation', () => {
// Set up mock transform and terrain objects
const transform = new Transform(0, 22, 0, 60, true);
transform.elevation = 50;
const terrain = {
getElevationForLngLatZoom: jest.fn().mockReturnValue(200)
} as any as Terrain;

// Set up camera with mock transform and terrain
camera.transform = transform;
camera.terrain = terrain;

// Call queryTerrainElevation with mock lngLat
const lngLatLike: LngLatLike = [1, 2];
const expectedElevation = 150; // 200 - 50 = 150
const result = camera.queryTerrainElevation(lngLatLike);

// Check that transform.getElevation was called with the correct arguments
expect(terrain.getElevationForLngLatZoom).toHaveBeenCalledWith(
expect.objectContaining({
lng: lngLatLike[0],
lat: lngLatLike[1],
}),
transform.tileZoom
);
test('Calls getElevationForLngLatZoom with correct arguments', () => {
const getElevationForLngLatZoom = jest.fn();
camera.terrain = {getElevationForLngLatZoom} as any as Terrain;
camera.transform = new Transform(0, 22, 0, 60, true);

camera.queryTerrainElevation([1, 2]);

// Check that the correct elevation value was returned
expect(result).toEqual(expectedElevation);
expect(camera.terrain.getElevationForLngLatZoom).toHaveBeenCalledWith(
expect.objectContaining({lng: 1, lat: 2,}),
camera.transform.tileZoom
);
});
});

Expand Down
3 changes: 1 addition & 2 deletions src/ui/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1493,7 +1493,6 @@ export abstract class Camera extends Evented {
if (!this.terrain) {
return null;
}
const elevation = this.terrain.getElevationForLngLatZoom(LngLat.convert(lngLatLike), this.transform.tileZoom);
return elevation - this.transform.elevation;
return this.terrain.getElevationForLngLatZoom(LngLat.convert(lngLatLike), this.transform.tileZoom);
}
}
8 changes: 1 addition & 7 deletions test/examples/add-3d-model-with-terrain.html
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
const axesHelper = new THREE.AxesHelper(100);
this.scene.add(axesHelper);

// Getting model elevations (in meters) relative to scene origin from maplibre's terrain.
// Getting model elevations in meters above sea level
const sceneElevation = map.queryTerrainElevation(sceneOrigin) || 0;
const model1Elevation = map.queryTerrainElevation(model1Location) || 0;
const model2Elevation = map.queryTerrainElevation(model2Location) || 0;
Expand Down Expand Up @@ -175,12 +175,6 @@
},

render(gl, mercatorMatrix) {

// `queryTerrainElevation` gives us the elevation of a point on the terrain
// **relative to the elevation of `center`**,
// where `center` is the point on the terrain that the middle of the camera points at.
// If we didn't account for that offset, and the scene lay on a point on the terrain that is
// below `center`, then the scene would appear to float in the air.
const offsetFromCenterElevation = map.queryTerrainElevation(sceneOrigin) || 0;
const sceneOriginMercator = maplibregl.MercatorCoordinate.fromLngLat(sceneOrigin, offsetFromCenterElevation);

Expand Down