使用pgrouting進行最短路徑搜索

   PgRouting是基於開源空間數據庫PostGIS用於網絡分析的擴展模塊,最初它被稱做pgDijkstra,由於它只是利用Dijkstra算法實現最短路徑搜索,以後慢慢添加了其餘的路徑分析算法,如A 算法,雙向A算法,Dijkstra算法,雙向Dijkstra算法,tsp貨郎擔算法等,而後被改名爲pgRouting。該擴展庫依託PostGIS自身的gist索引,豐富的座標系與圖形類型,強大的幾何處理能力,如空間查詢,空間處理,線性參考等優點,能保障在較大數據級別下的網絡分析效果更快更好。
最新源碼見:
一、環境搭建
須要先安裝PostgreSQL9.6,再安裝PostGIS,注意版本號PostGIS2.4後已經集成了pgRouting,無需單獨安裝
PostGIS 官網 http://www.postgis.org/
pgRouting官網http://pgrouting.org/documentation.html
二、啓用pgRouting功能,鏈接到對應postgres數據庫後執行下面的sql語句
CREATE EXTENSION postgis;
CREATE EXTENSION pgrouting;

 

三、路網數據處理
因爲路網分析的特殊性,只支持LineString類型,不支持MultiLineString類型,若是路網數據爲MultiLineString類型導入前需加工處理,可以使用arcgis在交叉點處使用打斷相交線來分割線,參見
http://resources.arcgis.com/zh-cn/help/main/10.1/index.html#//01m8,最終可用的數據必須爲路網不自相交,導入時選擇簡單的線類型,不然網絡拓撲計算數據會錯誤
 
四、路網拓撲數據計算處理,執行成功後,執行成功後會生產一個**_vertices_pgr的表,裏面包含路網相交點的空間數據
 alter table road add column source int;

alter table road add column target int;

create index road_source_idx on road("source");
create index road_target_idx on road("target");


ALTER TABLE road  ADD COLUMN length double precision;  


SELECT pgr_createTopology('road',0.00001, 'geom', 'gid');  

update road set length =st_length(geom); 


五、查詢最短路徑sql語句javascript

SELECT seq, id1 AS node, id2 AS edge, cost,geom  FROM pgr_dijkstra('  
SELECT gid AS id,                      
source::integer,                         
target::integer,                        
length::double precision AS cost  
FROM xmpark_road',  
1, 10, false, false) as di  
join xmpark_road pt  
on di.id2 = pt.gid

六、參數化的查詢sql語句,能夠用下面的語句,在geoserver中使用發佈sql視圖圖層來顯示導航搜索圖層,見下圖css

SELECT seq, id1 AS node, id2 AS edge, cost,geom  FROM pgr_dijkstra('  
SELECT gid AS id,                      
source::integer,                         
target::integer,                        
length::double precision AS cost  
FROM xmpark_road',  
%a%, %b%, false, false) as di  
join xmpark_road pt  
on di.id2 = pt.gid

 七、在ol中使用上面發佈的搜索圖層使用起止交叉點來顯示導航路徑,源碼以下
  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  5     <title></title>
  6     <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7     <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no" />
  8     <link rel="stylesheet" href="ol/ol.css" type="text/css">
  9     <script src="ol/ol-debug.js"></script>
 10     <script src="ol/proj4.js"></script>
 11     <script src="js/jquery-1.8.0.min.js"></script>
 12     <meta charset="utf-8" />
 13 </head>
 14 <body>
 15     <div id="map" style="width: 100%;height:800px;border:solid 1px red" class="map">
 16         <div>
 17             id1: <input id="id1" value="30" />
 18             id2: <input id="id2" value="66" />
 19             <input type="button" value="query" onclick="queryRoute()" />
 20         </div>
 21     </div>
 22 </body>
 23 </html>
 24 
 25 
 26 <script type="text/javascript">
 27     var format = 'image/png';
 28     var bounds = [501369.9375, 2494100.25,
 29         502073, 2495256.25];
 30     var mousePositionControl = new ol.control.MousePosition({
 31         className: 'custom-mouse-position',
 32         target: document.getElementById('location'),
 33         coordinateFormat: ol.coordinate.createStringXY(5),
 34         undefinedHTML: '&nbsp;'
 35     });
 36     var tiled = new ol.layer.Tile({
 37         visible: true,
 38         source: new ol.source.TileWMS({
 39             url: 'http://localhost:8080/geoserver/pg_ws/wms',
 40             params: {
 41                 'FORMAT': format,
 42                 'VERSION': '1.1.1',
 43                 tiled: true,
 44                 STYLES: '',
 45                 LAYERS: 'pg_ws:xmpark_road',
 46             }
 47         })
 48     });
 49 
 50     var cross_tiled = new ol.layer.Tile({
 51         //visible: true,
 52         source: new ol.source.TileWMS({
 53             url: 'http://localhost:8080/geoserver/pg_ws/wms',
 54             params: {
 55                 'FORMAT': format,
 56                 'VERSION': '1.1.1',
 57                 tiled: true,
 58                 STYLES: '',
 59                 LAYERS: 'pg_ws:xmpark_road_vertices_pgr',
 60             }
 61         })
 62     });
 63 
 64     var projection = new ol.proj.Projection({
 65         code: 'EPSG:3857',
 66         units: 'm',
 67         axisOrientation: 'neu',
 68         global: true
 69     });
 70     var map = new ol.Map({
 71         controls: ol.control.defaults({
 72             attribution: false
 73         }).extend([mousePositionControl]),
 74         target: 'map',
 75         layers: [
 76             tiled, cross_tiled
 77         ],
 78         view: new ol.View({
 79             projection: projection
 80         })
 81     });
 82    
 83    
 84     map.getView().fit(bounds, map.getSize());
 85 
 86     var routeLayer = null;
 87 
 88     function queryRoute() {
 89         if (routeLayer != null) {
 90             map.removeLayer(routeLayer);
 91         }
 92 
 93         var val1 = $("#id1").val();
 94         var val2 = $("#id2").val();
 95          routeLayer = new ol.layer.Tile({
 96             visible: true,
 97             source: new ol.source.TileWMS({
 98                 url: 'http://localhost:8080/geoserver/pg_ws/wms',
 99                 params: {
100                     'FORMAT': format,
101                     'VERSION': '1.1.1',
102                     tiled: true,
103                     STYLES: '',
104                     LAYERS: 'pg_ws:xmpark_road_route',
105                     'viewparams': 'a:' + val1 + ';b:' + val2
106                 }
107             })
108         });
109 
110         map.addLayer(routeLayer);
111     }
112 </script>
導航圖層搜索


最終實現效果以下:html

相關文章
相關標籤/搜索