基於PostGIS的高級應用(3)--線性參考

一 線性參考幹啥用的

  若是直接寫個「高大上」的定義結果每每是一臉懵逼的,也不知道爲何要定義這麼一個概念。其實線性參考技術在咱們生活中是很是常見的,好比打開高德,百度地圖的App,查看實時路況,道路被不一樣路況的顏色動態分段顯示了;高速中發生交通事故,電視廣播中經常對地點描述爲「距離xx高速入口xx千米處」,地圖是能很是精確的定位到這個地點的。生活中的兩個例子的說明,其實他們的規律都是針對圖形數據爲線(LineString)的一種GIS應用。
  線性參考必定要有線,線上必定要有權重值(也叫測量值M),上一段路況的測量值M就是路段上的傳感器發送回來的車流通行速度,交通事故的測量值就是道路的實際距離。不一樣的測量值能作不一樣的事,以下圖所示:html

不一樣權重值.pngnode


在不改變道路數據前提下,使用不一樣的維度(測量值M),分段展現不一樣的業務場景。sql

 

二 線性參考核心要素

  轉回嚴肅的工程技術範疇,我我的對線性參考總結包括如下幾個要素:數據庫

  • 線性數據:道路,河流,電網等一些列線性的業務基礎數據。
  • 測量值/M值:不一樣的業務部門,將本身的業務數據(路況啊,道路質量啊)疊加到線性基礎數據上的過程,就是被稱做「addMeasure」。
  • 應用方法:一種是動態分段,一種是事件定位
    本質:不改變線性基礎數據狀況下,將業務測量值/M值數據動態賦予到了每一個線性數據上,應用的時候,依據測量值,動態分段展現或者進行忽然事件的快速定位。以下例子:

    沿線距離.pngide


    道路數據創建了完整測量值M後,用戶想定位12千米處,就能快速提取出這個點的位置,用戶想找到18-26千米處的區間,也能快速提取出這個線段。

三 PostGIS中的線性參考

  以PostGIS2.4.0版本說明,經過查看API,能夠發現對線性參考核心三要素是所有支持的,本章節具體闡述。函數

3.1 線性數據

PostGIS支持LineString,MultiLineString類型,能夠將路網,河網,電網等各類LineString數據導入數據庫。徹底支持。oop

3.2 測量值/M值

ST_AddMeasure:用於對線性數添加測量值。
函數定義post

geometry ST_AddMeasure(geometry geom_mline, float8 measure_start, float8 measure_end);

參數說明:傳入一個線圖形,設置其起點測量值,終點測量值,返回一個創建了測量值的圖形。
使用示例測試

SELECT ST_AsText(ST_AddMeasure(ST_GeomFromText('LINESTRING(1 0, 2 0, 4 0)'),10,40)) As ewelev;;
ewelev
----------------------------------------
LINESTRINGM(1 0 10,2 0 20,4 0 40)

3.3 動態分段,事件定位

PostGIS提供了ST_LocateBetween與ST_LocateBetweenElevations方式對帶測量值的線進行動態分段提取,其中ST_LocateBetweenElevations是支持三維,四維數據的,簡單的就以ST_LocateBetween(這個是用於對二維進行動態分段的)函數說明。
ST_LocateBetween:二維線動態分段函數。
函數定義ui

geometry ST_LocateBetween(geometry geomA, float8 measure_start, float8 measure_end, float8 offset);

參數說明:傳入一個已創建測量值的線圖形,選擇一個起始測量M值與一個終點測量M值,返回測量值在這個區間內的動態截取線段圖形。
至於offset,看了官網說明,也不知道是幹嗎用的,請熟悉的朋友留言指點。
使用示例:

