pgrouting最短路径
来源:互联网 发布:sql被挂起的解决方法 编辑:程序博客网 时间:2024/05/16 17:59
仅支持起点和终点,postgis2.2版本测试
使用方法 select pro_short_path('POINT(101.2496030330658 21.932321190834045)','POINT(101.25415205955505 21.925079226493835)',150)
150表示在150米范围内查找路网中距离起点和终点最近的道路
drop function if exists pro_truncation(geometry,geometry,geometry,spheroid);drop function if exists pro_short_path(text,text,float);/*截取线段最短路径起点或终点第一要素最短路径起点下一要素或终点的前一要素起点或终点在线段上的点spheroid参数*/create function pro_truncation(i_lfirst geometry,i_lsecond geometry,i_linepoint geometry,i_spheroid spheroid)returns geometry as$$declarev_distance1 float;--距离v_distance2 float;--距离v_spoint geometry; --线段的起点v_epoint geometry; --线段的终点v_p float;--截取线段的比例begin--raise notice '%,%,%', ST_AsText(i_lfirst), ST_AsText(i_lsecond), ST_AsText(i_linepoint);v_p := ST_LineLocatePoint(i_lfirst,i_linepoint); --计算线段上的点在线段上的比例v_spoint := ST_StartPoint(i_lfirst);--获取线段的起点v_epoint := ST_EndPoint(i_lfirst);--获取线段的终点v_distance1 := ST_DistanceSpheroid(i_lsecond ,v_spoint, i_spheroid);--计算距离v_distance2 := ST_DistanceSpheroid(i_lsecond ,v_epoint, i_spheroid);--计算距离v_p := ST_LineLocatePoint(i_lfirst,i_linepoint); --计算线段上的点在线段上的比例if( v_distance1 > v_distance2 ) then --终点连接最短路径i_lfirst := ST_LineSubstring(i_lfirst,v_p, 1);else --起点连接最短路径i_lfirst := ST_LineSubstring(i_lfirst,0, v_p);end if;return i_lfirst;end;$$ language plpgsql;create function pro_short_path(i_start text,i_end text,i_distance float)returns text as$$declarev_spheroid spheroid;v_pstart geometry; --起点v_pend geometry; --终点v_lstart geometry;--离起点最近的线v_lend geometry;--离终点最近的线v_statpoint geometry;--在v_lstart上距离起点最近的点v_endpoint geometry;--在v_lend上距离终点最近的点--缓冲距离起点或终点最近的线段上点,用于判断是否相交v_sbuffer geometry;v_ebuffer geometry; v_sTarget road_2015.target%type;--在v_lstart上距离起点最近的点v_eTarget road_2015.target%type;--在v_lend上距离起点最近的点--最短路径起点和终点信息及几何对象v_path pgr_costResult3;v_shorts pgr_costResult3[];v_line geometry;v_geoms geometry[];v_i integer;v_count integer;v_curs cursor (itarget road_2015.target%type,isource road_2015.target%type) for select a.seq,a.id1,a.id2,a.id3,a.cost,ST_LineMerge(b.geom) from pgr_kdijkstraPath('select gid as id, source, target, length as cost from road_2015', itarget, array[isource], false, false) a,road_2015 b where a.id3=b.gid order by a.seq;v_results text;beginv_spheroid := 'SPHEROID["WGS84",6378137,298.257223563]' ; --WGS84椭球体参数定义v_pstart := ST_SetSRID(ST_GeomFromText(i_start),4326);v_pend := ST_SetSRID(ST_GeomFromText(i_end),4326);--查询i_distance米范围内离起点最近的线select ST_LineMerge(geom),target into v_lstart,v_sTarget from road_2015 where ST_DWithin(geom::geography ,v_pstart::geography,i_distance,true)order by ST_DistanceSpheroid(geom,v_pstart,v_spheroid) limit 1;--查询i_distance米范围内离终点最近的线select ST_LineMerge(geom),target into v_lend,v_eTarget from road_2015 where ST_DWithin(geom::geography ,v_pend::geography,i_distance,true)order by ST_DistanceSpheroid(geom,v_pend,v_spheroid) limit 1;if (v_lstart is null or v_lend is null) thenreturn null;--如果没找到最近的道路,就返回nullend if;--计算起点和终点在最近的线段距离最近的点select ST_ClosestPoint(v_lstart, v_pstart ) into v_statpoint;select ST_ClosestPoint(v_lend, v_pend ) into v_endpoint;v_sbuffer := ST_Buffer(v_statpoint::geography, 3);v_ebuffer := ST_Buffer(v_endpoint::geography, 3);--raise notice '%,%', v_sTarget, v_eTarget;--获取起点线段和编号open v_curs(v_sTarget,v_eTarget);loopfetch v_curs into v_path.seq,v_path.id1,v_path.id2,v_path.id3,v_path.cost,v_line;exit when not found;-- 假如没有检索到(主表)数据,结束循环处理v_shorts := array_append(v_shorts,v_path);v_geoms := array_append(v_geoms,v_line);end loop;close v_curs;v_count := array_length(v_shorts, 1);if( v_shorts is null ) thenraise exception '%','您设置的起点和终点没有连接的道路!';end if;--起点线段处理v_line := ST_MakeLine(v_pstart,v_statpoint);if( false = ST_Intersects(v_geoms[1],v_sbuffer) ) then --如果起点和起点线段没有相连v_lstart := pro_truncation(v_lstart,v_geoms[1], v_statpoint,v_spheroid);v_geoms[1] := ST_Union(v_geoms[1],v_lstart);v_geoms[1] := ST_Union(v_geoms[1],v_line);elsev_geoms[1] := pro_truncation(v_geoms[1],v_geoms[2], v_statpoint,v_spheroid);v_geoms[1] := ST_Union(v_geoms[1],v_line);end if;--终点线段处理v_line := ST_MakeLine(v_pend,v_endpoint);--raise notice '%,%,%',ST_Intersects(v_geoms[v_count],v_ebuffer),ST_AsText(v_geoms[v_count]),ST_AsText(v_ebuffer);if( false = ST_Intersects(v_geoms[v_count],v_ebuffer) ) then --如果终点和终点线段没有相连v_lend := pro_truncation(v_lend,v_geoms[v_count], v_endpoint,v_spheroid);v_geoms[v_count] := ST_Union(v_geoms[v_count],v_lend);v_geoms[v_count] := ST_Union(v_geoms[v_count],v_line);elsev_i := v_count-1;v_geoms[v_count] := pro_truncation(v_geoms[v_count],v_geoms[v_i], v_endpoint,v_spheroid);v_geoms[v_count] := ST_Union(v_geoms[v_count],v_line);end if;v_results ='[';for v_i in 1..v_count loopv_results := v_results || '{';v_results := v_results || '"seq":' || v_shorts[v_i].seq::varchar;v_results := v_results || ',"id1":' || v_shorts[v_i].id1::varchar;v_results := v_results || ',"id2":' || v_shorts[v_i].id2::varchar;v_results := v_results || ',"id3":' || v_shorts[v_i].id3::varchar;v_results := v_results || ',"cost":' || v_shorts[v_i].cost::varchar;v_results := v_results || ',"geom":' || '"' || ST_AsText(v_geoms[v_i]) || '"' ;v_results := v_results || '}';if( v_i < v_count ) thenv_results := v_results || ',';end if;end loop;v_results := v_results || ']';return v_results;end;$$ language plpgsql;
0 0
- pgrouting最短路径
- 最短路径分析算法in PgRouting
- 使用pgrouting求任意两点的最短路径
- 使用pgrouting和geotools实现最短路径,服务区分析
- pgrouting路径分析(任意两点之间的最短路径)
- 基于pgrouting的任意两点间的最短路径查询函数
- 基于pgrouting的任意两点间的最短路径查询函数二
- 关于pgrouting 的 最短路径 思路解析 以及C++代码实现
- 基于pgrouting求任意两点的最短路径的函数pgr_fromAtoB
- postgresql+pgrouting 最短路线sql (4)
- pgrouting路径分析(站点与GRID中心点最短距离)
- 最短路径算法
- 最短路径算法
- 最短路径理解
- 最短路径算法
- 最短路径算法
- 最短路径问题
- 最短路径
- WebRTC 初体验
- OpenCV——博客整理篇
- hdu2027
- vs2010 调试时提示调试信息不能生成或不匹配
- ADB shell出现error:device offline提示
- pgrouting最短路径
- (PHP)用cURL访问HTTPS资源
- BPMN2.0-概要
- GCD 扫盲篇<转载>
- 关系数据库 加 AsyncTask
- Alibaba-AndFix Bug热修复框架的使用
- Split分隔字符串几种方式
- windows平台下载android源码
- hdu2028