Fitting map to bounds with large padding - Uncaught Error: Invalid LngLat object: (NaN, -90)
mapbox-gl-js version: v1.3.1
browser: Google Chrome (MacOS) v76.0.3809.132
Steps to Trigger Behavior
- Initialise the map and set the map container width and height to something small, e.g. 529px by 400px.
- Create a lat long bounds instance, using any number of coords
- Call the fitBounds method, using large padding values
- View the console
Link to Demonstration
https://jsfiddle.net/benstaker/thawmsjd/
Expected Behavior
Map centers to supplied bounds.
Actual Behavior
The following error outputs in the console: lng_lat.js:30 Uncaught Error: Invalid LngLat object: (NaN, -90)
This is actually caused by an interaction between the size of the map and the padding.
We calculate the size and x and y scales necessary to fit the map to the given bounds in
https://github.com/mapbox/mapbox-gl-js/blob/75b9a4062c1f23495b1d7d10ae2c073072242920/src/ui/camera.js#L468-L470
What's causing the problem here is the scaleY calculation. The height of the map is 400 while the top and bottom paddings are 0 and 400 respectively, giving us 400 - 0 - 400 or 0.
https://github.com/mapbox/mapbox-gl-js/blob/75b9a4062c1f23495b1d7d10ae2c073072242920/src/ui/camera.js#L479
Here we calculate the necessary zoom level to fit the bounds. You can see we're taking the minimum of scaleX and scaleY, which in this case is 0 and multiplying that by tr.scale which is 256 but of course doesn't actually matter once the other side of the multiplication is set to 0.
So now we're passing 0 to tr.scaleZoom which is this:
https://github.com/mapbox/mapbox-gl-js/blob/75b9a4062c1f23495b1d7d10ae2c073072242920/src/geo/transform.js#L283
where we end up calculating Math.log(0) and MDN helpfully points out that
If the value of
xis 0, the return value is always-Infinity.
From there, the rest of the calculations are borked because they're trying to operate on Infinity.
I'm not sure what the best way to handle this is to be honest. Perhaps we should catch this error and emit a warning instead.
I just ran into this too.
There is already a check https://github.com/mapbox/mapbox-gl-js/blob/75b9a4062c1f23495b1d7d10ae2c073072242920/src/ui/camera.js#L472-L477
My opinion is that should be <= 0 since if scale is 0 you essentially need a negative infinity zoom to fit those bounds based on the canvas size and padding constraints.
There is also another edge case where scale is very small like 0.0001 then you'll need a zoom like -10 to fit, but -2 is the smallest support as far as I can tell.
In these cases, in my opinion, fitBounds should just go to the limit it can (which is a zoom of -2) plus the console warning, it won't completely meet the criteria but in these edge cases that's probably the best option.
This bug happed to me as well, any news about solving it?
This bug happed to me as well, any news about solving it?
It's not really a bug, though we need to decide and document what you can expect when making a request like this that can't be met.
At the moment you could wrap your request in a try catch, or for most cases if you're not fitting to large bounds, it's mostly sufficient to ensure you're padding is not too big compared with the map container size.
This bug just hit me and I was clueless of why my perfectly fine data was causing the error. The error message doesn't help at all