首页 > 数据库 >路径分析—PostgreSQL+GeoServer+Openlayers(二)

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

时间:2022-10-13 10:01:48浏览次数:82  
标签:路径分析 PostgreSQL -- res into ST 终点 Openlayers shPath

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

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

前言

上一篇文章中实现数据库层面的路径分析了,可以在数据库里面通过 SQL 查询到结果。

本篇文章实现了从前端页面直接可视化操作点选起点、终点,并返回最短路径进行展示。

一、数据库函数

在 PostgreSQL 数据库中创建函数,该函数实现的功能是:传入表名、起点、终点经纬度、距离等参数,返回对应的最短距离 geometry。

创建的函数具体如下:

-- 删除已经存在的函数(可能会报错,报错的话注释)
DROP FUNCTION pgr_fromAtoB(tbl varchar,startx float, starty float,endx float,endy float);
 
-- tbl路网表名
-- startx起点经度
-- starty起点纬度
-- endx终点经度
-- endy终点纬度
-- diatance 起点、终点到路径查询的距离
CREATE OR REPLACE function pgr_fromAtoB(tbl varchar,startx float, starty float,endx float,endy float, distance float)
 
--限制返回类型
returns geometry as $body$
declare
    v_startLine geometry;    -- 离起点最近的线 
    v_endLine geometry;        -- 离终点最近的线 
    
    v_startSource integer;    -- 距离起点最近线的起点
    v_startTarget integer;    -- 距离起点最近线的终点
    v_endSource integer;    -- 距离终点最近线的起点
    v_endTarget integer;    -- 距离终点最近线的终点
    
    v_statpoint geometry;    -- 在v_startLine上距离起点(传入的起点)最近的点 
    v_endpoint geometry;    -- 在v_endLine上距离终点(传入的终点)最近的点 
    
    v_res geometry;            -- 最短路径分析结果
    v_res_a geometry;
    v_res_b geometry;
    v_res_c geometry;
    v_res_d geometry; 
 
    v_perStart float;        -- v_statpoint在v_res上的百分比 
    v_perEnd float;            -- v_endpoint在v_res上的百分比 
    
    v_shPath_ss geometry;    --起点到最近距离点的线
    v_shPath_ee geometry;    --终点到最近距离点的线
    v_shPath geometry;        --最终结果
    
    tempnode float;      
