Mapbox fitbounds() - 无效的LngLat对象:(NaN,NaN)

5

在过去的几个小时里,我一直在苦思冥想。

我试图让Mapbox在加载时缩放到所有标记的边界区域。

但是,以下代码导致了错误:

在控制台日志图像之后出现此错误,因此经纬度坐标肯定存在。

未捕获的错误:无效的LngLat对象:(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


1
Mapbox官方问题在GitHub上的链接: https://github.com/mapbox/mapbox-gl-js/issues/10476 - nemanjabu
6个回答

8
在我的情况下,当填充值很高时,我会收到相同的错误提示。
//this did not work
map.fitBounds(fitBounds, {padding: 150});
    
//this worked
map.fitBounds(fitBounds);

5

如果你有多对坐标,应该先使用 coordinate.reduce 函数将数组减少,然后通过 new mapboxgl.LngLatBounds 定义边界。之后可以使用 map.fitBounds 将地图飞到边界上,并像在代码中一样定义喜欢的内边距和缓动函数。

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);
  }
});

我已经准备好了这个 fiddle,其中包含了解决方案如何适应一组坐标的边界,用一个三元素的数组,但是你可以很容易地应用到你的代码中。
然后点击 Zoom to bounds,就会得到以下结果: enter image description here enter image description here

1

对于fitBounds()函数,您需要将边界作为LngLatBounds对象、按[西南,东北]顺序的LngLatLike对象数组或按[西,南,东,北]顺序的数字数组传递。Mapbox在他们的网站上有一个例子here

如果您想捕获所有标记,您可以计算您的坐标最西、最南、最东和最北的值,然后将它们作为一个数组传递。在您的情况下:[-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

一种选择是找到东北部的最大经度和纬度以及西南部的最小经度和纬度,例如:


function buildBounds(cords) {
    const allLats = [];
    const allLngs = [];
    cords.forEach((cord) => {
        allLats.push(cord.lat);
        allLngs.push(cord.lng);
    });
    const ne = [Math.max(...allLngs), Math.max(...allLats)];
    const sw = [Math.min(...allLngs), Math.min(...allLats)];
    console.log(ne, sw);
    return [sw, ne];
}




1

这个答案提供了填充问题的线索

这里有一个TypeScript函数,它将尝试fitBounds,然后在最终放弃之前尝试不使用map.setPadding设置填充。

/**
 * Wraps `map.fitBounds` in an attempt to try a different padding
 * that might work when the screen is tiny, before finally giving up
 * in a way that doesn't crash.
 */
export function fitBounds(
  map: mapboxgl.Map,
  ...args: Parameters<mapboxgl.Map['fitBounds']>
): ReturnType<mapboxgl.Map['fitBounds']> | undefined {
  try {
    return map.fitBounds(...args)
  } catch (exc) {
    console.warn("Bounds didn't fit, trying without padding")
  }

  try {
    const [bounds, params, ...remainder] = args
    const padding = map.getPadding()

    return map.fitBounds(bounds, {
      ...params,
      // This is added to the existing padding you set with
      // map.setPadding
      padding: {
        left: -padding.left,
        top: -padding.top,
        bottom: -padding.bottom,
        right: -padding.right,
      },
      ...remainder,
    })
  } catch (exc) {
    console.warn("Bounds still didn't fit, giving up, need a bigger screen")
  }

  return undefined
}

0

我不知道这是否与您的问题相关,但当我在移动浏览器上使用我的地图时遇到此错误时,我使用以下代码解决了问题:

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

#mapContainer的默认宽度是100%。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接