本篇講講在GIS桌面軟件和實際數據中,以及各路GIS有關API的編程中,如何尋找坐標系信息。慣例:
本文約2000字,建議閱讀時間10分鍾。
作者:博客園/B站/知乎/csdn/小專欄 @秋意正寒
版權:轉載請告知,並在轉載文上附上轉載聲明與原文鏈接(https://www.cnblogs.com/onsummer/p/12082359.html)
有關“未定義坐標系”的數據如何粗略判別是什么坐標系,已經在上篇的第5.1節寫明了,這里想說的是,已經定義好坐標系統的程序/數據,在哪里找。
目錄:
0. 預備知識(WKT的概念)
1. 硬盤上的數據/數據庫(shp、geojson、tif柵格、幾個單文件數據庫、kml/gml/gpx)
2. GIS數據服務種的坐標系(2.1 ArcGIS家的/2.2 geoserver的)
3. 代碼種的坐標系(3.1 AO/AE 3.2 ArcGIS JsAPI 3.3 openlayers 3.4 ceisum)
0. 預備知識
0.1. WKT
和json在網絡傳輸的地位一樣,是一個標記語言,全稱Well-Known Text,和上文提及的Well-Known ID出自同一個組織——OGC。
WKT是用文本形式記錄地理信息的一個標記語言。什么是地理信息?除開我們常見的真·地理信息點線面之類,還包括坐標系統的定義。我們可以在epsg.io這個網站查詢想知道的坐標系的WKID,也可以查到想知道坐標系的WKT。
例如,WKID=4326的坐標系的WKT如下:
GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS 84",6378137,298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich",0, AUTHORITY["EPSG","8901"]], UNIT["degree",0.0174532925199433, AUTHORITY["EPSG","9122"]], AUTHORITY["EPSG","4326"]]
此處不展開WKT的每一項定義。因為WKT的博客實在太多了,本文略過不作為主要內容。
通常,如果拿到一個WKT,我會觀察最外層定義是GEOGCS還是PROJCS,這能判斷是地理坐標系或投影坐標系統。
然后,若為GEOGCS,我會在AUTHORITY處判斷它被epsg定義的WKID,上面這個wkt即4326.
WKT還有一種二進制存儲格式,叫WKB。有關這兩個東西的文檔在ogc官網是可查的。
1. 硬盤上的數據/數據庫
1.1. shapefiles
簡稱shp文件。shp文件至少有*.shp、*.shx、*.dbf三個同名文件組成,若想為shp文件定義一個坐標系,告訴它“你的空間信息落於哪個坐標系下”,那就要再多一個同名的*.prj文件。
一個shp文件通常要有以上4個文件,若無prj文件只會在加載時不知道它的坐標系信息,實際數據並無影響,所以說shp文件的最低下限是shp、shx、dbf三大文件。
有關shp文件的構成格式不再補充,也能在ogc官網查到對應標准。
此prj文件內坐標系的信息,就是WKT文本。
PROJCS["Xian_1980_3_Degree_GK_CM_114E", GEOGCS["GCS_Xian_1980", DATUM["D_Xian_1980", PHEROID["Xian_1980",6378140.0,298.257]], PRIMEM["Greenwich",0.0], UNIT["Degree",0.0174532925199433]], PROJECTION["Gauss_Kruger"], PARAMETER["False_Easting",500000.0], PARAMETER["False_Northing",0.0], PARAMETER["Central_Meridian",114.0], PARAMETER["Scale_Factor",1.0], PARAMETER["Latitude_Of_Origin",0.0], UNIT["Meter",1.0]]
此處若無AUTHORITY信息,可以用PROJCS內第一個字符串"Xian_1980_3_Degree_GK_CM_114E"去epsg.io查詢(epsg.io不支持模糊查詢,用空格替換下划線,盡量刪減一些關鍵詞)
1.2. GeoJson
geojson是一種用json標記的地理數據文件,記錄二維信息多一些,通常用於webgis傳遞。與turf、arcgis jsapi、openlayers等結合較好。
geojson也是一種ogc規范,開源。
打開一個geojson文件:
其中,頭部“crs”字段就是坐標系信息,我們可以訪問其properties.name獲取有關EPSG信息,此處WKID為32650。
但是,在大多數時候geojson是沒有crs字段的,例如:
這就要問數據的提供者了。
1.3. 影像數據(tif文件為例)
tif文件為柵格圖像文件,后綴為tif或tiff,是ogc規范的一種,全稱GeoTiff。
通常不能在資源管理器中查看tif柵格影像數據的坐標系信息,需要用GIS軟件查看,因為它的坐標系信息寫在數據文件內部。
如下圖:
此為ArcMap中Catalog查看數據的屬性。
1.4. postgis/geopackage/esri geodatabase等數據庫
這些地理數據庫的數據均可在客戶端查看,以QGIS為例,打開這些數據庫里的要素查看坐標系信息。
①postgis
postgresql的一個插件。
②geopackage
geopackage是一種輕量的單文件數據庫,是sqlite的特例應用。
geopackage在QGIS里的支持還不算很強,我的版本是3.8.1,還不支持右鍵導入,拖拽的方式倒是可以。
讀取坐標系的方法一樣。
③gdb
QGIS只能讀取gdb里的表格和要素數據,復雜的數據因為esri商用問題不能讀取。
1.5. kml(kmz)/gml/gpx
kmz用壓縮軟件解壓后可獲取kml文件。kml是xml格式的一種特殊化,原來用於Google Earth的數據交互,它與geojson的區別在於它可以帶符號、顏色、樣式信息。
kml由於早期為Google Earth使用,由上篇可知默認使用WGS84(WKID=4326)坐標系,所以大多數kml文件是沒有寫入坐標系信息的(至少我在QGIS里導出的kml沒有)。
但是,在ogc文檔中有定義坐標系:http://docs.opengeospatial.org/is/12-007r2/12-007r2.html#1274
此處不展開。
gml也是類似的一種xml擴展標記語言,同樣為ogc規范的一種。
其坐標系信息寫在這里,比較顯眼:
最后一個gpx文件,是GPS衛星的信息記錄,也是一種xml的應用。因為是GPS(早期GPS指美國GPS),所以用的是WGS84坐標系。
2. GIS數據服務
2.1. ArcGIS Server
①地圖服務
訪問MapServerURL,可查看地圖服務的基本信息:
https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer
圈出的Spatial Reference即為此地圖服務(包括所有圖層)的WKID。
②影像服務
同地圖服務,但是影像服務並沒有子圖層。
例子:https://landsat2.arcgis.com/arcgis/rest/services/Landsat8_Views/ImageServer
③場景服務
場景服務,URL結尾是SceneServer,訪問后返回json,在控制台可以通過這樣來訪問:
即可獲取其坐標系。
注意,fetch函數在各主流瀏覽器中較新版本均支持,IE不清楚未測試。
本例URL為:http://scene.arcgis.com/arcgis/rest/services/Hosted/Building_Hamburg/SceneServer
④要素服務
基本方法同地圖服務,但是要注意的是要素服務既可單獨作為FeatureServer,也可以存在於MapServer中(作為要素圖層)。
URL例子:
https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/ks_earthquakes_since_2000/FeatureServer
https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/0(若為MapServer中的要素圖層,請訪問上一級的MapServer查看坐標系)
⑤網絡分析服務
網絡分析服務,URL以NAServer結尾,因博主暫無網絡分析服務的URL,暫時不能給例子,用法應該與MapServer類似。
⑥高程服務
高程服務,以ImageServer為載體。方法同影像服務。
例子:https://sampleserver6.arcgisonline.com/arcgis/rest/services/Elevation/MtBaldy_Elevation/ImageServer
2.2. GeoServer
wms/wfs/wcs
訪問其描述xml,然后查看layer對應的"CRS"屬性即可。
例如:
wms的URL:http://<domain>:<port>/geoserver/wms?service=wfs&version=1.1.0&request=GetCapabilities
wfs的URL:http://<domain>:<port>/geoserver/wfs?service=wfs&version=1.1.0&request=GetCapabilities
wcs的URL:http://<domain>:<port>/geoserver/wfs?service=wcs&version=1.1.0&request=GetCapabilities
訪問此URL,瀏覽器會下載一個xml文件,通過尋找以下標簽的值,即可獲取對應圖層的坐標系:
<WMT_MS_Capabilities> 👉 <Capability> 👉 <Layer> (👉 <Layer> 如果有子圖層) 👉 <SRS>
若在Openlayers解析中,則叫作"CRS"。Openlayers解析wms信息的例子:https://openlayers.org/en/latest/examples/wms-capabilities.html?q=wms
若在 ArcGIS JsAPI中,則可通過訪問WMSLayer.description屬性獲取wms的描述。
3. 程序代碼
3.1. ArcObjects/ArcEngine(10.7為例)
①IMap
通過訪問IMap.SpatialReference屬性可獲取ISpatialReference類型的坐標系數據,意義是ArcMap里的數據框的坐標系。
②IGeometry
通過訪問IGeometry.SpatialReference屬性可獲取ISpatialReference類型的坐標系數據,意義是每個幾何圖形的坐標系。
③ILayer
ILayer.SpatialReference屬性只能設置,不能獲取,意義為給一個圖層設置坐標系。
④IGeoDataset
IGeoDataset.SpatialReference屬性只讀,意義為獲取任意地理數據集的坐標系數據。
地理數據集即要素類、shp文件、柵格數據等。
------------
AO編程不是本篇重點,不展開這些接口的獲取與設計。
3.2. ArcGIS JsAPI(4.x為例)
①View
View有兩個子類,SceneView和MapView。這兩個視圖都可以通過訪問其spatialReference屬性獲取坐標系信息。
②Geometry
Geometry是JsAPI前端的幾何,用來表示圖形或者要素的空間信息。通過訪問Geometry的spatialReference屬性獲取坐標系信息。
Geometry的子類Point、Polygon、Polyline等均可用此屬性查看當前幾何信息的坐標系信息。
3.3 openlayers(6.1為例)
ol的最頂層是Map類,通過訪問map.getView().getProjection()可獲取坐標系信息。(和ArcGIS JsAPI的不一樣,ol很多是通過方法訪問的)
此處打印了map實例的視圖的坐標系信息,注意ol的坐標系寫作“Projection”,直接翻譯是投影,實際上還是坐標系信息。我們關注的是code_屬性。
當前打印的坐標系信息,指明了當前地圖的坐標系是3857,即網絡墨卡托。
3.4 cesium(1.64為例)
①Viewer.scene
視圖中場景的坐標系可通過Scene類的mapProjection屬性訪問。
②MapProjection
提供坐標轉換用的幾個方法。
ps:cesium項目最好全用WGS84和Web墨卡托,否則容易出問題。這就意味着cesium弱化了坐標系這一概念,更強調“PCS2GCS”或“GCS2PCS”這種地理坐標和投影坐標的交叉轉換,更注重屏幕像素坐標到地圖坐標的運算。
3.5 leaflets(學習中)
3.6 mapbox(學習中)
下一篇將是一篇硬骨頭,開足馬力上吧!2019不遺憾