1.計算距離和范圍的思路
其實計算距離和面積屬于典型的Measurements(測量)需求,PostGIS也是把相應(yīng)的函數(shù)劃分在了Spatial Relationships and Measurements這個板塊里雷绢。ps:PostGIS的reference:http://postgis.net/docs/manual-2.3/reference.html
測量是一門古老且歷史悠久的技術(shù)泛烙,最早的記錄在公元前兩千多年大禹治水的時候就有了,他本身跟計算機和互聯(lián)網(wǎng)沒什么關(guān)系翘紊,思路大體上是:
我要測量的范圍大概有多大蔽氨?->我要在哪個地方測量?->我要測量多準(zhǔn)?
比較形象的比喻就是我在量一個東西的時候需要根據(jù)東西的大小和位置先找把合適的尺子鹉究,然后再開始測量宇立。
弄清以上三點選擇合適的測量方式(尺子)再進行測量(計算)是我個人推薦的方式。
2.在這就需要提一個組織:
EPSG(http://www.epsg.org)
EPSG:European Petroleum Survey Group自赔,歐洲石油調(diào)查組織(你沒看錯)妈嘹,該組織負責(zé)專門維護地球上所有的測量坐標(biāo)系統(tǒng)(找石油),并且給每組坐標(biāo)系統(tǒng)都賦予了一個編號和一組描述(WKT)绍妨,比如大家常用的WGS84坐標(biāo)系編號就是EPSG:4326润脸,再比如互聯(lián)網(wǎng)地圖(谷歌、高德等)常用的偽墨卡托投影編號就是EPSG:3857他去。(關(guān)于常用的坐標(biāo)系統(tǒng)以后的文章會單講)
可以理解成EPSG給大家維護了無數(shù)把尺子毙驯,并且給每把尺子搞了個編號,還標(biāo)明了這把尺子適合什么條件下用灾测。
舉三個例子幫助大家理解:
先推薦一個查EPSG坐標(biāo)系非常棒的網(wǎng)站:epsg.io(需要翻墻)
例子1. EPSG:4326:
直接在瀏覽器里敲:http://epsg.io/4326(注意要翻墻)爆价,進去你會看到大大的幾行字:
EPSG:4326
Geodectic coordinate system
WGS 84 -- WGS84 - World Geodetic System 1984, used in GPS
翻譯過來就是:EPSG:4326,一個地理坐標(biāo)系(也叫大地坐標(biāo)系)媳搪,用于描述WGS84坐標(biāo)系铭段,其是從1984年開始在GPS中使用的全球地理坐標(biāo)系統(tǒng)。(從字面看是不是感覺蠻好理解的)
再下面是Attributes蛾号、Covered area稠项、Export三個板塊:
Attributes中先重點看下Uint(單位),這里寫的是degree(度)鲜结,CRS展运、Ellipsoid等參數(shù)看不懂沒關(guān)系,以后文章會單獨講
Corverd area是重點要看的:
看到紅色的框框沒精刷,這是指該坐標(biāo)系適合計算的范圍拗胜,幾乎覆蓋了全球,再看下面的三條描述:
Center coordinates怒允,指坐標(biāo)系的中心點坐標(biāo)
WGS84 bounds埂软,指坐標(biāo)系的適用范圍
World,清晰的告訴你這是給全球范圍用的坐標(biāo)系
所以問題來了:這個坐標(biāo)系適合計算距離和面積嗎纫事?
答案是:否
因為該坐標(biāo)系是大地坐標(biāo)系(Geodectic coordinate system)勘畔,單位是度(角度單位),角度用來測量長度和面積是不合適的(尺子不好用袄龌獭)炫七,但可用于定位,而且它的范圍又覆蓋了全球钾唬,所以很適合全球定位(GPS衛(wèi)星定位的坐標(biāo)系用的就是它)
再看一個坐標(biāo)系
例子2. EPSG:3857:
點開http://epsg.io/3857可以看到:
EPSG:3857
Projected coordinate system
WGS 84 / Pseudo-Mercator -- Spherical Mercator, Google Maps, OpenStreetMap, Bing, ArcGIS, ESRI
意思就是万哪,EPSG:3857是一個投影坐標(biāo)系(Projected coordinate system)侠驯,在WGS84坐標(biāo)系基礎(chǔ)上進行了偽墨卡托投影(Pseudo-Mercator)。球形墨卡托地圖奕巍、谷歌地圖吟策、osm地圖、bing地圖的止、ArcGIS檩坚、ESRI會常用該坐標(biāo)系。
投影坐標(biāo)系(Projected coordinate system)是在大地坐標(biāo)系(Geodectic coordinate system)的基礎(chǔ)上冲杀,經(jīng)過數(shù)學(xué)運算效床,把大地坐標(biāo)系的曲面坐標(biāo)映射到平面上產(chǎn)生的一種平面坐標(biāo)系。
不太嚴謹?shù)睦斫饩褪悄阌袀€橘子权谁,沒剝開的時候在橘子皮上畫的畫就是大地坐標(biāo)系剩檀,包開以后把橘子皮拍平了上面畫的就是投影坐標(biāo)系。
再看下Unit(單位)是metre(米)
Covered area的WGS84 bounds是-180旺芽,-85.06到180沪猴,85.06,描述是World between 85.06°S and 85.06°N.采章,嗯运嗜。。悯舟。幾乎覆蓋整個地球了担租,感覺用它來計算距離和面積妥妥的。
但很遺憾答案還是:否抵怎,用它算測不了實地距離 >3<
雖然EPSG:3857是平面坐標(biāo)系奋救,單位是長度(米),但是他用了一個長度和面積都不靠譜的投影坐標(biāo)系:Pseudo-Mercator(偽墨卡托投影反惕,該投影是正軸等角切圓柱投影尝艘,在高緯度地區(qū)形變的非常嚴重)∽巳荆看到這你貌似突然知道了一個驚天秘密:原來高德地圖和谷歌地圖上面畫的東東都是變形的1澈ァ!沒錯悬赏,就是變形的狡汉,你看到的這些互聯(lián)網(wǎng)地圖用的都是類似的投影,他們在高緯度地區(qū)都是拉伸嚴重的闽颇,遠比他的實地面積要大轴猎。但是正軸墨卡托投影有個優(yōu)點:投影后角度不變形,所以用來導(dǎo)航和定位非常合適进萄。
這個例子還反應(yīng)了一件事:能幾乎覆蓋全球的坐標(biāo)系一般都算不了正確的距離和面積(沒有一個坐標(biāo)系能完美解決地球上的所有問題),想算正確的距離?找個小點的范圍吧中鼠。
在這直接扔一個北京市可以用的:
例子3.EPSG:4527:
點開http://epsg.io/4527可以看到:
EPSG:4527
Projected coordinate system
CGCS2000 / 3-degree Gauss-Kruger zone 39
翻譯過來就是:EPSG:4527可婶,是投影坐標(biāo)系,基于國家2000大地坐標(biāo)系做的高斯-克呂格3度帶投影中的第39帶坐標(biāo)系(看不懂沒關(guān)系援雇,高斯克呂格以后會慢慢講矛渴,知道它形變很小就好了)
其中國家2000(CGCS2000)指的就是咱中國自己的大地坐標(biāo)系(還有兩個比較舊的:北京54、西安80)惫搏,Unit是米具温,重點看Covered area:
紅色就是該投影最適合使用的范圍,WGS84 bounds:115.5 22.6到118.5筐赔,49.88铣猩,正好把北京市(116.46,39.92)包括在內(nèi)茴丰,下面的描述也很清楚:China - onshore between 115°30'E and 118°30'E.(適合中國內(nèi)陸東經(jīng)115°30'到東經(jīng)118°30'的范圍)达皿,跟圖上紅框區(qū)域完全匹配有木有,恭喜你找到了一把測量北京市距離和面積的好尺子贿肩。
3.PostGIS算北京市范圍內(nèi)的距離和面積:
坐標(biāo)系(尺子)有了峦椰,就差運算(測量)了:
算距離:
在北京選Mobike總部曼寧國際北門這面墻的兩個端點試驗:
左邊點是:經(jīng)度116.4677961543,緯度39.9486461337
右邊點是:經(jīng)度116.4680989087汰规,緯度39.9486998528
他們的坐標(biāo)系都是WGS84大地坐標(biāo)系汤功,也就是EPSG:4326。
執(zhí)行查詢:
SELECT st_distance(st_transform(st_geometryfromtext('POINT(116.4677961543 39.9486461337)',4326),4527),st_transform(st_geometryfromtext('POINT(116.4680989087 39.9486998528)',4326),4527));
結(jié)果是:26.55米
st_distance
------------------
26.5520226594034
(1 row)
其中用到幾個函數(shù):
st_geometryfromtext(geometry溜哮,srid):該方法作用是根據(jù)描述的幾何對象(geometry)的字符串轉(zhuǎn)化成幾何對象滔金,POINT說明幾何對象是點類型,第二個參數(shù)srid是4326茬射,是指這個點類型對象的空間參考(也就是EPSG的編號鹦蠕,也是所在的坐標(biāo)系)是EPSG:4326,即WGS84大地坐標(biāo)系。
st_transform(geometry在抛,srid):該方法是把某個幾何對象(geometry)的所有坐標(biāo)從一個坐標(biāo)系轉(zhuǎn)換到另一個坐標(biāo)系钟病。在這做的就是把EPSG:4326轉(zhuǎn)換為EPSG:4527(量北京的尺子到手)。
st_distance(geometry刚梭,geometry):該方法用于計算兩點距離肠阱,所用坐標(biāo)系根據(jù)geometry帶的srid(EPSG編號)決定。
上述查詢的含義就是:
兩個4236坐標(biāo)系下的點對象轉(zhuǎn)換成4527坐標(biāo)系后計算直線距離朴读,這個距離與地面實際距離很接近屹徘。
再用google地圖上瞄著位置手動量了下:結(jié)果差不多,26.52米
如果用3857試試:
SELECT st_distance(st_transform(st_geometryfromtext('POINT(116.4677961543 39.9486461337)',4326),3857),st_transform(st_geometryfromtext('POINT(116.4680989087 39.9486998528)',4326),3857));
結(jié)果是:34.59米衅金,距離明顯變長了噪伊,結(jié)果錯誤
st_distance
------------------
34.5933990100333
(1 row)
算面積:
同樣還是曼寧國際選了它前面停車場的矩形范圍的四個端點:
116.4679312706簿煌,39.9482801227
116.4677961543,39.9486461337
116.4680989087鉴吹,39.9486998528
116.4682182670姨伟,39.9483181633
執(zhí)行查詢:
SELECT st_area(ST_Transform(st_geometryfromtext('POLYGON((116.4679312706 39.9482801227,116.4677961543 39.9486461337,116.4680989087 39.9486998528,116.4682182670 39.9483181633,116.4679312706 39.9482801227))',4326),4527));
結(jié)果:1100平方米約等于1.65畝
st_area
------------------
1101.47601530779
(1 row)
這里geometry的類型用的是POLYGON(多邊形),注意要閉合(首尾的經(jīng)緯度要一樣)
st_area(geometry,srid):該函數(shù)用于計算在某個srid(某個坐標(biāo)系下)一個幾何對象的面積
上述查詢的含義就是:
一個4236坐標(biāo)系下的多邊形對象轉(zhuǎn)換成4527坐標(biāo)系后計算其面積豆励,這個面積與地面實際實際面積很接近夺荒。
可能有人會好奇PostGIS是怎么知道這些編號的?
請執(zhí)行下面語句:
SELECT * FROM spatial_ref_sys WHERE srid IN (4326,3857,4257);
結(jié)果:看到?jīng)]良蒸,PostGIS自帶的這張表spatial_ref_sys(空間參考系統(tǒng))包含了幾乎EPSG所有坐標(biāo)系編號定義和描述技扼,你甚至可以自己定義一套坐標(biāo)系統(tǒng)放到里面(只要你會寫WKT和proj4text)。