一、软件安装

GeoServer下载地址:

http://geoserver.org/download/

PostgreSQL下载地址:

https://www.postgresql.org/download/

paAdmin3下载地址:

https://www.pgadmin.org/download/pgadmin-3-windows/

PostGIS下载地址:

http://postgis.net/windows_downloads/

pgRouting已经包含在安装程序中。

所有下载程序如下:

安装过程不再详述。

二、数据制作

我使用的是ArcMap来绘制路网数据,也可以使用其它的GIS软件,但好像没有这么方便,地理坐标系使用GCS_WGS_1984,编号为:4326。

注意:所有线段连接的地方都需要断开,这样便于以后的分析。

三、数据处理

使用paAdmin3连接PostgreSQL,并执行以下语句,在新的空间数据库里添加空间扩展:

CREATE EXTENSION postgis;

CREATE EXTENSION pgrouting;

CREATE EXTENSION postgis_topology;

CREATE EXTENSION fuzzystrmatch;

CREATE EXTENSION postgis_tiger_geocoder;

CREATE EXTENSION address_standardizer;

制作完路网数据后,需要使用 来把路网数据导入到PostgreSQL中去。

点击“View connection details....”在弹出的窗口中填入PostgreSQL的账号和密码,以及Database。

连接成功后,需要设置一下“Optionns...”

需要使用GBK编码,并勾选最下面一个选项。

添加路网数据,并设置SRID为:4326

导入完成后,会在数据库中创建一个对应的表:

在查询表中分别执行下列SQL,对表结构进行修改:

1.修改表结构

--添加起点id

ALTER TABLE public.road_xblk ADD COLUMN source integer;

--添加终点id

ALTER TABLE public.road_xblk ADD COLUMN target integer;

--添加道路权重值

ALTER TABLE public.road_xblk ADD COLUMN length double precis

2.创建拓扑结构                  

--为sampledata表创建拓扑布局,即为source和target字段赋值

SELECT pgr_createTopology('public.road_xblk',0.0001, 'geom', 'gid');

3.创建索引

--为source和target字段创建索引

CREATE INDEX source_idx ON road_xblk("source");

CREATE INDEX target_idx ON road_xblk("target");

4.给长度赋值

--为length赋值

update road_xblk set length =st_length(geom);

--为road_xblk表添加reverse_cost字段并用length的值赋值

ALTER TABLE road_xblk ADD COLUMN reverse_cost double precision;

UPDATE road_xblk SET reverse_cost =length;

5.创建最短路径函数

