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

问题描述 投票:0回答:6

过去几个小时我一直用头撞桌子。

我正在尝试让 Mapbox 放大加载到所有标记的边界区域。

但是,这是我在下面的代码中遇到的错误。

此错误出现在下面的控制台日志图像之后,因此 lat lng 坐标肯定存在。

未捕获错误:无效的 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);
      },
    });

  };

mapbox mapbox-gl-js mapbox-gl
6个回答
7
投票

就我而言,当填充值很高时,我遇到了相同的错误。

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

5
投票

如果有多于一对坐标,则应首先使用

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

我已经准备了这个小提琴与解决方案如何将边界适应坐标列表与3个坐标的数组,但你可以轻松应用到你的。

这就是结果

然后点击缩放至边界


1
投票

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

如果您想捕获所有标记,您可以计算坐标的最西、最南、最东和最北值,然后将它们作为数组传递。在您的情况下:[-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
投票
我不知道这与您的问题相关,但是当我在地图工作的移动浏览器中收到此错误时,我用此代码解决了问题:

if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|OperaMini/i.test(navigator.userAgent)) { $('#mapContainer').css({ 'width': (($(window).width())) + 'px' }); }
#mapContainer 宽度默认为 100%。


1
投票
一种选择是找到东北的最大 lng 和 lat 以及西南的最小 lng 和 lat

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 }
    
© www.soinside.com 2019 - 2024. All rights reserved.