pgrouting 路径规划_路径分析是什么意思

pgrouting 路径规划_路径分析是什么意思一.技术背景,相关技术介绍   PgRouting是基于开源空间数据库PostGIS用于网络分析的扩展模块,最初它被称作pgDijkstra,因为它只是利用Dijkstra算法实现最短路径搜索,之后慢慢添加了其他的路径分析算法,如A算法,双向A算法,Dijkstra算法,双向Dijkstra算法,tsp货郎担算法等,然后被更名为pgRouting[1]。该扩展库依托PostGIS自身的g…


Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一.技术背景,相关技术介绍

      PgRouting是基于开源空间数据库PostGIS用于网络分析的扩展模块,最初它被称作pgDijkstra,因为它只是利用Dijkstra算法实现最短路径搜索,之后慢慢添加了其他的路径分析算法,如A算法,双向A算法,Dijkstra算法,双向Dijkstra算法,tsp货郎担算法等,然后被更名为pgRouting[1]。该扩展库依托PostGIS自身的gist索引,丰富的坐标系与图形类型,强大的几何处理能力,如空间查询,空间处理,线性参考等优势,能保障在较大数据级别下的网络分析效果更快更好。
  PostGIS早已奠定了最优秀的开源空间数据库地位,在新时代GIS中的应用将会越来越普遍。其实,网络分析算法很多服务端语言如java,C#等虽能实现,但基于真实城市道路数据量较大且查询分析操作步骤复杂与数据库交互频繁,以这类服务端频繁访问数据库导致数据库开销压力较大,分析较慢,故选择PgRouting在数据库内部实现算法,提升分析效率。最后,路径分析不仅仅是最短路径,在实际应用中还有最短耗时,最近距离,道路对车辆类型限制,道路对速度限制等因素,交通事故、市政事故导致的交通障碍点等问题,所有的问题本质其实是对路径分析权重(Weight)的设置问题。

二.数据准备

1.准备路网数据,从OSM下载中国区的数据,然后使用ArcMap对数据进行裁剪,获得自己想要的区域路网数据;

2.通过Postgis自带的shp导入工具导入被裁剪好的路网数据(注意shp路径不要太深,不要还有中文;对于中文乱码,可以设置GBK等转码);

3.设置导入的SRID为3857进行坐标系转化;

4.勾选Options里面的”Generate simple geometries instead of MULTI geometries”,因为路径分析只支持LineString类型,不支持MuliLineString类型,这里介绍一个方法,因为裁剪的过程或者数据自身问题,当勾选这个的时候可能会出现导入数据失败,当出现这个情况的时候,先不勾选此选项导入到数据库中,然后通过”SELECT gid from road_hz_two  where get_txt_count(st_astext(geom),'(‘)>2;”获得多线数据,手动删除这些数据,然后将数据通过shp2sql导出程shp数据,然后在重复上诉过程,实现支持路网分析的数据的导入;

5.查看刚才导入的表的数据,增加source,target字段,后面分析需要用到;

--在road_two中添加source,target字段
alter TABLE road_two add COLUMN source int;
alter table road_two add COLUMN target int;

6.通过pgrouting提供的pgr_createTopology方法,对道路数据创建拓扑关系

--创建连通性topo
--road_two是表名称,geom是该表的图形字段名称,gid是改变的主键
--一般我们使用shp2pgsql工具会自动创建gid为主键,geom为图形,如果是其他工具,注意对应字段
select pgr_createtopology('road_two', 0.0001, 'geom', 'gid');

7.对连通性字段建立索引,增加查询速度

create index road_source_index on road_two("source");
create index road_target_index on road_two("target");

8.到此为止,数据的准备工作完成;

三.路径分析

相关说明:osm下载的路网数据,里面包含”oneway”道路方向的说明 ,”B”代表双向,”T”代表仅反向,  “F”代表仅正向;

3.1.道路成本权重说明

在算法中分为有向图,无向图,图的长度一般设置为权重,路网分析中,具体到此交通领域,也分为双向通行道路,单向通行道路,交通师父导致的临时交通阻塞无法通行(障碍点),不同等级道路对车辆类型限制,以下是不同条件下如何设置通行成本权重的相关示例:

  • 双向通行
update road_two set length=st_length(geom),rev_length=st_length(geom) where oneway='B';
--采用真实地理距离是这样:
update road_two set lenght=st_length(st_transform(geom),4326),true),rev_length=st_length((st_transform(geom),4326),true) where oneway='B';
  • 单向通行
