路径分析—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+GeoServer+Openlayers(二)的更多相关文章

  1. 使用GeoServer+OpenLayers发布和调用WMTS、Vector Tile矢量切片服务 | Publishing and Calling WMTS, Vector Tile Service Using GeoServer + OpenLayers

    Web GIS系列: 1.搭建简易Web GIS网站:使用GeoServer+PostgreSQL+PostGIS+OpenLayers3 2.使用GeoServer+QGIS发布WMTS服务 3.使 ...

  2. Geoserver+Openlayers+MySQL设计思想,GeoServer服务器搭建(Docker构建镜像)

    Geoserver+Openlayers+MySQL设计思想,GeoServer服务器搭建(Docker构建镜像) 一.geoserver+openlayers+mysql主要设计思想 1.1 Geo ...

  3. PostgreSQL的存储系统二:REDOLOG文件存储结构二

    REDOLOG文件里的用户数据和数据文件里的用户数据存储结构相同 几个月前同事给台湾一家公司培训<pg9 ad admin>时,有个学员提及WAL里记录的内容为Query时的SQL语句(比 ...

  4. (转)PostGIS+QGIS+GeoServer+OpenLayers实现数据的存储、服务的发布以及地图的显示

    http://blog.csdn.net/gisshixisheng/article/details/41575833 标题比较长,主要呢是实现以下几点: 1.将shp数据导入到PostGIS中: 2 ...

  5. [GeoServer]Openlayers简单调用

    Openlayers Demo: <html> <head> <title>OpenLayers Example</title> <script ...

  6. Geoserver+Openlayers拉框查询

    1.代码 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" co ...

  7. 跟我一起读postgresql源码(二)——Parser(查询分析模块)

    上篇博客简要的介绍了下psql命令行客户端的前台代码.这一次,我们来看看后台的代码吧. 十分不好意思的是,上篇博客我们只说明了前台登陆的代码,没有介绍前台登陆过程中,后台是如何工作的.即:后台接到前台 ...

  8. shp格式数据发布服务:postGIS + postgresql + geoserver

    主要流程: ①使用postgresql创建数据库 ②下载安装postgis插件 ③在创建的数据库中使用postgis插件,执行下列语句 CREATE EXTENSION postgis; CREATE ...

  9. CentOS7 PostgreSQL 主从配置( 二)

    同步流复制配置PostgreSql的流复制是异步的,缺点是Standby上的数据落后于主库上的数据,如果使用Hot Standby做读写分离,就会存在数据一致性的问题.PostgreSql9.1版本后 ...

随机推荐

  1. Docker默认桥接网络是如何工作的

    1. 启动一个Docker容器 一般来说,我们起一个容器比如一个简单的nginx服务会向这样 docker run -d --rm nginx:XXX OK容器起来了,但是并不能通过宿主机被外面的机器 ...

  2. 彻底弄清楚session,cookie,sessionStorage,localStorage的区别及应用场景(面试向)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_94 客户端状态保持是一个老生常谈的问题了,归根结底追踪浏览器的用户身份及其相关数据无非就是以下四种方式:session,cooki ...

  3. pat链表专题训练+搜索专题

    本期题目包括: 1074:https://pintia.cn/problem-sets/994805342720868352/problems/994805394512134144 1052:http ...

  4. 使用 DolphinScheduler 调度 Kylin 构建

    本文章经授权转载 Apache Kylin 上游通常有复杂的数据 ETL 过程,如 Hive 入库.数据清洗等:下游有报表刷新,邮件分发等.集成 Apache DolphinScheduler 后,K ...

  5. C#/VB.NET 替换 PDF 文件上的现有图像

    我们都知道对PDF文件进行修改和编辑不是一件容易的事.但有时当我们想用新的图像来替换PDF文件上的现有图像时,该怎么办呢?别担心,本文将向您展示如何在 C#/VB.NET 中替换 PDF 文件中的现有 ...

  6. Clickhouse基准测试实践

    1.概述 本篇博客将对MySQL.InfluxDB.Clickhouse在写入时间.聚合查询时间.磁盘使用等方面的性能指标来进行比较. 2.内容 比较的数据集,是使用的Clickhouse官网提供的6 ...

  7. Html飞机大战(九): 使徒来袭 (设计敌机)

    好家伙,本篇介绍敌机 好了,按照惯例我们来理一下思路:   我们有一个敌机类,第一步当然是实例一个敌机对象, 然后我们把这个敌机放入我们的敌机群(敌机数组) 然后是熟悉的移动和绘制   那我们回顾一下 ...

  8. UE 实现镜头平移,旋转和缩放

    0x00 引 在数字孪生三维场景中,通过键盘和鼠标来控制镜头的移动,缩放是很常见的行为,也是很必要的行为,用户正是通过这些操作,达到对整个三维场景的观看和控制. 0x01 键盘控制镜头前后左右移动 通 ...

  9. Openstack之各组件命令

    openstack 组件命令 Glance组件操作(镜像服务组件) #环境配置: source /etc/keystone/admin-openrc.sh #查看镜像列表: glance image- ...

  10. 总在用户态调试 C# 程序,终还是搭了一个内核态环境

    一:背景 一直在用 WinDbg 调试用户态程序,并没有用它调试过 内核态,毕竟不是做驱动开发,也没有在分析 dump 中需要接触用内核态的需求,但未知的事情总觉得很酷,加上最近在看 <深入解析 ...