惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
云风的 BLOG
云风的 BLOG
小众软件
小众软件
IT之家
IT之家
T
Tailwind CSS Blog
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
美团技术团队
博客园 - 叶小钗
V
V2EX
博客园 - Franky
大猫的无限游戏
大猫的无限游戏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
阮一峰的网络日志
阮一峰的网络日志
博客园 - 【当耐特】
罗磊的独立博客
博客园_首页
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
爱范儿
爱范儿
宝玉的分享
宝玉的分享
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Jina AI
Jina AI
月光博客
月光博客
有赞技术团队
有赞技术团队

博客园 - 漂泊雪狼

关于SeaTunnel 达梦数据迁移无法自动建表的问题 Kettel链接达梦数据 Elastic Job 入门笔记 记一次Spring boot集成mybatis错误修复过程 Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. Spring Boot 框架下使用MyBatis访问数据库之基于XML配置的方式 CentOS7下载配置PostgreSQL的pgAgent运行代理作业 ElasticSearch 中文分词搜索环境搭建 学习笔记——Ubuntu下使用Docker包部署禅道任务管理系统 windows下的Redis主从集群搭建 asp.net mvc5中使用Swagger 自动生成WebApi文档笔记 Centos 7.5下搭建SVN源代码服务器 使用Fiddler 4 调用WebService 获取geometry边界范围的示例代码 Nginx设置防止IP及非配置域名访问 java 调用c# web api 代码 一台机器部署多个tomcat服务 nginx反向代理多个服务 笔记 利用Kettle 从Excel中抽取数据写入SQLite sql server 统计信息 sql server 索引碎片相关问题
使用pgrouting进行最短路径搜索
漂泊雪狼 · 2018-01-13 · via 博客园 - 漂泊雪狼

   PgRouting是基于开源空间数据库PostGIS用于网络分析的扩展模块,最初它被称作pgDijkstra,因为它只是利用Dijkstra算法实现最短路径搜索,之后慢慢添加了其他的路径分析算法,如A算法,双向A算法,Dijkstra算法,双向Dijkstra算法,tsp货郎担算法等,然后被更名为pgRouting。该扩展库依托PostGIS自身的gist索引,丰富的坐标系与图形类型,强大的几何处理能力,如空间查询,空间处理,线性参考等优势,能保障在较大数据级别下的网络分析效果更快更好。

最新源码见:

1、环境搭建

需要先安装PostgreSQL9.6,再安装PostGIS,注意版本号PostGIS2.4后已经集成了pgRouting,无需单独安装

PostGIS 官网 http://www.postgis.org/

pgRouting官网http://pgrouting.org/documentation.html

2、启用pgRouting功能,连接到对应postgres数据库后执行下面的sql语句

CREATE EXTENSION postgis;
CREATE EXTENSION pgrouting;

3、路网数据处理

由于路网分析的特殊性,只支持LineString类型,不支持MultiLineString类型,如果路网数据为MultiLineString类型导入前需加工处理,可使用arcgis在交叉点处使用打断相交线来分割线,参见

http://resources.arcgis.com/zh-cn/help/main/10.1/index.html#//01m8,最终可用的数据必须为路网不自相交,导入时选择简单的线类型,否则网络拓扑计算数据会错误

4、路网拓扑数据计算处理,执行成功后,执行成功后会生产一个**_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); 


5、查询最短路径sql语句

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

6、参数化的查询sql语句,可以用下面的语句,在geoserver中使用发布sql视图图层来显示导航搜索图层,见下图

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

 7、在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>

导航图层搜索


最终实现效果如下: