路徑模型
本文介紹了路徑模型的用途、基本構(gòu)成和快速入門(mén)等內(nèi)容。
模型用途
簡(jiǎn)介
路徑模型是一種以點(diǎn)、邊描述的圖結(jié)構(gòu),用于解決基于道路網(wǎng)的路徑規(guī)劃問(wèn)題、電子地圖GPS導(dǎo)航路徑搜索規(guī)劃問(wèn)題、路由問(wèn)題等。路徑模型完全兼容PGRouting接口,支持已有應(yīng)用的平滑遷移。路徑數(shù)據(jù)是由Edge和Node構(gòu)成的幾何網(wǎng)絡(luò)圖,主要用于構(gòu)建道路和交通網(wǎng)絡(luò)。
Ganos Networking是對(duì)象關(guān)系型數(shù)據(jù)庫(kù)PostgreSQL兼容版本(PolarDB PostgreSQL版)的一個(gè)時(shí)空引擎擴(kuò)展,Networking擴(kuò)展提供了一系列的函數(shù)和存儲(chǔ)過(guò)程,用于根據(jù)代價(jià)模型查找最快、最短甚至是最優(yōu)的路徑,它能夠提供地理空間路由功能,支持多種路徑分析和網(wǎng)絡(luò)分析算法,為數(shù)據(jù)庫(kù)增加了路徑分析和網(wǎng)絡(luò)分析的功能。
功能概述
Ganos Networking主要提供了一系列的路徑規(guī)劃與網(wǎng)絡(luò)分析函數(shù):
Johnson算法。
Floyd-Warshall算法。
AStar/雙向AStar最短路徑算法。
Dijkstra/雙向Dijkstra最短路徑算法。
旅行推銷(xiāo)員算法。
Prim算法。
Kruskal算法。
K最短路徑算法。
流量(Flow)分析。
圖拓?fù)洌═opology)相關(guān)操作。
圖部件(Component) 相關(guān)操作。
圖收縮。
轉(zhuǎn)彎限制最短路徑(Turn Restriction Shortest Path)算法。
同時(shí),部分函數(shù)還支持設(shè)置成本(cost)或成本矩陣(cost matrix)進(jìn)行計(jì)算。
主要業(yè)務(wù)場(chǎng)景
Ganos Networking的使用場(chǎng)景非常廣泛:
最優(yōu)路線(xiàn)規(guī)劃
在物流、快遞、出租車(chē)服務(wù)等行業(yè)中,可以使用Ganos Networking來(lái)計(jì)算兩點(diǎn)之間的最短路徑或最快路徑,以便進(jìn)行路線(xiàn)規(guī)劃和優(yōu)化。同時(shí),對(duì)于非地理路徑,如互聯(lián)網(wǎng)節(jié)點(diǎn)的連接,也可以借助Ganos Networking得到更優(yōu)的網(wǎng)絡(luò)拓?fù)洹?
地理空間分析
Ganos Networking可以用于執(zhí)行基于路網(wǎng)的分析。例如,最近鄰搜索、服務(wù)區(qū)分析等。這些分析可以幫助用戶(hù)了解地理空間數(shù)據(jù)的分布和關(guān)系,進(jìn)一步進(jìn)行決策和規(guī)劃。
交通流量管理
通過(guò)結(jié)合交通流數(shù)據(jù),Ganos Networking可以幫助分析交通流量,預(yù)測(cè)擁堵情況,并提供優(yōu)化建議。這對(duì)于城市交通管理、智能交通系統(tǒng)等應(yīng)用非常有價(jià)值。
基本構(gòu)成
圖的概念
圖是一個(gè)有序?qū)Γ裱?code data-tag="code" code-type="xCode" class="code">G = (V ,E),其中:
V
表示圖的頂點(diǎn)集合,V
中的元素稱(chēng)為頂點(diǎn)(vertex)或節(jié)點(diǎn)(node)。E ? {( u, v ) | u , v ∈ V }
。
存在無(wú)向圖、簡(jiǎn)單無(wú)向圖、有向圖、簡(jiǎn)單有向圖等多種類(lèi)型。
在Ganos中,有兩種圖的表示方式:
成本圖。
正反向成本圖。
兩種圖在執(zhí)行計(jì)算時(shí)都可以指定為有向或無(wú)向。
成本圖
成本圖在數(shù)據(jù)庫(kù)內(nèi)具有如下結(jié)構(gòu):
列名 | 描述 |
id | 邊的唯一標(biāo)識(shí)符。 |
source | 該條邊的起點(diǎn)。 |
target | 該條邊的終點(diǎn)。 |
cost | 從起點(diǎn)到終點(diǎn)的邊的權(quán)重(成本)。 |
正反向成本圖
正反向成本圖在數(shù)據(jù)庫(kù)內(nèi)具有如下結(jié)構(gòu):
列名 | 描述 |
id | 某條邊的唯一標(biāo)識(shí)符。 |
source | 該條邊的起點(diǎn)。 |
target | 該條邊的終點(diǎn)。 |
cost | 從起點(diǎn)到終點(diǎn)的邊的權(quán)重(成本)。 |
reverse_cost | 從終點(diǎn)到起點(diǎn)的邊的權(quán)重(成本)。 |
函數(shù)體結(jié)構(gòu)
Ganos Networking兼容Pgrouting標(biāo)準(zhǔn),函數(shù)體的一般結(jié)構(gòu)為:
pgr_<name>(Inner_queries, Parameters, [ Optional_parameters ])
其中:
Inner_queries:內(nèi)部查詢(xún),是SQL字符串,用于構(gòu)建函數(shù)所需要的數(shù)據(jù)。
Parameters:參數(shù),函數(shù)所需的附加強(qiáng)制參數(shù)。
Optional_parameters:可選參數(shù),省略時(shí)具有默認(rèn)值。
一個(gè)函數(shù)可能有不同的重載。常見(jiàn)的重載方式為:
一對(duì)一: 從一個(gè)起點(diǎn)導(dǎo)航到一個(gè)終點(diǎn) 。
一對(duì)多:從一個(gè)起點(diǎn)導(dǎo)航到多個(gè)終點(diǎn) 。
多對(duì)一:從多個(gè)起點(diǎn)導(dǎo)航到一個(gè)終點(diǎn) 。
多對(duì)多:從多個(gè)起點(diǎn)導(dǎo)航到多個(gè)終點(diǎn) 。
組合:從多個(gè)不同的起點(diǎn)導(dǎo)航到多個(gè)不同的終點(diǎn),每個(gè)元組指定一對(duì)起點(diǎn)和終點(diǎn)。
內(nèi)部查詢(xún)依賴(lài)的數(shù)據(jù)結(jié)構(gòu)
用戶(hù)需要構(gòu)建內(nèi)部查詢(xún)以將圖結(jié)構(gòu)傳遞給函數(shù)模型。按需求類(lèi)型,可將內(nèi)部查詢(xún)分為如下幾種:
邊查詢(xún)(Edge SQL)。
通用邊查詢(xún):適用于Dijkstra/雙向Dijkstra最短路徑算法。
不帶ID的通用邊查詢(xún):適用于全對(duì)(All Pairs)算法。
帶有X/Y值的通用邊查詢(xún):適用于A(yíng)Star/ 雙向AStar最短路徑算法。
組合查詢(xún) (Combinations SQL)。
限制查詢(xún)(Restrictions SQL)。
點(diǎn)查詢(xún)(Points SQL)。
通用邊查詢(xún)
列名 | 類(lèi)型 | 默認(rèn)值 | 說(shuō)明 |
id | integer | 無(wú) | 邊的唯一標(biāo)識(shí)符。 |
source | integer | 無(wú) | 該條邊的起點(diǎn)。 |
target | integer | 無(wú) | 該條邊的終點(diǎn) |
cost | numeric | 無(wú) | 邊的權(quán)重。 |
reverse_cost | numeric | -1 | 從終點(diǎn)到起點(diǎn)的邊的權(quán)重。 當(dāng)為負(fù)值時(shí)邊\((target \rightarrow source)\)不存在于圖中。 |
不帶ID的邊查詢(xún)
列名 | 類(lèi)型 | 默認(rèn)值 | 說(shuō)明 |
source | integer | 無(wú) | 該條邊的起點(diǎn)。 |
target | integer | 無(wú) | 該條邊的終點(diǎn) |
cost | numeric | 無(wú) | 邊的權(quán)重。 |
reverse_cost | numeric | -1 | 從終點(diǎn)到起點(diǎn)的邊的權(quán)重。 當(dāng)為負(fù)值時(shí)邊\((target \rightarrow source)\)不存在于圖中。 |
帶有X/Y值的邊查詢(xún)
列名 | 類(lèi)型 | 默認(rèn)值 | 說(shuō)明 |
source | integer | 無(wú) | 該條邊的起點(diǎn)。 |
target | integer | 無(wú) | 該條邊的終點(diǎn) |
cost | numeric | 無(wú) | 邊的權(quán)重。 當(dāng)為負(fù)值時(shí)邊\((source \rightarrow target)\)不存在于圖中。 |
reverse_cost | numeric | -1 | 從終點(diǎn)到起點(diǎn)的邊的權(quán)重。 當(dāng)為負(fù)值時(shí)邊\((target \rightarrow source)\)不存在于圖中。 |
x1 | numeric | 無(wú) | 邊的起點(diǎn)X坐標(biāo)。 |
y1 | numeric | 無(wú) | 邊的起點(diǎn)Y坐標(biāo)。 |
x2 | numeric | 無(wú) | 邊的終點(diǎn)X坐標(biāo)。 |
y2 | numeric | 無(wú) | 邊的終點(diǎn)Y坐標(biāo)。 |
限制查詢(xún)
列名 | 類(lèi)型 | 默認(rèn)值 | 說(shuō)明 |
path | integer array | 無(wú) | 描述所有不可通過(guò)邊的ID的序列。 |
cost | numeric | 無(wú) | 通行于不可通過(guò)邊的成本。 |
點(diǎn)查詢(xún)
列名 | 類(lèi)型 | 默認(rèn)值 | 說(shuō)明 |
pid | integer | auto value | 點(diǎn)的唯一標(biāo)識(shí)符。 |
edge_id | integer | 無(wú) | 距離該點(diǎn)最近的邊的唯一標(biāo)識(shí)。 |
fraction | numeric | 無(wú) | 點(diǎn)在該邊的相對(duì)位置。值必須位于[0,1]之間。 |
side | char | b | 當(dāng)前點(diǎn)的位置。值必須為[ |
結(jié)果列數(shù)據(jù)結(jié)構(gòu)
根據(jù)函數(shù)的不同,返回的列也有多種。
返回單條路徑的結(jié)果
列名 | 類(lèi)型 | 說(shuō)明 |
seq | integer | 從1開(kāi)始的順序值。 |
path_seq | integer | 在整個(gè)路徑中的相對(duì)位置。從1開(kāi)始的順序值。 |
[start_vid] | big integer | 起始頂點(diǎn)的唯一標(biāo)識(shí)符。僅在查詢(xún)中有多個(gè)起始頂點(diǎn)時(shí)返回。 |
[end_vid] | big integer | 結(jié)束頂點(diǎn)的唯一標(biāo)識(shí)符。僅在查詢(xún)中有多個(gè)結(jié)束頂點(diǎn)時(shí)返回。 |
node | big integer | 從"start_vid"到"end_vid"路徑中節(jié)點(diǎn)的標(biāo)識(shí)符。 |
edge | big integer | 從當(dāng)前節(jié)點(diǎn)到路徑序列中的下一個(gè)節(jié)點(diǎn)的邊的標(biāo)識(shí)符。-1表示路徑的最后一個(gè)節(jié)點(diǎn)。 |
cost | float | 從當(dāng)前節(jié)點(diǎn)到路徑序列中的下一個(gè)節(jié)點(diǎn)的成本。 |
agg_cost | float | 從"start_vid"到"node"的總成本。 |
適用于pgr_withPoints函數(shù):
列名 | 類(lèi)型 | 說(shuō)明 |
seq | integer | 從1開(kāi)始的順序值。 |
path_seq | integer | 在整個(gè)路徑中的相對(duì)位置。從1開(kāi)始的順序值。 |
[start_vid] | big integer | 起始頂點(diǎn)(Vertex)/點(diǎn)(Point)的唯一標(biāo)識(shí)符。僅在查詢(xún)中有多個(gè)起始頂點(diǎn)時(shí)返回。
|
[end_vid] | big integer | 結(jié)束頂點(diǎn)(Vertex)/點(diǎn)(Point)的唯一標(biāo)識(shí)符。僅在查詢(xún)中有多個(gè)起始頂點(diǎn)時(shí)返回。
|
node | big integer | 從"start_vid"到"end_vid"路徑中節(jié)點(diǎn)的標(biāo)識(shí)符。
|
edge | big integer | 從當(dāng)前節(jié)點(diǎn)到路徑序列中的下一個(gè)節(jié)點(diǎn)的邊的標(biāo)識(shí)符。-1表示路徑的最后一個(gè)節(jié)點(diǎn)。 |
cost | float | 從當(dāng)前節(jié)點(diǎn)到路徑序列中的下一個(gè)節(jié)點(diǎn)的成本。 |
agg_cost | float | 從"start_vid"到"node"的總成本。0表示路徑的第一條記錄。 |
適用于pgr_dijkstraNear函數(shù):
列名 | 類(lèi)型 | 說(shuō)明 |
seq | integer | 從1開(kāi)始的順序值。 |
path_seq | integer | 在整個(gè)路徑中的相對(duì)位置。從1開(kāi)始。 |
start_vid | big integer | 當(dāng)前路徑起始頂點(diǎn)的唯一標(biāo)識(shí)符。 |
end_vid | big integer | 當(dāng)前路徑結(jié)束頂點(diǎn)的唯一標(biāo)識(shí)符。 |
node | big integer | 從"start_vid"到"end_vid"路徑中節(jié)點(diǎn)的標(biāo)識(shí)符。 |
edge | big integer | 從當(dāng)前節(jié)點(diǎn)到路徑序列中的下一個(gè)節(jié)點(diǎn)的邊的標(biāo)識(shí)符。 -1表示路徑的最后一個(gè)節(jié)點(diǎn)。 |
cost | float | 從當(dāng)前節(jié)點(diǎn)到路徑序列中的下一個(gè)節(jié)點(diǎn)的成本。 |
agg_cost | float | 從"start_vid"到"node"的總成本。 |
返回多條路徑的結(jié)果
適用于對(duì)多條路徑具有選擇性的函數(shù):
列名 | 類(lèi)型 | 說(shuō)明 |
seq | integer | 從1開(kāi)始的順序值。 |
path_id | integer | 路徑的唯一標(biāo)識(shí)符。 從"start_vid"到"end_vid"路徑的第一個(gè)路徑的ID為1。 |
path_seq | integer | 在整個(gè)路徑中的相對(duì)位置。從1開(kāi)始的順序值。 |
[start_vid] | big integer | 起始頂點(diǎn)的唯一標(biāo)識(shí)符。僅在查詢(xún)中有多個(gè)起始頂點(diǎn)時(shí)返回。 |
[end_vid] | big integer | 結(jié)束頂點(diǎn)的唯一標(biāo)識(shí)符。僅在查詢(xún)中有多個(gè)結(jié)束頂點(diǎn)時(shí)返回。 |
node | big integer | 從"start_vid"到"end_vid"路徑中節(jié)點(diǎn)的標(biāo)識(shí)符。 |
edge | big integer | 從當(dāng)前節(jié)點(diǎn)到路徑序列中的下一個(gè)節(jié)點(diǎn)的邊的標(biāo)識(shí)符。 -1表示路徑的最后一個(gè)節(jié)點(diǎn)。 |
cost | float | 從當(dāng)前節(jié)點(diǎn)到路徑序列中的下一個(gè)節(jié)點(diǎn)的成本。 |
agg_cost | float | 從"start_vid"到"node"的總成本。 |
適用于對(duì)多條路徑不具有選擇性的函數(shù):
列名 | 類(lèi)型 | 說(shuō)明 |
seq | integer | 從1開(kāi)始的順序值。 |
path_id | integer | 路徑的唯一標(biāo)識(shí)符。 從"start_vid"到"end_vid"路徑的第一個(gè)路徑的ID為1。 |
path_seq | integer | 在整個(gè)路徑中的相對(duì)位置。從1開(kāi)始。 |
start_vid | big integer | 起始頂點(diǎn)的唯一標(biāo)識(shí)符。 |
end_vid | big integer | 結(jié)束頂點(diǎn)的唯一標(biāo)識(shí)符。 |
node | big integer | 從"start_vid"到"end_vid"路徑中節(jié)點(diǎn)的標(biāo)識(shí)符。 |
edge | big integer | 從當(dāng)前節(jié)點(diǎn)到路徑序列中的下一個(gè)節(jié)點(diǎn)的邊的標(biāo)識(shí)符。 -1表示路徑的最后一個(gè)節(jié)點(diǎn)。 |
cost | float | 從當(dāng)前節(jié)點(diǎn)到路徑序列中的下一個(gè)節(jié)點(diǎn)的成本。 |
agg_cost | float | 從"start_vid"到"node"的總成本。 |
成本函數(shù)的結(jié)果
適用于使用成本或成本矩陣的函數(shù):
列名 | 類(lèi)型 | 說(shuō)明 |
start_vid | big integer | 起始頂點(diǎn)的唯一標(biāo)識(shí)符。 |
end_vid | big integer | 結(jié)束頂點(diǎn)的唯一標(biāo)識(shí)符。 |
agg_cost | float | 從"start_vid"到"end_vid"的路徑的總成本。 |
快速入門(mén)
簡(jiǎn)介
快速入門(mén)文檔幫助用戶(hù)快速理解Ganos Networking引擎的基本用法,包括擴(kuò)展創(chuàng)建、建表、插入數(shù)據(jù)、更新屬性、創(chuàng)建拓?fù)洹⒙窂讲樵?xún)等內(nèi)容。
語(yǔ)法說(shuō)明
創(chuàng)建擴(kuò)展。
CREATE Extension Ganos_Networking cascade;
說(shuō)明建議將擴(kuò)展安裝在public模式下,避免權(quán)限問(wèn)題。
CREATE extension Ganos_Networking WITH schema public cascade;
創(chuàng)建表。
CREATE TABLE edge_table ( id BIGSERIAL, dir character varying, source BIGINT, target BIGINT, cost FLOAT, reverse_cost FLOAT, capacity BIGINT, reverse_capacity BIGINT, category_id INTEGER, reverse_category_id INTEGER, x1 FLOAT, y1 FLOAT, x2 FLOAT, y2 FLOAT, the_geom geometry );
插入記錄。
INSERT INTO edge_table ( category_id, reverse_category_id, cost, reverse_cost, capacity, reverse_capacity, x1, y1, x2, y2) VALUES (3, 1, 1, 1, 80, 130, 2, 0, 2, 1), (3, 2, -1, 1, -1, 100, 2, 1, 3, 1), (2, 1, -1, 1, -1, 130, 3, 1, 4, 1), (2, 4, 1, 1, 100, 50, 2, 1, 2, 2), (1, 4, 1, -1, 130, -1, 3, 1, 3, 2), (4, 2, 1, 1, 50, 100, 0, 2, 1, 2), (4, 1, 1, 1, 50, 130, 1, 2, 2, 2), (2, 1, 1, 1, 100, 130, 2, 2, 3, 2), (1, 3, 1, 1, 130, 80, 3, 2, 4, 2), (1, 4, 1, 1, 130, 50, 2, 2, 2, 3), (1, 2, 1, -1, 130, -1, 3, 2, 3, 3), (2, 3, 1, -1, 100, -1, 2, 3, 3, 3), (2, 4, 1, -1, 100, -1, 3, 3, 4, 3), (3, 1, 1, 1, 80, 130, 2, 3, 2, 4), (3, 4, 1, 1, 80, 50, 4, 2, 4, 3), (3, 3, 1, 1, 80, 80, 4, 1, 4, 2), (1, 2, 1, 1, 130, 100, 0.5, 3.5, 1.999999999999,3.5), (4, 1, 1, 1, 50, 130, 3.5, 2.3, 3.5,4);
更新表屬性。
UPDATE edge_table SET the_geom = st_makeline(st_point(x1,y1),st_point(x2,y2)), dir = CASE WHEN (cost>0 AND reverse_cost>0) THEN 'B' -- both ways WHEN (cost>0 AND reverse_cost<0) THEN 'FT' -- direction of the LINESSTRING WHEN (cost<0 AND reverse_cost>0) THEN 'TF' -- reverse direction of the LINESTRING ELSE '' END;
創(chuàng)建拓?fù)洹?/p>
SELECT pgr_createTopology('edge_table',0.001);
查詢(xún)最短路徑。
-- dijkstra 最短路徑 SELECT * FROM pgr_dijkstra( 'SELECT id, source, target, cost, reverse_cost FROM edge_table', 2, 3 ); seq | path_seq | node | edge | cost | agg_cost -----+----------+------+------+------+---------- 1 | 1 | 2 | 4 | 1 | 0 2 | 2 | 5 | 8 | 1 | 1 3 | 3 | 6 | 9 | 1 | 2 4 | 4 | 9 | 16 | 1 | 3 5 | 5 | 4 | 3 | 1 | 4 6 | 6 | 3 | -1 | 0 | 5 (6 rows) -- astar 路徑算法 SELECT * FROM pgr_astar( 'SELECT id, source, target, cost, reverse_cost, x1, y1, x2, y2 FROM edge_table', 2, 12, directed := false, heuristic := 2); seq | path_seq | node | edge | cost | agg_cost -----+----------+------+------+------+---------- 1 | 1 | 2 | 2 | 1 | 0 2 | 2 | 3 | 3 | 1 | 1 3 | 3 | 4 | 16 | 1 | 2 4 | 4 | 9 | 15 | 1 | 3 5 | 5 | 12 | -1 | 0 | 4 (5 rows) -- trsp 路徑算法 SELECT * FROM pgr_trsp( 'SELECT id::INTEGER, source::INTEGER, target::INTEGER, cost FROM edge_table', 2, 7, false, false, 'SELECT to_cost, target_id::int4, from_edge || coalesce('','' || via_path, '''') AS via_path FROM restrictions' ); seq | id1 | id2 | cost -----+-----+-----+------ 0 | 2 | 4 | 1 1 | 5 | 10 | 1 2 | 10 | 12 | 1 3 | 11 | 11 | 1 4 | 6 | 8 | 1 5 | 5 | 7 | 1 6 | 8 | 6 | 1 7 | 7 | -1 | 0 (8 rows)
刪除擴(kuò)展(可選)。
Drop Extension Ganos_Networking cascade;
SQL參考
詳細(xì)SQL手冊(cè)請(qǐng)參見(jiàn)pgrouting 官方文檔 。