Skip to content

Fix map.fitBounds() with non-zero bearing #11568

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

Merged
merged 3 commits into from
Mar 9, 2022

Conversation

TannerPerrien
Copy link
Contributor

@TannerPerrien TannerPerrien commented Mar 6, 2022

Fix bounds/bearing calculation bug (#10064) in the following methods:

  • map.fitBounds()
  • map.fitScreenCoordinates()
  • map.cameraForBounds()

Consider bearings of 45 and 135 and how all four corners need to be taken into account.

Changes in tests:

  • Fix tests for camera => #cameraForBounds (they were incorrect)
  • Add new test for camera => #fitBounds with non-zero bearing
  • Changed input coordinates in tests camera => #fitScreenCoordinates to make the input region not square

Before
before
After
after

Launch Checklist

  • briefly describe the changes in this PR
  • include before/after visuals or gifs if this PR includes visual changes
  • write tests for all new functionality
  • document any changes to public APIs
  • manually test the debug page
  • apply changelog label ('bug', 'feature', 'docs', etc) or use the label 'skip changelog'
  • add an entry inside this element for inclusion in the mapbox-gl-js changelog: <changelog>Fix bounds calculation where map.fitBounds(), map.fitScreenCoordinates(), and map.cameraForBounds() behave incorrectly with non-zero bearing. (#10064)</changelog>

Sorry, something went wrong.

…thods:

* `map.fitBounds()`
* `map.fitScreenCoordinates()`
* `map.cameraForBounds()`

Consider 45 and 135 rotations and how all four corners need to be taken into account.

Changes in tests:

* Fix tests for camera => #cameraForBounds (they were incorrect)
* Add new test for camera => #fitBounds with non-zero bearing
* Changed input coordinates in tests camera => #fitScreenCoordinates to make the input region not square
@CLAassistant
Copy link

CLAassistant commented Mar 6, 2022

CLA assistant check
All committers have signed the CLA.

Copy link
Contributor

@SnailBones SnailBones left a comment

Choose a reason for hiding this comment

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

Thanks for your work on this @TannerPerrien! I tested this out and it seems to work.

I've added a few small suggestions for code styling.

Another nice touch would be pushing a change to padding.html to make manual testing easier. Perhaps the call to fitBounds should preserve the current map bearing?

src/ui/camera.js Outdated
const p0world = tr.project(p0LatLng);
const p1world = tr.project(p1LatLng);
const p2world = tr.project(new LngLat(p0LatLng.lng, p1LatLng.lat));
const p3world = tr.project(new LngLat(p1LatLng.lng, p0LatLng.lat));
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I think this can be simplified by calculating the latter two points in world coordinates, i.e.:

Suggested change
const p3world = tr.project(new LngLat(p1LatLng.lng, p0LatLng.lat));
const p3world = new Point(p1world.x, p0world.y);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Much better. Thanks!

src/ui/camera.js Outdated
const upperRight = new Point(Math.max(p0rotated.x, p1rotated.x), Math.max(p0rotated.y, p1rotated.y));
const lowerLeft = new Point(Math.min(p0rotated.x, p1rotated.x), Math.min(p0rotated.y, p1rotated.y));
const p2rotated = p2world.rotate(-bearing * Math.PI / 180);
const p3rotated = p3world.rotate(-bearing * Math.PI / 180);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Can we keep using the degToRad helper function for consistency here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

* Updated padding.html: added a control to toggle if the `fitBounds` should use the map's current bearing
Copy link
Contributor

@SnailBones SnailBones left a comment

Choose a reason for hiding this comment

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

Nice improvement to he debug page! Added one small nitpick, otherwise this looks good to me.

src/ui/camera.js Outdated
const upperRight = new Point(Math.max(p0rotated.x, p1rotated.x), Math.max(p0rotated.y, p1rotated.y));
const lowerLeft = new Point(Math.min(p0rotated.x, p1rotated.x), Math.min(p0rotated.y, p1rotated.y));
const p2rotated = p2world.rotate(-degToRad(bearing));
const p3rotated = p3world.rotate(-degToRad(bearing));
Copy link
Contributor

@SnailBones SnailBones Mar 8, 2022

Choose a reason for hiding this comment

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

I think that -degToRad(bearing) should be pulled into its own variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call. Apologies for the slop!

@SnailBones SnailBones merged commit 7fcfcb6 into mapbox:main Mar 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants