postgis+geoserver+openlayers路径规划导航

postgis+geoserver+openlayers路径规划导航 记录

  • 路径数据的处理(使用qgis )
    • 如何画好自己的路径
  • 路径分析
    • shapefile 文件导入postgres 数据库
    • 处理表
    • 创建数据分析函数
    • geoserver 处理
    • openlayers 处理

路径数据的处理(使用qgis )

如何画好自己的路径

  1. 创建一个线的shapefile图层:
    postgis+geoserver+openlayers路径规划导航_第1张图片
  2. 编辑线的图层 启用吸附功能:
    postgis+geoserver+openlayers路径规划导航_第2张图片
  3. 下面就是开始画的了这个需要注意一下
    postgis+geoserver+openlayers路径规划导航_第3张图片

之前画一个线段的时候是一笔画成的(上图),在转折处没有一个生成一个结束点在后面导入数据库进行路径分析寻找绿色的路(下图)的时候调用ST_Line_Locate_Point函数的时候会出错,因为在绿色和红色之前没有生成结束点所以找不到线就会报错。
你可以分开画,或则画好了之后分割一下。
postgis+geoserver+openlayers路径规划导航_第4张图片
画好了用分析工具分析一下相交的地方会有点就是ok的~
postgis+geoserver+openlayers路径规划导航_第5张图片

路径分析

shapefile 文件导入postgres 数据库

  1. 创建新的数据库的时候,使用paAdmin连接PostgreSQL,并执行以下语句,在新的空间数据库里添加空间扩展:
    //提供如下空间信息服务功能:空间对象、空间索引、空间操作函数和空间操作符
    CREATE EXTENSION postgis;
    //用于网络分析的扩展模块
    CREATE EXTENSION pgrouting;
    //gis 拓扑
    CREATE EXTENSION postgis_topology;
    //提供了几个函数来确定字符串之间的相似性和距离
    CREATE EXTENSION fuzzystrmatch;
    CREATE EXTENSION postgis_tiger_geocoder;
    CREATE EXTENSION address_standardizer;

  2. 设置srid 后面的函数srid 设置的就是4326 ,可以自己改。
    postgis+geoserver+openlayers路径规划导航_第6张图片

处理表

  1. 修改表结构
 --添加起点id
ALTER TABLE public.export_road ADD COLUMN source integer;

--添加终点id

ALTER TABLE public.export_road ADD COLUMN target integer;

--添加道路权重值

ALTER TABLE public.export_road ADD COLUMN length double precis


创建拓扑结构                  

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

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


创建索引

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

CREATE INDEX source_idx ON export_road ("source");

CREATE INDEX target_idx ON export_road ("target");

 

给长度赋值

--为length赋值
UPDATE export_road SET length =st_length(geom);

--为export_road 表添加reverse_cost字段并用length的值赋值
ALTER TABLE export_road ADD COLUMN reverse_cost double precision;
UPDATE export_road SET reverse_cost =length;
  1. 测试数据有结果基本没问题
--通过起点号、终点号查询最短路径
--source为线表起点字段名称
--target为线表终点字段名称
--起点终点前后顺序无固定要求
--length为长度字段,也可以使用自己的评价体系
--19为测试使用起点号\终点号
--roa_4m路网表名
--id1经过节点号
--id2经过路网线的gid
SELECT seq, id1 AS node, id2 AS edge, cost FROM pgr_dijkstra('
                SELECT  gid AS id,
                         source::integer,
                         target::integer,
                         length::double precision AS cost
                        FROM export_road',
                1, 4, false, false);

创建数据分析函数

  1. 创建最短路径函数
DROP FUNCTION pgr_fromAtoB(tbl varchar,startx float, starty float,endx float,endy float);
 
--tbl路网表名
--startx起点经度
--starty起点纬度
--endx终点经度
--endy终点纬度
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
 
    --查询离起点最近的线 
    --4326坐标系
    --找起点15米范围内的最近线
 
    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; 
 
     
 
    --查询离终点最近的线 
    --找终点15米范围内的最近线
 
    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 处理

  1. geoserver 添加数据存储 发布>> 图层里面配置新的sql 视图
    postgis+geoserver+openlayers路径规划导航_第7张图片
    postgis+geoserver+openlayers路径规划导航_第8张图片
    之后填好数据保存发布即可。
    新建图层如下配置新的sql 视图

postgis+geoserver+openlayers路径规划导航_第9张图片
postgis+geoserver+openlayers路径规划导航_第10张图片
sql 视图:
SELECT * FROM pgr_fromAtoB(‘road_xblk’, %x1%, %y1%, %x2%, %y2%)
验证的正则表达式:^-?[\d.]+$
类型:LingString
SRID:4326
postgis+geoserver+openlayers路径规划导航_第11张图片

openlayers 处理

  1. openlayers 显示路径规划
<!doctype html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
    <style>
      .map {
        height: 70%;
        width: 100%;
      }
    </style>
    <script src="https://openlayers.org/en/v4.6.5/build/ol.js" type="text/javascript"></script>
    <title>OpenLayers example</title>
  </head>
  <body>
    <div id="map" class="map"></div>
    <script type="text/javascript">
		var format = 'image/png';
		var bounds = [-97499.84375, -544430.1875,
                    -80675.4609375, -530069.5625];
		var mousePositionControl = new ol.control.MousePosition({
        className: 'custom-mouse-position',
        target: document.getElementById('map'),
        coordinateFormat: ol.coordinate.createStringXY(5),
        undefinedHTML: ' '
      });
	  
	     var untiled = new ol.layer.Image({
        source: new ol.source.ImageWMS({
          ratio: 1,
          url: 'http://localhost:8087/geoserver/cite/wms',
          params: {'FORMAT': format,
                   'VERSION': '1.1.1',  
                "LAYERS": 'cite:export_main',
                "exceptions": 'application/vnd.ogc.se_inimage',
          }
        })
      });
	  
	  
	  var params1 = {
            LAYERS: 'cite:indoor_test_gis_1',
            FORMAT: 'image/png',
        };
		
        var viewparams = [
            'x1:-79081.02565' , 'y1:-536464.45228' ,
            'x2:-88189.51634' , 'y2:-538550.99455' 
            //'x1:' + 12952117.2529, 'y1:' + 4836395.5717,
            //'x2:' + 12945377.2585, 'y2:' + 4827305.7549
        ];
        console.log(viewparams);   
        params1.viewparams = viewparams.join(';');
		
		var result = new ol.layer.Image({
            source: new ol.source.ImageWMS({
					
                    url: 'http://localhost:8087/geoserver/cite/wms',
                    params: params1
                })
        });
	 
	 
      var projection = new ol.proj.Projection({
          code: 'EPSG:41001',
          units: 'm',
          global: true
      });
      var map = new ol.Map({
        controls: ol.control.defaults({
          attribution: false
        }).extend([mousePositionControl]),
        target: 'map',
        layers: [
          untiled,//主视图
		  result //路径视图
        ],
        view: new ol.View({
           projection: projection
        })
      });
	  
	 
	  
	  map.getView().fit(bounds, map.getSize());

		
      
    </script>
  </body>
</html>

结果:
postgis+geoserver+openlayers路径规划导航_第12张图片

参考博客:https://www.cnblogs.com/liongis/p/7692477.html
https://blog.csdn.net/weixin_40184249/article/details/82970999

你可能感兴趣的:(gis)