Leaflet+Turf.js如何根据数据点动态设置地图初始视图边界
问题原因
- 调用
line.getBounds报错的核心原因:Turf.js生成的line是标准GeoJSON格式的普通JS对象,不是Leaflet封装后的图层实例。getBounds是Leaflet图层类的内置方法,原生GeoJSON对象本身没有挂载这个方法,直接调用必然抛错。 - 拿到bbox后无法定位初始视图的原因:Turf的
bbox方法返回结果格式为[最小经度, 最小纬度, 最大经度, 最大纬度],但Leaflet的map.fitBounds()方法要求传入的边界格式是[[最小纬度, 最小经度], [最大纬度, 最大经度]],二者经纬度顺序、数组结构不匹配,所以无法正常定位。
解决方法
两种方案都可以实现动态适配初始视图,按需选择即可:
- 方案1:直接调用Leaflet图层实例的
getBounds方法。把Turf生成的GeoJSON通过L.geoJSON渲染为Leaflet图层后,保存图层实例,直接调用实例上的getBounds()方法传入fitBounds即可,不需要额外用Turf计算边界。 - 方案2:转换Turf返回的bbox格式。如果已经通过Turf算出了bbox,手动调整经纬度顺序、转成Leaflet要求的二维数组结构,再传入
fitBounds即可。
修正后的可运行代码
// 点位数据 var somePoints = [ [-3.535,55.62], [-3.54,55.61], [-3.547,55.6], [-3.55,55.59], [-3.57,55.58] ]; // 初始化地图时不需要写死setView var map = L.map('map'); L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© <a href="https://openstreetmap.org" target=blank>OpenStreetMap</a> Contributors', maxZoom: 18, }).addTo(map); var line = turf.lineString(somePoints); var options = {units: 'miles'}; // 保存线图层实例,不要直接调用addTo后丢弃引用 var lineLayer = L.geoJSON(line).addTo(map); var along = turf.along(line, 1.25, options); L.geoJSON(along).addTo(map).bindTooltip("my tooltip text"); along = turf.along(line, 2.123, options); L.geoJSON(along).addTo(map).bindTooltip("12345"); var bbox = turf.bbox(line); var bboxPolygon = turf.bboxPolygon(bbox); L.geoJSON(bboxPolygon).addTo(map) // 动态定位视图核心代码 // 方法1:直接取Leaflet图层的边界适配 map.fitBounds(lineLayer.getBounds()); // 方法2:转换Turf bbox格式适配(二选一即可) // turf bbox格式: [minLng, minLat, maxLng, maxLat] // 转Leaflet要求格式: [[minLat, minLng], [maxLat, maxLng]] // var leafletBounds = [[bbox[1], bbox[0]], [bbox[3], bbox[2]]]; // map.fitBounds(leafletBounds);
注意:原代码中重复声明了
features和center变量,运行时会抛出重复声明错误,如果不需要用到这两个计算结果直接删除即可。
内容的提问来源于stack exchange,提问作者BigIWT
相关产品推荐
相关产品推荐

