• 路径分析—QGIS+PostgreSQL+PostGIS+pgRouting(一)


    路径分析—QGIS+PostgreSQL+PostGIS+pgRouting(一)

    路径分析—PostgreSQL+GeoServer+Openlayers(二)

    前言

    因业务需求,需要做最短路径分析。最近几天查询资料,并自己动手,实现了简单的路径分析。

    下面就介绍具体的实现过程。

    本篇文章最终结果是在 PostgreSQL 数据库中实现的,后续的可视化展示会跟进。

    一、道路数据处理

    如果你已经有了道路数据,那就直接使用。

    由于当前并没有较好的道路数据,这里我自己用 QGIS 造了些数据以供使用。

    为了效果较好,在创建道路数据时是叠加了影像图的。并且要开启“捕捉工具”,这样在后续的拓扑分析中更好。

    在完成道路数据的创建后,我直接进行了后续的工作,但是最终发现有问题,分析时发现:道路的数据在每个相交的点处要进行打断,否则无法进行路径分析。

    于是在这里对道路数据做了处理。使用“线相交”工具,输入、相交图层选当前道路图层:

    如下图:

    这三段本是一条道路,但是为了拓扑分析,需要进行在和别的道路相交点进行打断。

     

    此处部分要注意:

      1、编辑时开启“捕捉工具”

      2、完成道路后进行线的打断

    二、数据入库

    数据库这一块,因为 PostgreSQL  有强大的空间数据处理扩展插件(PostGIS),并且也有路径分析的插件(pgRouting),所以选用该数据库。

    1)、PostgreSQL 数据安装

      1、windows 下,直接在官网下载安装包即可,安装完成数据库后,会有 stackbuilder 安装向导,可以安装对应的一些插件等,比较方便;

      2、Ubuntu下(我用的服务器),在 18.04 及以上,可以使用 PostgreSQL Apt Repository ,这样可以安装需要的版本;

        2.1、PostgreSQL Apt Repository 使用

      3、安装及配置参考

    2)、PostGIS

      这部分有两块,一个是 PostgreSQL 的扩展,一个是 PostGIS的GUI(需要单独安装,主要用于导入空间数据)。

    3)、数据导入

      1、创建数据库,创建完成后需要进行对数据库添加空间扩展

    复制代码
    -- 提供如下空间信息服务功能:空间对象、空间索引、空间操作函数和空间操作符
    CREATE EXTENSION postgis;
    -- 用于网络分析的扩展模块
    CREATE EXTENSION pgrouting;
    -- gis 拓扑
    CREATE EXTENSION postgis_topology;
    -- 提供了几个函数来确定字符串之间的相似性和距离
    CREATE EXTENSION fuzzystrmatch;
    CREATE EXTENSION postgis_tiger_geocoder;
    CREATE EXTENSION address_standardizer;
    复制代码

      2、使用工具导入空间数据,最新版本在Windows下名字比较长,如下图:

     

     

    到这里就完成了空间数据的导入,在这个过程中会遇到一些问题,可以参考:PostgreSQL 与 PostGIS 安装使用注意坑

    三、构建拓扑

    这一块主要是在数据库中使用 SQL 完成,创建对应的 source、target、length、reverse_cost 字段并赋值。

    创建拓扑函数的使用

    复制代码
    -- 添加起点id
    ALTER TABLE public.roads ADD COLUMN source integer;
    
    -- 添加终点id
    ALTER TABLE public.roads ADD COLUMN target integer;
    
    -- 添加道路权重值
    ALTER TABLE public.roads ADD COLUMN length double precision;
    
    
    -- 创建拓扑结构                  
    -- 为roads表创建拓扑布局,即为source和target字段赋值
    SELECT pgr_createTopology('roads',0.00001, 'geom','id');
    
    
    -- 创建索引
    -- 为source和target字段创建索引
    CREATE INDEX source_idx ON roads ("source");
    CREATE INDEX target_idx ON roads ("target");
    
    
    -- 为length赋值,这里在计算的时候用 ST_Transform 进行了转换
    UPDATE roads SET length =st_length(ST_Transform(geom,3857));
    
    -- 为 roads 表添加 reverse_cost 字段并用length的值赋值
    ALTER TABLE roads ADD COLUMN reverse_cost double precision;
    UPDATE roads SET reverse_cost =length;
    复制代码

    四、路径分析

    pgRouting 提供的最佳路径算法比较多,具体可以参考:pgRouting 最短路径算法查询

    这里用 Shortest Path Dijkstra(狄克斯特拉)算法进行计算。

    最新的 pgr_dijkstra 算法,支持多种方式,一对一、一对多、多对一、多对多等。

    1)、用例分析

    复制代码
    pgr_dijkstra(Edges SQL, start vid, end vid , [directed])
    pgr_dijkstra(Edges SQL, start vid, end vids , [directed])
    pgr_dijkstra(Edges SQL, start vids, end vid , [directed])
    pgr_dijkstra(Edges SQL, start vids, end vids , [directed])
    pgr_dijkstra(Edges SQL, Combinations SQL , [directed])
    RETURNS SET OF (seq, path_seq, [start_vid], [end_vid], node, edge, cost, agg_cost)
    OR EMPTY SET
    复制代码

    传入的参数:

      1、Edges SQL

        a、id,创建拓扑的标识,名称不同用 as

        b、source,边起点标识符,拓扑后添加的字段

        c、target,边终点标识符,拓扑后添加的字段

        d、cost,边权重(长度)

        e、reverse_cost,回程权重

      2、start vid:路径起始点标识

      3、end vid:路径终点标识

      4、directed:ture 时,图被认为是有向的

    返回参数:

      1、seq:查询结果排序值

      2、path_seq:一个路径下的排序值,新的路径重新从1开始

      3、start_vid:多对一、多对,有这个字段,路径的起始点标识

      4、end_vid:一对多、多对多,有这个字段,路径的终点标识

      5、node:路径中个个边连接点的标识(上一个边的 end,下一个边的 start)

      6、edge:路径中边的标识

      7、cost:当前边的成本(长度)

      8、reverse_cost:总成本(总长度)

    2)、具体使用

    复制代码
    -- 最短路径分析
    -- 直接使用,返回的是算法默认数据
    SELECT * from  public.pgr_dijkstra(
        'SELECT
        id,
        source::integer,
        target::integer,
        length::double precision AS cost,
        reverse_cost
        FROM roads', 
        1, 
        20, 
        false
    );
    
    
    -- edge 是创建拓扑时的 id 标识字段,所以可以通过这个在 roads 中筛选,并通过数据库自带的可视化查看结果
    SELECT * from roads where "id" in
    (
        SELECT edge from  public.pgr_dijkstra(
            'SELECT
            id,
            source::integer,
            target::integer,
            length::double precision AS cost,
            reverse_cost
            FROM roads', 
            1, 
            20, 
            false
        )
    );
    复制代码

    第二个SQL效果如下:

  • 相关阅读:
    20道前端高频面试题(附答案)
    3、Elasticsearch功能使用
    IDEA 28 个天花板技巧 + 12 款神级插件,生产力起飞...
    Arcgis使用教程(十一)ARCGIS地图制图之经纬网格设置参数详解
    springboot~封装依赖引用包jar还是pom,哪种更规范
    腾讯mini项目-【指标监控服务重构】2023-08-04
    【uniapp】通用列表封装组件
    Jenkins+vue发布项目
    小规模自建 Elasticsearch 的部署及优化
    【C语言库函数模拟实现 】# Strlen()
  • 原文地址:https://www.cnblogs.com/zhurong/p/16778528.html