1. 程式人生 > >用postgresql(postgis) 查詢指定範圍內的興趣點

用postgresql(postgis) 查詢指定範圍內的興趣點

在地圖中一個任意經,緯度下點選.想要找到以這個點為中心指定半徑下包含多少個興趣點.

檢視postgis手冊找到了這麼一個函式(ST_Distance(geometry g1, geometry g2);)

官方文件上是這麼說的:

ST_Distance — For geometry type Returns the 2-dimensional cartesian minimum distance (based on spatial ref) between two geometries in projected units. For geography type defaults to return spheroidal minimum distance between two
geographies in meters.

即給定兩個空間點計算兩點間的距離.計算結果的單位與你的空間資料的參考系有關.

如果你使用的是4326(wgs84)這個座標系的話他是以度為單位的.要想轉成米為單位的話還得做一下轉換.下面會提到:

GEOCS代表的是地理座標系,也就是以經緯度表示的座標系統,例如4326
PROJCS代表的投影座標系,它是通過一種演算法把球面座標系轉成平面座標系,以便計算,一般是以米為單位表示, 例如26986

因此,在求兩點之間的距離時,由於存的資料都是經緯度,因此它參考的是GEOCS,要想得到以米為單位的結果,首先要把它轉成PROJCS,可以通過ST_Transform來實現

 檢視postgis手冊 geometry ST_Transform

(geometry g1, integer srid);

第一個引數是原來的幾何對像. 第二個引數為要把他轉換到這個投影所代表的做標系下.

這時我們只要找一個單位是米的投影做標系把他轉換過去就好了

例:

SELECT ST_Distance(
   ST_Transform(ST_GeomFromText('POINT(-87.734087560562 43.770129071141)',4326),26986),
   ST_Transform(ST_GeomFromText('POINT(-87.747382933006 43.759234252055)', 4326),26986)
  );

這個查出來的結果即是以米為單位的兩點間的距離了

 

現在在說如何查詢一定範圍內的點

這裡用到了postgis裡的這第一個函式:boolean ST_DWithin(geometry g1, geometry g2, double precision distance_of_srid);

第一個引數為參考對像.第二個引數為目標對像.第三個引數為距離(同樣如果是地理座標系單位是度.投影做標系單位是米)

即以g1為中心,半徑為distance_of_srid,這個範圍內包不包含g2,如果包含反回true,否則即為假

 

如了給一個完整的例子.查詢以(-87.71 43.741)為中心半徑1516米範圍內的興趣點,之後按與這個中心點由近到遠的順序排列結果

SELECT t.feat_id,astext(t.geometry) FROM gis_site t 
WHERE ST_DWithin(

ST_Transform(GeomFromText('POINT(-87.71 43.741)',4326),26986),

ST_Transform(t.geometry,26986), 1516) 
ORDER BY ST_Distance(GeomFromText('POINT(-87.71 43.741)',4326), t.geometry);

 

結果:

24;"POINT(-87.718330082111 43.753078987035)"
17;"POINT(-87.726085716036 43.736952192682)"
18;"POINT(-87.726085716036 43.736952192682)"

找到了三個點