黃 鵬
(長江工程職業技術學院, 武漢 430212)
定位技術與地理位置服務的廣泛應用,使得空間地理信息在智慧城市建設中占據重要位置。與傳統數據相比,空間數據具有數據量大、非結構化、分類編碼、空間位置相關、更新速度快等特點。目前空間數據庫有兩種主流技術模式:一種是采用空間數據引擎+關系型數據庫的中間件技術,如ESRI公司的ArcSDE。另一種是關系數據庫+空間功能擴展的對象關系型數據庫融合模式,由數據庫廠商專門實現,如Oracle Spatial,PostGIS,Mysql Spatial等[1]。
對象關系型數據庫采用關系模型組織屬性數據,按對象存取空間數據,實現了在數據庫內核中進行空間操作和處理,其優點是擴展SQL比較方便,較易實現數據共享與互操作[2]。目前市場上流行的三種對象關系型空間數據庫分別是Oracle Spatial,PostGIS和Mysql Spatial。
Oracle spatial 是Oracle數據庫為實現快速、高效地存取分析空間數據而推出的專用組件。Oracl Spatial定義了一種可自定義的空間對象類型SDO_Geometry,在該類型中,可以進一步定義數據的幾何體類型、空間參考坐標系、數據結構、坐標值信息等。Oracl Spatial還提供了四叉樹、參照樹等空間索引方案,支持直接在SQL語句中調用完整的空間操作函數,極大地提高了空間數據的查詢效率。Oracle Spatial實現了非結構化、有嵌套關系的空間數據與屬性數據的統一存儲和管理,為空間數據的管理和利用帶來方便。
PostGIS是在開源數據庫Postgre SQL基礎上研發出來的空間功能擴展插件,它彌補了Postgre SQL在空間數據管理上的缺陷和不足。PostGIS支持幾乎所有的空間數據類型,如點、線、多邊形、復合點、復合線、復合多邊形,也支持所有的數據存儲和構造方法。PostGIS提供了Union(求并)、Difference(求差)、Distance(求距離)等空間分析函數來操作空間數據,也提供二元謂詞來監測空間對象之間的空間關系[3]。此外,PostGIS還提供了空間坐標系轉換、空間聚集函數、柵格數據切片緩存等功能,拓展了空間數據管理能力,在目前的開源GIS建設方案中占據重要地位。
MySQL是最初由瑞典MySQL AB公司所研發的中小型數據庫管理系統,據數據庫權威網站DB-Engines統計,2020-2022三年間,MySQL牢牢占據數據庫排行榜第二名的位置。MySQL從4.0版本開始加入了Spatial模塊,簡稱為MySQL Spatial。該模塊遵循了美國OGC協會提出的開放式地理數據互操作規范,支持空間幾何數據類型,并實現了相關的空間操作函數和空間索引方法。隨著8.0版本的推出,MySQL Spatial在空間操作功能方面逐步完善,引入了地理參照坐標系,豐富了空間分析函數,又因其開源免費、知名度高等特點,已成為空間數據管理的優選方案之一。
Mysql Spatial實現了OpenGIS規范的一個子集,實現了有限的空間幾何數據類型[4],如Geometry(幾何基類)、Point(點)、LineString(線)、Polygon(面)等基礎數據類型,和MulitPoint(復合點)、MultiLineString(復合線)、MultiPolygon(復合面)、GeometryCollection(幾何集合)等復雜數據類型。Mysql Spatial已支持的幾何數據模型如圖1所示。

