postGIS+GeoServer+Openlayer实现路径分析
目录
postGIS+GeoServer+Openlayer实现路径分析
一、软件安装
1、GeoServer安装(略)
2、postgres+postGIS(插件)+pgRouting(插件)安装(略)
二、创建数据库
可以新建,也可以在安装时就建立,安装时建立如图:
三、把shp数据导入空间数据库
1、打开postgis工具
postgis安装目录下的PostGISShapefile Import/Export Manager
会弹出对话框
2、设置数据库连接
单击view connection details,设置数据库的连接
3、添加shp数据
添加需要导入的shp文件
单击Add File ,会弹出文件选中对话框
选择需要导入是shp文件,注意此处路径一定要是英文,否则会导入失败
4、编码设置
单击options,设备编码格式为GBK,选中generate simple geometries instead of multi geometries。
此处导入的shp数据一定要是单线的,否则无法完成路径计算。
5、查看导入数据
成功导入数据之后就能在postgresql中看到导入的数据表
四、创建路网拓扑结构
1、添加字段
对导入数据添加source、target和length(cost)字段
ALTER TABLE beijing_line ADD COLUMN source integer;
ALTER TABLE beijing_line ADD COLUMN target integer;
ALTER TABLE beijing_line ADD COLUMN length double precision;
UPDATE beijing_line SET length = ST_Length(the_geom);
ps:执行createTopology这个函数之前一定得对数据库执行以下三句sql查询:
CREATE EXTENSION postgis;
CREATE EXTENSION postgis_topology;
CREATE EXTENSION fuzzystrmatch;
2、放大容差
把容差值设置的大一点,可能结果会好点
select pgr_createTopology(‘beijing_line’,0.001,source:=’source’,id:=’gid’,target:=’target’,the_geom:=’the_geom’);
select pgr_createTopology(‘beijing_line’,0.1,source:=’source’,id:=’gid’,target:=’target’,the_geom:=’the_geom’);
把容差值设置的大一点,可能结果会好点
3、测试路网拓扑
1、查询路径:
SELECT * FROM pgr_dijkstra(‘
SELECT gid as id,
source::integer,
target::integer,
length::double precision as cost
FROM beijing_line’,
30, 60, false, false);
无查询结果就执行下面这几个试一试,也可能是两点之间就没有路径
select source from beijing_line;
select target from beijing_line;
select length from beijing_line;
2、查询所经过的所有点:
SELECT st_astext(the_geom) FROM pgr_dijkstra(‘
SELECT gid AS id,
source::integer,
target::integer,
length::double precision AS cost
FROM beijing_line’,
30, 60, false, false) as di
join beijing_line pt
on di.id2 = pt.gid;
3、将路径写入一个几何文件内:
SELECT seq, id1 AS node, id2 AS edge, cost,the_geom into dijkstra_res FROM pgr_dijkstra(‘
SELECT gid AS id,
source::integer,
target::integer,
length::double precision AS cost
FROM beijing_line’,
30, 60, false, false) as di
join beijing_line pt
on di.id2 = pt.gid;
经历过以上的步骤,如果一切顺利,应该能看到结果,这里不再截图。这时初步的准备工作已经完成。
五、定义函数名及函数参数
前面文章介绍了如何利用postgresql创建空间数据库,建立空间索引和进行路径规划。但是在真实的场景中用户进行路径规划的时候都是基于经纬度数据进行路径规划的,因为用户根本不会知道道路上节点的ID。因此文本讲述如何查询任意两点间的最短路径。
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_endSource integer;–距离终点最近线的起点
v_statpoint geometry;–在v_startLine上距离起点最近的点
v_endpoint geometry;–在v_endLine上距离终点最近的点
v_res geometry;–最短路径分析结果 ST_LineSubstring
v_perStart float;–v_statpoint在v_res上的百分比
v_perEnd float;–v_endpoint在v_res上的百分比
v_shPath geometry;–最终结果
tempnode float;
begin
—查询离起点最近的线
execute ‘select geom ,target from ‘ ||tbl||
‘ where
ST_DWithin(geom,ST_Geometryfromtext(”point(‘|| startx ||’ ‘ || starty||’)”),15)
order by ST_Distance(geom,ST_GeometryFromText(”point(‘|| startx ||’ ‘|| starty ||’)”)) limit 1′
into v_startLine ,v_startTarget;
—查询离终点最近的线
execute ‘select geom,source from ‘ ||tbl||
‘ where ST_DWithin(geom,ST_Geometryfromtext(”point(‘|| endx || ‘ ‘ || endy ||’)”),15)
order by ST_Distance(geom,ST_GeometryFromText(”point(‘|| endx ||’ ‘ || endy ||’)”)) limit 1′
into v_endLine,v_endSource;
—如果没找到最近的线,就返回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 ||’)’)) into v_statpoint;
select ST_ClosestPoint(v_endLine, ST_GeometryFromText(‘point(‘|| endx ||’ ‘ || endy ||’)’)) into v_endpoint;
—最短路径
execute ‘SELECT st_linemerge(st_union(b.geom)) ‘ ||
‘FROM pgr_dijkstra(
”SELECT gid as id, source::integer, target::integer, length::double precision AS cost FROM ‘ || tbl ||”’,’
||v_startTarget || ‘, ‘|| v_endSource||’ , false, false
) a, ‘
|| tbl || ‘ b
WHERE a.id2=b.gid
GROUP by id1
ORDER by id1′ into v_res;
—如果找不到最短路径,就返回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(ST_LineMerge(v_res), v_statpoint) into v_perStart;
select ST_LineLocatePoint(ST_LineMerge(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;
return v_shPath;
end;
$body$
LANGUAGE plpgsql VOLATILE STRICT
六、创建基于geoserver的wms服务
上面写了求任意两点间最短路径的sql函数,这篇文章讲一下如何把上面介绍的子功能整合到系统中去。
1、geoserver登录
待geoserver启动后,在浏览器中输入,http://localhost:8080/geoserver/web/
2、创建工作区
单击左侧工作区,如下图所示:
会进入新建工作区页面,单击“添加新的工作区”,如下图所示
在弹出的工作区设置中输入新工作区的名字和命名空间
3、发布shp图层
单击左侧数据存储图标,会进入新建数据源页面
选择shapefile,会进入新建数据源页面
选择工作区,设置数据源名称,选中浏览选中所需要的发布的shp文件,字符集编码选择为GBK。
在新出现的页面中单击发布按钮
在定义srs中选择900913,计算数据边框
4、创建路径规划结果
单击左侧数据存储图标,会进入新建数据源页面
单击postgis,会弹出数据库的访问设置对话框
在对话框中选择工作区,填入数据源名称、数据库名以及用户名密码
在弹出的新页面中单击配置新的SQL视图,
在出现的新页面中输入视图名称以及最短路径规划的查询sql语句(pgr_fromAtoB为自定义的查询函数,需要添加到postgresql中),
SELECT ST_MakeLine(route.geom) FROM (
SELECT geom FROM pgr_fromAtoB(‘ways’, %x1%, %y1%, %x2%, %y2%
)ORDER BY seq) AS route
单击从sql猜想的参数,把x1 y1 x2 y2的默认值都设为0,正则表达式中全部输入”^-?[\d.]+$” 。最后点刷新按钮,在出现的st_makeline结果数据中选择其类型为linestring,坐标系为900913
单击保存。
转载自:https://blog.csdn.net/u011365716/article/details/84431630