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

前面文章介绍了如何利用postgresql创建空间数据库,建立空间索引和进行路径规划。但是在真实的场景中用户进行路径规划的时候都是基于经纬度数据进行路径规划的,因为用户根本不会知道道路上节点的ID。因此文本讲述如何查询任意两点间的最短路径。

一、定义函数名及函数参数

函数名定义为: pgr_fromAtoB

参数设置分别为:

输入为数据库表名,起点和终点的经纬度坐标

输出为:路段序号,gid号,道路名,消耗及道路集合体。

IN tbl varchar, --数据库表名

IN x1 double precision, --起点x坐标

IN y1 double precision, --起点y坐标

IN x2 double precision, --终点x坐标

IN y2 double precision, --终点y坐标

OUT seq integer, --

OUT gid integer,

OUT name text,

OUT heading double precision,

OUT cost double precision,

OUT geom geometry

二、计算距离起点和终点距离最近的道路节点,

可以使用的函数为

SELECT id::integer FROM minidata_vertices_pgr

ORDER BY the_geom <-> ST_GeometryFromText(‘‘POINT(‘

|| x1 || ‘ ‘ || y1 || ‘)‘‘,900913) LIMIT 1

三、然后根据检索到的节点再调用pgrouting的最短路径查询函数进行计算。

可以使用的函数为:

SELECT gid, geom, name, cost, source, target,

ST_Reverse(geom) AS flip_geom FROM ‘ ||

‘pgr_bdAstar(‘‘SELECT gid as id, source::int, target::int, ‘

|| ‘length::float AS cost,x1,y1,x2,y2 FROM ‘

|| quote_ident(tbl) || ‘‘‘, ‘

|| source || ‘, ‘ || target

|| ‘ ,false, false), ‘

|| quote_ident(tbl) || ‘ WHERE id2 = gid ORDER BY seq

四、整合上面几个子过程,得到的最终查询sql函数如下:

--
--DROP FUNCTION pgr_fromAtoB(varchar, double precision, double precision,
--                           double precision, double precision);

CREATE OR REPLACE FUNCTION pgr_fromAtoB(
                IN tbl varchar,
                IN x1 double precision,
                IN y1 double precision,
                IN x2 double precision,
                IN y2 double precision,
                OUT seq integer,
                OUT gid integer,
                OUT name text,
                OUT heading double precision,
                OUT cost double precision,
                OUT geom geometry
        )
        RETURNS SETOF record AS
$BODY$
DECLARE
        sql     text;
        rec     record;
        source	integer;
        target	integer;
        point	integer;

BEGIN
	-- 查询距离出发点最近的道路节点
	EXECUTE 'SELECT id::integer FROM minidata_vertices_pgr
			ORDER BY the_geom <-> ST_GeometryFromText(''POINT('
			|| x1 || ' ' || y1 || ')'',900913) LIMIT 1' INTO rec;
	source := rec.id;

	-- 查询距离目的地最近的道路节点
	EXECUTE 'SELECT id::integer FROM minidata_vertices_pgr
			ORDER BY the_geom <-> ST_GeometryFromText(''POINT('
			|| x2 || ' ' || y2 || ')'',900913) LIMIT 1' INTO rec;
	target := rec.id;

	-- 最短路径查询
        seq := 0;
        sql := 'SELECT gid, geom, name, cost, source, target,
				ST_Reverse(geom) AS flip_geom FROM ' ||
                        'pgr_bdAstar(''SELECT gid as id, source::int, target::int, '
                                        || 'length::float AS cost,x1,y1,x2,y2 FROM '
                                        || quote_ident(tbl) || ''', '
                                        || source || ', ' || target
                                        || ' ,false, false), '
                                || quote_ident(tbl) || ' WHERE id2 = gid ORDER BY seq';

	-- Remember start point
        point := source;

        FOR rec IN EXECUTE sql
        LOOP
		-- Flip geometry (if required)
		IF ( point != rec.source ) THEN
			rec.geom := rec.flip_geom;
			point := rec.source;
		ELSE
			point := rec.target;
		END IF;

		-- Calculate heading (simplified)
		EXECUTE 'SELECT degrees( ST_Azimuth(
				ST_StartPoint(''' || rec.geom::text || '''),
				ST_EndPoint(''' || rec.geom::text || ''') ) )'
			INTO heading;

		-- Return record
                seq     := seq + 1;
                gid     := rec.gid;
                name    := rec.name;
                cost    := rec.cost;
                geom    := rec.geom;
                RETURN NEXT;
        END LOOP;
        RETURN;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE STRICT;

时间: 2024-10-13 02:39:24

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

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

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

任意两点间的最短路问题 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][