基于pgrouting的任意两点间的最短路径查询函数二

在前面的博文中写过一篇查询任意两点间最短路径的函数,当时对pgrouting不熟悉,功能很low。现在对该函数进行扩展,支持用户自己输入查询的数据库表,这一点看似简单,其实意义很大,在做室内导航的时候当用户所在的楼层变化的时候最短路径函数查询的数据表名称也会发生变化,不可能一栋大楼里的道路都是一样的吧,另外进行跨楼层的最短路径规划时,需要查询从A到楼梯口的最短路径和楼梯口到B的最短路径,这些都需要进行最短路径规划的时候能够自己选择数据表。

DROP FUNCTION pgr_fromAtoB(tbl varchar,startx float, starty float,endx float,endy float);
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_endSource integer;--距离终点最近线的起点  

    v_statpoint geometry;--在v_startLine上距离起点最近的点
    v_endpoint geometry;--在v_endLine上距离终点最近的点  

    v_res geometry;--最短路径分析结果  

    v_perStart float;--v_statpoint在v_res上的百分比
    v_perEnd float;--v_endpoint在v_res上的百分比  

    v_shPath geometry;--最终结果
    tempnode float;
begin     

    --查询离起点最近的线
    execute 'select geom ,target  from ' ||tbl||
			' where
			ST_DWithin(geom,ST_Geometryfromtext(''point('||	startx ||' ' || starty||')''),15)
			order by ST_Distance(geom,ST_GeometryFromText(''point('|| startx ||' '|| starty ||')''))  limit 1'
			into v_startLine ,v_startTarget;  

    --查询离终点最近的线
    execute 'select geom,source  from ' ||tbl||
			' where ST_DWithin(geom,ST_Geometryfromtext(''point('|| endx || ' ' || endy ||')''),15)
			order by ST_Distance(geom,ST_GeometryFromText(''point('|| endx ||' ' || endy ||')''))  limit 1'
			into v_endLine,v_endSource;  

    --如果没找到最近的线,就返回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 ||')')) into v_statpoint;
    select  ST_ClosestPoint(v_endLine, ST_GeometryFromText('point('|| endx ||' ' || endy ||')')) into v_endpoint;  

    --最短路径
    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;  

    --如果找不到最短路径,就返回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  

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 23:27:24

基于pgrouting的任意两点间的最短路径查询函数二的相关文章

基于pgrouting的任意两点间的最短路径查询函数

前面文章介绍了如何利用postgresql创建空间数据库,建立空间索引和进行路径规划.但是在真实的场景中用户进行路径规划的时候都是基于经纬度数据进行路径规划的,因为用户根本不会知道道路上节点的ID.因此文本讲述如何查询任意两点间的最短路径. 一.定义函数名及函数参数 函数名定义为: pgr_fromAtoB 参数设置分别为: 输入为数据库表名,起点和终点的经纬度坐标 输出为:路段序号,gid号,道路名,消耗及道路集合体. IN tbl varchar, --数据库表名 IN x1 double

任意两点间的最短路问题 Floyd-Warshall算法

这一算法与之前的Bellman-F=Ford算法一样,都可以判断负环 只需要检查dp [i] [j] 是负数的顶点i即可 1 // 求解任意两点间的最短路径问题 2 // Floyed-Warshall算法 3 // 复杂度O(N^3),N为顶点数 4 5 #include <cstdio> 6 #include <iostream> 7 8 using namespace std; 9 // 用dp的思路来求解 10 // dp[k][i][j]:从i到j,只利用前K个节点的最短

Floyd-Warshall算法(求解任意两点间的最短路) 详解 + 变形 之 poj 2253 Frogger

/* 好久没有做有关图论的题了,复习一下. --------------------------------------------------------- 任意两点间的最短路(Floyd-Warshall算法) 动态规划: dp[k][i][j] := 节点i可以通过编号1,2...k的节点到达j节点的最短路径. 使用1,2...k的节点,可以分为以下两种情况来讨论: (1)i到j的最短路正好经过节点k一次 dp[k-1][i][k] + dp[k-1][k][j] (2)i到j的最短路完全

图论之最短路02-2——改进的任意两点间最短距离及路径

======================================================== 重要程度 ***** 求任意两点间最短距离及其路径.(万能最短路) 输入:权值矩阵,起点,终点 输出:最短距离矩阵,指定起讫点路径(经过的顶点编号) ======================================================== function renyizuiduanlu(W) clc disp('                        

图论之最短路02-1——任意两点间最短距离及路径

======================================================== 求任意两点间最短距离及其路径.(万能最短路) 输入:权值矩阵,起点,终点 输出:最短距离矩阵,指定起讫点路径(经过的顶点编号) 为任意一点到其他点最短路奠定基础 ======================================================== function [P d]=liangdianzuiduanlu(W,qidian,zhongdian) W

任意两点间的最短路 Floyd及其本质

我们知道在已知起点的情况下,求到其他任何一点的最短路是用dijkstra,那么在一个有向图中,我们想知道任意两点之间的最短路,我们就可以使用floyd,而且这个算法表面看起来非常的简单,就是一个三重循环,如果这个图有N个点,那么复杂度为O(|N|3),代码如下. 1 for(int k=0;k<n;k++) 2 for(int i=0;i<n;i++) 3 for(int j=0;j<n;j++) 4 d[i][j]=min(d[i][j],d[i][k]+d[k][j]); 在复杂度这

任意两点间最短距离floyd-warshall ---- POJ 2139 Six Degrees of Cowvin Bacon

floyd-warshall算法 通过dp思想 求任意两点之间最短距离 重复利用数组实现方式dist[i][j] i - j的最短距离 for(int k = 1; k <= N; k++) for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) dist[i][j] = min(dist[i][j], dist[i][k]+dist[k][j]); 非常好实现 O(V^3) 这里贴一道刚好用到的题 http://poj.org

Openlayers3 计算地图上任意两点间的距离

主要用的接口是new ol.Sphere(6378137).haversineDistance([x1,y1],[x2,y2]): 4326坐标系中计算两点距离的方式为: var a = new ol.Sphere(6378137).haversineDistance([120.21592590991689, 30.210793016606],[120.21670777384473, 30.211168525868086]); 版权声明:本文为博主原创文章,未经博主允许不得转载.

任意两点间最短路问题及路径还原

1Floyd-Warshall算法 考虑用动态规划的方法,只使用顶点0~k和i,j的情况下,记i到j的最短路径为d[k][i][j].当k=0时,只考虑i和j,即d[0][i][j]=cost[i][j].然后我们就开始讨论从k到k+1是怎样变化的. 对于顶点0~k的i到j的最短路,如果这条路径不经过第k个顶点,那么d[k][i][j]=d[k-1][i][j].当经过第k个顶点时,d[k][i][j]=d[k-1][i][k]+d[k-1][k][j](分成两短),这样总的递推式即为d[k][