---创建查询随意两点之前的最短路径的函数

 DROP FUNCTION pgr_fromAtoB(tbl varchar,startx float, starty float,endx float,endy float);

 CREATE OR REPLACE function pgr_fromAtoB(tbl varchar,startx float, starty float,endx float,endy float)  

 returns geometry as 

 $body$  

 declare 

     v_startLine geometry;--离起点最近的线 

     v_endLine geometry;--离终点最近的线 

     v_startTarget integer;--距离起点最近线的终点

     v_startSource 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_se geometry;--开始到结束

     v_shPath_es geometry;--结束到开始

     v_shPath geometry;--最终结果

     tempnode float;      

 begin

     --查询离起点最近的线 

     execute 'select geom, source, target  from ' ||tbl||

                             ' where ST_DWithin(geom,ST_Geometryfromtext(''point('||         startx ||' ' || starty||')'',4326),15)

                             order by ST_Distance(geom,ST_GeometryFromText(''point('|| startx ||' '|| starty ||')'',4326))  limit 1'

                             into v_startLine, v_startSource ,v_startTarget; 

     --查询离终点最近的线 

     execute 'select geom, source, target from ' ||tbl||

                             ' where ST_DWithin(geom,ST_Geometryfromtext(''point('|| endx || ' ' || endy ||')'',4326),15)

                             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; 

    -- ST_Distance 

     --从开始的起点到结束的起点最短路径 

     execute 'SELECT st_linemerge(st_union(b.geom)) ' ||

     'FROM pgr_kdijkstraPath( 

     ''SELECT gid as id, source, target, length as cost FROM ' || tbl ||''',' 

     ||v_startSource || ', ' ||'array['||v_endSource||'] , false, false 

     ) a, ' 

     || tbl || ' b 

     WHERE a.id3=b.gid   

     GROUP by id1   

     ORDER by id1' into v_res ;

     --从开始的终点到结束的起点最短路径

     execute 'SELECT st_linemerge(st_union(b.geom)) ' ||

     'FROM pgr_kdijkstraPath( 

     ''SELECT gid as id, source, target, length as cost FROM ' || tbl ||''',' 

     ||v_startTarget || ', ' ||'array['||v_endSource||'] , false, false 

     ) a, ' 

     || tbl || ' b 

     WHERE a.id3=b.gid   

     GROUP by id1   

     ORDER by id1' into v_res_b ;

     --从开始的起点到结束的终点最短路径

     execute 'SELECT st_linemerge(st_union(b.geom)) ' ||

     'FROM pgr_kdijkstraPath( 

     ''SELECT gid as id, source, target, length as cost FROM ' || tbl ||''',' 

     ||v_startSource || ', ' ||'array['||v_endTarget||'] , false, false 

     ) a, ' 

     || tbl || ' b 

     WHERE a.id3=b.gid   

     GROUP by id1   

     ORDER by id1' into v_res_c ;

     --从开始的终点到结束的终点最短路径

     execute 'SELECT st_linemerge(st_union(b.geom)) ' ||

     'FROM pgr_kdijkstraPath( 

     ''SELECT gid as id, source, target, length as cost FROM ' || tbl ||''',' 

     ||v_startTarget || ', ' ||'array['||v_endTarget||'] , false, false 

     ) a, ' 

     || tbl || ' b 

     WHERE a.id3=b.gid   

     GROUP by id1   

     ORDER by id1' 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_Line_Locate_Point(v_res, v_statpoint) into v_perStart; 

     select  ST_Line_Locate_Point(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_Line_SubString(v_res,v_perStart, v_perEnd) into v_shPath;

     return v_shPath; 

 end; 

 $body$ 

 LANGUAGE plpgsql VOLATILE STRICT;

四、数据发布

数据准备完成后,就需要用GeoServer来进行发布:

启动GeoServer,在浏览器中输入,http://localhost:8080/geoserver/web/,登录到GeoServer。

1.创建工作区

添加xblk名称的工作区。

2.添加数据存储:

填入对应的连接信息:

3.添加图层:

注意红框中的内容。

4.添加路径查询服务,添加图层,选择“配置新的SQL视图”:

视图名称:navigation

SQL语句:

SELECT * FROM pgr_fromAtoB('road_xblk', %x1%, %y1%, %x2%, %y2%)

验证的正则表达式:^-?[\d.]+$

类型:LingString

SRID:4326

点击保存后,填入SRS,并自动计算范围:

五、结果展示

使用OpenLayer进行结果展示,代码请直接下载,结果如下:

OpenLayer展示代码下载

说明:这个最短路径的算法有一定的问题,在特定的条件下,查找的不一定是最短的路径,需要对数据进行再处理,或者对算法进行优化。

GeoServer+PostgreSQL+PostGIS+pgRouting实现最短路径查询的更多相关文章

  1. postgresql+postgis+pgrouting实现最短路径查询(2)---openlayers+geoserver实现最短路径

    自己的最短路径实现基本上是按照参考博文的1.2和3进行的,实现的时候也是问题不断,只能是一个一个解决. 问题1:自己发布的geoserver服务无法和OSM底图叠加到一起. 解决:参考博文2提到发布服 ...

  2. postgresql+postgis+pgrouting实现最短路径查询(3)--流程图

    项目结束,做一个项目的总结汇报,就把最短路径查询的实现流程图画了一下,现在补出来:

  3. postgresql+postgis+pgrouting实现最短路径查询(1)---线数据的处理和建立拓扑

    准备一个线shp数据,并将其导入postgres里面,postgres安装postgis和pgrouting两个插件(方法见http://www.cnblogs.com/nidaye/p/455352 ...

  4. 搭建简易Web GIS网站:使用GeoServer+PostgreSQL+PostGIS+OpenLayers3

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

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

    前言 因业务需求,需要做最短路径分析.最近几天查询资料,并自己动手,实现了简单的路径分析. 下面就介绍具体的实现过程. 本篇文章最终结果是在 PostgreSQL 数据库中实现的,后续的可视化展示会继 ...

  6. Geoserver+Postgresql+PostGIS 进行数据发布

    1.postgressql+postgis安装 由于我已经安装了,因此没法进行截图,给出下载地址 下载地址:https://www.postgresql.org/ 记得一定要下载edu的版本 因为这个 ...

  7. postgresql+postgis+pgrouting安装步骤图解

    1.在此(https://www.bigsql.org/postgresql/installers.jsp/)下载postgresql(开源数据库,gis行业推荐使用); 2.在此(http://wi ...

  8. WFS: postgresql(postgis)和shp文件查询效率对比

    对GeoServer上的WFS的各种数据源查询效率感兴趣,做个测试.本次测试了Postgresql.geopackage.shp文件三种数据源的查询效率,无论是本机还是服务器环境,pg存储查询效率都比 ...

  9. 基于pgrouting的最短路径规划

    最近项目上有一个计算两点最短路径的需求,即就是类似于百度地图的路径规划问题,小编研究了一段时间,并参考了相关资料,基于postgresql+postgis+pgrouting实现了简单的路径规划,计算 ...

随机推荐

  1. 201521123002 《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...

  2. 201521123071《java程序设计》第三周学习总结

    1. 本周学习总结 这周主要学习了构造函数,类与对象,就是这周事情很多,还没来得及好好复习,所以有很多知识都没有认识透彻.但我会尽力补上的. http://images2015.cnblogs.com ...

  3. 201521123106《java程序设计》第二周学习总结

    1. 本周学习总结 学习了java的基础语法.在java中使用浮点型会不精确,改用double行就好.学习了string的类型,string的对象是不可变的,创建之后不能再修改,在string的拼接中 ...

  4. 201521123057 《Java程序设计》第1周学习总结

    本章学习总结 第一章是本学期Java学习的起步,主要介绍了Java版本,平台以及JDK,JRE,JDK的内容 书面作业 为什么java程序可以跨平台运行?执行java程序的步骤是什么?(请用自己的语言 ...

  5. 如何将ubuntu文件夹中文名改为英文

    其实我已经忍了很久. ubuntu在中文界面下面,自动创建了"桌面","文档",图片 .公共的 .下载. 音乐. 视频等中文目录. 在命令行下操作的时候,要么切 ...

  6. 201521123121 《Java程序设计》第12周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. Java流(Stream).文件(File)和IO Java.io包几乎包含了所有操作输入.输出需要的类.所有 ...

  7. 《Java课程设计》

    一. 本组课题 简易文件资源管理器 需求分析 查找文件功能:可以根据指定的目录名与待查找的文件,在指定目录中进行查找,并返回结果 实现文件的拷贝与粘贴功能 实现文本类文件(.txt, .java, . ...

  8. linux系统命令<二>----du的使用方法

    1> 要显示一个目录树及其每个子树的磁盘使用情况 du /home/linux 这在/home/linux目录及其每个子目录中显示了磁盘块数. 2> 要通过以1024字节为单位显示一个目录 ...

  9. temp-重庆农商行二次出差

    1, 住宿(远舰商务酒店) 与胡仕川一起住   1722房间,  178-27=151(返现后). 7月30日   7月31日  8月1日 8月2日 8月3日 2, 住宿(郎菲酒店)一个人住, 158 ...

  10. 克隆虚拟机 virtualbox 修改 uuid

    cmd E:\Program Files\Oracle\VirtualBox>VBoxManage.exe internalcommands sethduuid "E:\Program ...