Mapbox GL JS getBounds()/ fitBounds()

时间:2016-02-23 19:24:37

标签: javascript json mapbox

我使用的是Mapbox GL JS v0.14.2,我通过文档搜索了高低,但很少有人明白这一点。

如果您使用标准的JS API,那么它非常清楚地适合标记的映射'使用他们提供的示例(https://www.mapbox.com/mapbox.js/example/v1.0.0/fit-map-to-markers/);但是使用GL api时的设置是完全不同的。 GL API有getBounds()https://www.mapbox.com/mapbox-gl-js/api/#Map.getBounds)但是因为您没有像标准JS API那样的命名图层,所以我很难弄清楚如何使用{{ 1}}。

我发现了这个(Mapbox GL JS API Set Bounds),但肯定不是正确的答案?

这是我的大部分设置;排除JSON设置和其他选项。

getBounds()

我尝试了以下内容:

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();

});

所以我知道如何fitBounds,但我不确定如何获得它们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); 似乎只是返回设置中心位置lng / lat。

Markers JSON:

map.getBounds()

5 个答案:

答案 0 :(得分:62)

如果要使贴图适合标记,可以创建包含所有标记的边界。

var bounds = new mapboxgl.LngLatBounds();

markers.features.forEach(function(feature) {
    bounds.extend(feature.geometry.coordinates);
});

map.fitBounds(bounds);

答案 1 :(得分:9)

对于适用于所有GeoJSON对象的解决方案,而不仅仅是一组标记,请查看Mapbox的Turf.js

此代码对我非常有帮助:https://bl.ocks.org/danswick/83a8ddff7fb9193176a975a02a896792

但只是在链接死亡的情况下重复基础知识:

var bounds = turf.bbox(markers);
map.fitBounds(bounds, {padding: 20});

链接代码中提到的extent方法已被弃用,而不是bbox,但结果是相同的。

答案 2 :(得分:5)

Mapbox自己的geojson-extent插件可以解决这个问题。假设您的markers对象为valid GeoJSON,您只需将其传递给geojsonExtent()函数即可获得一组边界,然后您可以将其传递给fitBounds()

加载geojson-extent.js文件后(例如,在HTML代码中使用<script>标记),您应该可以执行此操作以使地图适合您的GeoJSON {{{ 1}}对象:

markers

<强>更新

GeoJSONLint报告您的map.fitBounds(geojsonExtent(markers)); 对象无效GeoJSON,因为每个位置的元素都被解释为字符串,而不是数字。如果从lon-lat坐标中删除引号,它应该可以正常工作:

markers

答案 3 :(得分:0)

这是我基于Mapbox example的reduce操作的解决方案。

它适用于包含点要素和线等多点要素的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
})

答案 4 :(得分:-1)

如果此处有人使用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

您可以在render函数之前以构造函数的方式完成所有这些操作,并获取插件init的值。