begin
 
    -- 4326坐标系
    -- 查询离起点最近的线 
    -- 找起点15米范围内的最近线
    execute 'select geom, source, target  from ' ||tbl||
                            ' where ST_DWithin(geom,ST_Geometryfromtext(''point('|| startx || ' ' || starty||')'',4326),'|| distance ||')
                            order by ST_Distance(geom,ST_GeometryFromText(''point('|| startx ||' '|| starty ||')'',4326))  limit 1'
                            into v_startLine, v_startSource ,v_startTarget;
                            
    -- 查询离终点最近的线 
    -- 找终点15米范围内的最近线
    execute 'select geom, source, target from ' ||tbl||
                            ' where ST_DWithin(geom,ST_Geometryfromtext(''point('|| endx || ' ' || endy ||')'',4326),'|| distance ||')
                            order by ST_Distance(geom,ST_GeometryFromText(''point('|| endx ||' ' || endy ||')'',4326))  limit 1'
                            into v_endLine, v_endSource,v_endTarget;

    -- 如果没找到最近的线,就返回null
    if (v_startLine is null) or (v_endLine is null) then 
        return null;
    end if ; 

    -- 分别找到路径上距离起点和终点最近的点
    select  ST_ClosestPoint(v_startLine, ST_Geometryfromtext('point('|| startx ||' ' || starty ||')',4326)) into v_statpoint; 
    select  ST_ClosestPoint(v_endLine, ST_GeometryFromText('point('|| endx ||' ' || endy ||')',4326)) into v_endpoint;
    
    -- 从开始的起点到结束的起点最短路径
    execute 'SELECT ST_Union(b.geom) ' ||
    'FROM pgr_dijkstra( 
    ''SELECT id, source, target, length as cost FROM ' || tbl ||''',' || v_startSource || ', ' || v_endSource || ' , false ) a LEFT JOIN '
    || tbl || ' b 
    ON a.edge=b.id' into v_res ;
    
    
    --从开始的终点到结束的起点最短路径
    execute 'SELECT ST_Union(b.geom) ' ||
    'FROM pgr_dijkstra( 
    ''SELECT id, source, target, length as cost FROM ' || tbl ||''',' || v_startTarget || ', ' || v_endSource || ' , false ) a LEFT JOIN '
    || tbl || ' b 
    ON a.edge=b.id' into v_res_b ;
    
    --从开始的起点到结束的终点最短路径
    execute 'SELECT ST_Union(b.geom) ' ||
    'FROM pgr_dijkstra( 
    ''SELECT id, source, target, length as cost FROM ' || tbl ||''',' || v_startSource || ', ' || v_endTarget || ' , false ) a LEFT JOIN '
    || tbl || ' b 
    ON a.edge=b.id' into v_res_c ;
    
    --从开始的终点到结束的终点最短路径
    execute 'SELECT ST_Union(b.geom) ' ||
    'FROM pgr_dijkstra( 
    ''SELECT id, source, target, length as cost FROM ' || tbl ||''',' || v_startTarget || ', ' || v_endTarget || ' , false ) a LEFT JOIN '
    || tbl || ' b 
    ON a.edge=b.id' into v_res_d ;

    if(ST_Length(v_res) > ST_Length(v_res_b)) then
       v_res = v_res_b;
    end if;
    
    if(ST_Length(v_res) > ST_Length(v_res_c)) then
       v_res = v_res_c;
    end if;

    if(ST_Length(v_res) > ST_Length(v_res_d)) then
       v_res = v_res_d;
    end if;

    -- 如果找不到最短路径,就返回null (根据实际情况是否需要)
--     if(v_res is null) then 
--        return null; 
--     end if; 
 
    --将 v_res,v_startLine,v_endLine 进行拼接
    select  ST_LineMerge(ST_Union(array[v_res,v_startLine,v_endLine])) into v_res;
    -- 根据起点、终点最近距离点,找到在路径中的百分比
    select  ST_LineLocatePoint(v_res, v_statpoint) into v_perStart;
    select  ST_LineLocatePoint(v_res, v_endpoint) into v_perEnd;

    if(v_perStart > v_perEnd) then 
        tempnode =  v_perStart;
        v_perStart = v_perEnd;
        v_perEnd = tempnode;
    end if;
    
    --截取 v_res
    SELECT ST_LineSubstring(v_res,v_perStart, v_perEnd) into v_shPath;
    
    SELECT ST_MakeLine(ST_SetSRID(ST_Point( startx, starty),4326),v_statpoint) into v_shPath_ss;
    SELECT ST_MakeLine(ST_SetSRID(ST_Point( endx, endy),4326),v_endpoint) into v_shPath_ee;
    -- 将 v_shPath、v_shPath_ss、v_shPath_ee 拼接
    select  ST_LineMerge(ST_Union(array[v_shPath,v_shPath_ss,v_shPath_ee])) into v_shPath;
    
    return v_shPath; 
end;
$body$ LANGUAGE plpgsql VOLATILE STRICT;

注意:

  在使用 PostGIS 中的函数时,由于不同版本下函数名写法会有些不一样,查看自己所用版本的文档。

二、GeoServer SQL View 创建

在创建完成数据库函数后,有两种方式可以调用:

  1、代码连接数据库查询

  2、GeoServer 中创建图层,以PostGIS为数据源,并创建 SQL View

因为原先项目中已经有在用 GeoServer,所用直接选用方式2。

1)、创建数据源

 

 里面的参数主要有:正常的数据源参数、数据库连接参数等

2)、创建图层、编辑 SQL View

新建图层

