简体   繁体   English

缩放 MapBox GL map 以适应标记集

[英]Scale MapBox GL map to fit set of markers

Say I have the following code for a mapbox map:假设我有以下 mapbox 代码 map:

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

How would I scale the map to fit a set of points on a map?我将如何缩放 map 以适应 map 上的一组点? I can't find any solutions for mapboxgl.我找不到 mapboxgl 的任何解决方案。 Also, I'm not 100% sure that I should be creating a separate layer for each marker, but I couldn't find a way to put all the makers into one layer.此外,我不是 100% 确定我应该为每个标记创建一个单独的层,但我找不到将所有标记放入一个层的方法。 Thanks in advance.提前致谢。

I think what you are looking for is map.fitBounds that will create a bounding box to adapt map view to a list of coordinates.我认为您正在寻找的是map.fitBounds它将创建一个边界框以使 map 视图适应坐标列表。

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

But if you could have a bunch of points in a source as it seems based in your code, then you need to first push all the coordinates of each marker to an array, and then use coordinates.reduce但是,如果您的源代码中可能有一堆点,那么您需要首先将每个标记的所有坐标推送到一个数组中,然后使用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
});

I have created a fiddle for you with this solution, how to fit mapbox bounds to a list of coords , it works your using your own code and coords.我用这个解决方案为你创建了一个小提琴,如何将 mapbox 边界拟合到 coords 列表中,它可以使用你自己的代码和 coords。 在此处输入图像描述 在此处输入图像描述

Regarding the creation of a layer for each marker, definitely you should try to avoid that practice and create a single layer only to host all the markers.关于为每个标记创建一个图层,您绝对应该尽量避免这种做法,并创建一个仅用于托管所有标记的图层。

To use Mapbox GL JS map.fitBounds(bounds, options?) you can also use an array of [lng, lat] pairs which represent the most southwestern and most northeastern corners of the specified geographical bounds.要使用 Mapbox GL JS map.fitBounds(bounds, options?)您还可以使用[lng, lat]对数组,它们代表指定地理边界的最西南角和最东北角。

Always keep in mind:永远记住:
lng (lon): longitude (London = 0, Bern = 7.45, New York = -74) lng (lon):经度(伦敦=0,伯尔尼=7.45,纽约=-74)
→ the lower, the more western → 越低越西

lat : latitude (Equator = 0, Bern = 46.95, Capetown = -33.9) lat :纬度(赤道 = 0,伯尔尼 = 46.95,开普敦 = -33.9)
→ the lower, the more southern → 越低越南

To calculate these I created the following functions to get the most southwestern and most northeastern corners of a collection of coordinates and merge them into an array:为了计算这些,我创建了以下函数来获取坐标集合的最西南角和最东北角,并将它们合并到一个数组中:

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

To use the function, you can just call calcBoundsFromCoordinates and enter an array containing all your markers coordinates:要使用 function,您只需调用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]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM