动态分段的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翻译整理,转载请标明出处