微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

路径规划PgRouting

路径规划PgRouting

sf2gis@163.com

2015年7月1日

1 目标:根据矢量路线图,进行路线规划计算。

输入起止点,生成路线规划的最短路径。

2方法:pgRouting。

目标:使用已有的成熟算法,利用postgresql中的postgis图层和postgis算法,进行路线规划。

原理:Dijkstra,A*(A Star)。

Dijkstra:从起点开始计算到各点的最短路径,逐个取出。找到最短路径。

参考:

http://baike.baidu.com/view/1712262.htm?fromtitle=Dijkstra%E7%AE%97%E6%B3%95&fromid=215612&type=syn

A*:与Dijkstra类似,从起点开始计算与各点的最短路径和终点的估计最短路径之和,逐个取出。找到最短路径。效率较高。

参考:http://www.jb51.cc/article/p-cknoyiud-yt.html

2.1 方法:安装

参考:http://www.xuebuyuan.com/1655300.html

2.1.1下载源程序

下载pgRouting,解压后复制到postgres的目录中,与原程序合并。

如果安装的postgis中已经包含pgRouting则不用再手动安装。

2.1.2添加postgis和pgRouting扩展

Create Extension Postgis;

Create Extension pgRouting;

参见:..\postgis\Postgis.docx中扩展安装方法

2.2 方法:准备规划数据

规则数据要求各个线路之间具有相互独立,在换乘站具有节点。

2.2.1创建换乘节点:在线路相交的位置生成节点。

2.2.1.1 使用Qgis生成一副简单的线路矢量图。

2.2.1.2 使用OpenJump进行交点分割。

参见:..\QGIS\编译过程\qgis应用\qgis应用-矢量操作.docx中OpenJump部分。

2.2.1.3 将数据导入postgis。

参见:..\postgis\Postgis.docx

2.2.2构建拓扑关系:pgr_createtopology()。

拓扑关系:所有线段节点之间的相互关系。包括每一条线段的节点与其它节点之间的连接线起点、终点,且每条线段只使用一次。目的是路径的可达性基础数据。

起点:source。

终点:target。

2.2.2.1 添加起止点:

2.2.2.2 构建拓扑数据索引:认创建source和target的btree索引。

如果没有创建,可以使用create index IndexName on TableName(“colName”);创建索引。

2.2.3添加每条线段的权重:cost

可以使用qgis或者直接在postgis中添加cost的字段(integer)并设置一些值。

2.3 方法:Dijkstra计算最短路径,pgr_dijkstra()。

dijstra算法需要提供每个元素的id,source,target,cost;路径起点,终点。

结果为id,起点,经过的边,cost数组。

将结果保存为新的表供使用。

示例:将结果保存为数据表

select seq,id1 asnode,id2 as edge,cost into dijkstra from pgr_dijkstra(

'select gid asid,cost::double precision from road_noded',1,8,false,false

);

示例:将结果保存为矢量表,并在qgis中显示

参考:http://www.bubuko.com/infodetail-907849.html

create tabledijkstraResult as

select seq,a.cost,the_geom from pgr_dijkstra(

'select gid asid,

1,false) a

left join

road_noded b

on

a.id2=b.gid;

2.4 方法:A*计算最短路径

A*算法需要使用每个线段的起点x,y和终点x,y坐标。

添加线段起止点的x1,y1,x2,y2字段。

为每个字段赋值。

查询结果保存为新表。

示例:结果保存为数据表。

select seq,cost into astar from pgr_astar(

'select gid asid,cost::double precision,x1,y2 fromroad_noded',false

);

示例:结果保存为矢量表,并在Qgis中显示

selectthe_geom,id,id1,id2,di.cost into astar2 from pgr_astar(

'select gid asid,false

) as di joinroad_noded pt on di.id2=pt.gid;

3 方法:发布WMS路径查询服务

3.1 生成最短路径查询函数生成sql函数pgr_framAtoB()。

-- Function:pgr_fromatob(character varying,double precision,doubleprecision,double precision)

-- DROP FUNCTIONpgr_fromatob(character varying,double precision);

CREATE OR REPLACEFUNCTION pgr_fromatob(

IN tbl character varying,

IN x1 double precision,

IN y1 double precision,

IN x2 double precision,

IN y2 double precision,

OUT seq integer,

OUT gid integer,

OUT name text,

OUT heading double precision,

OUT cost double precision,

OUT geom geometry)

RETURNS SetoF record AS

$BODY$

DECLARE

sqltext;

recrecord;

source integer;

target integer;

point integer;

BEGIN

-- Find nearest node

EXECUTE 'SELECT id::integer FROM road_noded_vertices_pgr