SELECT ST_AsText(the_geom)
FROM
(SELECT ST_LocateBetween(
ST_GeomFromText('MULTILINESTRING M ((1 2 3, 3 4 2, 9 4 3),
(1 2 3, 5 4 5))'),1.5, 3) As the_geom) As foo;
------------------------------------------------------------------------------------
GEOMETRYCOLLECTION M (LINESTRING M (1 2 3,3 4 2,9 4 3),POINT M (1 2 3))

草圖示意圖.png

 

要求截取M值在1.5到3之間的圖形,上圖中(1 2 3, 3 4 2, 9 4 3)都知足,(1 2 3, 5 4 5)只有起點知足,因此輸出結果符合預期。

ST_LocateAlong:事件定位函數,已知測量值,計算線性數據上的幾何定位。
函數定義:

geometry ST_LocateAlong(geometry ageom_with_measure, float8 a_measure, float8 offset);

參數說明:傳入一個已創建測量值的線圖形,任意設置一個測量M值,返回該M值對應在線性數據上的幾何位置。(如前文高速事故以這種事件點形式描述)。
使用說明

SELECT ST_AsText((ST_Dump(the_geom)).geom)
FROM
(SELECT ST_LocateAlong(
ST_GeomFromText('MULTILINESTRINGM((1 2 3, 3 4 2, 9 4 3),
(1 2 3, 5 4 5))'),2.5) As the_geom) As foo;
st_asewkt
---------------
POINT M (2 3 2.5)
POINT M (6 4 2.5)

草圖示意圖.png

ST_InterpolatePoint:與ST_LocateAlong函數相反,計算線性數據上任意一點位置的測量M值。
函數定義

float8 ST_InterpolatePoint(geometry line, geometry point);

參數說明:輸入創建測量值M的line與已知線上的一點point,返回這個point點對應的測量值M的value。
使用說明

SELECT ST_InterpolatePoint('LINESTRING M (0 0 0, 10 0 20)', 'POINT(5 5)');
st_interpolatepoint
---------------------
10

以上幾個函數,是線性參考應用場景中所必需的,主要解決如何給線性數據添加測量值,如何定位,如何反算,如何動態獲取。PostGIS線性參考章節剩餘幾個函數都是純圖形計算的。

ST_LineInterpolatePoint:geometry ST_LineInterpolatePoint(geometry a_linestring, float8 a_fraction)
說明:輸入LineString圖形與一個分割百分比數,返回LineString從起點到終點之間任意一個0-1之間的百分比數a_fraction所處的點圖形。
示例:

route=# select ST_AsText(ST_LineInterpolatePoint(ST_GeomFromText('LineString(0 0,10 10)'),0.5));
 st_astext
------------
 POINT(5 5)
(1 行記錄)
route=# select ST_AsText(ST_LineInterpolatePoint(ST_GeomFromText('LineString(0 0,10 10)'),0.3));
 st_astext
------------
 POINT(3 3)
(1 行記錄)

ST_LineLocatePoint: float8 ST_LineLocatePoint(geometry a_linestring, geometry a_point)
說明:輸入LineString圖形與線上任意一個Point(並不是線的node節點,而是這個點確定與線相交(intersects)),返回LineString從起點到終點之間任意一個0-1之間的百分比數a_fraction。
示例

route=# select ST_LineLocatePoint(ST_GeomFromText('LineString(0 0,10 10)'),ST_GeomFromText('Point(5 5)'));
 st_linelocatepoint
--------------------
                0.5
(1 行記錄)

ST_LineSubstring:geometry ST_LineSubstring(geometry a_linestring, float8 startfraction, float8 endfraction);
說明:輸入LineString圖形與起點停靠值s_f與終點停靠值e_f,返回停靠值之間的線段,若是s_f是0,e_f是1,結果就是完整的線的自己。
示例

select ST_AsText(ST_LineSubstring(ST_GeomFromText('LINESTRING(0 0, 10 10)'),0.5,1));
----------------------------------------------------
LINESTRING(5 5,10 10)

四 線性參考實際案例

  本章節我製做了一批測試數據模擬一些實際應用。場景模擬是:武漢軍運會重點保障線路之一的「武漢火車站--江夏運動員村「,相關部門爲了增強掌握道路通行狀況,在該條線路上安裝了不少rfid監控傳感設備,實時上傳該路段的道路通行速度。監管部門設置速度區間,如35-45區間路段是紅色,45-55區間路段顯示黃色,55-75區間路段是綠色。

 

rfid數據.png

 

道路與monitor圖形.png

數據處理步驟方案是:

  • 1 以rfid_monitor點將完整的線路打斷,拆分紅監控點兩兩組成的區間子路段。
  • 2 使用ST_AddMeasure方法,對拆分的子路段創建線性參考。
  • 3 創建線性參考後,根據動態分段的紅黃綠動態分區,可視化顯示便可。

如下數據處理腳本,根據監控點對路段進行了切割打斷,每個segment路段,起點終點都是一個傳感器的位置,在創建線性參考的時候,只須要把segment的起點終點測量值M設置爲對應的傳感器的speed便可。

do language plpgsql $$  
 DECLARE
        rec record;
        route_line geometry;
        initinfo boolean:=true;
        start_fraction float;
        end_fraction float;
        line geometry;
        speed_s numeric;
        speed_e numeric;
BEGIN
        --提取出重點線路的圖形
        select geom from routes limit 1 into route_line;
        initinfo:=true;
        for rec in select t1.gid,t1.speed,t1.geom from rfid_monitor t1 order by t1.gid loop
            if(initinfo=true) then
                initinfo:=false;
                --起點百分比
                start_fraction:=ST_LineLocatePoint(route_line,rec.geom);
                end_fraction:=start_fraction;
                speed_s:=rec.speed;
                speed_e:=rec.speed;
            else
                speed_s:=speed_e;
                speed_e:=rec.speed;
                start_fraction:=end_fraction;
                end_fraction:=ST_LineLocatePoint(route_line,rec.geom);
                line:=ST_LineSubstring(route_line,start_fraction,end_fraction);
                --子路段提取,創建線性參考
                insert into substring_road(seg,geom) values(rec.gid,ST_AddMeasure(line,speed_s,speed_e));
            end if;
        end loop;
end;  
$$;

查詢下子路段數據並可視化下:

 

創建測量值.png

到這這一步,數據都處理完了,都創建了M值了。應用系統根據配置,動態顯示就可使用了。
根據速度動態分段:

select ST_LocateBetween(geom,35,45) geom,'紅色' as color from substring_road union
select ST_LocateBetween(geom,45,55) geom,'黃色' as color from substring_road union
select ST_LocateBetween(geom,55,75) geom,'綠色' as color from substring_road;

查詢結果可視化以下:

 

動態分段渲染.png

[ArcGIS線性參考幫助文檔][1]
[1]: http://desktop.arcgis.com/zh-cn/arcmap/10.3/guide-books/linear-referencing/what-is-linear-referencing.htm
[PostGIS線性參考開發文檔][2]
[2]: http://postgis.net/docs/manual-2.4/reference.html#Linear_Referencing

 

做者:遙想公瑾當年 連接:https://www.jianshu.com/p/4916b85bea65 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。

相關文章
相關標籤/搜索