本文介紹了幾何模型的用途、基本構成和快速入門等內容。
模型用途
簡介
幾何模型是開放地理空間聯盟(Open Geospatial Consortium,以下簡稱為OGC)設計的簡單要素訪問標準(Simple Features Access standard,以下簡稱為SFA),用於描述地理空間資料。該標準定義了基本的空間模型Geometry模型及對該模型的操作、轉換等行為,以實現各種空間分析任務。
GanosBase Geometry是對象關係型資料庫PostgreSQL相容版本(PolarDB PostgreSQL版(相容Oracle))的一個時空引擎擴充,GanosBase Geometry擴充採用了OGC Simple Features規範,它包含了Geometry和Geography兩種類型,用於表示平面或曲面上的點、線、面等幾何對象。
功能概述
GanosBase Geometry支援構建、訪問、編輯、處理、彙總、匯出空間對象的多種方法,支援空間對象關係查詢,支援空間對象線性參考設定等。
GanosBase Geometry相容多種外部格式的直接輸入,例如:WKT、WKB、EKWT、EWKB、KML、GML、GeoHash、Geojson等,也支援通過其他工具輸入Esri Shape File等格式。
主要業務情境
在實際應用中,Geometry類型可以用於幾何Object Storage Service分析的情境:
地圖製作和可視化
地圖可視化可以直觀地展現地理空間中資料的分布、趨勢和關係,通過在地圖上標記不同的資料點、線、面等元素,選擇合適的地圖投影、色彩、符號等元素,展示資料在地理空間中的分布情況,實現地圖的製作和可視化。Geometry類型可以用於表示地圖上的各種要素,例如道路、河流、建築物等。
位置服務
對位置資料進行空間查詢,彙總和分析,可以找到最佳位置、評估風險或計算兩點之間距離等。Geometry類型可以描述點狀地物同時對點狀地物進行各種空間處理,可為位置服務提供支援。
空間關係查詢
空間關係查詢可以用於多種情境,例如空間資料挖掘、城市規劃等。通過空間關係查詢,可以快速地找到滿足特定條件的空間實體,為決策提供有力的支援。Geometry類型支援多個幾何對象之間空間關係的判斷,例如確定兩個物體是否相交或相切等。
空間分析和計算
空間分析和計算用於各種量測情境,例如計算建築物的面積、計算兩個城市之間的距離等。Geometry類型支援各種空間分析和計算,例如計算面積、長度、距離、質心等。
基本構成
幾何模型概述
Geometry模型在二維或三維笛卡爾座標系中進行建模,其大小與位置由其座標決定。每一個座標都有一個X和Y座標值,同時,可以包含可選的Z和M座標值。 Z座標通常用於表示高程。M座標表示測量值,可以表示時間或距離。 如果Geometry中存在Z或M值,則必須為其中的每個點定義它們。 若Geometry具有Z或M座標,則其座標維度為3DZ或3DM,如果它同時具有Z和M,則為4D。
空間參考系
空間參考系(Spatial Reference System,以下簡稱為 SRS )定義了如何將Geometry對象關聯到地球表面上某個具體位置。
GanosBase使用一個整數來表示SRS的定義引用,稱為SRID。Geometry對象通過其自身的SRID值與SRS關聯。
更多內容請參見空間參考。
OGC外部交換格式
SFA規範同時定義了兩種用於外部資料交換的格式:
方便閱讀的文本形式:Well-Known Text (以下簡稱為WKT)。
可以保留資料精度且方便傳輸的二進位形式:Well-Known Binary (以下簡稱為WKB)。
WKT和WKB均包含對象的類型資訊和定義它的座標資訊,但不包含其關聯的SRID,也不支援非二維資料。
GanosBase擴充WKT/WKB為EKWT/EKWB,添加了對3DZ、3DM、4D資料的支援,同時支援嵌入SRID資訊。
EKWT/EKWB為WKT/WKB的超集,目前的版本下,任意有效WKT/WKB都是有效EKWT/EKWB。
OGC幾何類型詳情
原子類型
模型名稱
模型說明
模型WKT樣本
Point
Point是一個零維幾何圖形,表示座標空間中的單個位置。
POINT (1 2) * POINT Z (1 2 3)
POINT ZM (1 2 3 4)
LineString
LineString是由連續的線段序列形成的一維線。每條線段由兩個點定義,一條線段的終點形成下一條線段的起點。 LineString可以自相交。
LINESTRING (1 2, 3 4, 5 6)
Polygon
Polygon由外部邊界和零個或多個內部邊界(孔)界定。每個邊界都是一個LinearRing 。
POLYGON ((0 0 0,4 0 0,4 4 0,0 4 0,0 0 0),(1 1 0,2 1 0,2 2 0,1 2 0,1 1 0))
參數化型別
模型名稱
模型說明
模型WKT樣本
EllipticalString
橢圓弧。
ELLIPTICALSTRING(-2 0,2 0,0 0,0,0,0,2,0.5)
Bezier3Curve
四個點確定的一條三階貝茲路徑。
BEZIER3CURVE(1 1, 2 2, 3 2, 3 1)
集合類型
模型名稱
模型說明
模型WKT樣本
MultiPoint
MultiPoint是Point的集合。
MULTIPOINT ( (0 0), (1 2) )
MultiLineString
MultiLineString是LineString的集合。
MULTILINESTRING ( (0 0,1 1,1 2), (2 3,3 2,5 4) )
MultiPolygon
MultiPolygon是不重疊、不相鄰的Polygon的集合。集合中的Polygon只能在有限點處相接。
MULTIPOLYGON (((1 5, 5 5, 5 1, 1 1, 1 5)), ((6 5, 9 1, 6 1, 6 5)))
GeometryCollection
GeometryCollection是Geometry的集合,可以混合不同類型的Geometry對象。
GEOMETRYCOLLECTION ( POINT(2 3), LINESTRING(2 3, 3 4))
CompoundCurve
含線、橢圓弧或貝茲路徑的複合線對象。 CompoundCurve中每個單元對象的幾何必須連續。
COMPOUNDCURVE((1 0,2 0),ELLIPTICALSTRING(2 0 ,4 0, 3 0 ,1,0,0,1,0.5))
COMPOUNDCURVE((1 2,2 0),BEZIER3CURVE(2 0,20 20 ,30 10,10 10))
CurvePolygon
含曲線的複合面對象。 CurvePolygon中的各個子物件必須是閉合的。
CURVEPOLYGON(ELLIPTICALSTRING(2 0,2 0,0 0,0,0,0,2,0.5),CIRCULARSTRING(-0.5 0,0.5 0,-0.5 0))
CURVEPOLYGON(BEZIER3CURVE(1 1, 2 2, 3 1, 1 1),CIRCULARSTRING(1.7 1.2,1.9 1.2,1.7 1.2))
空間資料行視圖
在GanosBase中,geometry_columns是從資料庫系統目錄表中讀取全部幾何列的視圖。該視圖遵循了OGC的Simple Features Specification for SQL標準。
空間資料行視圖具有如下結構:
列名 | 類型 | 說明 |
f_table_catalog | varchar(256) | 一般為固定值postgres。 |
f_table_schema | varchar(256) | 該表所在的schema。 |
f_table_name | varchar(256) | 該表的表名。 |
f_geometry_column | varchar(256) | 該表中某個Geometry列的列名。 |
coord_dimension | integer | Geometry列的維度(2,3或4)。 |
srid | integer | Geometry列SRID,是引用到spatial_ref_sys表的外鍵。 |
type | varchar(30) | Geometry對象的類型,應為OGC標準類型之一。若為混合類型,則值為GEOMETRY。 |
可以通過如下語句查詢當前資料庫中全部幾何資料列:
SELECT * FROM geometry_columns;索引
空間索引使GanosBase處理大型空間資料集時避免對資料庫進行全域“順序掃描”。索引通過將資料群組織到搜尋樹中來加速搜尋,可以快速遍曆該搜尋樹以尋找特定記錄。
GanosBase為空白間資料提供了三種空間索引:
索引名稱 | 索引簡介 | 索引特點 |
GiST (Generalized Search Tree) | GiST索引是一種平衡搜尋樹,是最常用、最通用的空間索引方法,提供非常好的查詢效能。 | GiST索引允許定義一些規則將任意類型的資料分布在一棵平衡樹上,同時也允許定義一些方法訪問這些資料。 |
BRIN (Block Range Index) | BRIN索引通過匯總空間表中一定數量記錄的空間範圍進行處理。搜尋是通過掃描空間範圍來完成的。 |
|
SP-GiST (Space-Partitioned Generalized Search Tree) | SP-GiST是一種通用索引方法,支援四叉樹、kd樹和根基樹等分區搜尋樹。 |
|
快速入門
簡介
快速入門協助使用者快速理解GanosBase Geometry引擎的基本用法,包括擴充建立、建立表、匯入資料、建立索引、空間分析量測、空間關係判斷等內容。
文法說明
建立擴充。
--建立幾何擴充 CREATE extension ganos_geometry cascade;說明建議將擴充安裝在public模式下,避免許可權問題。
CREATE extension ganos_geometry WITH schema public cascade;建立幾何表。
--方式一:直接建立帶geometry欄位的表 CREATE TABLE ROADS ( ID int4, ROAD_NAME varchar(25), geom geometry(LINESTRING,3857) ); --方式二:先建立普通表,再附加幾何欄位 CREATE TABLE ROADS ( ID int4, ROAD_NAME varchar(25) ); SELECT AddGeometryColumn( 'roads', 'geom', 3857, 'LINESTRING', 2);添加幾何約束。
ALTER TABLE ROADS ADD CONSTRAINT geometry_valid_check CHECK (ST_IsValid(geom));匯入幾何資料。
INSERT INTO roads (id, geom, road_name) VALUES (1,ST_GeomFromText('LINESTRING(191232 243118,191108 243242)',3857),'北五環'); INSERT INTO roads (id, geom, road_name) VALUES (2,ST_GeomFromText('LINESTRING(189141 244158,189265 244817)',3857),'東五環'); INSERT INTO roads (id, geom, road_name) VALUES (3,ST_GeomFromText('LINESTRING(192783 228138,192612 229814)',3857),'南五環'); INSERT INTO roads (id, geom, road_name) VALUES (4,ST_GeomFromText('LINESTRING(189412 252431,189631 259122)',3857),'西五環'); INSERT INTO roads (id, geom, road_name) VALUES (5,ST_GeomFromText('LINESTRING(190131 224148,190871 228134)',3857),'東長安街'); INSERT INTO roads (id, geom, road_name) VALUES (6,ST_GeomFromText('LINESTRING(198231 263418,198213 268322)',3857),'西長安街');查詢幾何對象資訊。
SELECT id, ST_AsText(geom) AS geom, road_name FROM roads; -------------------------------- id | geom| road_name --------+-----------------------------------------+----------- 1 | LINESTRING(191232 243118,191108 243242) | 北五環 2 | LINESTRING(189141 244158,189265 244817) | 東五環 3 | LINESTRING(192783 228138,192612 229814) | 南五環 4 | LINESTRING(189412 252431,189631 259122) | 西五環 5 | LINESTRING(190131 224148,190871 228134) | 東長安街 6 | LINESTRING(198231 263418,198213 268322) | 西長安街 (6 rows)建立索引。
--GiST索引 CREATE INDEX [indexname] ON [tablename] USING GIST ( [geometryfield] ); CREATE INDEX [indexname] ON [tablename] USING GIST ([geometryfield] gist_geometry_ops_nd); VACUUM ANALYZE [table_name] [(column_name)]; --舉例 Create INDEX sp_geom_index ON ROADS USING GIST(geom); VACUUM ANALYZE ROADS (geom); --BRIN索引 CREATE INDEX [indexname] ON [tablename] USING BRIN ( [geometryfield] ); CREATE INDEX [indexname] ON [tablename] USING BRIN ([geometryfield] brin_geometry_inclusion_ops_3d); CREATE INDEX [indexname] ON [tablename] USING BRIN ([geometryfield] brin_geometry_inclusion_ops_4d); --指定塊大小的brin索引 CREATE INDEX [indexname] ON [tablename] USING BRIN ( [geometryfield] ) WITH (pages_per_range = [number]);空間測量和空間分析。
--Create Table bc_roads: Column | Type | Description ------------+-------------------+------------------- gid | integer | Unique ID name| character varying | Road Name the_geom| geometry | Location Geometry (Linestring) --Create table bc_municipality: Column | Type | Description -----------+-------------------+------------------- gid| integer | Unique ID code | integer | Unique ID name | character varying | City / Town Name the_geom | geometry | Location Geometry (Polygon) --長度計算 SELECT sum(ST_Length(the_geom))/1000 AS km_roads FROM bc_roads; km_roads ------------------ 70842.1243039643 (1 row) --面積計算 SELECT ST_Area(the_geom)/10000 AS hectares FROM bc_municipality WHERE name = 'PRINCE GEORGE'; hectares ------------------ 32657.9103824927 (1 row)空間關係判斷。
--ST_Contains SELECT m.name, sum(ST_Length(r.the_geom))/1000 as roads_km FROM bc_roads AS r, bc_municipality AS m WHERE ST_Contains(m.the_geom,r.the_geom) GROUP BY m.name ORDER BY roads_km; name| roads_km ----------------------------+------------------ SURREY | 1539.47553551242 VANCOUVER | 1450.33093486576 LANGLEY DISTRICT| 833.793392535662 BURNABY | 773.769091404338 PRINCE GEORGE | 694.37554369147 ... --ST_Covers,a circle covering a circle SELECT ST_Covers(smallc,smallc) As smallinsmall, ST_Covers(smallc, bigc) As smallcoversbig, ST_Covers(bigc, ST_ExteriorRing(bigc)) As bigcoversexterior, ST_Contains(bigc, ST_ExteriorRing(bigc)) As bigcontainsexterior FROM (SELECT ST_Buffer(ST_GeomFromText('POINT(1 2)'), 10) As smallc, ST_Buffer(ST_GeomFromText('POINT(1 2)'), 20) As bigc) As foo; --Result smallinsmall | smallcoversbig | bigcoversexterior | bigcontainsexterior --------------+----------------+-------------------+--------------------- t| f | t | f (1 row) --ST_Disjoint SELECT ST_Disjoint('POINT(0 0)'::geometry, 'LINESTRING ( 2 0, 0 2 )'::geometry); st_disjoint --------------- t (1 row) SELECT ST_Disjoint('POINT(0 0)'::geometry, 'LINESTRING ( 0 0, 0 2 )'::geometry); st_disjoint --------------- f (1 row) --ST_Overlaps SELECT ST_Overlaps(a,b) As a_overlap_b, ST_Crosses(a,b) As a_crosses_b, ST_Intersects(a, b) As a_intersects_b, ST_Contains(b,a) As b_contains_a FROM (SELECT ST_GeomFromText('POINT(1 0.5)') As a, ST_GeomFromText('LINESTRING(1 0, 1 1, 3 5)') As b) As foo a_overlap_b | a_crosses_b | a_intersects_b | b_contains_a ------------+-------------+----------------+-------------- f | f | t | t --ST_Relate SELECT ST_Relate(ST_GeometryFromText('POINT(1 2)'), ST_Buffer(ST_GeometryFromText('POINT(1 2)'),2), '0FFFFF212'); st_relate ----------- t --ST_Touches SELECT ST_Touches('LINESTRING(0 0, 1 1, 0 2)'::geometry, 'POINT(1 1)'::geometry); st_touches ------------ f (1 row) SELECT ST_Touches('LINESTRING(0 0, 1 1, 0 2)'::geometry, 'POINT(0 2)'::geometry); st_touches ------------ t (1 row) --ST_Within SELECT ST_Within(smallc,smallc) As smallinsmall, ST_Within(smallc, bigc) As smallinbig, ST_Within(bigc,smallc) As biginsmall, ST_Within(ST_Union(smallc, bigc), bigc) as unioninbig, ST_Within(bigc, ST_Union(smallc, bigc)) as biginunion, ST_Equals(bigc, ST_Union(smallc, bigc)) as bigisunion FROM ( SELECT ST_Buffer(ST_GeomFromText('POINT(50 50)'), 20) As smallc, ST_Buffer(ST_GeomFromText('POINT(50 50)'), 40) As bigc) As foo; --Result smallinsmall | smallinbig | biginsmall | unioninbig | biginunion | bigisunion --------------+------------+------------+------------+------------+------------ t| t | f | t | t | t (1 row)幾何對象存取。
SELECT ST_IsSimple(ST_GeomFromText('POLYGON((1 2, 3 4, 5 6, 1 2))')); st_issimple ------------- t (1 row) SELECT ST_IsSimple(ST_GeomFromText('LINESTRING(1 1,2 2,2 3.5,1 3,1 2,2 1)')); st_issimple ------------- f (1 row) --查詢地形中擁有環島且面積最大的城市 SELECT gid, name, ST_Area(the_geom) AS area FROM bc_municipality WHERE ST_NRings(the_geom) > 1 ORDER BY area DESC LIMIT 1; gid | name | area -----+--------------+------------------ 12 | 安寧市 | 257374619.430216 (1 row)刪除擴充(可選)。
--刪除幾何擴充 Drop extension ganos_geometry cascade;
SQL參考
詳細SQL手冊請參見Geometry SQL參考。