OpenLayers+PostGIS實(shí)現(xiàn)路徑分析

??本文內(nèi)容默認(rèn)已在PostGIS中添加了PgRouting擴(kuò)展模塊帖渠。

1. 數(shù)據(jù)準(zhǔn)備

??路徑分析功能是針對(duì)路網(wǎng)圖層進(jìn)行的空間分析應(yīng)用思币,在將shp文件導(dǎo)入數(shù)據(jù)庫(kù)之前诉濒,需要對(duì)其進(jìn)行拓?fù)錂z驗(yàn)钞诡,主要是道路的自相交以及路段之間的道路節(jié)點(diǎn)的相離的檢驗(yàn)镐捧。可以利用ArcGIS對(duì)文件進(jìn)行拓?fù)涞臉?gòu)建和檢驗(yàn)臭增,保證數(shù)據(jù)的準(zhǔn)確性懂酱。

??利用PostGIS自帶的工具將文件入庫(kù)。如下圖所示誊抛,1是將編碼方式設(shè)置為GBK列牺,一般Shapfile文件的編碼方式均為GBK,若選用其他編碼方式拗窃,可能會(huì)出現(xiàn)亂碼瞎领。2是對(duì)線要素進(jìn)行簡(jiǎn)化,Pgrouting不支持對(duì)多線的路徑計(jì)算随夸。


圖1

設(shè)定空間參考系統(tǒng)標(biāo)識(shí)(SRID)常用的3857或者4326九默,見下圖。

圖2

2. 最短路徑功能

??要生成路徑宾毒,首先要生成合法的拓?fù)渫招蕖Mㄟ^(guò)創(chuàng)建拓?fù)潢P(guān)系,可以完成最短路徑查詢函數(shù)的編寫。

2.1 構(gòu)建拓?fù)潢P(guān)系:pgr_createTopology

??這里創(chuàng)建的是路段道路節(jié)點(diǎn)與弧段之間的關(guān)系乙各,通過(guò)節(jié)點(diǎn)間可達(dá)性可以完成路徑的導(dǎo)航墨礁。

1、 添加起止點(diǎn)耳峦,存儲(chǔ)線段的首尾編號(hào)
ALTER TABLE prjroad ADD COLUMN source integer;
ALTER TABLE prjroad ADD COLUMN target integer;
2恩静、添加道路權(quán)重值
ALTER TABLE prjroad ADD COLUMN length double precision;
3、創(chuàng)建拓?fù)涠卓溃删€段的首尾編號(hào)
SELECT pgr_createTopology(prjroad,0.00001, 'geom', 'gid');
//表名驶乾、容差、線段列名循签、gid
第一步默認(rèn)創(chuàng)建起止點(diǎn)的索引轻掩,如果沒有創(chuàng)建,可以執(zhí)行以下sql創(chuàng)建
CREATE INDEX source_idx ON prjroad ("source");
CREATE INDEX target_idx ON prjroad ("target");
4懦底、為權(quán)重賦值,這里將路段的長(zhǎng)度賦值給權(quán)重值
UPDATE prjroad SET length =st_length(geom);
5罕扎、回程成本設(shè)置聚唐,則可支持回程
ALTER TABLE prjroad ADD COLUMN reverse_cost double precision;
UPDATE prjroad SET reverse_cost = length;

2.2 驗(yàn)證可行性

pgr_dijkstra函數(shù)詳見:

http://docs.pgrouting.org/2.2/en/src/dijkstra/doc/pgr_dijkstra.html#pgr-dijkstra

pgr_dijkstra(

text sql, __用于計(jì)算最佳路徑的數(shù)據(jù)來(lái)源,用SOL表示

integer source, __規(guī)劃路徑的起點(diǎn)

integer target, __規(guī)劃路徑的終點(diǎn)

Boolean directed, __ if the graph is directed 有向圖

Boolean has_rcost __if true 需要添加reverse_cost計(jì)算回程路徑

)

查詢節(jié)點(diǎn)2到節(jié)點(diǎn)36之間的最短路徑腔召,寫入表dijkstra_res中杆查。

SELECT seq, id1 AS node, id2 AS edge, cost,geom into dijkstra_res FROM pgr_dijkstra('

SELECT gid AS id,                   

source::integer,                      

target::integer,                     

length::double precision AS cost

FROM prjroad',

2, 36, false, false) as di

join prjroad pt

on di.id2 = pt.gid;
圖2.1 可行性驗(yàn)證結(jié)果

將表導(dǎo)出页滚,加載到qgis中缴挖,可看到最短路徑如圖2.2:

圖2.2 驗(yàn)證結(jié)果展示

2.3 功能函數(shù)fromAtoB

1、若使用A*算法焰雕,則需要知道起止點(diǎn)的坐標(biāo)值浊仆,可以為prjroad表添加字段并賦值

ALTER TABLE prjroad ADD COLUMN x1 double precision;

ALTER TABLE prjroad ADD COLUMN y1 double precision;

ALTER TABLE prjroad ADD COLUMN x2 double precision;

ALTER TABLE prjroad ADD COLUMN y2 double precision;

UPDATE prjroad SET x1 =ST_x(ST_PointN(geom, 1));

UPDATE prjroad SET y1 =ST_y(ST_PointN(geom, 1));

