Leaflet结合turf.js实现指定点前后折线分段设置不同颜色
Leaflet + turf.js 实现折线分段差异化样式
实现思路
不需要自定义复杂的线渲染逻辑,直接用turf的线段切割能力把整条折线按指定点位拆成独立的两个线段要素,分别配置不同样式渲染即可,性能和可维护性都更好。
核心用到的能力:
turf.lineSlice(起点, 终点, 原折线):截取两个点之间的折线段- 如果分割点不是严格落在折线上(比如用户点击的点位、外部传入的标记点),先用
turf.nearestPointOnLine(原折线, 外部点)计算出点在折线上的投影点,再用投影点做分割,避免线段截取偏移。
修改后的完整代码
// 路径坐标 注意turf使用[经度, 纬度]顺序 var coords = [ [-3.535,55.62], [-3.54,55.61], [-3.547,55.6], [-3.55,55.59], [-3.57,55.58] ]; var map = L.map('map'); L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap Contributors', maxZoom: 18, }).addTo(map); var line = turf.lineString(coords); var options = {units: 'miles'}; // 生成分割点:沿路径1.25英里位置的点 var splitPoint = turf.along(line, 1.25, options); // 截取已通行段:折线起点 -> 分割点 var traveledSegment = turf.lineSlice( turf.point(coords[0]), splitPoint, line ); // 截取未通行段:分割点 -> 折线终点 var remainSegment = turf.lineSlice( splitPoint, turf.point(coords[coords.length - 1]), line ); // 渲染已通行段:红色实线 L.geoJSON(traveledSegment, { style: { color: '#ff2d2d', weight: 5, opacity: 0.9 } }).addTo(map); // 渲染未通行段:灰色虚线 L.geoJSON(remainSegment, { style: { color: '#8c8c8c', weight: 3, dashArray: '6,8', opacity: 0.7 } }).addTo(map); // 渲染分割点标记 L.geoJSON(splitPoint).addTo(map).bindTooltip("当前位置"); // 起点标记 注意Leaflet使用[纬度, 经度]顺序 L.marker([55.62, -3.535]).bindPopup("起点").addTo(map); // 自动适配视图 var bbox = turf.bbox(line); map.fitBounds([[bbox[1], bbox[0]],[bbox[3], bbox[2]]]);
注意事项
- 坐标顺序不要搞混:所有turf方法的入参坐标统一用
[经度, 纬度],Leaflet的Marker、视图设置相关方法统一用[纬度, 经度],顺序写反会导致坐标位置偏移 - 如果后续需要动态更新进度,只需要重新计算分割点、重新生成两个线段替换旧的图层即可,不需要重绘整幅地图
- 如果需要多段不同样式(比如多个途经点分段着色),按顺序循环切割折线、逐段配置样式渲染即可
内容的提问来源于stack exchange,提问作者BigIWT
相关产品推荐
相关产品推荐

