缩放 MapBox GL 地图以适合标记集

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

假设我有以下 Mapbox 地图代码:

mapboxgl.accessToken = '<token>';
var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/satellite-v9',
    center: [-96, 37.8],
    zoom: 2,
    interactive: true
});

var geojson = {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [-77.03238901390978, 38.913188059745586]
            },
            "properties": {
                "id": 1,
                "color": "#007cbf",
                "text": "1"
            }
        }, 
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [-78.03238901390978, 39.913188059745586]
            },
            "properties": {
                "id": 2,
                "color": "red",
                "text": "2"
            }
        }
    ]
}

map.on('style.load', function (e) {
    map.addSource('markers', {
        "type": "geojson",
        "data": geojson
    });
    geojson.features.forEach(function(marker){
        map.addLayer({
            "id": String(marker.properties.id)+'-circle',
            "source": "markers",
            "type": "circle",
            "paint": {
                "circle-radius": 20,
                "circle-color": marker.properties.color,
                "circle-opacity": 0.8,
                "circle-stroke-width": 0,
            },
            "filter": ["==", "id", marker.properties.id],
        });
        map.addLayer({
            "id": String(marker.properties.id)+'-text',
            "source": "markers",
            "type": "symbol",
            "layout": {
                'text-field': marker.properties.text,
                'text-size': 20
            },
            "filter": ["==", "id", marker.properties.id]
        })
    });
});

如何缩放地图以适应地图上的一组点?我找不到 mapboxgl 的任何解决方案。另外,我不能 100% 确定我应该为每个标记创建一个单独的图层,但我找不到一种方法将所有标记放入一个图层中。预先感谢。

javascript html mapbox
2个回答
5
投票

我认为您正在寻找的是

map.fitBounds
,它将创建一个边界框以使地图视图适应坐标列表。

map.fitBounds([
  [-77.03238901390978, 38.913188059745586],
  [-78.03238901390978, 39.913188059745586]
]);

但是,如果源中可能有一堆点,因为它看起来基于您的代码,那么您需要首先将每个标记的所有坐标推送到数组中,然后使用

coordinates.reduce

var coordinates = coords;

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

map.fitBounds(bounds, {
  padding: 20
});

我用这个解决方案为您创建了一个小提琴,如何将地图框绑定到坐标列表,它可以使用您自己的代码和坐标来工作。

关于为每个标记创建一个图层,您绝对应该尝试避免这种做法,并仅创建一个图层来托管所有标记。


0
投票

要使用 Mapbox GL JS

map.fitBounds(bounds, options?)
,您还可以使用一组
[lng, lat]
对来表示指定地理边界的最西南角和最东北角。

永远记住:

lng
(lon):经度(伦敦 = 0,伯尔尼 = 7.45,纽约 = -74)
→ 越低,越西

lat
:纬度(赤道= 0,伯尔尼= 46.95,开普敦= -33.9)
→ 越低,越南

为了计算这些,我创建了以下函数来获取坐标集合的最西南角和最东北角并将它们合并到一个数组中:

getSWCoordinates(coordinatesCollection) {
  const lowestLng = Math.min(
    ...coordinatesCollection.map((coordinates) => coordinates[0])
  );
  const lowestLat = Math.min(
    ...coordinatesCollection.map((coordinates) => coordinates[1])
  );

  return [lowestLng, lowestLat];
}

getNECoordinates(coordinatesCollection) {
  const highestLng = Math.max(
    ...coordinatesCollection.map((coordinates) => coordinates[0])
  );
  const highestLat = Math.max(
    ...coordinatesCollection.map((coordinates) => coordinates[1])
  );

  return [highestLng, highestLat];
}

calcBoundsFromCoordinates(coordinatesCollection) {
  return [
    getSWCoordinates(coordinatesCollection),
    getNECoordinates(coordinatesCollection),
  ];
}

要使用该功能,您只需调用

calcBoundsFromCoordinates
并输入一个包含所有标记坐标的数组:

calcBoundsFromCoordinates([
  [8.03287, 46.62789],
  [7.53077, 46.63439],
  [7.57724, 46.63914],
  [7.76408, 46.55193],
  [7.74324, 46.7384]
])

// returns [[7.53077, 46.55193], [8.03287, 46.7384]]
© www.soinside.com 2019 - 2024. All rights reserved.