mapbox / mapbox/mapbox-gl-js

fitScreenCoordinates results in bounding box occupying only appr 1/9th of map view

Open
#13,347 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

auto-triaged bug :lady_beetle:
Dominant language
TypeScript
Stars
12.4k
Forks
2.4k
PR merge metrics
No merged PRs in 30d

Description

When trying to use map.fitScreenCoordinates() to fit a point pair to the map view, the results end up with the bounding box for the pair only occupying the central 9th of the map view (approximately), roughly a a zoom order of 1 lower than it should be and not quite centred correctly.

mapbox-gl-js version: 3.8

browser: Firefox/Chrome latest

Steps to Trigger Behavior
const drawMap = (token) => {
  mapboxgl.accessToken = token;
  const container = document.getElementById("map-container");
  container.innerHTML = "";
  container.style.background = "lightgray";
  const bottomLeft = [175.43187052379676, -40.740663977932265];
  const bottomRight = [175.08267490014015, -40.89324128225486];
  const topLeft = [175.5725422482024, -40.925014779134294];
  const topRight = [175.22334662454864, -41.0771677780363];
  const initialBounds = new mapboxgl.LngLatBounds([bottomLeft, topRight]);
  const map = new mapboxgl.Map({
    container: container,
    style: "mapbox://styles/mapbox/standard",
    bounds: initialBounds,
    fitBoundsOptions: {
      bearing: 150,
      padding: 0,
      pitch: 45
    }
  }).on("style.load", () => {
    p0 = map.project(bottomLeft);
    p1 = map.project(topRight);
    console.log("Before", p0, p1);
    map
      .addSource("screenBounds-box", {
        type: "geojson",
        data: {
          type: "FeatureCollection",
          features: [
            {
              type: "Feature",
              geometry: {
                type: "LineString",
                coordinates: [
                  topLeft,
                  topRight,
                  bottomRight,
                  bottomLeft,
                  topLeft
                ]
              }
            }
          ]
        }
      })
      .addLayer({
        id: "screenBounds-box-layer",
        type: "line",
        source: "screenBounds-box",
        layout: {
          "line-join": "round",
          "line-cap": "round"
        },
        paint: {
          "line-color": "#ff0000",
          "line-width": 3
        }
      })
      .fitScreenCoordinates(p0, p1, 150, {
        padding: 0,
        pitch: 45
      });
    p0 = map.project(bottomLeft);
    p1 = map.project(topRight);
    console.log("After", p0, p1);
  });
};

Example output:

"Before" // [object Object] 
{
  "x": 311.3005111725074,
  "y": 267.52395746441937
} // [object Object] 
{
  "x": 628.6428320111704,
  "y": 110.9528432699433
}
"After" // [object Object] 
{
  "x": 311.3005111725074,
  "y": 267.52395746441937
} // [object Object] 
{
  "x": 628.6428320111704,
  "y": 110.9528432699433
}

Screenshot 2024-12-12 163148

The bounding box after applying fitScreenCoordinates is drawn in red with p0 being the bottom left corner, p1 the top right. In the pictured example, p0.y should be the map container height, p1.y should be zero.

The issue is there whether the pitch and/or bearing are zero or not and unrelated to initial position or zoom level before issuing fitScreenCoordinates().

map.getPadding() confirms the padding is zero and not related to the issue.

I've seen the related issue #11795 that states this can be related to using the globe projection in place of mercator. I changed the style projection to mercator and passed this in the Map options (confirmed with map.getProjection()) - this made no difference.

Codepen

https://codepen.io/enzedonline/pen/emOdGbx
NB: use your token in the input field to get working example

Expected Behavior

Zoom and map position should be such that the bounding box fills the map view area taking any padding into consideration.

Actual Behavior

Map is not properly centred, zoom level is approximately an order of 1 smaller than it should be to fill the map view area.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the map.fitScreenCoordinates() entry point and reproduce the CodePen case using the coordinates, bearing, pitch, and zero padding from the issue. Compare the projected points before and after fitting, and consider the issue done when the bounding box is correctly centered and fills the map view while preserving the documented padding, bearing, and pitch behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
frontend, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.