我正在设置这样的Mapbox GL JS地图:
mapboxgl.accessToken = 'pk.my_token';
var cityBoundaries = new mapboxgl.GeoJSONSource({ data: 'http://domain.com/city_name.geojson' } );
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v8',
center: [cityLongitude,cityLatitude],
zoom: 13
});
然后我在加载后将GeoJSON数据加载到地图上:
map.on('style.load', function(){
map.addSource('city', cityBoundaries);
map.addLayer({
'id': 'city',
'type': 'line',
'source': 'city',
'paint': {
'line-color': 'blue',
'line-width': 3
}
});
});
此时,我的地图位于我在new mapboxgl.Map
指定的位置,并且它处于缩放级别13。因此,只有一块GeoJSON数据是在地图上可见。我想重新居中并重新缩放地图,以便显示整个GeoJSON数据。
在Mapbox JS中,我会通过将GeoJSON数据加载到featureLayer
然后将地图拟合到其边界来实现:
map.fitBounds(featureLayer.getBounds());
Mapbox GL JS的fitBounds documentation表示它希望格式为[[minLng, minLat], [maxLng, maxLat]]
。
有没有办法确定混合/最大纬度&此GeoJSON图层的经度值?
答案 0 :(得分:6)
基于'获取边界框' this post部分,我已经提出了这个过程...
map.on('style.load', function(){
$.getJSON('http://citystrides.dev/city_name.geojson', function(response){
var boundingBox = getBoundingBox(response);
var cityBoundary = new mapboxgl.GeoJSONSource({ data: response } );
map.addSource('city', cityBoundary);
map.addLayer({
'id': 'city',
'type': 'line',
'source': 'city',
'paint': {
'line-color': 'blue',
'line-width': 3
}
});
map.fitBounds([[boundingBox.xMin, boundingBox.yMin], [boundingBox.xMax, boundingBox.yMax]]);
})
});
function getBoundingBox(data) {
var bounds = {}, coords, point, latitude, longitude;
for (var i = 0; i < data.features.length; i++) {
coords = data.features[i].geometry.coordinates;
for (var j = 0; j < coords.length; j++) {
longitude = coords[j][0];
latitude = coords[j][1];
bounds.xMin = bounds.xMin < longitude ? bounds.xMin : longitude;
bounds.xMax = bounds.xMax > longitude ? bounds.xMax : longitude;
bounds.yMin = bounds.yMin < latitude ? bounds.yMin : latitude;
bounds.yMax = bounds.yMax > latitude ? bounds.yMax : latitude;
}
}
return bounds;
}
这里是对代码正在做什么的演练,适用于那些需要详细解释的人:
map.on('style.load', function(){
$.getJSON('http://citystrides.dev/city_name.geojson', function(response){
response
)放在此函数中。var boundingBox = getBoundingBox(response);
, function(){
。块。var cityBoundary = new mapboxgl.GeoJSONSource({ data: response } );
map.addSource('city', cityBoundary);
map.addLayer({
map.fitBounds([[boundingBox.xMin, boundingBox.yMin], [boundingBox.xMax, boundingBox.yMax]]);
function getBoundingBox(data) {
getBoundingBox
函数中需要注意的一点是:
coords = data.features[i].geometry.coordinates;
在上面链接的原始帖子中,这一行被写为coords = data.features[i].geometry.coordinates[0];
,因为他们的坐标列表数据是一个数组数组。我的数据没有这样格式化,所以我不得不放弃[0]
。如果你试试这个代码&amp;它爆炸了,这可能是原因。
答案 1 :(得分:2)
我使用了turf-extent库,无论如何都是由Mapbox群维护的。 https://www.npmjs.com/package/turf-extent是节点模块链接。 在您的代码中,您只需导入(ES6)或要求如下:
ES6/Webpack: import extent from 'turf-extent';
Via script tag: `<script src='https://api.mapbox.com/mapbox.js/plugins/turf/v2.0.2/turf.min.js'></script>`
然后将您的回复提供给该函数,例如:
ES6/Webpack: let orgBbox = extent(response);
Normal: var orgBbox = turf.extent(geojson);
然后您可以使用数组值来设置地图中心:
center: [orgBbox[0], orgBbox[1]]
或者根据需要,适合界限:
map.fitBounds(orgBbox, {padding: 20});
以下是在常规html标记中使用turf.min.js的示例,以防您使用webpack或浏览器: https://bl.ocks.org/danswick/83a8ddff7fb9193176a975a02a896792
快乐的编码和映射!
答案 2 :(得分:1)
基于James Chevalier的回答。对于分配给Mapbox Studio中的地图的多边形/多边形tileset,我使用它来获取边界框:
getPolygonBoundingBox: function(feature) {
// bounds [xMin, yMin][xMax, yMax]
var bounds = [[], []];
var polygon;
var latitude;
var longitude;
for (var i = 0; i < feature.geometry.coordinates.length; i++) {
if (feature.geometry.coordinates.length === 1) {
// Polygon coordinates[0][nodes]
polygon = feature.geometry.coordinates[0];
} else {
// Polygon coordinates[poly][0][nodes]
polygon = feature.geometry.coordinates[i][0];
}
for (var j = 0; j < polygon.length; j++) {
longitude = polygon[j][0];
latitude = polygon[j][1];
bounds[0][0] = bounds[0][0] < longitude ? bounds[0][0] : longitude;
bounds[1][0] = bounds[1][0] > longitude ? bounds[1][0] : longitude;
bounds[0][1] = bounds[0][1] < latitude ? bounds[0][1] : latitude;
bounds[1][1] = bounds[1][1] > latitude ? bounds[1][1] : latitude;
}
}
return bounds;
}
答案 3 :(得分:1)