路径分析—PostgreSQL+GeoServer+Openlayers(二)
路径分析—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。
实现效果
路径分析—PostgreSQL+GeoServer+Openlayers(二)的更多相关文章
- 使用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.使 ...
- Geoserver+Openlayers+MySQL设计思想,GeoServer服务器搭建(Docker构建镜像)
Geoserver+Openlayers+MySQL设计思想,GeoServer服务器搭建(Docker构建镜像) 一.geoserver+openlayers+mysql主要设计思想 1.1 Geo ...
- PostgreSQL的存储系统二:REDOLOG文件存储结构二
REDOLOG文件里的用户数据和数据文件里的用户数据存储结构相同 几个月前同事给台湾一家公司培训<pg9 ad admin>时,有个学员提及WAL里记录的内容为Query时的SQL语句(比 ...
- (转)PostGIS+QGIS+GeoServer+OpenLayers实现数据的存储、服务的发布以及地图的显示
http://blog.csdn.net/gisshixisheng/article/details/41575833 标题比较长,主要呢是实现以下几点: 1.将shp数据导入到PostGIS中: 2 ...
- [GeoServer]Openlayers简单调用
Openlayers Demo: <html> <head> <title>OpenLayers Example</title> <script ...
- Geoserver+Openlayers拉框查询
1.代码 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" co ...
- 跟我一起读postgresql源码(二)——Parser(查询分析模块)
上篇博客简要的介绍了下psql命令行客户端的前台代码.这一次,我们来看看后台的代码吧. 十分不好意思的是,上篇博客我们只说明了前台登陆的代码,没有介绍前台登陆过程中,后台是如何工作的.即:后台接到前台 ...
- shp格式数据发布服务:postGIS + postgresql + geoserver
主要流程: ①使用postgresql创建数据库 ②下载安装postgis插件 ③在创建的数据库中使用postgis插件,执行下列语句 CREATE EXTENSION postgis; CREATE ...
- CentOS7 PostgreSQL 主从配置( 二)
同步流复制配置PostgreSql的流复制是异步的,缺点是Standby上的数据落后于主库上的数据,如果使用Hot Standby做读写分离,就会存在数据一致性的问题.PostgreSql9.1版本后 ...
随机推荐
- 8月份的.NET Conf 活动 专注于 .NET MAUI
.NET Conf:Focus on MAUI 是一个为期一天的免费直播活动,将于太平洋时间 8 月 9 日上午 9 点开始,来自社区和 Microsoft 团队的演讲者们将分享使用MAUI .了解. ...
- 服务器配置IP
1.服务器系统一般有两个或多个网卡.在企业中一般给服务器网卡配一个可连外网的IP,如172.16.20.22 255.255.255.0 172.16.20.1 方便联网下载安装部分软件,若没有VPN ...
- Java基础 | Stream流原理与用法总结
Stream简化元素计算: 一.接口设计 从Java1.8开始提出了Stream流的概念,侧重对于源数据计算能力的封装,并且支持序列与并行两种操作方式:依旧先看核心接口的设计: BaseStream: ...
- WAF对抗-安全狗(联合查询篇)
WAF对抗-安全狗(联合查询篇) 实验环境 网站安全狗APACHE版V4.0.靶场:dvwa 为了方便对比可以在这个在线靶场申请一个dvwa https://www.vsplate.com/ mysq ...
- 【c语言简单算法】1-阶乘
求n的阶乘 算法要求 从键盘输入一个数,求出这个数的阶乘 代码实现 #include main() { double result=1; size_t n; scanf("%d", ...
- KingbaseES sys_blocking_pids 函数
会话出现了锁等待,想要快速查询到堵塞的会话,可以使用 sys_blocking_pids 函数来实现这一目的. sys_blocking_pids:获取哪些会话阻塞了某个会话(输入参数). sys_b ...
- MySQL半同步复制源码解析
今天 DBA 同事问了一个问题,MySQL在半同步复制的场景下,当关闭从节点时使得从节点的数量 < rpl_semi_sync_master_wait_for_slave_count时,show ...
- 华南理工大学 Python第6章课后测验-1
1.(单选)以下关于语句 a = [1,2,3,(4,5)]的说法中,正确的个数有( )个.(1)a是元组类型 (2)a是列表类型 (3)a有5个元素 (4)a有4个元素(5)a[2] ...
- DFS文件夹无法访问
最近DFS的文件服务器出现了部分文件和文件夹无法访问的情况.客户端直接访问DFS成员的共享文件夹时有是会出现Element not found的错误.有时打开文件的时候会出现文件不存在,或者你没有权限 ...
- 2020年12月-第01阶段-前端基础-HTML CSS 项目阶段(一)
品优购项目(一) 目标: 能会引入ico图标 能简单看懂网站优化的三大标签 能使用字体图标 ( 重点 ) 能说出我们css属性书写顺序 1. 品优购项目介绍 项目名称:品优购 项目描述:品优购是一个电 ...