圖1 MySQL Spatial支持的幾何數據模型
Mysql Spatial采用三種數據格式WKT、WKB、內部存儲格式來描述空間數據的幾何結構。WKT(Well-Known Text format)是一種文本標記語言,用于表示地圖上的矢量幾何對象、空間參照系以及空間參照系之間的轉換。如將點對象表示為POINT(x y),線對象表示為LINESTRING(x1 y1,x2 y2,…,xn yn),而面對象則采用內環坐標加外環坐標的形式來表示,如POLYGON((x01 y01,x02 y02,…,x0n y0n), (x11 y11,x12 y12,…,x1n y1n))。
WKB(Well-Known Binary Format)格式以二進制流的形式交互幾何數據,將幾何信息存儲在BLOB值中。如一個點狀對象表示為21個字節的二進制數,其中1個字節代表字節序、4個字節代表幾何類型、16個字節代表雙精度x坐標、y坐標。線狀和面狀對象則保留前部“字節序和幾何類型”的位置,剩余的字節由子對象數目和子對象的坐標數組共同決定。
內部存儲格式是Mysql實際存儲幾何對象的數據格式,它與WKB格式不完全相同,而是在二進制數的頭部再加4個字節表示空間參考系的ID(SRID)值,如WGS84坐標系的SRID為4326。這樣一個點狀對象在Mysql中的實際存儲長度是25個字節。
為了提高空間數據的搜索效率,MySQL Spatial支持為空間數據添加R-Trees(R樹)空間索引[5]。R樹索引將空間對象按范圍進行劃分,分為葉節點和非葉節點。其中葉節點不可再分,由空間對象的最小外接矩形(MBR)構成。非葉節點是可以再分的節點,也稱為父節點,它由所有子節點的公共外接矩形MBR構成,并存儲有指向各子節點的指針。自8.0版本以后,MySQL Spatial支持為MyISAM和INNODB存儲引擎的數據表添加空間索引,添加索引的關鍵字為SPATIAL INDEX,且添加索引的字段不能為空。
MySQL Spatial也提供了大量的空間處理函數來操作空間數據。這些函數可以分為以下5類:幾何對象構造函數、格式轉換函數、幾何屬性訪問函數、空間關系函數和空間運算函數,如表1所示。在MySQL 8.0版本以前,空間函數的操作都是在幾何平面(笛卡爾坐標系)下進行,沒有考慮幾何對象的空間參照關系。而在MySQL 8.0版本中,空間函數已經支持同一坐標系下的幾何空間運算,極大地擴展了MySQL的空間數據處理能力。

表1 Mysql Spatial空間函數表
為了驗證MySQL Spatial在空間數據存儲管理上的有效性,選取湖北省行政區劃數據(面類型)與綠地公園數據(點類型)為樣本,通過Shapelib開源庫實現Shapefile矢量格式數據的讀取,再調用Mysql Connector Net驅動程序的API接口,將其轉存到Mysql數據庫中。
Shapelib是采用c語言編寫的輕量級地圖工具,在.net環境下,可以通過DLLImport方法將其引入到c#語言中使用(注意指針與IntPtr、數組等參數的轉換關系),也可以使用SharpShape版本來讀取數據。Shapelib讀取Shapefile數據的具體過程如下:(1)通過ShapeOpen()函數獲取文件句柄,調用SHPGetInfo()和SHPReadObject()函數讀取要素的幾何類型和坐標數據;(2)通過DBFOpen()打開屬性數據,再通過字段處理函數讀取字段類型及屬性值;(3)讀取.proj投影文件信息,根據空間參考規范,確定數據的SRID值。由于Mysql目前僅支持同一空間參考系下的函數運算,因此統一定義數據坐標系為WGS84,其SRID值為4326。Shapefile文件的讀取及存儲過程如圖2所示。

圖2 Shapefile矢量文件讀取及存儲過程
在數據庫中,通過SQL語句“Create database myGIS; use myGIS;”創建并打開空間數據庫。由于Shapelib讀取獲得的字段類型與Mysql數據庫中的字段類型不完全一致,因此在創建數據表之前,需要確立兩者之間的轉換關系。幾何數據類型直接轉換為Mysql支持的幾何類型,而字符串類型和數字類型在轉換時還要保留數據的長度和精度信息。如表2所示。

表2 Shapelib讀取字段類型與MySQL字段類型對比
根據空間數據的特性,幾何坐標信息采用Point、
Linestring、Polygon幾何字段類型保存,屬性信息采用Mysql基礎數據類型保存。通過SQL語句“Create Table Name()”創建空間數據表,其建表過程如下:加載Mysql-connector-net驅動程序,根據之前讀取到的幾何字段類型和屬性字段類型,確定空間數據表的各個字段類型,創建對應的數據表。由于Mysql Spatial的空間函數已支持同一坐標系的空間運算,因此在建立幾何字段的同時,需附加空間參考約束‘SRID 4326’。建立行政區劃數據表的Sql語句如下所示:
CRETTETABLEhubeiRegion(FIDintprimarykeyauto_increment, -- 主鍵
SHAPEpolygonnotnullSRID4326,-- 幾何字段
NAMEvarchar(30), -- 區劃名稱
KINDvarchar(4), -- 分類碼
ADMINCODEvarchar(6), -- 行政編碼
PROVINCENAvarchar(50)); -- 所屬省份名稱
數據表建好之后,將Shapefile中的坐標數據轉為標準SQL語句“Insert into values”插入表中。(1)將空間坐標數據逐一轉為WKT文本格式,緯度在前,經度在后;對于線、面對象,需要逐一獲取其子對象Part的坐標串數據,再附加其空間參考ID,以保證與數據表的結構相一致;(2)利用Mysql Spatial提供的ST_GeomFromText()函數逐一構造幾何參數;(3)依據shapelib讀取得到的屬性數據,補齊其余的屬性字段參數;(4)調用API接口的ExecuteNonQuery()方法,執行SQL語句向數據表插入一條記錄。插入空間數據后的行政區劃表如圖3所示。

