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

Zoom to bounding box (fitBounds) zooming in too far with non-Mercator projections #11284

Open
marenab opened this issue Nov 15, 2021 · 12 comments
Labels

Comments

@marenab
Copy link

marenab commented Nov 15, 2021

mapbox-gl-js version: 2.6.0

browser: Chrome

Steps to Trigger Behavior

  1. Set up GL JS map using a non-Mercator projection
  2. Use fitBounds to zoom map to a defined bounding box
  3. Most apparent if the bounding box is being used ensure an entire area (e.g. admin boundary) is displayed in a window. I notice it happen more obviously if the window is small.
  4. No console errors or warnings observed.
  5. Not sure if this is related to Box-zoom / Fit screen coordinates isn't working with non-mercator projections #11246 or not

Mercator (expected behavior): zoom-to-bbox-mercator

Natural Earth projection: zoom-to-bbox-naturalearth

Equal Earth projection: zoom-to-bbox-equalearth

Link to Demonstration

Made using the 'Fly To' GL JS demo: https://jsbin.com/huhataxilu/edit?html,output

Also two counties that demonstrate this issue quite clearly, reported to me:

Boulder County [-105.694362, 39.912886, -105.052774, 40.262785]
Dane County [-89.838567, 42.845036, -89.008729, 43.294198]

Expected Behavior

Zoom to display the full bounding box (not cut off any area within the bounding box)

Actual Behavior

Zooms slightly too far in, cutting off part of the bounding box area.
Workaround solution is to increase the padding as a 'buffer' around the bounding box.

@mourner mourner added this to the projections milestone Nov 16, 2021
@DornMoore
Copy link

DornMoore commented Nov 16, 2021

On further testing, this issue should be renamed to "Zoom bounding box (fitBounds) zooming incorrectly with non-Mercator projections.

When using 'albers' for the projection, the fitBounds does not zoom far enough in and shows much more than the bounding box. You can use the demo link above to test and just change the projection to "albers".

Similarly, when a user performs an interactive zoom (shift + draw box on desktop) the zoom function does not work as expected.

@planemad
Copy link

Possibly related bug:

When the map is pitched with a non mercator projection, the shift+bbox zoom behaves quite erratically

screen2
https://docs.mapbox.com/mapbox-gl-js/example/map-projection/

@asheemmamoowala asheemmamoowala removed this from the projections milestone Dec 15, 2021
@csimpi
Copy link

csimpi commented Mar 8, 2022

The same bug is happening with using winkelTripel projection. Zooms in way too much, like -200px is missing on each side.
Default projection:
image

winkelTripel projection
image

@mikelmaron
Copy link

We've encountered this issue as well in some of our work. What's the primary cause of this bug? Is there a pathway to solving it?

@LeVarez
Copy link

LeVarez commented Jan 16, 2023

I had the same problem. I solved adding a center on the fitbounds method.

    let bbox = turf.bbox(currentRegion);
    map.fitBounds(bbox, {
      padding: 20,
      center: turf.center(
        turf.points([
          [bbox[0], bbox[1]],
          [bbox[2], bbox[3]]
        ])
      ).geometry.coordinates
    });

@stonetip
Copy link

I could not get adding a center to work properly. Still over-zoomed past the bounds when not using mercator. I then did a test like this...and it kind of works, but with some amusing visual results (especially if you exaggerate the duration):

    map.setProjection({
        name: 'mercator'
    });
    
    const mapPadding = 20;

    // Fit the map
    map.fitBounds(bbox, {
        padding: {top: mapPadding, bottom: mapPadding, left: mapPadding, right: mapPadding},
        duration: 5000,
        center: turf.center(
            turf.points([
                [bbox._ne.lng, bbox._ne.lat],
                [bbox._sw.lng, bbox._sw.lat]
            ])
        ).geometry.coordinates
    });

    map.setProjection({
        name: 'lambertConformalConic',
        center: [-96, 39],
        parallels: [33, 45]
    });

@chriszrc
Copy link

@stonetip for whatever reason, adding center did work me, using albers-

@chriszrc
Copy link

chriszrc commented Feb 1, 2023

I could not get adding a center to work properly. Still over-zoomed past the bounds when not using mercator. I then did a test like this...and it kind of works, but with some amusing visual results (especially if you exaggerate the duration):

    map.setProjection({
        name: 'mercator'
    });
    
    const mapPadding = 20;

    // Fit the map
    map.fitBounds(bbox, {
        padding: {top: mapPadding, bottom: mapPadding, left: mapPadding, right: mapPadding},
        duration: 5000,
        center: turf.center(
            turf.points([
                [bbox._ne.lng, bbox._ne.lat],
                [bbox._sw.lng, bbox._sw.lat]
            ])
        ).geometry.coordinates
    });

    map.setProjection({
        name: 'lambertConformalConic',
        center: [-96, 39],
        parallels: [33, 45]
    });

@stonetip Oh, I noticed fitBounds does weird things if you're trying to change projection at the same time. I would put the setProjection call in a timeout so that it execute once fitBounds is done (5000ms in your example). Or alternatively, change the projection before calling fitBounds-

@federico-bellucci
Copy link

This is still happening with the globe projection. Adding the center to the options doesn't work. Is this going to be fixed any time soon?

@Dakuan
Copy link

Dakuan commented Mar 28, 2024

with globe projection, fitBounds does zoom to the bounds im looking for (in my case its a collection of pins, and the top and bottom pins are at the top and bottom of the window)...but ignores the padding value. Adding a center doesnt help for me.

@stepankuzmin
Copy link
Contributor

Hey everyone,

We've improved the fitBounds in the latest v3.7.0-beta.1 release. Could you please try it out and share your feedback here? Thanks!

@federico-bellucci
Copy link

It looks like it's already working on v3.4.0 with the globe projection. I'm sorry, I should have mentioned the version I used in my previous comment. It was only 3.0.1.

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

No branches or pull requests