#FT是道路方向与数字化方向一致,那么正向通行成本为道路长度,反向成本为正无穷(以极大值代替)
update road_two set length=st_length(geom),rev_length=99999999999 where oneway='F';
update road_two set length=99999999999,rev_length=st_length(geom) where oneway='T';
  • 障碍点
#假设gid=20的道路因事故,修路暂时不能通行
update road_two set lenght=99999999999,rev_length=99999999999 where gid=20;
  • 限制通行

假设当前是一辆大货车,通过有限高限重的道路,在为他做规划时,先获取车辆类型,再查询road表中是否有对其限制的因素(以下纯逻辑描述sql)

#假设道路表有字段restrict,该字段是array,记录了不可通行的车辆类型
update road_two set lenght=99999999999,rev_length=99999999999 where 'lorry'=any(restrict);

 3.2设置道路权重

1.本文只涉及单向,双向等简单情况,复杂情况不考虑。

通过以下方式设置道路权重

--FT是道路方向与数字化方向一致,那么正向通行成本为道路长度,反向成本为正无穷(以极大值代替)
UPDATE road_two SET cost = CASE WHEN oneway='B'THEN length --双向
WHEN oneway='T' THEN 999999999 -- 反向
WHEN oneway='F' THEN length -- 正向
ELSE length END;
--------------------- 
UPDATE road_two SET rev_cost = CASE WHEN oneway='B' THEN length --双向
WHEN oneway='T' THEN length -- 反向
WHEN oneway='F' THEN 999999999 -- 正向
ELSE length END;
--------------------- 

2.计算最短路径

  • 最短路径,不包含方向
SELECT line.*,pt.geom FROM pgr_dijkstra(
    'SELECT gid AS id,
         source,
         target,
         cost,  rev_cost::double precision AS reverse_cost
        FROM road_two',
    1060, 1661,false,false) line LEFT JOIN road_two pt on line.id2=pt.gid;
--通过id转edge来实现对边表的对应
drop table if exists dijkstra_res_edge_dretrue;
SELECT seq,id1 AS node, id2 AS edge,line."cost",pt.geom  into  dijkstra_res_node_point_true FROM pgr_dijkstra(
    'SELECT gid AS id,
         source,
         target,
         cost, 
         rev_cost::double precision AS reverse_cost
        FROM road_two',
    1,10,true,false) line LEFT JOIN road_two pt on line.id2=pt.gid;

--通过edge直接对应边表
drop table if exists dijkstra_res_node_dretrue;
SELECT line.* ,pt.the_geom as geom  into dijkstra_res_true_one  FROM pgr_dijkstra(
    'SELECT gid AS id,
         source,
         target,
         cost
        FROM road_two',
    1,10,true) line LEFT JOIN road_two_vertices_pgr pt on line.node=pt.id;

--以上两种方式都是包含方向的,但第四个参数的使用还需要查明-todo
  • 最短路径,包含方向
SELECT seq,id1 AS node, id2 AS edge,line."cost",pt.geom   FROM pgr_dijkstra(
    'SELECT gid AS id,
         source,
         target,
         cost, 
         rev_cost::double precision AS reverse_cost
        FROM road_two',
    1, 10,true,true) line LEFT JOIN road_two pt on line.id2=pt.gid;