UPDATE prjroad SET x2 =ST_x(ST_PointN(geom, ST_NumPoints(geom)));

UPDATE prjroad SET y2 =ST_y(ST_PointN(geom, ST_NumPoints(geom)));

2客峭、創(chuàng)建函數(shù)

//create function

--

--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 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

 -- 查詢距離出發(fā)點(diǎn)最近的道路節(jié)點(diǎn)

 EXECUTE 'SELECT id::integer FROM line_vertices_pgr

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

 || x1 || ' ' || y1 || ')'',3857) LIMIT 1' INTO rec;

 source := rec.id;

 -- 查詢距離目的地最近的道路節(jié)點(diǎn)

 EXECUTE 'SELECT id::integer FROM line_vertices_pgr

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

 || x2 || ' ' || y2 || ')'',3857) LIMIT 1' INTO rec;

 target := rec.id;

 -- 最短路徑查詢

 seq := 0;

 sql := 'SELECT gid, geom, cost, source, target,

 ST_Reverse(geom) AS flip_geom FROM ' ||

 'pgr_dijkstra(''SELECT gid as id, source::int, target::int, '

 //這里可以省略坐標(biāo)值                  || '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;

 cost := rec.cost;

 geom := rec.geom;

 RETURN NEXT;

 END LOOP;

 RETURN;

END;

$BODY$

LANGUAGE 'plpgsql' VOLATILE STRICT;

坐標(biāo)系要保持一致性。

3. 路徑分析功能實(shí)現(xiàn)

3.1 發(fā)布服務(wù)

在geoserver中發(fā)布服務(wù)

數(shù)據(jù)存儲(chǔ)——添加新的數(shù)據(jù)存儲(chǔ)——PostGIS

圖3.1 配置信息

輸入相關(guān)信息抡柿,點(diǎn)擊保存

圖3.2 SQL配置

如圖3.2舔琅,選擇“配置新的SQL視圖”

圖3.3 SQL配置步驟

1、 輸入視圖名稱
2洲劣、 輸入SQL語(yǔ)句

SELECT ST_MakeLine(route.geom) geom FROM (

 SELECT geom FROM pgr_fromAtoB_3('prjroad', %x1%, %y1%, %x2%, %y2%)

ORDER BY seq) AS route

3备蚓、 從SQL猜想的參數(shù)
4、 獲取到參數(shù)囱稽,輸入默認(rèn)值和正則表達(dá)式
5郊尝、 刷新,得到SQL語(yǔ)句返回的結(jié)果
6战惊、 設(shè)定類型和SRID
7流昏、 保存
8、 計(jì)算邊框,保存

圖3.4 計(jì)算邊框

3.2 功能實(shí)現(xiàn)

傳入起止點(diǎn)坐標(biāo)横缔,計(jì)算最短路徑

圖3.5 功能展示

核心代碼如下:

var viewparams = ['x1:' + cordx, 'y1:' + cordy, 'x2:' + cordx1, 'y2:' + cordy1];
viewparams = viewparams.join(';');
testLayer1 = new OpenLayers.Layer.Vector("result3", {
    request: new OpenLayers.Request.GET({
        url: "http://192.168.15.97:8080/hgisserver/network/wfs?service=WFS&version=1.1.0&request=GetFeature" + "&typeName=network:newview&outputformat=JSON" + "&viewparams=" + viewparams,
        success: function (req) {
            var jsonStr = req.responseText;
            var jsonFormat = new OpenLayers.Format.GeoJSON();
            var featureArray = jsonFormat.read(jsonStr);
            testLayer1.addFeatures(featureArray);
            testLayer1.redraw();
        }
    })
});
testLayer1.style = {
    strokeWidth: 3,
    strokeOpacity: 1,
    strokeColor: "#FF0000"
}
map.addLayer(testLayer1); //添加圖層

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末铺遂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子茎刚,更是在濱河造成了極大的恐慌襟锐,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膛锭,死亡現(xiàn)場(chǎng)離奇詭異粮坞,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)初狰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門莫杈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人奢入,你說(shuō)我怎么就攤上這事筝闹。” “怎么了腥光?”我有些...
    開封第一講書人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵关顷,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我武福,道長(zhǎng)议双,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任捉片,我火速辦了婚禮平痰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘伍纫。我一直安慰自己宗雇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開白布莹规。 她就那樣靜靜地躺著逾礁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪访惜。 梳的紋絲不亂的頭發(fā)上嘹履,一...
    開封第一講書人閱讀 49,837評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音债热,去河邊找鬼砾嫉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛窒篱,可吹牛的內(nèi)容都是我干的焕刮。 我是一名探鬼主播舶沿,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼配并!你這毒婦竟也來(lái)了括荡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤溉旋,失蹤者是張志新(化名)和其女友劉穎畸冲,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體观腊,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡邑闲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了梧油。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苫耸。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖儡陨,靈堂內(nèi)的尸體忽然破棺而出褪子,到底是詐尸還是另有隱情,我是刑警寧澤骗村,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布嫌褪,位于F島的核電站,受9級(jí)特大地震影響叙身,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜硫狞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一信轿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧残吩,春花似錦财忽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至活尊,卻和暖如春隶校,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蛹锰。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工深胳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铜犬。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓舞终,卻偏偏與公主長(zhǎng)得像轻庆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子敛劝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349