如何获取mapboxgl.GeoJSONSource对象的边界框?

Jam*_*ier 5 mapbox mapbox-gl-js

我正在设置这样的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
});
Run Code Online (Sandbox Code Playgroud)

然后我将这样的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
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

此时,我有一个以我指定的位置为中心的地图new mapboxgl.Map,并且它处于缩放级别13.因此,地图上只能看到一块GeoJSON数据.我想重新居中并重新缩放地图,以便可以看到整个GeoJSON数据.

在Mapbox JS中,我会通过将GeoJSON数据加载到a featureLayer然后将地图拟合到其边界来实现:

map.fitBounds(featureLayer.getBounds());
Run Code Online (Sandbox Code Playgroud)

Mapbox GL JS 的fitBounds文档表明它需要格式为的边界[[minLng, minLat], [maxLng, maxLat]].

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

Jam*_*ier 6

基于这篇文章的"获取边界框"部分,我想出了这个过程......

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;
}
Run Code Online (Sandbox Code Playgroud)

以下是对代码正在进行的演练,对于那些需要详细解释的人:

  • map.on('style.load', function(){
    • 加载地图时,让我们在这个函数中做一些事情.
  • $.getJSON('http://citystrides.dev/city_name.geojson', function(response){
    • 获取城市的GeoJSON数据.这是一个异步调用,因此我们必须将使用此数据的所有代码(response)放在此函数中.
  • var boundingBox = getBoundingBox(response);
    • 获取此GeoJSON数据的边界框.这是, function(){在'map on style load'块之后调用它.
  • 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;
Run Code Online (Sandbox Code Playgroud)

在上面链接的原始帖子中,这一行被写为coords = data.features[i].geometry.coordinates[0];因为他们的坐标列表数据是一个数组数组.我的数据没有格式化,所以我不得不放弃[0].如果您尝试此代码并且它会爆炸,那可能就是原因.


Sto*_*ace 6

您可以使用turf.js图书馆。它有一个bbox功能:

const bbox = turf.bbox(foo);
Run Code Online (Sandbox Code Playgroud)

https://turfjs.org/docs/#bbox