按顺序经过多个点的最短路径:从1->10->20(待完善)

SELECT line.*,pt.geom      FROM pgr_dijkstraVia(
    'SELECT gid AS id,
         source,
         target,
         cost, 
         rev_cost::double precision AS reverse_cost
        FROM road_two order by gid',
    ARRAY[1,10,20],true,false,true) line LEFT JOIN road_two pt on line.edge=pt.gid;

关于pgr_dijkstraVia,pgr_dijkstra的详细用法可以参看pgrouting官网

3.结果查看

可以将查询到的数据生成到一个新表,然后通过udig查看路径分析的结果是否正确

 

参考资料

1.https://www.jianshu.com/p/34c8378c3da9

2.https://blog.csdn.net/redtomemory/article/details/78293447

3.https://workshop.pgrouting.org/2.5/en/chapters/shortest_path.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/172662.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 使用多线程实现文件的下载_多线程写同一个文件

    使用多线程实现文件的下载_多线程写同一个文件首先,我们要下载一个文件,可以通过多线程的方式快速下载!!!多线程下载文件的步骤:1、首先要知道请求下载的服务器支持断点下载,即支持request头信息中的Range的设置2、然后通过对请求头设置httpRequest.setRequestProperty(“Range”,”bytes=”+startIndex+”-“+endIndex);3、然后获取整个文件的大小4、在……

    2022年9月10日
  • 普罗米修斯监控系统_一步步教你用Prometheus搭建实时监控系统系列(二)——详细分析拉取和推送两种不同模式…

    普罗米修斯监控系统_一步步教你用Prometheus搭建实时监控系统系列(二)——详细分析拉取和推送两种不同模式…前言本系列着重介绍Prometheus以及如何用它和其周边的生态来搭建一套属于自己的实时监控告警平台。本系列受众对象为初次接触Prometheus的用户,大神勿喷,偏重于操作和实战,但是重要的概念也会精炼出提及下。系列主要分为以下几块Prometheus各个概念介绍和搭建,如何抓取数据(一步步教你用Prometheus搭建实时监控系统系列(一)——上帝之火,普罗米修斯的崛起)如何推送数据…

    2022年7月19日
  • matlab里for循环语句_matlab中的for循环语句

    matlab里for循环语句_matlab中的for循环语句matlab循环语句for怎么用?matlab中for语句使用方法和应用实例for循环语句1、一般格式为:forx(循环变量)=array(数组)commands(执行的循环代码)end2、array可以是一个数字,也可以是数组,例如输入:fora=5fora=1:5fora=1:1:5(以1为步长到5)只不过在a=1:5和a=1:1:5时,会显示之间的结果,a=5时只显示最后结果。a…

    2022年10月6日
  • LSTM模型搭建_LSTM神经网络

    LSTM模型搭建_LSTM神经网络defLSTM_Classifier(self,train,trainLabel,test,testLabel,val_test,val_label,new_test=None):train,test=np.array(train),np.array(test)train,test=train.reshape(train.shape[0],1,train.shape[1]),test.reshape(test.shape[0],1,tes…

    2022年9月11日
  • FFmpeg从入门到精通笔记之一库介绍

    FFmpeg从入门到精通笔记之一库介绍FFmpeg:FastForwardMovingPictureExpertsGroup(mpeg:动态图像专家组)H.264:国际标准化组织(ISO)和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式.H.264是ITU-T以H.26x系列为名称命名的标准之一AVC(AdvanedVideoCoding):ISO/IECMPEG一方对H.264的称呼…

    2022年6月26日
  • sql 聚合函数对 null 的处理[通俗易懂]

    sql 聚合函数对 null 的处理[通俗易懂]聚合函数计数类型(count)SELECTCOUNT(*)FROM(SELECT1ASnumUNIONALLSELECT1ASnumUNIONALLSELECT2ASnumUNIONALLSELECTNULLASnum);SELECTCO

    2022年6月21日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号