Javascript Mapbox GL JS getBounds()/fitBounds()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35586360/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mapbox GL JS getBounds()/fitBounds()
提问by John the Painter
I'm using Mapbox GL JS v0.14.2 and I've searched high and low through the documentation and very little is clear about this.
我正在使用 Mapbox GL JS v0.14.2 并且我已经通过文档进行了高低搜索,但对此知之甚少。
If you use the standard JS API, it's very clear to 'fit map to markers' using an example they have provided (https://www.mapbox.com/mapbox.js/example/v1.0.0/fit-map-to-markers/); however the setup when using the GL api is quite different. The GL API has getBounds()
(https://www.mapbox.com/mapbox-gl-js/api/#Map.getBounds) but because you don't have a named layer, like the standard JS API, so I'm struggling to work out how to use getBounds()
at all.
如果您使用标准 JS API,使用他们提供的示例(https://www.mapbox.com/mapbox.js/example/v1.0.0/fit-map-to -标记/); 然而,使用 GL api 时的设置是完全不同的。GL API 有getBounds()
(https://www.mapbox.com/mapbox-gl-js/api/#Map.getBounds)但是因为你没有命名层,就像标准的 JS API,所以我很挣扎弄清楚如何使用getBounds()
。
I've found this (Mapbox GL JS API Set Bounds) but surely can't be the right answer?
我找到了这个(Mapbox GL JS API Set Bounds),但肯定不是正确的答案?
This is the bulk of my setup; excluding JSON setup and other options.
这是我的大部分设置;不包括 JSON 设置和其他选项。
mapboxgl.accessToken = '<myaccesstoken>';
var markers = <?php echo $programme_json; ?>;
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/richgc/cikyo5bse00nqb0lxebkfn2bm',
center: [-1.470085, 53.381129],
zoom: 15
});
map.on('style.load', function() {
map.addSource('markers', {
'type': 'geojson',
'data': markers
});
map.addLayer({
"id": "markers",
"interactive": true,
"type": "symbol",
"source": "markers",
"layout": {
"icon-image": "venue-map-icon-blue",
'icon-size': 0.5,
"icon-allow-overlap": true
}
});
map.scrollZoom.disable();
});
I have tried the following:
我尝试了以下方法:
alert(map.getBounds()); // LngLatBounds(LngLat(-1.4855345239256508, 53.37642500812015), LngLat(-1.4546354760740883, 53.38583247227842))
var bounds = [[-1.4855345239256508, 53.37642500812015],[-1.4546354760740883, 53.38583247227842]]
map.fitBounds(bounds);
So I know how to fitBounds, but I'm unsure how to get them map.getBounds()
just seems to return the set centre position lng/lat.
所以我知道如何拟合边界,但我不确定如何获得它们map.getBounds()
似乎只是返回设置的中心位置 lng/lat。
Markers JSON:
标记 JSON:
var markers = {"type":"FeatureCollection","features":[{"type":"Feature","properties":{"title":"Site Gallery","url":"\/Freelance\/art-sheffield-2016\/programme\/site-gallery\/","summary":"Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Donec id justo. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Suspendisse feugiat. Etiam rhoncus.","image":"\/Freelance\/art-sheffield-2016\/site\/assets\/files\/1032\/site_gallery.jpg","marker-symbol":"venue-map-icon-blue","colour":"blue"},"geometry":{"type":"Point","coordinates":["-1.466439","53.376842"]}},{"type":"Feature","properties":{"title":"Moore Street Substation","url":"\/Freelance\/art-sheffield-2016\/programme\/moore-street-substation\/","summary":"","image":null,"marker-symbol":"venue-map-icon-green","colour":"green"},"geometry":{"type":"Point","coordinates":["-1.477881","53.374798"]}},{"type":"Feature","properties":{"title":"S1 Artspace","url":"\/Freelance\/art-sheffield-2016\/programme\/s1-artspace\/","summary":"","image":null,"marker-symbol":"venue-map-icon-red","colour":"red"},"geometry":{"type":"Point","coordinates":["-1.459620","53.380562"]}}]};
回答by Timur Bilalov
If you want to fit map to markers, you can create bounds that contains all markers.
如果要使地图适合标记,可以创建包含所有标记的边界。
var bounds = new mapboxgl.LngLatBounds();
markers.features.forEach(function(feature) {
bounds.extend(feature.geometry.coordinates);
});
map.fitBounds(bounds);
回答by ChidG
For a solution that will work for all GeoJSON objects, not just a set of markers, check out Mapbox's Turf.js.
对于适用于所有 GeoJSON 对象的解决方案,而不仅仅是一组标记,请查看 Mapbox 的Turf.js。
This code was very helpful to me: https://bl.ocks.org/danswick/83a8ddff7fb9193176a975a02a896792
这段代码对我很有帮助:https: //bl.ocks.org/danswick/83a8ddff7fb9193176a975a02a896792
But just to repeat the basics in case that link dies:
但只是为了重复基础知识,以防链接失效:
var bounds = turf.bbox(markers);
map.fitBounds(bounds, {padding: 20});
The extent
method mentioned in the linked code has been deprecated in favour of bbox
, but the result is the same.
extent
链接代码中提到的方法已被弃用bbox
,但结果是相同的。
回答by Charlie Greenbacker
Mapbox's own geojson-extentplugin will do the trick. Assuming your markers
object is valid GeoJSON, you can simply pass it to the geojsonExtent()
function to get a set of bounds that you can then pass to fitBounds()
.
Mapbox 自己的geojson-extent插件可以解决这个问题。假设您的markers
对象是有效的 GeoJSON,您可以简单地将它传递给geojsonExtent()
函数以获得一组边界,然后您可以将其传递给fitBounds()
。
Once you load the geojson-extent.jsfile (e.g., by using a <script>
tag in your HTML code), you should be able to do this to fit your map to the bounds of your GeoJSON markers
object:
加载geojson-extent.js文件后(例如,通过<script>
在 HTML 代码中使用标签),您应该能够执行此操作以使地图适合 GeoJSONmarkers
对象的边界:
map.fitBounds(geojsonExtent(markers));
UPDATE
更新
GeoJSONLintreports that your markers
object is not valid GeoJSON because the elements in each position are being interpreted as strings, not numbers. If you remove the quotes from the lon-lat coordinates, it should work fine:
GeoJSONLint报告您的markers
对象不是有效的 GeoJSON,因为每个位置的元素都被解释为字符串,而不是数字。如果从 lon-lat 坐标中删除引号,它应该可以正常工作:
var markers = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"title": "Site Gallery",
"url": "\/Freelance\/art-sheffield-2016\/programme\/site-gallery\/",
"summary": "Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Donec id justo. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Suspendisse feugiat. Etiam rhoncus.",
"image": "\/Freelance\/art-sheffield-2016\/site\/assets\/files\/1032\/site_gallery.jpg",
"marker-symbol": "venue-map-icon-blue",
"colour": "blue"
},
"geometry": {
"type": "Point",
"coordinates": [
-1.466439,
53.376842
]
}
},
{
"type": "Feature",
"properties": {
"title": "Moore Street Substation",
"url": "\/Freelance\/art-sheffield-2016\/programme\/moore-street-substation\/",
"summary": "",
"image": null,
"marker-symbol": "venue-map-icon-green",
"colour": "green"
},
"geometry": {
"type": "Point",
"coordinates": [
-1.477881,
53.374798
]
}
},
{
"type": "Feature",
"properties": {
"title": "S1 Artspace",
"url": "\/Freelance\/art-sheffield-2016\/programme\/s1-artspace\/",
"summary": "",
"image": null,
"marker-symbol": "venue-map-icon-red",
"colour": "red"
},
"geometry": {
"type": "Point",
"coordinates": [
-1.459620,
53.380562
]
}
}
]
};
回答by rriemann
This is my solution based on the reduce operation from a Mapbox example.
这是我基于Mapbox 示例中的 reduce 操作的解决方案。
It works for geojson that contain point features and multi-point features like lines.
它适用于包含点特征和多点特征(如线)的 geojson。
let bounds = geoJSON.features.reduce(function(bounds, feature) {
if(!Array.isArray(feature.geometry.coordinates[0])) { // point feature
return bounds.extend(feature.geometry.coordinates);
} else {
return feature.geometry.coordinates.reduce(function(bounds, coord) {
return bounds.extend(coord);
}, bounds);
}
}, new mapboxgl.LngLatBounds());
map.fitBounds(bounds, {
maxZoom: 12,
padding: 30, // in px, to make markers on the top edge visible
})
回答by Scott Leonard
If anyone here is using React-Map-GL, has more than two markers, and wants to figure out the bounds beforeloading the map and retrieving the Mapbox instance you can do this:
如果这里有人使用React-Map-GL,有两个以上的标记,并且想在加载地图和检索 Mapbox 实例之前找出边界,你可以这样做:
const lat = myCoordinatesArray.map(location => parseFloat(location.lat));
const lng = myCoordinatesArray.map(location => parseFloat(location.lng));
// Note that WebMercatorViewport requires this format [lng, lat]
const minCoords = [Math.min.apply(null, lng), Math.min.apply(null, lat)];
const maxCoords = [Math.max.apply(null, lng), Math.max.apply(null, lat)];
const formattedGeoData = [minCoords, maxCoords];
const vPort = new WebMercatorViewport(this.state.viewport).fitBounds(formattedGeoData, {
padding: 100
});
const { latitude, longitude, zoom } = vPort;
Src: https://stackoverflow.com/a/40506115/1259863
源代码:https: //stackoverflow.com/a/40506115/1259863
You can do all this in the constructor way before the render function and get your values for the plugin init.
您可以在渲染函数之前以构造函数的方式完成所有这些操作,并获取插件 init 的值。