编辑 SQL View,在编辑好查询语句后,参数、返回结果都可以自动读出。

 

 这样一个 PostGIS 数据源的图层就发布好了

三、Openlayers 调用

在 openlayers 中调用,主要就是WMS图层的调用,这里主要是参数的传递。

下面就只贴出调用 WMS 图层,关于其他起始点点击、清空、分析等具体交互就不在这里。

      const params = {
        LAYERS: 'layername',
        VERSION: '1.1.0',
        REQUEST: 'GetMap',
        FORMAT: 'image/png'
      }
    // pathPoint 起点、终点坐标
      const viewparams = [`x1:${this.pathPoint[0][0]}`, `y1:${this.pathPoint[0][1]}`, `x2:${this.pathPoint[1][0]}`, `y2:${this.pathPoint[1][1]}`]
      params.viewparams = viewparams.join(';')
      this.pathLayer = new Image({
        source: new ImageWMS({
          url: `${GEOSERVER_URL}/wms`,
          params
        })
      })
      this.map.addLayer(this.pathLayer)

这里用的是 ImageWMS。

关于TileWMS 和 ImageWMS 的使用参考这里。

 

实现效果

 

标签:路径分析,PostgreSQL,--,res,into,ST,终点,Openlayers,shPath
From: https://www.cnblogs.com/zhurong/p/16787057.html

相关文章

  • PostgreSQL Create Index Concurrently
    PostgreSQL支持在线创建索引(CREATEINDEXCONCURRENTLY),不堵塞其他会话对被创建索引表的DML(INSERT,UPDATE,DELETE)操作。PostgreSQL提供了一个创建索引的高效特性,即“并发......
  • 【GIS开发】OpenLayers入门学习(JavaScript库)
    1、简介官网地址:https://openlayers.org/源码地址:https://github.com/openlayers/openlayersOpenLayers是一个高性能、功能丰富的库,用于在Web上创建交互式地图。它......
  • 【OpenLayers笔记】对要素进行新增绘制、选择、修改等交互
    绘制-Draw新建一个用来绘制要素的图层:  constvector=newVectorLayer({   source:newVectorSource(),   style:{    "fill-color":"......
  • 路径分析—QGIS+PostgreSQL+PostGIS+pgRouting(一)
    前言因业务需求,需要做最短路径分析。最近几天查询资料,并自己动手,实现了简单的路径分析。下面就介绍具体的实现过程。本篇文章最终结果是在PostgreSQL数据库中实现的,后......
  • postgresql 备份和恢复
    备份pg_dump-ddbname--format=c-h172.20.1.1-p5432-Uodoo>/tmp/bak.dump.$(date+'%Y%m%d')恢复指定参数-C,会自动帮你创建数据库,恢复的数据库名称没法......
  • 1、Linux下源码编译安装PostgreSQL
    操作系统:Centos7说明:postgresql必须在postgres用户下初始化数据库和启动,否则报错。PostgreSQL的特性PostgreSQL是一种几乎可以运行在各种平台上的免费的开放源码的对象关系......
  • 【OpenLayers】绘制基本几何图形
     基本图形有以下几种:CircleLinearRingLineStringMultiLineStringMultiPointMultiPolygonPointPolygon LineString letlayer=newVectorLayer({......
  • Ubuntu20.04和22.04离线安装PostgreSQL14
    今天安装Postgresql14遇到一个问题,目标服务器只有内网,内网提供标准的apt仓库,但是因为不能连接外网,所以没法添加第三方仓库,这样安装pg14就成了问题.从pg的官网......
  • 【OpenLayers】绘制基本图形标注
    letlayer=newVectorLayer();//新建一个绘线层letpointFeature=newFeature(newPoint(fromLonLat([114.02,24])));pointFeature.setStyle(new......
  • camunda_13_postgresql
    前面都是使用H2数据库,体验功能非常方便,但分析table数据就比较麻烦了,下面介绍如何使用postgresql作为后台数据库.按照Camunda官方文档,生产环境优先推荐Oracle和P......