空間數據存儲
使用
幾何類型(Geometry Type)
Geometry(幾何對象類型)是PG的一個基本存儲類型,PostGIS的空間數據都會以Geometry的形式存儲在PostgreSQL里,本質是個二進制對象。
OGC的WKB和WKT格式
PostGIS基於OGC的“Simple Feature for Specification for SQL”規范,在Geometry對象上實現了一系列的GIS Object(地物對象),使用了OGC推薦的WKT(Well-Known Text)和WKB(Well-Known Binary)格式進行描述,大幅增加了易用性,例如WKT的7個基本類型:
點:POINT(0 0)
線:LINESTRING(0 0,1 1,1 2)
面(多邊形):POLYGON((0 0,4 0,4 4,0 4,0 0)) 簡單多邊形
POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1)) 多邊形有一個內部的"孔洞(hole)"
多點:MULTIPOINT((0 0),(1 2))
多線:MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))
多面:MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))
幾何集合:GEOMETRYCOLLECTION(POINT(2 3),LINESTRING(2 3,3 4))
EWKT、EWKB和Canonical格式
PostGIS自身又在WKT和WKB基礎上擴展實現了EWKT和EWKB來滿足更復雜的場景需求,EWKT和EWKB相比OGC WKT和WKB格式主要的擴展有3DZ、3DM、4D坐標和內嵌空間參考支持
SQL-MM格式
SQL-MM格式定義了一些插值曲線,這些插值曲線和EWKT有點類似,也支持3DZ、3DM、4D坐標,但是不支持嵌入空間參考。
地理類型(Geography Type)
地理類型提供支持本地空間特性的“地理”坐標(有時稱為“大地”坐標,或“緯度/經度”,或“經度/緯度”)。它的幾何基礎是球面。計算兩點間的距離相當於計算圓弧的距離,不能使用平面幾何原理,需要通過其他參考方法計算。由於底層算法復雜,定義的地理類型比空間類型少很多,隨之算法的增加,將出現新的地理類型。
PostGresSQL8.3推出一張表輔助空間參考表:spatial_ref_sys表,它存放的是OGC規范的空間參考。輔助轉化。 地理類型只支持簡單的簡單的元素。標准幾何類型數據將自動轉換到地理WGS84坐標。還可以使用EWKT和EWKB約定來插入數據。
patial_ref_sys表,它存放的是OGC規范的空間參考。我們取我們最熟悉的4326參考看一下:
它的srid存放的就是空間參考的Well-Known ID,對這個空間參考的定義主要包括兩個字段,srtext存放的是以字符串描述的空間參考,proj4text存放的則是以字符串描述的PROJ.4 投影定義(PostGIS使用PROJ.4實現投影)
SRID 4326聲明了地理空間參考系統
如下創建表:
CREATE TABLE global_points (
id SERIAL PRIMARY KEY,
name VARCHAR(64),
location GEOGRAPHY(POINT,4326)
);
插入數據:
INSERT INTO global_points (name, location) VALUES
('London', ST_GeographyFromText('SRID=4326; POINT(-72.1235 42.3521)'));
PostGIS對幾何信息的檢查
PostGIS可以檢查幾何信息的正確性,這主要是通過IsValid函數實現的。 以下語句分辨檢查了2個幾何對象的正確性,顯然,(0, 0)點和(1,1)點可以構成一條線,但是(0, 0)點和(0, 0)點則不能構成,這個語句執行以后的得出的結果是TRUE,FALSE。
select IsValid('LINESTRING(0 0, 1 1)'), IsValid('LINESTRING(0 0,0 0)')
默認PostGIS並不會使用IsValid函數檢查用戶插入的新數據,因為這會消耗較多的CPU資源(特別是復雜的幾何對象)。當你需要使用這個功能的時候,你可以使用以下語句為表新建一個檢查約束:
ALTER TABLE cities
ADD CONSTRAINT geometry_valid CHECK (IsValid(shape))
這時當我們往這個表試圖插入一個錯誤的空間對象的時候,會得到一個錯誤:
INSERT INTO test.cities ( shape, name )
VALUES ( GeomFromText('LINESTRING(0 0,0 0)', 4326), '北京');
ERROR: new row for relation "cities" violates check constraint "geometry_valid"
SQL 狀態: 23514