圖3 MySQL空間數據存儲
空間數據轉入數據庫后,還需要建立空間索引,
為后續的空間查詢做好鋪墊??臻g索引的方法默認為R-Tree索引。其創建的方法是在幾何字段上建立R樹索引約束,關鍵字為Spatial Index。創建索引之前,還要確??臻g索引字段不為空(非空約束),且數據表的存儲引擎為InnoDB,以支持地理空間參考下的空間查詢功能。建立空間索引的SQL語句如下所示。
ALTERTABLEhubeiRegionADDSPATIALINDEX(shape);
(1)以查詢“與武漢市接壤的市級行政區劃”為例,實現行政區劃圖層內部的空間鄰接關系查詢。由于ST_Touches()函數在8.0.27版本中不能良好支持地理空間坐標系下的關系運算,因此可利用空間拓撲關系的映射不變特性,將其置于平面坐標系(SRID:0)來間接判斷要素間的空間鄰接關系。SQL查詢語句如下,查詢結果如圖4(a)所示。

圖4 MySQL空間查詢結果
SET@g= (SELECTST_SRID(shape,0)fromhubeiregionWHERENAME=“武漢市”);
SELECTNAME,ST_AsText(shape)FROMhubeiregionWHEREST_Touches(@g,ST_SRID(shape,0));
(2)以查詢“武漢市行政區劃內的綠地公園”為例,實現行政區劃圖層與綠地圖層的空間包含關系查詢。Mysql Spatial提供ST_Contains()函數來判斷實體要素間的空間包含關系。SQL查詢語句如下,查詢結果圖4(b)所示。
SET@g= (SELECTshapefromhubeiregionWHERENAME=“武漢市”);
SELECTNAMEFROMgreenlandWHEREST_Contains(@g,shape)limit14;
將上述樣本數據導入PostGIS 14中,與Mysql Spatial的查詢結果作對比分析。評測指標采用服務器執行SQL語句的實際查詢用時,排除查詢緩存和客戶端渲染技術對結果的影響,對比結果如表3所示。(1)數據導入方式:PostGIS提供了工具命令shp2pgsql及圖形化界面來導入Shapefile數據,導入后的坐標數據被定義為Geometry類型;而Mysql Spatial不提供shapefile文件導入功能,本文中使用shapelib第三方庫實現;(2)空間關系判斷:以“市內綠地”(點-面包含)及“行政區劃接壤”(面-面相鄰)的關系判斷為例,在不考慮空間參照系時,PostGIS中的查詢時間分別為67ms、116ms,Mysql Spatial中的查詢時間分別為88ms,48ms,后者總耗時少于前者。而在代入地理參照系后,前者的查詢時間幾乎沒有變化,而后者的“包含查詢”用時增加到508ms,且無法直接判斷鄰接關系,提示Mysql在空間關系的判斷上還存在不足;(3)距離量測與邊界查詢:兩者均提供了ST_Distance()函數進行地面距離的測算,在PostGIS中需要將Geometry幾何對象轉為Geography地理對象,才能獲得大地距離。以“白玉公園”到“新城廣場”中心點的距離為例,在PostGIS中的測量值為13 802.145m,耗時71ms,在Mysql中的測量值為13 802.158m,耗時66ms。另外,在讀取面要素的幾何邊界(武漢市行政邊界)時,兩者分別用時75ms、31ms,說明在不考慮空間關系運算時,Mysql的計算速度略優于PostGIS;(4)空間索引:PostGIS綜合使用了R樹與GIST索引兩種方式,而Mysql采用的是R樹索引,這也是導致兩者查詢效率產生差異的因素之一。

表3 Mysql Spatial與PostGIS查詢結果對比
隨著8.0版本的推出,Mysql Spatial進一步豐富了其空間處理函數,引入了地理坐標系和投影坐標系,并支持同一參考坐標系下的空間運算。其空間運算性能雖然相比PostGIS還有差距,但已能實現基于地理實體的空間關系判斷與距離測量,讀取幾何數據較快,具備了在中小型GIS系統中存儲和管理矢量數據的能力。研究中也發現,Mysql Spatial 8.0在地理坐標系下的鄰接關系判斷不夠完善,其空間分析函數不如專業的GIS應用軟件豐富。因此,Mysql Spatial未來可能會繼續專注于空間數據存儲、管理與查詢功能的完善,而將專業的地理分析功能交由商業GIS軟件來實現。