坐標系統是GIS、大地測量及製圖的核心,而坐標轉換則是開發webGIS最常會遇到的課題。
由於地球是近似橢球,會有很多模式來描述這個橢球,以及球上面的點位坐標,描述這個橢球及球上位置的系統稱作大地坐標系統,需要定義的東西很多,包含幾何面的橢球參數、其他物理面及觀測資料的整合推估,GPS使用的WGS84經緯度屬此類,簡單來說,大地坐標系統是想描述橢球及球上面的位置。
為了製造地圖,人們必須把近似橢球狀的地球投影到平面上,這個坐標系統稱作投影坐標系統,只要是地圖,一定會採用投影系統。
投影的方式有很多,麥卡托、藍柏特投影等等...,而從Map Projection Transitions網站的各種投影機制的模擬圖可以看得出來,投影一定會有失真的情況,所以才會常常有以下新聞出現:
投影系統一定都是有一好沒兩好,只有最適合的投影,沒有最好的投影,包含小小的台灣,因考量投影的誤差,也分了121中央子午線及119中央子午線的投影帶。
我們直接來看看訂定及維護我國坐標系統的內政部怎麼說明TWD97(引述自內政部)
大致上可以劃兩個重點: (1)有定義所採用的大地系統、 (2)定義了投影,採橫麥卡托二度分帶,且分兩種投影帶(台灣本島121分帶、澎湖金門馬祖119分帶)
ps.好像也遇過117分帶(太平島、南沙等離島)、123分帶(釣魚台等)
我國官方的坐標系統是TWD97,而在webgis中,為了互操作性通用的系統為Web Mercator(或稱Google Web Mercator、Spherical Mercator、WGS 84 Web Mercator),相關說明可以及其前世今生可以參考這篇文章,它其實不是真正的麥卡托投影,儘管這個坐標系一度不被GIS專業人士接受,但目前已經廣泛使用於webgis。
為了方便世界各國的坐標系統的轉換及辨識,一般使用EPSG Wkid來為坐標系統取代號,EPSG是(European Petroleum Survey Group) 的縮寫,EPSG定義了世界各國投影、坐標系統一系列的編號WKID(Well Known ID),在台灣的我們常使用的編碼如下:
坐標系統在GIS資料中應該都要被記錄,像是shapefile的.prj檔,在解析資料時才能判讀,但在geojson、kml通常沒有類似prj的東西,默認使用EPSG:4326 (也就是WGS84經緯度)
stackexchange上有這麼一個問題:
到底在Google Earth、Googlemaps、Openlayers、Leaflet應該是要使用EPSG:3857還是EPSG:4326?
最佳答案是這樣:
有些事被混淆了...
- Google Earth是 EPSG:4326也就是WGS84大地基準
- Googlemaps是使用投影系統的EPSG:3857(其中EPSG:3857大地框架是WGS84,使用麥卡托投影)
- 我們使用的底圖圖磚的資料來源是使用EPSG:4326儲存
- 但是其發布的Web Service如WMS、WMTS是用EPSG:3857發布的
簡單來說,資料用EPSG:4326存,但地圖底圖Web Service都是使用EPSG:3857(因為地圖是平面,一定是要經過投影的呀!)
兩者坐標值域是差很多的:
通常我們只會使用EPSG:4326的資料但不會直接運算EPSG:3857
WMTS跟WMS主要使用EPSG:3857、geojson、kml通常採用EPSG:4326儲存資料,而我們取得的opendata資料常出現EPSG:3826甚至EPSG:3828等坐標系統....實務上一定會遇到這類問題。
所以我們需要坐標轉換!
proj4是OSGeo(Open Source Geospatial Foundation)維護的坐標轉換工具,有許多程式語言的版本,Javascirpt可以使用proj4js。
安裝 npm install proj4
建立test.js
var proj4=require('proj4');
//首先定義坐標系統的參數(這些內容包含使用大地框架、橢球、投影等),proj4轉換是根據這些參數
proj4.defs([
[
'EPSG:4326',
'+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees'],
[
'EPSG:3826',
'+title=TWD97 TM2+proj=tmerc +lat_0=0 +lon_0=121 +k=0.9999 +x_0=250000 +y_0=0 +ellps=GRS80 +units=公尺 +no_defs'
],
[
'EPSG:3828',
'+proj=tmerc +lat_0=0 +lon_0=121 +k=0.9999 +x_0=250000 +y_0=0 +ellps=aust_SA'
]
]);
轉換
var EPSG3826 = new proj4.Proj('EPSG:3826');//TWD97 121分帶
var EPSG3828 = new proj4.Proj('EPSG:3828');//TWD67 121分帶
var EPSG4326 = new proj4.Proj('EPSG:4326');//WGS84
//4326轉3826 (經緯度轉TWD97)
var data1 = proj4(EPSG4326, EPSG3826, [121, 23]);
//[250000,2544283.12479424]
//3826轉3828(TWD97轉TWD67)
var data2 = proj4(EPSG4326, EPSG3826, data1);
//[249171.10594810007, 2544488.5274230908]
註:Proj4參數取自:台灣大地座標系統的轉換
執行 node test.js
順著上面的案例,
我國有兩個時代的坐標系統TWD97跟TWD67
兩者在本島121分帶的差值大概是[dx,dy]=[8xx,2xx] (單位:公尺)
因此,如果在拿到一份資料時,如果發現X方向差了800公尺而Y方向差了200公尺,又沒有prj檔的狀況下,可能拿到的資料把TWD67跟TWD97弄混了,對坐標需要有一些敏銳度。
而文中一直提到,在geojson中通常都使用EPSG:4326,但我們取得國內政府平台提供的資料,應該是以適合我國的TWD97測量建置而來。
另外一個重點,如果在金門、澎湖、馬祖等坐標系統記得使用EPSG:3825(TWD97,119)或EPSG:3827(TWD67,119)喔,綜上所述,proj4在webgis一定會需要用到。