PostGIS之线性参考

1. 概述

PostGIS 是PostgreSQL数据库一个空间数据库扩展,它添加了对地理对象的支持,允许在 SQL 中运行空间查询

PostGIS官网:About PostGIS | PostGIS

PostGIS官方教程:PostGIS 简介 — Introduction to PostGIS

PostGIS相关教程:文章目录汇总 - 知乎 (zhihu.com)

本文基于官方教程描述PostGIS中的线性参考

数据准备可参考:

数据介绍可参考:

2. 线性参考

2.1 定义与用途

线性参考,ArcGIS文档中是这样定义的:线性参考是使用沿测量的线状要素的相对位置存储地理位置的方法

一个很常见的例子就是GPS轨迹,如下图,通常GPS轨迹是在道路上产生的,由于误差和精度问题,轨迹点往往是在道路两侧:

img

根据实际,GPS轨迹点应该是在路网上的,所以,需要以路网为参考,对GPS轨迹点纠偏,将轨迹点放到路网上,利用路网的相对位置存储GPS轨迹点,这就是线性参考

img

2.2 创建线性参考

计算某个点在一个线段(LineString)中的相对位置,主要使用的函数有:

  • ST_LineLocatePoint (a_linestring, a_point) Returns the fractional location of the closest point on a line to a point

比如计算线段LINESTRING(0 0, 2 2)上(1, 1)和(0, 2)的相对位置:

-- Simple example of locating a point half-way along a line
SELECT ST_LineLocatePoint('LINESTRING(0 0, 2 2)', 'POINT(1 1)');
-- Answer 0.5

-- What if the point is not on the line? It projects to closest point
SELECT ST_LineLocatePoint('LINESTRING(0 0, 2 2)', 'POINT(0 2)');
-- Answer 0.5

可以看到,如果点不在线段上,它会投影到离它最近的线段上的点,再计算相对位置

2.3 还原线性参考

有了线性参考值,知道了它的相对位置,就可以还原出它所在的点,主要使用的函数有:

  • ST_LineInterpolatePoint (a_linestring, a_fraction) Returns a point interpolated along a line at a fractional location

比如,利用上面求的线性参考值0.5,还原POINT在线段LINESTRING(0 0, 2 2)上的位置:

-- Simple example of locating a point half-way along a line
SELECT ST_AsText(ST_LineInterpolatePoint('LINESTRING(0 0, 2 2)', 0.5));
-- Answer POINT(1 1)

可以看到,利用线性参考值0.5,就记录了POINT(1 1)的位置,当然,这也说明,使用线性参考记录的点,必须在线段上

2.4 路网匹配

通过上述的例子,很自然的就想到了一个应用:路网匹配

路网匹配是基于位置服务中的关键预处理步骤,它将GPS轨迹点匹配到实际路网上,以此为基础对数据进行分析和挖掘,能够辅助解决城市计算中相关问题,例如建立智能交通系统、协助用户规划出行

在这里进行扩展,基于nyc数据集,将公交站点数据匹配到路网上

比如,原始数据上,公交站点是和路网之间是存在偏离的:

image-20230106150603328

站点匹配的第一步,找到每个站点和其最近的路段:

-- 1. 建立一个临时表,按站点ID和街道距离排序
CREATE TABLE station_nearest_street AS
SELECT nyc_subway_stations.gid AS stations_gid,
nyc_streets.gid AS streets_gid,
nyc_subway_stations.geom AS stations_geom,
ST_GeometryN(nyc_streets.geom, 1) AS streets_geom,
ST_Distance(nyc_subway_stations.geom, nyc_streets.geom) AS distance
FROM nyc_streets
JOIN nyc_subway_stations
ON ST_DWithin(nyc_subway_stations.geom, nyc_streets.geom, 200)
ORDER BY stations_gid, distance ASC;

image-20230106153643920

第二步,建立线性参考值:

-- 2. 选取每个站点最近的街道(即每个stations_gid的第一条记录)计算线性参考值表
CREATE TABLE stations_ref AS
SELECT DISTINCT ON (stations_gid)
stations_gid,
streets_gid,
ST_LineLocatePoint(streets_geom, stations_geom) AS reference,
distance
FROM station_nearest_street;

image-20230106160818464

第三步,还原线性参考值到路网上:

-- 3. 利用线性参考值与街道路网还原站点
CREATE TABLE stations_reduction AS
SELECT stations_gid,
streets_gid,
ST_LineInterpolatePoint(ST_GeometryN(nyc_streets.geom, 1), reference) AS geom
FROM stations_ref
JOIN nyc_streets
ON streets_gid = nyc_streets.gid;

image-20230106160927903

使用QGIS加载匹配后的公交站点:

image-20230106161031425

可以看到,公交站点已经被匹配到路网上,另外,利用线性参考表stations_ref,有效记录了公交站点数据

3. 参考资料

[1]25. 线性参考 — PostGIS 简介

[2]PostGIS教程十七:线性参考 - 知乎 (zhihu.com)

[3]PostGIS 3.3.3dev Manual

[4]PostGIS Cheat Sheet

[5]基于PostGIS的高级应用(3)--线性参考-阿里云开发者社区 (aliyun.com)

[6]什么是线性参考?—ArcMap | 文档 (arcgis.com)

[7]线性参考情景—ArcGIS Pro | 文档

[8]轨迹数据处理 - 简书 (jianshu.com)

posted @ 2023-01-09 17:24  当时明月在曾照彩云归  阅读(257)  评论(0编辑  收藏  举报