16. 投影資料¶
地球不是平坦的,也沒有簡單的方式可將其繪製在平坦的紙質地圖(或電腦螢幕)上,因此人們想出各種巧妙的解決方案,各有利弊。某些投影會保留面積,讓所有物件彼此之間保持相對大小比例;其他投影會保留角度(共形),例如麥卡托投影;有些投影則嘗試找出折衷的良好混合方式,在多個參數上僅造成輕微扭曲。所有投影的共通點都是將(球狀)世界轉換到平面笛卡爾座標系統,而應選用哪一種投影則取決於你如何使用資料。
當我們 載入我們的紐約市資料 時,我們已經遇見投影。(記住那個討厭的 SRID 26918)。然而,有時你需要在空間參考系統之間轉換並重新投影。PostGIS 內建了使用 ST_Transform(geometry, srid) 函數變更資料投影的支援。為了管理幾何圖形的空間參考識別碼,PostGIS 提供了 ST_SRID(geometry) 和 ST_SetSRID(geometry, srid) 函數。
我們可以使用 ST_SRID 函數確認我們資料的 SRID
SELECT ST_SRID(geom) FROM nyc_streets LIMIT 1;
26918
而「26918」的定義又是什麼?正如同我們在「載入資料」單元中所見,定義包含在 spatial_ref_sys
表格中。事實上,那裡有 **兩個** 定義。定義在 srtext
欄中是「已知文字」(WKT),而 proj4text
欄中則有以「proj.4」格式表示的第二個定義。
SELECT * FROM spatial_ref_sys WHERE srid = 26918;
PostGIS 重新投影引擎會嘗試從 spatial_ref_sys
表格中尋找最佳投影
auth_name / auth_srid 如果 proj 可以在其內部目錄中找到有效的「授權名稱」和「授權 srid」,它將使用這些資訊產生投影定義。
srtext 如果 proj 可以從
srtext
中解析並形成定義物件,它將會使用該物件。proj4text 最後,proj 會嘗試處理
proj4text
。
所有這些冗餘表示只要使用有效的 srtext
字串或 proj4text
字串就能在 PostGIS 中建立新的投影。預設所有通用的權威名稱/代碼配對已載入至資料表中。
如果您在建立自訂投影時有選擇,請填寫 srtext
欄位,這是因為該欄位也會由 GeoServer、QGIS、FME 等外部程式使用。
16.1. 比較資料¶
座標與 SRID 合起來定義了地球上的位置。沒有 SRID 的座標只是一個抽象概念。「笛卡兒」座標平面定義為置於地球表面的「平面」座標系統。因為 PostGIS 函數適用於此類平面,比較運算需要兩個幾何圖形以相同的 SRID 表示。
如果您輸入具有不同 SRID 的幾何圖形,只會產生錯誤
SELECT ST_Equals(
ST_GeomFromText('POINT(0 0)', 4326),
ST_GeomFromText('POINT(0 0)', 26918)
);
ERROR: ST_Equals: Operation on mixed SRID geometries (Point, 4326) != (Point, 26918)
注意
不要過度依賴使用 ST_Transform 進行動態轉換。空間索引是使用已儲存幾何圖形的 SRID 建立的。如果比較在不同的 SRID 中進行,則不會(經常)使用空間索引。最佳做法是為資料庫中的所有資料表選擇一個 SRID。僅在您讀取或寫入資料到外部應用程式時才使用轉換函數。
16.2. 轉換資料¶
如果我們返回 SRID 26918 的 proj4 定義,我們可以看到我們的作業投影是第 18 區的 UTM(萬用橫軸墨卡托投影),單位是公尺。
SELECT srtext FROM spatial_ref_sys WHERE srid = 26918;
PROJCS["NAD83 / UTM zone 18N",
GEOGCS["NAD83",
DATUM["North_American_Datum_1983",
SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],
TOWGS84[0,0,0,0,0,0,0],
AUTHORITY["EPSG","6269"]],
PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4269"]],
PROJECTION["Transverse_Mercator"],
PARAMETER["latitude_of_origin",0],
PARAMETER["central_meridian",-75],
PARAMETER["scale_factor",0.9996],
PARAMETER["false_easting",500000],
PARAMETER["false_northing",0],
UNIT["metre",1,AUTHORITY["EPSG","9001"]],
AXIS["Easting",EAST],AXIS["Northing",NORTH],
AUTHORITY["EPSG","26918"]]
讓我們將資料從我們的作業投影轉換成地理座標(也稱為「經度/緯度」)。
要將資料從一個 SRID 轉換成另一個 SRID,您必須先驗證您的幾何圖形是否有有效的 SRID。由於我們已經確認有效的 SRID,接下來我們需要轉換成投影的 SRID。換句話說,地理座標的 SRID 是什麼?
地理座標最常見的 SRID 是 4326,對應於「WGS84 球體上的經度/緯度」。您可以在這裡看到定義
您也可以從spatial_ref_sys
資料表中提取定義
SELECT srtext FROM spatial_ref_sys WHERE srid = 4326;
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.01745329251994328,AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4326"]]
讓我們將「Broad St」地鐵站的座標轉換成地理座標
SELECT ST_AsText(ST_Transform(geom,4326))
FROM nyc_subway_stations
WHERE name = 'Broad St';
POINT(-74.01067146887341 40.70710481558761)
如果您載入資料或建立新的幾何圖形,而不指定 SRID,SRID 的值將會是 0。回想在 Geometries中,當我們建立 geometries
資料表时,並未指定 SRID。如果我們查詢我們的資料庫,我們應該預期所有 nyc_
資料表的 SRID 為 26918,而 geometries
資料表的 SRID 預設為 0。
若要查看資料表的 SRID 指定,請查詢資料庫的 geometry_columns
資料表。
SELECT f_table_name AS name, srid
FROM geometry_columns;
name | srid
---------------------+-------
nyc_census_blocks | 26918
nyc_homicides | 26918
nyc_neighborhoods | 26918
nyc_streets | 26918
nyc_subway_stations | 26918
geometries | 0
但是,如果您知道座標的 SRID 應該是多少,您可以使用幾何圖形的 ST_SetSRID 來事後設定。之後您將能轉換幾何圖形到其他系統。
SELECT ST_AsText(
ST_Transform(
ST_SetSRID(geom,26918),
4326)
)
FROM geometries;
16.3. 函式清單¶
ST_AsText:傳回幾何圖形/地理資訊的公開文本 (WKT) 表示法,不含 SRID 的元資料。
ST_SetSRID(geometry, srid):將几何图形的 SRID 设为特定的整数。
ST_SRID(geometry):傳回在 spatial_ref_sys 資料表中定義的 ST_Geometry 的空間參考識別碼。
ST_Transform(geometry, srid):傳回一個新幾何圖形,其座標已轉換成由整數參數所參照的 SRID。