Leaflet中通过Turf实现生成缓冲区功能

576 阅读3分钟

背景:近日,由于公司维护之前GIS方面开发的大神离职了,但是在项目中使用生成线缓冲区方法的时候发生了问题没办法生成正确坐标的缓冲区。于是花时间查阅了相关文档最终解决了这一问题,所以记录一下。

解决思路

经过查阅资料发现,定位问题应该是Turf方法支持的坐标系是WGS84的,但是公司项目用到的坐标系是BJ54,所以生成缓冲区坐标时候会出现奇奇怪怪的远离线段坐标的缓冲区。 所以解决思路是将坐标系转成WGS84之后在进行缓冲区生成。但是由于没有BJ54转WGS84的方法,遇是想到的思路是,通过将BJ54转成ESPG3857坐标,然后借助turf的toWGS84方法,将ESPG3857坐标系转成WGS84,再生成缓冲区,将缓冲区WGS84坐标数据转回ESPG3857,再将ESPG3857转回bj54.

方法

因为Leaflet生成点线面都是以经纬度坐标为参数,所以要将后台返回的bj54经纬度坐标的坐标字符串利用leaflet的L.project()转成xy坐标(Leaflet默认的xy坐标是ESPG:3857,pro需要配置转换参数才可以实现不同坐标系做换,这边网上有很多,这里核心主要是阐述实现生成缓冲区所以这里就展开写了)

1.引入需要的包

//引入turt的包
import * as turt from "@turf/helper"
import buffer from "@turf/buffer"
import * as turfproj from "@turf/projection"

2.具体方法代码

//参数
//xy:生成线缓冲区的xy坐标字符串(ESPG:3857)
//distance:缓冲区范围
//unit:单位,默认米
//返回值:
//ESPG:3857坐标系的xy坐标

mybufferLine(xy,distance,unit ='meter'){
//对XY字符串进行处理
let routexy = xy.map(item = >{
    return [item.x,item.y]
})
//因为tuft生成缓冲区和坐标转换方法只支持geoJSON格式,通过turf.lineString()可以生成geoJSON格式的多段线。
const geoJSONLine=turf.lineString(rouotexy);
//转成wgs84坐标系
const wgs84Coord = turfproj.toWgs84(geoJSONLine);
//开始生成缓冲区
const bufferLine =buffer(wgs84Coord,distance,unit);
//将生成的wgs84坐标的缓冲区转成xy坐标形式
const finalBufferLine = turfproj.toMercator(bufferLine);

return finalBufferLine.geometry.coordinates;
}

3.将缓冲区添加到leaflet的图层中

let bufferLine = []
let bufferLineXy = mybufferLine(route,distance);
//将ESPG:3857坐标转回bj54
//unproject坐标的转换也是根据不同的项目的坐标系而转换参数不同
bufferLine.forEach(item=>{
   let latlngs =  L.unproject({x:item.x,y:item.y})
   bufferLine.push(latlngs)
})
L.Polygon(bufferLine,{fillColor:red}).addTo(bufferGroup)

最后

该方法主要聚焦于怎么解决非wgs84坐标系坐标生成缓冲区的方案(mybufferLine()),对于生成缓冲区前后的处理,例如目标经纬度坐标系->ESPG:3857和ESPG:3857->目标坐标系具体转换方法和转换参数没有做具体的探讨。毕竟不同坐标系之间参数也不同,就不做阐述。最后,作为一名刚实习半年多的实习生,有很多方面都很欠缺,发出来自己的想法主要也是能得到大家的指点。