路径分析—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. OPC UA分布式IO模块

    OPC UA IO模块对工业物联网的影响 OPC UA IO模块是指IO模块支持OPC UA协议,可以直接与OPC Client进行通信,这样就可以从OPC Client上直接远程通过以太网对IO口进 ...

  2. 利用CSS3自定义属性来为网站添加“暗黑模式”(暗色模式/DarkMode)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_114 究竟什么是暗黑模式?这个概念起初来源于macOS系统,该系统的mojave版本为用户提供两个主题皮肤,即浅色和深色的皮肤.自 ...

  3. 2019国家集训队论文《整点计数》命题报告 学习笔记/Min25

    \(2019\)国家集训队论文<整点计数>命题报告 学习笔记/\(Min25\) 补了个大坑 看了看提交记录,发现\(hz\)的\(xdm\)早过了... 前置知识,\(HAOI\)< ...

  4. 面向开发的内存调试神器,如何使用ASAN检测内存泄漏、堆栈溢出等问题

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 目录 介绍 如何使用 ASAN 检测内存泄漏 检测悬空指针访问 检测堆溢出 C++ 中的new/delete不匹配 检测栈 ...

  5. Vue3中插槽(slot)用法汇总

    Vue中的插槽相信使用过Vue的小伙伴或多或少的都用过,但是你是否了解它全部用法呢?本篇文章就为大家带来Vue3中插槽的全部用法来帮助大家查漏补缺. 什么是插槽 简单来说就是子组件中的提供给父组件使用 ...

  6. Queue-jumpers - 平衡树

    题面 Ponyo and Garfield are waiting outside the box-office for their favorite movie. Because queuing i ...

  7. Java 解析Tiff深入研究

    最近在读取客户发过来的tiff文件是,底层竟然报错了,错误:bandOffsets.length is wrong!   没办法,因为错误消息出现在tiff的read中,因此就对 底层序中tiff读取 ...

  8. 【unity游戏入门】1 环境安装

    作者 罗芭Remoo 2021年9月24日 这一个系列随笔记录如何使用unity引擎从零开始开发游戏,软件版本均使用最新版本 有关unity的背景介绍可以通过unity官网https://unity. ...

  9. KingbaseES批量数据加载的实践技巧

    有时,KingbaseES数据库需要在单个或最少的步骤中导入大量数据,这通常称为批量数据导入.其中数据源通常是一个或多个大文件,这个过程有时可能非常慢. 造成性能不佳的原因有很多:索引.触发器.外键. ...

  10. KingbaseES R3 集群删除test库导致主备无法切换问题

    案例说明: 在KingbaseES R3集群中,kingbasecluster进程会通过test库访问,连接后台数据库服务测试:如果删除test数据库,导致后台数据库服务访问失败,在集群主备切换时,无 ...