路径分析—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. PHP断点续传(下载)代码

    <?php /** * PHP-HTTP断点续传实现 * @param string $path: 文件所在路径 * @param string $file: 文件名 * @return voi ...

  2. SpringBoot定时任务 - 集成quartz实现定时任务(单实例和分布式两种方式)

    最为常用定时任务框架是Quartz,并且Spring也集成了Quartz的框架,Quartz不仅支持单实例方式还支持分布式方式.本文主要介绍Quartz,基础的Quartz的集成案例本,以及实现基于数 ...

  3. rsync 文件备份

    # rsync # 实现文件的备份. # 备份位置可以是当前主机,也可以是远程主机. # rsync实现了完全备份和增量备份 # 可以做到:1.将本地主机的文件复制到另一个位置(本地.远程). # 2 ...

  4. Javaweb05-Ajax

    1.基于jQuery的Ajax 1.1 基本Ajax 参数 说明 url 请求地址 type 请求类型 data 请求参数 dataType 返回参数 success 成功处理函数 error 错误处 ...

  5. Qt 国际化翻译

    简介 Qt Linguist 提供了一套加速应用程序翻译和国际化的工具.Qt 使用单一的源码树和单一的应用程序二进制包就可同时支持多个语言和书写系统. 使用 QTranslator 来加载生成的 qm ...

  6. ChromePortable-Chrome便携化、绿化软件v2.0

    ChromePortable-Chrome便携化.绿化软件v2.0-用户手册 By:ybmj@vip.163.com ,http://bbs.kafan.cn/thread-1806385-1-1.h ...

  7. 臭名远扬之 goto 语句

    C 语言自学之 goto 语句 Dome1:以下程序实现从控制台输出1-10,使用goto语句,实现当输出完3之后跳出循环体. 1 #include <stdio.h> 2 3 int m ...

  8. Docker 11 自定义镜像

    参考源 https://www.bilibili.com/video/BV1og4y1q7M4?spm_id_from=333.999.0.0 https://www.bilibili.com/vid ...

  9. Java SE 9 新增特性

    Java SE 9 新增特性 作者:Grey 原文地址: Java SE 9 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new_ ...

  10. MySQL-配置参数时 报错:remove CMakeCache.txt and rerun cmake.On Debian/Ubuntu......

    报错:remove CMakeCache.txt and rerun cmake.On Debian/Ubuntu...... 原因: 1.第一次配置参数时,不完整,出现错误!,(报错也会产生CMak ...