[英]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.