基于PostGIS的高级应用(3)--线性参考

简介: 一 线性参考干啥用的  如果直接写个“高大上”的定义结果往往是一脸懵逼的,也不知道为什么要定义这么一个概念。其实线性参考技术在我们生活中是非常常见的,比如打开高德,百度地图的App,查看实时路况,道路被不同路况的颜色动态分段显示了;高速中发生交通事故,电视广播中常常对地点描述为“距离xx高速入口xx公里处”,地图是能非常精确的定位到这个地点的。

一 线性参考干啥用的

  如果直接写个“高大上”的定义结果往往是一脸懵逼的,也不知道为什么要定义这么一个概念。其实线性参考技术在我们生活中是非常常见的,比如打开高德,百度地图的App,查看实时路况,道路被不同路况的颜色动态分段显示了;高速中发生交通事故,电视广播中常常对地点描述为“距离xx高速入口xx公里处”,地图是能非常精确的定位到这个地点的。生活中的两个例子的说明,其实他们的规律都是针对图形数据为线(LineString)的一种GIS应用。
  线性参考一定要有线,线上一定要有权重值(也叫测量值M),上一段路况的测量值M就是路段上的传感器发送回来的车流通行速度,交通事故的测量值就是道路的实际距离。不同的测量值能做不同的事,如下图所示:

img_29960a4cc260e8c30ae0034cd90d0dce.png
不同权重值.png

在不改变道路数据前提下,使用不同的维度(测量值M),分段展示不同的业务场景。

二 线性参考核心要素

  转回严肃的工程技术范畴,我个人对线性参考总结包括以下几个要素:

  • 线性数据:道路,河流,电网等一些列线性的业务基础数据。
  • 测量值/M值:不同的业务部门,将自己的业务数据(路况啊,道路质量啊)叠加到线性基础数据上的过程,就是被称作“addMeasure”。
  • 应用方法:一种是动态分段,一种是事件定位
    本质:不改变线性基础数据情况下,将业务测量值/M值数据动态赋予到了每个线性数据上,应用的时候,依据测量值,动态分段展示或者进行突然事件的快速定位。如下例子:
    img_6518f9a90091b86a24940a68ef28172d.png
    沿线距离.png

    道路数据建立了完整测量值M后,用户想定位12公里处,就能快速提取出这个点的位置,用户想找到18-26公里处的区间,也能快速提取出这个线段。

三 PostGIS中的线性参考

  以PostGIS2.4.0版本说明,通过查看API,可以发现对线性参考核心三要素是全部支持的,本章节具体阐述。

3.1 线性数据

PostGIS支持LineString,MultiLineString类型,可以将路网,河网,电网等各种LineString数据导入数据库。完全支持。

3.2 测量值/M值

ST_AddMeasure:用于对线性数添加测量值。
函数定义

geometry ST_AddMeasure(geometry geom_mline, float8 measure_start, float8 measure_end);

参数说明:传入一个线图形,设置其起点测量值,终点测量值,返回一个建立了测量值的图形。
使用示例

SELECT ST_AsText(ST_AddMeasure(ST_GeomFromText('LINESTRING(1 0, 2 0, 4 0)'),10,40)) As ewelev;;
ewelev
----------------------------------------
LINESTRINGM(1 0 10,2 0 20,4 0 40)

3.3 动态分段,事件定位

PostGIS提供了ST_LocateBetween与ST_LocateBetweenElevations方式对带测量值的线进行动态分段提取,其中ST_LocateBetweenElevations是支持三维,四维数据的,简单的就以ST_LocateBetween(这个是用于对二维进行动态分段的)函数说明。
ST_LocateBetween:二维线动态分段函数。
函数定义

geometry ST_LocateBetween(geometry geomA, float8 measure_start, float8 measure_end, float8 offset);

参数说明:传入一个已建立测量值的线图形,选择一个起始测量M值与一个终点测量M值,返回测量值在这个区间内的动态截取线段图形。
至于offset,看了官网说明,也不知道是干嘛用的,请熟悉的朋友留言指点。
使用示例:

SELECT ST_AsText(the_geom)
FROM
(SELECT ST_LocateBetween(
ST_GeomFromText('MULTILINESTRING M ((1 2 3, 3 4 2, 9 4 3),
(1 2 3, 5 4 5))'),1.5, 3) As the_geom) As foo;
------------------------------------------------------------------------------------
GEOMETRYCOLLECTION M (LINESTRING M (1 2 3,3 4 2,9 4 3),POINT M (1 2 3))
img_4027ff641177e02a70a7bf622526dff1.png
草图示意图.png

要求截取M值在1.5到3之间的图形,上图中(1 2 3, 3 4 2, 9 4 3)都满足,(1 2 3, 5 4 5)只有起点满足,所以输出结果符合预期。

ST_LocateAlong:事件定位函数,已知测量值,计算线性数据上的几何定位。
函数定义:

geometry ST_LocateAlong(geometry ageom_with_measure, float8 a_measure, float8 offset);

参数说明:传入一个已建立测量值的线图形,任意设置一个测量M值,返回该M值对应在线性数据上的几何位置。(如前文高速事故以这种事件点形式描述)。
使用说明

SELECT ST_AsText((ST_Dump(the_geom)).geom)
FROM
(SELECT ST_LocateAlong(
ST_GeomFromText('MULTILINESTRINGM((1 2 3, 3 4 2, 9 4 3),
(1 2 3, 5 4 5))'),2.5) As the_geom) As foo;
st_asewkt
---------------
POINT M (2 3 2.5)
POINT M (6 4 2.5)
img_3b80b001ddb5e053ad1547447099cd53.png
草图示意图.png

ST_InterpolatePoint:与ST_LocateAlong函数相反,计算线性数据上任意一点位置的测量M值。
函数定义

float8 ST_InterpolatePoint(geometry line, geometry point);

参数说明:输入建立测量值M的line与已知线上的一点point,返回这个point点对应的测量值M的value。
使用说明

SELECT ST_InterpolatePoint('LINESTRING M (0 0 0, 10 0 20)', 'POINT(5 5)');
st_interpolatepoint
---------------------
10

以上几个函数,是线性参考应用场景中所必需的,主要解决如何给线性数据添加测量值,如何定位,如何反算,如何动态获取。PostGIS线性参考章节剩余几个函数都是纯图形计算的。

ST_LineInterpolatePoint:geometry ST_LineInterpolatePoint(geometry a_linestring, float8 a_fraction)
说明:输入LineString图形与一个分割百分比数,返回LineString从起点到终点之间任意一个0-1之间的百分比数a_fraction所处的点图形。
示例:

route=# select ST_AsText(ST_LineInterpolatePoint(ST_GeomFromText('LineString(0 0,10 10)'),0.5));
 st_astext
------------
 POINT(5 5)
(1 行记录)
route=# select ST_AsText(ST_LineInterpolatePoint(ST_GeomFromText('LineString(0 0,10 10)'),0.3));
 st_astext
------------
 POINT(3 3)
(1 行记录)

ST_LineLocatePoint: float8 ST_LineLocatePoint(geometry a_linestring, geometry a_point)
说明:输入LineString图形与线上任意一个Point(并非线的node节点,而是这个点肯定与线相交(intersects)),返回LineString从起点到终点之间任意一个0-1之间的百分比数a_fraction。
示例

route=# select ST_LineLocatePoint(ST_GeomFromText('LineString(0 0,10 10)'),ST_GeomFromText('Point(5 5)'));
 st_linelocatepoint
--------------------
                0.5
(1 行记录)

ST_LineSubstring:geometry ST_LineSubstring(geometry a_linestring, float8 startfraction, float8 endfraction);
说明:输入LineString图形与起点停靠值s_f与终点停靠值e_f,返回停靠值之间的线段,如果s_f是0,e_f是1,结果就是完整的线的本身。
示例

select ST_AsText(ST_LineSubstring(ST_GeomFromText('LINESTRING(0 0, 10 10)'),0.5,1));
----------------------------------------------------
LINESTRING(5 5,10 10)

四 线性参考实际案例

  本章节我制作了一批测试数据模拟一些实际应用。场景模拟是:武汉军运会重点保障线路之一的“武汉火车站--江夏运动员村“,相关部门为了加强掌握道路通行情况,在该条线路上安装了很多rfid监控传感设备,实时上传该路段的道路通行速度。监管部门设置速度区间,如35-45区间路段是红色,45-55区间路段显示黄色,55-75区间路段是绿色。


img_638f2cbb7fa06c46527c1291b3e12211.png
rfid数据.png

img_42742dae4e5f5e80bfe7f33aa228496d.png
道路与monitor图形.png

数据处理步骤方案是:

  • 1 以rfid_monitor点将完整的线路打断,拆分成监控点两两组成的区间子路段。
  • 2 使用ST_AddMeasure方法,对拆分的子路段建立线性参考。
  • 3 建立线性参考后,根据动态分段的红黄绿动态分区,可视化显示即可。

以下数据处理脚本,根据监控点对路段进行了切割打断,每一个segment路段,起点终点都是一个传感器的位置,在建立线性参考的时候,只需要把segment的起点终点测量值M设置为对应的传感器的speed即可。

do language plpgsql $$  
 DECLARE
        rec record;
        route_line geometry;
        initinfo boolean:=true;
        start_fraction float;
        end_fraction float;
        line geometry;
        speed_s numeric;
        speed_e numeric;
BEGIN
        --提取出重点线路的图形
        select geom from routes limit 1 into route_line;
        initinfo:=true;
        for rec in select t1.gid,t1.speed,t1.geom from rfid_monitor t1 order by t1.gid loop
            if(initinfo=true) then
                initinfo:=false;
                --起点百分比
                start_fraction:=ST_LineLocatePoint(route_line,rec.geom);
                end_fraction:=start_fraction;
                speed_s:=rec.speed;
                speed_e:=rec.speed;
            else
                speed_s:=speed_e;
                speed_e:=rec.speed;
                start_fraction:=end_fraction;
                end_fraction:=ST_LineLocatePoint(route_line,rec.geom);
                line:=ST_LineSubstring(route_line,start_fraction,end_fraction);
                --子路段提取,建立线性参考
                insert into substring_road(seg,geom) values(rec.gid,ST_AddMeasure(line,speed_s,speed_e));
            end if;
        end loop;
end;  
$$;

查询下子路段数据并可视化下:


img_df173acb398c7c0a17417cd6a78c55ac.png
建立测量值.png

到这这一步,数据都处理完了,都建立了M值了。应用系统根据配置,动态显示就可以使用了。
根据速度动态分段:

select ST_LocateBetween(geom,35,45) geom,'红色' as color from substring_road union
select ST_LocateBetween(geom,45,55) geom,'黄色' as color from substring_road union
select ST_LocateBetween(geom,55,75) geom,'绿色' as color from substring_road;

查询结果可视化如下:


img_67afb96ae320e4f133a549dc61120745.png
动态分段渲染.png

[ArcGIS线性参考帮助文档][1]
[1]: http://desktop.arcgis.com/zh-cn/arcmap/10.3/guide-books/linear-referencing/what-is-linear-referencing.htm
[PostGIS线性参考开发文档][2]
[2]: http://postgis.net/docs/manual-2.4/reference.html#Linear_Referencing

相关文章
|
5月前
|
SQL 存储 数据可视化
Ganos矢量快显功能上手系列2:增强的MVT能力
本文主要介绍Ganos新增的2D矢量动态切片函数及其使用方法。新增的矢量动态切片函数能够大幅提升可视化效率,有效解决小比例尺MVT显示耗时久的问题。和PostGIS相比,小比例尺MVT的可视化效率提升可达60%以上。
|
4月前
|
关系型数据库 数据库 PostgreSQL
PostgreSQL【应用 01】使用Vector插件实现向量相似度查询(Docker部署的PostgreSQL安装pgvector插件说明)和Milvus向量库对比
PostgreSQL【应用 01】使用Vector插件实现向量相似度查询(Docker部署的PostgreSQL安装pgvector插件说明)和Milvus向量库对比
179 1
|
4月前
|
SQL 关系型数据库 C语言
PostgreSQL【应用 03】Docker部署的PostgreSQL扩展SQL之C语言函数(编写、编译、载入)计算向量余弦距离实例分享
PostgreSQL【应用 03】Docker部署的PostgreSQL扩展SQL之C语言函数(编写、编译、载入)计算向量余弦距离实例分享
45 0
|
9月前
|
定位技术
GIS开发:blender调整模型信息
GIS开发:blender调整模型信息
|
10月前
|
存储 SQL 数据可视化
Ganos矢量快显功能上手
本文介绍了由阿里巴巴独立研发的多模态时空数据库组件Ganos的2D和3D矢量快显功能。其中,2D矢量快显功能可用于对亿级规模2D矢量数据的高效可视化。Ganos的2D矢量快显快显功能解决了传统切片方案切片时间长和切片存储开销大两大痛点,并且支持局部更新,相较于现有系统,在效率、存储开销以及功能丰富性上都有很大提升。本文以实例的形式介绍了如何创建和更新2D矢量金字塔,以及如何返回切片等功能。通过参考本文,用户可以很快上手体验这一功能。Ganos的3D矢量可视化功能通过对2D矢量切片进行扩展,使其能够支持Geometry3D数据的可视化,可用于可视化大范围3D场景。
|
算法 数据可视化
OushuDB 用户指南图算法之点类型
OushuDB 用户指南图算法之点类型
62 0
|
1天前
|
存储 关系型数据库 分布式数据库
使用 PolarDB 开源版 和 imgsmlr 存储图像特征值以及快速的进行图像相似搜索
背景PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力.本文将介绍使用 PolarDB 开源版 和 imgsmlr 存储图像特征值以及快速的...
|
1天前
|
存储 并行计算 关系型数据库
PolarDB 开源版通过pg_rational插件支持Stern-Brocot trees , 实现高效自定义顺序和调整顺序需求
背景PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力.本文将介绍PolarDB 开源版通过pg_rational插件支持Stern-Bro...
|
存储 并行计算 Cloud Native
使用 PolarDB 开源版 和 imgsmlr 存储图像特征值以及快速的进行图像相似搜索
PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力. 本文将介绍使用 PolarDB 开源版 和 imgsmlr 存储图像特征值以及快速的进行图像相似搜索
449 0
|
存储 并行计算 Cloud Native
PolarDB 开源版通过pg_rational插件支持Stern-Brocot trees , 实现高效自定义顺序和调整顺序需求
PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力. 本文将介绍PolarDB 开源版通过pg_rational插件支持Stern-Brocot trees , 实现高效自定义顺序和调整顺序需求.
163 0