ORDER BY the_geom <->ST_GeometryFromText(''POINT('

|| x1 || ' ' || y1 ||')'',4326) LIMIT 1' INTO rec;

source := rec.id;

EXECUTE 'SELECT id::integer FRomroad_noded_vertices_pgr

ORDER BY the_geom <->ST_GeometryFromText(''POINT('

|| x2 || ' ' || y2 ||')'',4326) LIMIT 1' INTO rec;

target := rec.id;

-- Shortest path query (Todo: limit extentby BBox)

seq := 0;

sql := 'SELECT gid,the_geom,name,

ST_Reverse(the_geom) ASflip_geom FROM ' ||

'pgr_dijkstra(''SELECTgid as id,source::int,target::int,'

||'cost::float AS cost FROM '

||quote_ident(tbl) || ''','

|| source ||',' || target

|| ',false) a,'

||quote_ident(tbl) || ' WHERE id2 = gid ORDER BY seq';

-- Remember start point

point := source;

FOR rec IN EXECUTE sql

LOOP

-- Flip geometry (if required)

IF ( point != rec.source ) THEN

rec.the_geom := rec.flip_geom;

point := rec.source;

ELSE

point := rec.target;

END IF;

-- Calculate heading (simplified)

EXECUTE 'SELECT degrees( ST_Azimuth(

ST_StartPoint(''' ||rec.the_geom::text || '''),

ST_EndPoint(''' ||rec.the_geom::text || ''') ) )'

INTO heading;

-- Return record

seq := seq + 1;

gid :=rec.gid;

name := rec.name;

cost := rec.cost;

geom := rec.the_geom;

RETURN NEXT;

END LOOP;

RETURN;

END;

$BODY$

LANGUAGE plpgsql VOLATILE STRICT

COST 100

ROWS 1000;

ALTER FUNCTIONpgr_fromatob(character varying,double precision)

OWNER TO postgres;

3.2 发布WMS的postgis sqlview

关于sqlview的使用,参见:GeoServer.docx中postgis参数WMS部分。

注意:发布要的图层要使用4326,使用其它srs不能正常显示???。

不要使用从数据计算范围,会报错。手动输入。

参考:http://lists.osgeo.org/pipermail/postgis-users/2014-January/038518.html

3.2.1设置sqlview的sql及相关属性

SELECT ST_MakeLine(route.geom)FROM (

SELECT geom FROM pgr_fromAtoB('road_noded',%x1%,%y1%,%x2%,%y2%

) ORDER BY seq) AS route

3.2.2测试:使用layer preview显示openlayers,添加参数查看。

认的url上添加查询参数,结果如下:

http://localhost:8080/geoserver/pgrouting/wms?service=WMS&version=1.1.0&request=GetMap&layers=pgrouting:pgrouting&styles=&bbox=-10.0,10.0&width=768&height=768&srs=EPSG:4326&format=application/openlayers&viewparams=x1:-3;y1:1.6;x2:-2.7;y2:1.7

4方法:OpenLayers中使用最短路径

参考:http://workshop.pgrouting.org/chapters/ol3_client.html

4.1 构建WMS的viewparams参数。

//pgrouting test

var params = {

LAYERS: 'pgrouting:pgrouting',

FORMAT: 'image/png',

CRS:'epsg:4326'

};

//add pgrouting

var viewparams = [

'x1:' +startPoint.getGeometry().getCoordinates()[0],'y1:' +startPoint.getGeometry().getCoordinates()[1],

'x2:' +destPoint.getGeometry().getCoordinates()[0],'y2:' +destPoint.getGeometry().getCoordinates()[1]

];

params.viewparams = viewparams.join(';');

4.2 示例:设置起止点,自动生成最短路径。

放大后如下图所示。

<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.0 Transitional//EN">

<html>

<head>

<style>

.map2{height:400px;width:100%;}

</style>

<script src="D:/Data/test/openlayers/jquery-1.11.1.min.js"></script>

<link rel="stylesheet"href="D:/ProgramData/OpenLayers_SDK_v3.6.0/apidoc/styles/bootstrap.min.css">

<scriptsrc="D:/ProgramData/OpenLayers_SDK_v3.6.0/apidoc/scripts/bootstrap.min.js"></script>

<link rel="stylesheet" href="D:/ProgramData/OpenLayers_SDK_v3.6.0/css/ol.css"type="text/css">

<scriptsrc="D:/ProgramData/OpenLayers_SDK_v3.6.0/build/ol.js"></script>

<title>testOpenLayers</title>

</head>

<body>

<h2>Head Test OpenLayers</h2>

<div id="map2"class="map2">Map</div>

<script type="text/javascript">

/************************************/

//base map

map=new ol.Map

({

target:'map2',

layers:[new ol.layer.Image({source:newol.source.ImageWMS({

url:'http://localhost:8080/geoserver/testShp/wms',

params: {'LAYERS': 'states'},

serverType:'geoserver',

projection:ol.proj.get('epsg:4326'),

})

})],

view:new ol.View

({

zoom:4,

projection: new ol.proj.get('epsg:4326'),

center:[0,0]

})

});

var bounds=[-180,-10,10,60];

map.getView().fitExtent(bounds,map.getSize());

/************************************/

// The "start" and "destination" features.

var startPoint = new ol.Feature();

var destPoint = new ol.Feature();

startPoint.setGeometry(new ol.geom.Point([-3,1.6]));//([-3.8,0.67]));//([-3,1.6]));

destPoint.setGeometry(newol.geom.Point([-0.84,1.5]));//([-2.7,1.7]));

// The vector layer used to display the "start" and"destination" features.

var vectorLayer = new ol.layer.Vector({

source: new ol.source.Vector({

features: [startPoint,destPoint]

})

});

map.addLayer(vectorLayer);

//pgrouting test

var params = {

LAYERS: 'pgrouting:pgrouting',

CRS:'epsg:4326'

};

//add pgrouting

var viewparams = [

'x1:' + startPoint.getGeometry().getCoordinates()[0],'y1:' + startPoint.getGeometry().getCoordinates()[1],

'x2:' + destPoint.getGeometry().getCoordinates()[0],'y2:'+ destPoint.getGeometry().getCoordinates()[1]

];

params.viewparams = viewparams.join(';');

//add result layer

result = new ol.layer.Image({

source: new ol.source.ImageWMS({

url:'http://localhost:8080/geoserver/pgrouting/wms',

params: params

})

});

map.addLayer(result);

</script>

</body>

</html>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