动态分段的JS实现
有许多很酷的 GIS 应用程序将海拔和距离结合在一起。 当用户沿着高程图拖动光标时,地图上的位置通常会更新。
在尝试将此功能构建到我的一个项目中时,我了解到它需要一种称为线性参考(Linear Referencing)的东西 — 有时候也称为动态分段(Dynamic Segmentation)。 下面介绍了线性参考是什么,以及我如何使用 JavaScript 和 PostGIS 将其合并到我现有的 GIS 应用程序中。
1、线性参考标准
我当前的 GPS 路线包含纬度、经度和海拔(即它们是 3 维点)。 我需要知道每个点距路线起点有多远,以便填充高程图的 x 轴。
幸运的是,GIS 社区已经提出了有关线性参考的标准。 该点距直线起点的距离(称为 m 值)可以存储为 GPS 点的第 3 维或第 4 维。
具有线性参考的几何图形的名称中包含 M,例如:
- LINESTRING M:包含 3 维点(纬度、经度、线性参考)
- LINESTING ZM:包含 4 维点(纬度、经度、海拔、线性参考)
2、JavaScript 计算线性参考
沿着 LINESTING 应用线性参考相当简单:只需循环沿线的每个点,计算距起点的距离,并将其附加到点的终点。
我使用了两个 JavaScript 库来帮助进行这些计算:
- Turf – 我在 Node/JavaScript 中进行几何计算的首选地理空间库
- Wellknown – MapBox 的另一个库,用于在 WKT 和 GeoJSON 之间进行转换
生成的 JavaScript 在第 5 行接受 WKT 中的 LINESTRING Z,在第 21 行使用 Turf 的距离函数计算引用,并在第 31 行返回更新的 LINESTING ZM。
const parse = require('wellknown')
const turf = require('@turf/turf')
// convert WKT to geoJSON (optional; required by Turf library)
const inputGeoJSON = parse(inputWKT).coordinates
// parse geoJSON into Turf LineString
const linestring = turf.lineString(inputGeoJSON)
// add linear referencing - loop through points and add 4th "M" dimension
let previousLength = 0 // track previous length
let previousCoord = null
linestring.geometry.coordinates.forEach( (currentCoord, index) => {
const currentLength = 0
// if first point set length to 0, otherwise append length to end of point array
if (index===0) {
currentCoord.push(0)
} else {
const distance = turf.distance(previousCoord, currentCoord, {units: 'miles'})
currentCoord.push(previousCoord[3] + distance)
}
previousLength = currentLength
previousCoord = currentCoord
})
// output back to WKT (including 4th dimension)
const updatedWKT = parse.stringify(linestring)
此 JavaScript 逻辑已打包到Node.js模块中,并且还发布在 GitHub 上,并在 README 中包含示例。
3、在 PostGIS 中存储参考几何图形
PostGIS 支持上面讨论的线性参考标准。 用于存储和查询几何图形的基本空间函数按预期工作,并且我使用 ST_GeomFromText() 插入我的 LINESTRING ZM 没有任何问题。
INSERT INTO sampletable(id, geom) VALUES(1, ST_GeomFromText('LINESTRING ZM (1 1 0 0, 1 2 1 1, 1 3 2 2, 2 2 3 3)'));
4、在 WKT 中检索几何图形
我很快了解到 GeoJSON 不支持 4 维几何图形。因此,在从 PostGIS 导出几何图形时,我必须使用 WKT 格式,以便可以包含高程和参考(通过 ST_AsText() 函数完成)。
SELECT id, ST_AsText(geom) FROM sampletable;
5、将 WKT 发送到前端
GeoJSON 通常是我通过 REST API 编码几何图形的方式,但在这种情况下,我必须以 WKT 格式传输几何图形。 这样我的点的所有 4 维都可以包含在内(记住,GeoJSON 仅支持 3 维!)。
幸运的是,主要的地图库支持从 WKT 本地或通过插件导入几何图形。 前面提到的 Wellknown JavaScript 库是另一个在需要时在 WKT 和 GeoJSON 之间进行转换的好工具。
原文链接:Linear Referencing GPS Routes using JavaScript and PostGIS
BimAnt翻译整理,转载请标明出处