路徑分析—QGIS+PostgreSQL+PostGIS+pgRouting(一)
路徑分析—PostgreSQL+GeoServer+Openlayers(二)
前言上一篇文章中實(shí)現(xiàn)數(shù)據(jù)庫層面的路徑分析了,可以在數(shù)據(jù)庫里面通過 SQL 查詢到結(jié)果 。
本篇文章實(shí)現(xiàn)了從前端頁面直接可視化操作點(diǎn)選起點(diǎn)、終點(diǎn),并返回最短路徑進(jìn)行展示 。
一、數(shù)據(jù)庫函數(shù)在 PostgreSQL 數(shù)據(jù)庫中創(chuàng)建函數(shù),該函數(shù)實(shí)現(xiàn)的功能是:傳入表名、起點(diǎn)、終點(diǎn)經(jīng)緯度、距離等參數(shù),返回對應(yīng)的最短距離 geometry 。
創(chuàng)建的函數(shù)具體如下:
-- 刪除已經(jīng)存在的函數(shù)(可能會報錯,報錯的話注釋)DROP FUNCTION pgr_fromAtoB(tbl varchar,startx float, starty float,endx float,endy float);-- tbl路網(wǎng)表名-- startx起點(diǎn)經(jīng)度-- starty起點(diǎn)緯度-- endx終點(diǎn)經(jīng)度-- endy終點(diǎn)緯度-- diatance 起點(diǎn)、終點(diǎn)到路徑查詢的距離CREATE OR REPLACE function pgr_fromAtoB(tbl varchar,startx float, starty float,endx float,endy float, distance float)--限制返回類型returns geometry as $body$declare v_startLine geometry; -- 離起點(diǎn)最近的線 v_endLine geometry; -- 離終點(diǎn)最近的線 v_startSource integer; -- 距離起點(diǎn)最近線的起點(diǎn) v_startTarget integer; -- 距離起點(diǎn)最近線的終點(diǎn) v_endSource integer; -- 距離終點(diǎn)最近線的起點(diǎn) v_endTarget integer; -- 距離終點(diǎn)最近線的終點(diǎn) v_statpoint geometry; -- 在v_startLine上距離起點(diǎn)(傳入的起點(diǎn))最近的點(diǎn) v_endpoint geometry; -- 在v_endLine上距離終點(diǎn)(傳入的終點(diǎn))最近的點(diǎn) v_res geometry; -- 最短路徑分析結(jié)果 v_res_a geometry; v_res_b geometry; v_res_c geometry; v_res_d geometry; v_perStart float; -- v_statpoint在v_res上的百分比 v_perEnd float; -- v_endpoint在v_res上的百分比 v_shPath_ss geometry; --起點(diǎn)到最近距離點(diǎn)的線 v_shPath_ee geometry; --終點(diǎn)到最近距離點(diǎn)的線 v_shPath geometry; --最終結(jié)果 tempnode float;begin -- 4326坐標(biāo)系 -- 查詢離起點(diǎn)最近的線 -- 找起點(diǎn)15米范圍內(nèi)的最近線 execute 'select geom, source, target from ' ||tbl|| ' where ST_DWithin(geom,ST_Geometryfromtext(''point('|| startx || ' ' || starty||')'',4326),'|| distance ||') order by ST_Distance(geom,ST_GeometryFromText(''point('|| startx ||' '|| starty ||')'',4326)) limit 1' into v_startLine, v_startSource ,v_startTarget; -- 查詢離終點(diǎn)最近的線 -- 找終點(diǎn)15米范圍內(nèi)的最近線 execute 'select geom, source, target from ' ||tbl|| ' where ST_DWithin(geom,ST_Geometryfromtext(''point('|| endx || ' ' || endy ||')'',4326),'|| distance ||') order by ST_Distance(geom,ST_GeometryFromText(''point('|| endx ||' ' || endy ||')'',4326)) limit 1' into v_endLine, v_endSource,v_endTarget; -- 如果沒找到最近的線,就返回null if (v_startLine is null) or (v_endLine is null) then return null; end if ; -- 分別找到路徑上距離起點(diǎn)和終點(diǎn)最近的點(diǎn) select ST_ClosestPoint(v_startLine, ST_Geometryfromtext('point('|| startx ||' ' || starty ||')',4326)) into v_statpoint; select ST_ClosestPoint(v_endLine, ST_GeometryFromText('point('|| endx ||' ' || endy ||')',4326)) into v_endpoint; -- 從開始的起點(diǎn)到結(jié)束的起點(diǎn)最短路徑 execute 'SELECT ST_Union(b.geom) ' || 'FROM pgr_dijkstra( ''SELECT id, source, target, length as cost FROM ' || tbl ||''',' || v_startSource || ', ' || v_endSource || ' , false ) a LEFT JOIN ' || tbl || ' b ON a.edge=b.id' into v_res ; --從開始的終點(diǎn)到結(jié)束的起點(diǎn)最短路徑 execute 'SELECT ST_Union(b.geom) ' || 'FROM pgr_dijkstra( ''SELECT id, source, target, length as cost FROM ' || tbl ||''',' || v_startTarget || ', ' || v_endSource || ' , false ) a LEFT JOIN ' || tbl || ' b ON a.edge=b.id' into v_res_b ; --從開始的起點(diǎn)到結(jié)束的終點(diǎn)最短路徑 execute 'SELECT ST_Union(b.geom) ' || 'FROM pgr_dijkstra( ''SELECT id, source, target, length as cost FROM ' || tbl ||''',' || v_startSource || ', ' || v_endTarget || ' , false ) a LEFT JOIN ' || tbl || ' b ON a.edge=b.id' into v_res_c ; --從開始的終點(diǎn)到結(jié)束的終點(diǎn)最短路徑 execute 'SELECT ST_Union(b.geom) ' || 'FROM pgr_dijkstra( ''SELECT id, source, target, length as cost FROM ' || tbl ||''',' || v_startTarget || ', ' || v_endTarget || ' , false ) a LEFT JOIN ' || tbl || ' b ON a.edge=b.id' into v_res_d ; if(ST_Length(v_res) > ST_Length(v_res_b)) then v_res = v_res_b; end if; if(ST_Length(v_res) > ST_Length(v_res_c)) then v_res = v_res_c; end if; if(ST_Length(v_res) > ST_Length(v_res_d)) then v_res = v_res_d; end if; -- 如果找不到最短路徑,就返回null (根據(jù)實(shí)際情況是否需要)-- if(v_res is null) then-- return null;-- end if; --將 v_res,v_startLine,v_endLine 進(jìn)行拼接 select ST_LineMerge(ST_Union(array[v_res,v_startLine,v_endLine])) into v_res; -- 根據(jù)起點(diǎn)、終點(diǎn)最近距離點(diǎn),找到在路徑中的百分比 select ST_LineLocatePoint(v_res, v_statpoint) into v_perStart; select ST_LineLocatePoint(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_LineSubstring(v_res,v_perStart, v_perEnd) into v_shPath; SELECT ST_MakeLine(ST_SetSRID(ST_Point( startx, starty),4326),v_statpoint) into v_shPath_ss; SELECT ST_MakeLine(ST_SetSRID(ST_Point( endx, endy),4326),v_endpoint) into v_shPath_ee; -- 將 v_shPath、v_shPath_ss、v_shPath_ee 拼接 select ST_LineMerge(ST_Union(array[v_shPath,v_shPath_ss,v_shPath_ee])) into v_shPath; return v_shPath;end;$body$ LANGUAGE plpgsql VOLATILE STRICT;
經(jīng)驗(yàn)總結(jié)擴(kuò)展閱讀
- 90年屬馬33歲有一劫
- 十二星座和哪些星座在一起是善緣
- 十二星座和哪個星座在一起是孽緣
- 十二星座在愛情里對哪個星座最狠心
- 交往中的十二星座最不想聽?wèi)偃苏f什么話
- 和十二星座冷戰(zhàn)后需要做什么來緩和
- 十二星座女生誘惑男友屢屢失敗的原因
- 十二星座在戀愛時最傷對方的言論
- 十二星座如何保持愛情的儀式感
- 十二星座戀愛在哪方面缺根筋
