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

Keep camera outside terrain #4300

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

chrneumann
Copy link

@chrneumann chrneumann commented Jun 19, 2024

Fix for #1542. Currently proof of concept, comments appreciated.

It uses the transformCameraUpdate functionality to validate the next camera position, possibly adjusting it. By using transformCameraUpdate, the changes can be kept small. The assigned function checks if the next camera position will be inside terrain. If that would be the case, the camera is moved up (keeping its center), so that it is above the terrain. The pitch is adjusted to keep the map's center. IMHO this leads to a good user experience. Tried other options (stopping the camera or just adjusting height), but this seems best.

Proof of concept: Needs some more testing. transformCameraUpdate type signature is changed to pass the whole transform. Might not be needed, did not look at this yet. If needed, an internal wrapper for transformCameraUpdate might be the solution.

Includes a temporary workaround for #4233.

Launch Checklist

  • Confirm your changes do not include backports from Mapbox projects (unless with compliant license) - if you are not sure about this, please ask!
  • Briefly describe the changes in this PR.
  • Link to related issues.
  • Include before/after visuals or gifs if this PR includes visual changes.
  • Write tests for all new functionality.
  • Document any changes to public APIs.
  • Post benchmark scores.
  • Add an entry to CHANGELOG.md under the ## main section.

// this.transformCameraUpdate = resolvedOptions.transformCameraUpdate;
this.transformCameraUpdate = (tr: Transform) => {
try {
const buffer = Math.min(500, 20 * (25 - tr.zoom));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it's clear what this buffer holds, a better name is probably a good idea here.

@@ -589,7 +589,28 @@ export class Map extends Camera {
this._clickTolerance = resolvedOptions.clickTolerance;
this._overridePixelRatio = resolvedOptions.pixelRatio;
this._maxCanvasSize = resolvedOptions.maxCanvasSize;
this.transformCameraUpdate = resolvedOptions.transformCameraUpdate;
// this.transformCameraUpdate = resolvedOptions.transformCameraUpdate;
this.transformCameraUpdate = (tr: Transform) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing this entire method should be part of terrain class? Not sure, but it shouldn't be here I think...

try {
const buffer = Math.min(500, 20 * (25 - tr.zoom));
const camera = tr.getCameraPosition();
const minAllowedAltitude = this.terrain.getElevationForLngLatZoom(camera.lngLat, tr.zoom) + buffer;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand why this is the minimal altitude, can you add some diagram with some explanation on how you know if the camera is inside the terrain or not?

@HarelM
Copy link
Member

HarelM commented Jun 19, 2024

I think the approach presented here is a very elegant one. Thanks! This still needs some love and care, but otherwise a very good idea to solve this issue.
Assuming we solve the questions raised in #4243

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants