2016-02-27 410 views
3

我设立一个Mapbox GL JS图是这样的:如何获取mapboxgl.GeoJSONSource对象的边界框?

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数据。

map.fitBounds(featureLayer.getBounds()); 

fitBounds documentation为Mapbox GL JS表明它想的范围在:

在Mapbox JS,我会由GeoJSON的数据加载到一个featureLayer,然后将地图安装到它的界限与要这样做格式为[[minLng, minLat], [maxLng, maxLat]]

有没有办法确定这个GeoJSON图层的经度值的混合/最大纬度&?

回答

5

基于对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){
    • 获取城市的GeoJSON的数据。这是一个异步调用,因此我们必须将使用此数据的所有代码(response)放在此函数内。
  • var boundingBox = getBoundingBox(response);
    • 获得此GeoJSON的数据的边界框。这是调用“样式加载映射”块后出现的, function(){
  • var cityBoundary = new mapboxgl.GeoJSONSource({ data: response });
    • 建设Mapbox的GeoJSON的数据。
  • map.addSource('city', cityBoundary);
    • 源添加到Mapbox。
  • map.addLayer({
    • 的层添加到Mapbox。
  • map.fitBounds([[boundingBox.xMin, boundingBox.yMin], [boundingBox.xMax, boundingBox.yMax]]);
    • 调整地图来以GeoJSON数据修正成图。
  • function getBoundingBox(data) {
    • 该函数迭代返回以GeoJSON数据,找到最小和最大经度和纬度值。

一件事在getBoundingBox功能需要注意的是这一行:

coords = data.features[i].geometry.coordinates; 

在原岗位,上面链接,这条线被写成coords = data.features[i].geometry.coordinates[0];,因为他们对数据坐标列表是一个数组数组。我的数据没有格式化,所以我不得不放弃[0]。如果你尝试这个代码&它爆炸,这可能是原因。

+0

此函数应该可能指定它只适用于多边形。就像你说的那样,它不适用于不具有相同结构的其他几何体,例如Point,MultiPoint和LineStrings。 – jabbermonkey

2

我使用turbo-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}); 

这里是你不使用的WebPack或浏览器的情况下,使用turf.min.js在常规html标记的例子: https://bl.ocks.org/danswick/83a8ddff7fb9193176a975a02a896792

快乐编码和绘图!

1

根据James Chevalier的回答。对于与Mapbox Studio中的地图相对应的多边形/多面多边形地图集,我使用它来获取边界框:

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