1
votes

I have been banging my head against the desk for the last few hours.

I am trying to get Mapbox to zoom in on load to the bounding area of all my markers.

However, this is the error I am getting for the code below.

This error comes after the console log image below, so the lat lng coordinates are definitely there.

Uncaught Error: Invalid LngLat object: (NaN, NaN)

  const onLoad = () => {

    let points = [];

    props.cats.forEach(cat => (
      points.push([ cat.lat, cat.lng ])
    ));

    points.length > 0 && ref.current.getMap().fitBounds(points, {
      padding: { top: 50, bottom: 50, left: 50, right: 50 },
      easing(t) {
          return t * (2 - t);
      },
    });

  };

Console log of points

4

4 Answers

3
votes

If you have more than a pair of coordinates, you should first reduce the array with coordinates.reduce, and then define the bounds through new mapboxgl.LngLatBounds. After that you can fly with map.fitBounds to the bounds, defining your favorite padding and easing function as you did in your code.

var coordinates = points;

var bounds = coordinates.reduce(function(bounds, coord) {
  return bounds.extend(coord);
}, new mapboxgl.LngLatBounds(coordinates[0], coordinates[0]));

map.fitBounds(bounds, {
  padding: { top: 50, bottom: 50, left: 50, right: 50 },
  easing(t) {
      return t * (2 - t);
  }
});

I have prepared this fiddle with the solution how to fit bounds to a list of coords with an array of 3 coords, but you can apply easily to yours.

And this is the result enter image description here

Then tap on Zoom to bounds enter image description here

2
votes

I don't know this is relevant with your problem but when I get this error in mobile browsers on my map work, I solved problem with this code:

if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|OperaMini/i.test(navigator.userAgent)) { 
$('#mapContainer').css({ 'width': (($(window).width())) + 'px' }); 
}

#mapContainer width was 100% on default.

1
votes

For the fitBounds() function you will need to pass your bounds as a LngLatBounds object, an array of LngLatLike objects in [South West, North East] order, or an array of numbers in [west, south, east, north] order. Mapbox has an example of this on their website here.

If you want to capture all of your markers you could calculate the most western, southern, eastern, and northern values of your coordinates and then pass them as an array. In your case: [-0.54664079, 51.38542169, -0.3735228, 51.45368209].

    mapboxgl.accessToken = 'pk.eyJ1IjoicGxtYXBib3giLCJhIjoiY2s3MHkzZ3VnMDFlbDNmbzNiajN5dm9lOCJ9.nbbtDF54HIXo0mCiekVxng';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [-74.5, 40],
zoom: 9
});
 
document.getElementById('fit').addEventListener('click', function() {
map.fitBounds([-0.54664079, 51.38542169, -0.3735228, 51.45368209]);
});
    body { margin: 0; padding: 0; }
    #map { position: absolute; top: 0; bottom: 0; width: 100%; }
#fit {
  display: block;
  position: relative;
  margin: 0px auto;
  width: 50%;
  height: 40px;
  padding: 10px;
  border: none;
  border-radius: 3px;
  font-size: 12px;
  text-align: center;
  color: #fff;
  background: #ee8a65;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Fit a map to a bounding box</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css" rel="stylesheet" />

</head>
<body>

<div id="map"></div>
<br />
<button id="fit">Fit to Box</button>

 
</body>
</html>
1
votes

In my case, I was getting the same error when the padding value was high.

//this did not work
map.fitBounds(fitBounds, {padding: 150});
    
//this worked
map.fitBounds(fitBounds);