第19章:MySQL中的空間延伸

目錄

19.1. 前言
19.2. OpenGIS幾何模型
19.2.1. Geometry類的層次
19.2.2. 類Geometry
19.2.3. 類Point
19.2.4. 類Curve
19.2.5. 類LineString
19.2.6. 類Surface
19.2.7. 類Polygon
19.2.8. 類GeometryCollection
19.2.9. 類MultiPoint
19.2.10. 類MultiCurve
19.2.11. 類MultiLineString
19.2.12. 類MultiSurface
19.2.13. 類MultiPolygon
19.3. 支援的空間數據格式
19.3.1. 著名的文本(WKT)格式
19.3.2. 著名的二進制(WKB)格式
19.4. 建立具備空間功能的MySQL資料庫
19.4.1. MySQL空間數據類型
19.4.2. 建立空間值
19.4.3. 建立空間列
19.4.4. 填充空間列
19.4.5. 獲取空間數據
19.5. 分析空間訊息
19.5.1. Geometry格式轉換函數
19.5.2. Geometry函數
19.5.3. 從已有Geometry建立新Geometry的函數
19.5.4. 測試幾何對像間空間關係的函數
19.5.5. 關於幾何最小邊界矩形(MBR)的關係
19.5.6. 測試幾何類之間空間關係的函數
19.6. 最佳化空間分析
19.6.1. 建立空間索引
19.6.2. 使用空間索引
19.7. MySQL的一致性和相容性
19.7.1. 尚未實施的GIS特性

MySQL支援空間延伸,允許生成、保存和分析地理特徵。這些特徵可用於MyISAMInnoDBNDBBDBARCHIVE資料表(但是,ARCHIVE引擎不支援索引功能,因此,不能為ARCHIVE列中的空間列編製索引)。

本章介紹了下述議題:

·         OpenGIS幾何模型中這些空間延伸的基礎。

·         用於資料表示空間數據的數據格式。

·         如何在MySQL中使用空間數據。

·         使用關於空間數據的索引功能。

·         MySQLOpenGIS規範的差異。

如果在MySQL空間延伸的使用方面有任何問題,可在我們網站的GIS論壇中討論。

19.1. 前言

遵從OpenGIS聯盟(OGC)的規範,MySQL實施了空間延伸。OGC是一個由250多家公司、代理機構和大學參與的國際聯盟,負責開發公開的概念解決方案,這類解決方案對所有用來管理空間數據的應用都是有用的。OGC的網站是http://www.opengis.org/

1997年,OpenGIS聯盟(OGC)發佈了針對SQLOpenGISR簡單特徵規範,在該文檔中,提出了延伸SQL RDBMS以支援空間數據的一些概念性方法。該規範可從OpenGIS網站上獲得http://www.opengis.org/docs/99-049.pdf。其中包含與本章有關的額外訊息。

MySQL實施了OGC建議的具有Geometry類型的SQL環境的一個子集。該術語指的是用一組集合類型延伸的環境。具有幾何值的SQL列是作為擁有集合類型的列實施的。該規範描述了SQL幾何類型集合,以及作用在這些類型上用於建立和分析幾何值的函數。

地理特徵指的是世界上具有地理位置的任何事物。它可以是:

·         實體,如山、池溏、城市。

·         空間,如郵政區域、熱帶。

·         可定義的位置,如兩條街道相交的十字路口。

有些檔案採用術語地理空間特徵來指代地理特徵。

幾何是另一個資料表示地理特徵的術語。最初,單詞幾何資料表示的是對大地的測量。來自製圖學的另一個含義指的是製圖人員用於繪製世界地圖的地理特徵。

本章將所有這些術語當作同義詞對待:地理特徵、地理空間特徵或幾何。最常使用的術語是幾何

我們將幾何定義為世界上具有地理位置的點或點的集合。

19.2. OpenGIS幾何模型

OGC具有幾何類型的SQL環境建議的幾何類型集合,基於OpenGIS幾何模型。在本模型中,每個幾何對像均具有下述一般屬性:

·         與空間參考系統相關,其中介紹了定義對象的坐標空間。

·         屬於某種幾何類。

19.2.1. Geometry類的層次

幾何類定義了下述層次:

·         Geometry(非實例化)

o        Point(可實例化的)

o        Curve(非實例化)

§         LineString(可實例化的)

·         Line

·         LinearRing

o        Surface(非實例化)

§         Polygon(可實例化的)

o        GeometryCollection(可實例化的)

§         MultiPoint(可實例化的)

§         MultiCurve(非實例化)

·         MultiLineString(可實例化的)

§         MultiSurface(非實例化)

·         MultiPolygon(可實例化的)

不能在非實例化類中建立對象。能夠在可實例化類中建立對象。所有類均有屬性,可實例化類還可以包含聲明(定義有效類實例的規則)。

Geometry是一種基本類。它是一種抽像類。Geometry的可實例化子類限制為可在2維坐標空間中存在的012維幾何對象。所有的可實例化幾何類是這樣定義的,從而使得幾何類的實例從拓撲意義上講是閉合的(也就是說,所有定義的幾何類包含其邊界)。

基本Geometry類具有關於PointCurveSurfaceGeometryCollection的子類:

·         Point資料表示0維對象。

·         Curve資料表示1維對像,具有子類LineString,以及次級子類LineLinearRing

·         Surface是為2維對像設計的,具有子類Polygon

·         GeometryCollection具有特殊的0維、1維和2維類集合,名為MultiPointMultiLineStringMultiPolygon,分別用於為對應的PointsLineStringsPolygons集合進行幾何建模。MultiCurveMultiSurface是作為抽像超類引入的,它們歸納了用於處理CurvesSurfaces的集合接口。

GeometryCurveSurfaceMultiCurveMultiSurface定義為非實例化類。它們為其子類定義了公用方法集合,而且是為延伸而包含在內的。

PointLineStringPolygonGeometryCollectionMultiPointMultiLineStringMultiPolygon定義為可實例化類。

19.2.2. 類Geometry

Geometry是層次結構的根類。它是一種非實例化類,但具有很多屬性,這些屬性對由任何Geometry子類建立的所有幾何值來說是共同的。下面介紹了這些屬性(尤其是具有自己特殊屬性的子類)。

Geometry屬性

Geometry值具有下述屬性:

·         type(類型)。每個geometry屬於層次結構中可實例化類之一。

·         SRID,或空間參考ID。該值確定了用於描述定義幾何對象的坐標空間的空間坐標系統。

MySQL中,SRID值僅是與geometry值相關的整數值。所有計算均是在歐幾里得幾何系(平面)中進行的。

·         它在其空間坐標系統中的coordinates(坐標),資料表示為雙精度數值(8字節)。所有的非空幾何對像至少包含一對坐標(XY)。空幾何對像不含坐標。

坐標與SRID相關。例如,在不同的坐標系內,兩個對像之間的距離會有所不同,即使這兩個對像具有相同的坐標也同樣。這是因為,平面坐標系中的距離和地心坐標系(地球表面上的坐標)中的距離是不同的事項。

·         interior(內部)、boundary(邊界)和exterior(外部)。

每個幾何對像均佔據空間中的某一位置。幾何對象的exterior(外部)指的是未被該對像佔據的所有空間。其interior(內部)指的是被該對像佔據的空間。其boundary(邊界)指的是幾何對像內部和外部之間的界面。

·         MBR(最小邊界矩形)或包絡面。這是一種邊界幾何值,由最小和最大坐標(X,Y)構成。

·                ((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))

·         無論值是簡單的非簡單的。類型(LineStringMultiPointMultiLineString)的幾何值或是簡單的,或是非簡單的。每個類型決定了其自己的簡單或非簡單聲明。

·         無論值是封閉的非封閉的。類型(LineStringMultiPoint)的幾何值或是封閉的,或是非封閉的。每個類型決定了其自己的封閉或非封閉聲明。

·         無論值是空的非空的。如果沒有任何點,幾何對象是空的。空幾何對象的內部、外部和邊界未定義(也就是說,它們由Null值資料表示)。空的幾何對像定義為總是簡單的,面積為0

·         dimension(維數)。幾何對象的維數為1012

o        1用於空幾何對象。

o        0用於無長度、無面積的幾何對象。

o        1用於具有非0長度和0面積的幾何對象。

o        2用於具有非0面積的幾何對象。

Point對象的維數為0LineString對象的維數為1Polygon對象的維數為2MultiPointMultiLineStringMultiPolygon對象的維數與構成它們的元素的維數相同。

19.2.3. 類Point

Point(點)指的是代資料表坐標空間中單個位置的幾何類。

Point示範

·         想像一張具有眾多城市的大世界地圖。每個Point對象可代資料表1個城市。

·         在城市地圖上,Point對象可代資料表1個公共汽車站。

Point屬性

·         X-坐標值。

·         Y-坐標值。

·         Point定義為0維幾何對象。

·         Point的邊界為空集合。

19.2.4. 類Curve

Curve(曲線)是一種1幾何對象,通常由一系列點資料表示。Curve的特殊子類定義了點之間的內插類型。Curve是一種非實例化類。

Curve屬性

·         Curve具有其點的坐標。

·         Curve定義為1維幾何對象。

·         如果未通過相同的點兩次,Curve就是簡單的。

·         如果其起點等於其終點,Curve就是封閉的。

·         封閉Curve的邊界為空。

·         非封閉Curve的邊界由其兩個端點構成。

·         簡單且封閉的CurveLinearRing

19.2.5. 類LineString

LineString是具有點之間線性內插特性的Curve

LineString示範

·         在世界地圖上,LineString對象可資料表示河流。

·         在城市地圖上,LineString對象可資料表示街道。

LineString屬性

·         LineString具有線段的坐標,由每個連續的點對(兩點)定義。

·         如果僅包含兩點,LineStringLine

·         如果它既是簡單的也是封閉的,LineStringLinearRing

19.2.6. 類Surface

Surface是一種2維幾何對像。它是一種非實例化類。其唯一的可實例化子類是Polygon.

Surface屬性

·         Surface定義為2維幾何對象。

·         OpenGIS規範中,將簡單的Surface定義為由單一patch」構成的幾何對象,它與單個外部邊界以及0或多個內部邊界有關。

·         簡單Surface的邊界是一組與其內部和外部邊界對應的封閉曲線的集合。

19.2.7. 類Polygon

Polygon是代資料表多邊幾何對象的平面Surface。它由單個外部邊界以及0或多個內部邊界定義,其中,每個內部邊界定義為Polygon中的1個孔。

Polygon示範

·         在地區地圖上,Polygon對象可資料表示森林、區等。

Polygon聲明

·         Polygon的邊界由一組構成其外部邊界和比內部邊界的LinearRing歸向集合構成(即,簡單且封閉的LineString對像)。

·         Polygon沒有交叉的環。Polygon邊界中的環可能會在Point處相交,但僅以切線方式相交。

·         Polygon沒有線、尖峰或穿孔。

·         Polygon有由連接點集合構成的內部。

·         Polygon可能包含孔。對於具有孔的Polygon,其外部不連接。每個孔定義了連接的外部部件。

前述聲明使得Polygon成為簡單的幾何對象。

19.2.8. 類GeometryCollection

GeometryCollection是由1個或多個任意類幾何對像構成的幾何對象。

GeometryCollection中的所有元素必須具有相同的空間參考系(即相同的坐標系)。對GeometryCollection的元素無任何限制,但下面介紹的GeometryCollection的子類會限制其成員。這類限制可能基於:

·         元素類型(例如,MultiPoint可能僅包含Point元素)。

·         維數。

·         對元素間空間交迭程度的限制。

19.2.9. 類MultiPoint

MultiPoint是一種由Point元素構成的幾何對像集合。這些點未以任何方式連接或排序。

MultiPoint示範

·         在世界地圖上,MultiPoint可以代資料表島鏈。

·         在城市地圖上,MultiPoint可以資料表示售票處的出口。

MultiPoint屬性

·         MultiPoint0維幾何對象。

·         如果沒有兩個Point是相同的(具有等同的坐標值),MultiPoint是簡單的。

·         MultiPoint的邊界為空集合。

19.2.10. 類MultiCurve

MultiCurve是一種由Curve元素構成的幾何對像集合。MultiCurve是一種非實例化類。

MultiCurve屬性

·         MultiCurve1維幾何對象。

·         當且僅當其所有元素均是簡單的時,MultiCurve才是簡單的。任意兩元素的唯一交叉僅出現在兩元素邊界的點上。

·         MultiCurve邊界是通過採用「模2聯合規則」(也稱為奇偶規則)獲得的:如果某一點位於奇數編號MultiCurve元素的邊界內,它將位於MultiCurve的邊界內。

·         如果其所有元素均是封閉的,則MultiCurve為封閉的。

·         封閉MultiCurve的邊界總為空。

19.2.11. 類MultiLineString

MultiLineString是一種由 LineString元素構成的MultiCurve幾何對像集合。

MultiLineString示範

·         在地區地圖上,MultiLineString可資料表示河流體系或高速路系統。

19.2.12. 類MultiSurface

MultiSurface是一種由Surface元素構成的幾何對像集合。MultiSurface是一種非實例化類。其唯一的可實例化子類是MultiPolygon

MultiSurface聲明

·         2MultiSurface面沒有相交的內部。

·         2MultiSurface元素具有最多在有限點上相交的邊界。

19.2.13. 類MultiPolygon

MultiPolygon是一種由Polygon元素構成的幾何對像集合。

MultiPolygon示範

·         在地區地圖上,MultiPolygon可資料表示湖泊系統。

MultiPolygon聲明

·         MultiPolygon沒有內部相交的的2Polygon元素。

·         MultiPolygon沒有2個交叉的Polygon元素(前述聲明也禁止交叉),也沒有在無數點處相接觸的2Polugon元素。

·         MultiPolygon不能含有有中斷的線、尖峰或穿孔。MultiPolygon是一種正常的封閉點集合。

·         對於有1個以上Polygon元素的MultiPolygon具有不連接的內部。MultiPolygon內部已連接部件的數目等於MultiPolygonPolygon值的數目。

MultiPolygon屬性

·         MultiPolygon2維幾何對象。

·         MultiPolygon邊界是與其Polygon元素的邊界對應的封閉曲線集合LineString值)。

·         MultiPolygon邊界中的每個Curve準確位於1Polygon元素的邊界內。

·         Polygon元素邊界中的每個Curve位於MultiPolygon的邊界中。

19.3. 支援的空間數據格式

在本節中,介紹了用於資料表示查詢中幾何對象的標準空間數據格式。它們是:

·         著名的文本(WKT)格式

·         著名的二進制(WKB)格式

從其內部看,MySQL以不完全等同於WKTWKB的格式保存幾何對像值。

19.3.1. 著名的文本(WKT)格式

對於Geometry的著名文本(WKT)資料表示,它是為與採用ASCII格式的幾何數據進行交換而設計的。

幾何對像WKT資料表示的示範:

·         Point

·                POINT(15 20)

注意,指定點坐標時不使用分隔用逗號。

·         具有4個點的LineString

·                LINESTRING(0 0, 10 10, 20 25, 50 60)

注意,點坐標對採用逗號隔開。

·         具有1個外部環和1個內部環的Polygon

·                POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))

·         具有三個Point值的MultiPoint

·                MULTIPOINT(0 0, 20 20, 60 60)

·         具有2LineString值的MultiLineString

·                MULTILINESTRING((10 10, 20 20), (15 15, 30 15))

·         具有2Polygon值的MultiPolygon

·                MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))

·         2Point值和1LineString構成的GeometryCollection

·                GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))

在本章開始處給出的OGC規範文檔中,可找到相應的Backus-Naur語法,它指定了用於編寫WKT值的正式生產規則。

19.3.2. 著名的二進制(WKB)格式

用於幾何值的著名二進制(WKB)資料表示是由OpenGIS規範定義的。它還定義在ISO SQL/MM Part 3: Spatial」標準中。

WKB用於以二進制流的形式交換幾何數據,二進制流由含幾何WKB訊息的BLOB值資料表示。

WKB使用1字節無符號整數、4字節無符號整數、以及8字節雙精度數(IEEE 754格式)。1字節等於8比特。

例如,與POINT(1 1)對應的WKB值由下述21字節序列構成(在此,每個字節由2個十六進制數值資料表示):

0101000000000000000000F03F000000000000F03F

該序列可分為下述部分:

Byte order : 01
WKB type   : 01000000
X          : 000000000000F03F
Y          : 000000000000F03F

資料表示如下:

·         字節順序(Byte order)可以是01,分別表明little-endianbig-endian儲存。little-endianbig-endian字節順序也分別稱為網絡數據資料表示(NDR)和外部數據資料表示(XDR)。

·         WKB type」(WKB類型)是指明幾何類型的代碼。取值從17,分別資料表示PointLineStringPolygonMultiPointMultiLineStringMultiPolygon、和GeometryCollection

·         Point值具有XY坐標,每個值均用雙精度值資料表示。

對於更複雜幾何值的WKB值,它們是由更複雜的數據結構資料表示的,詳情請參見OpenGIS規範。

19.4. 建立具備空間功能的MySQL資料庫

本節介紹了可用於資料表示MySQL中空間數據的數據類型,以及用於建立和檢索空間值的函數。

19.4.1. MySQL空間數據類型

MySQL具有與OpenGIS類對應的數據類型。某些類型只能保存單個幾何值:

·         GEOMETRY

·         POINT

·         LINESTRING

·         POLYGON

GEOMETRY能夠保存任何類型的幾何值。其他的單值類型POINTLINESTRING以及POLYGON只能保存特定幾何類型的值。

其他數據類型能保存多個值:

·         MULTIPOINT

·         MULTILINESTRING

·         MULTIPOLYGON

·         GEOMETRYCOLLECTION

GEOMETRYCOLLECTION能保存任意類型的對象集合。對於其他集合類型,MULTIPOINTMULTILINESTRINGMULTIPOLYGONGEOMETRYCOLLECTION,僅限於具有特定幾何類型的集合成員。

19.4.2. 建立空間值

在本節中,介紹了使用OpenGIS標準中定義的WKTWKB函數建立空間值的方法,以及使用相應MySQL函數的方法。

19.4.2.1. 使用WKT函數建立Geometry(幾何)值

MySQL提供了眾多以WKT資料表達式、以及可選的空間參考系IDSRID)為輸入參數的函數。它們將返回對應的幾何對象。

GeomFromText()接受任何幾何類型的WKT作為其第1個參量。在實施方案中也提供了與類型相關的構造函數,用於構造每一種幾何類型的幾何值。

  • GeomCollFromText(wkt[,srid]) , GeometryCollectionFromText(wkt[,srid])

    使用其WKT資料表示和SRID構造GEOMETRYCOLLECTION值。

  • GeomFromText(wkt[,srid]) , GeometryFromText(wkt[,srid])

    使用其WKT資料表示和SRID構造任何類型的幾何值。

  • LineFromText(wkt[,srid]) , LineStringFromText(wkt[,srid])

    使用其WKT資料表示和SRID構造LINESTRING值。

  • MLineFromText(wkt[,srid]) , MultiLineStringFromText(wkt[,srid])

    使用其WKT資料表示和SRID構造MULTILINESTRING值。

  • MPointFromText(wkt[,srid]) , MultiPointFromText(wkt[,srid])

    使用其WKT資料表示和SRID構造MULTIPOINT值。

  • MPolyFromText(wkt[,srid]) , MultiPolygonFromText(wkt[,srid])

    使用其WKT資料表示和SRID構造MULTIPOLYGON值。

  • PointFromText(wkt[,srid])

    使用其WKT資料表示和SRID構造POINT值。

  • PolyFromText(wkt[,srid]) , PolygonFromText(wkt[,srid])

    使用其WKT資料表示和SRID構造POLYGON值。

OpenGIS規範還介紹了用於構造PolygonMultiPolygon值的可選函數,這些值基於環和封閉LineString值集合的WKT資料表達式。這些值可以相交。MySQL未實施下述函數:

  • BdMPolyFromText(wkt,srid)

    以包含已關閉LineString值任意集合的WKT格式,從MultiLineString值構造MultiPolygon值。

  • BdPolyFromText(wkt,srid)

    以包含已關閉LineString值任意集合的WKT格式,從MultiLineString值構造Polygon值。

19.4.2.2. 使用WKB函數建立Geometry(幾何)值

MySQL提供了眾多函數,它們將包含WKT資料表達式、或可選的空間參考系統IDSRID)的BLOB作為輸入參數。它們返回對應的幾何對象。

GeomFromWKB()接受任何幾何類型的WKB作為其第1個參量。在實施方案中也提供了與類型相關的構造函數,用於構造每一種幾何類型的幾何值。
  • GeomCollFromWKB(wkb[,srid]) , GeometryCollectionFromWKB(wkb[,srid])

    使用其WKB資料表示和SRID構造GEOMETRYCOLLECTION值。

  • GeomFromWKB(wkb[,srid]) , GeometryFromWKB(wkb[,srid])

    使用其WKB資料表示和SRID構造任意類型的幾何值。

  • LineFromWKB(wkb[,srid]) , LineStringFromWKB(wkb[,srid])

    使用其WKB資料表示和SRID構造LINESTRING值。

  • MLineFromWKB(wkb[,srid]) , MultiLineStringFromWKB(wkb[,srid])

    使用其WKB資料表示和SRID構造MULTILINESTRING值。

  • MPointFromWKB(wkb[,srid]) , MultiPointFromWKB(wkb[,srid])

    使用其WKB資料表示和SRID構造MULTIPOINT值。

  • MPolyFromWKB(wkb[,srid]) , MultiPolygonFromWKB(wkb[,srid])

    使用其WKB資料表示和SRID構造MULTIPOLYGON值。

  • PointFromWKB(wkb[,srid])

    使用其WKB資料表示和SRID構造POINT值。

  • PolyFromWKB(wkb[,srid]) , PolygonFromWKB(wkb[,srid])

    使用其WKB資料表示和SRID構造POLYGON值。

OpenGIS規範還介紹了用於構造PolygonMultiPolygon值的可選函數,這些值基於環和封閉LineString值集合的WKB資料表達式。這些值可以相交。MySQL未實施下述函數:

  • BdMPolyFromWKB(wkb,srid)

    以包含已關閉LineString值任意集合的WKB格式,從MultiLineString值構造MultiPolygon值。

  • BdPolyFromWKB(wkb,srid)

    以包含已關閉LineString值任意集合的WKB格式,從MultiLineString值構造Polygon值。

19.4.2.3. 使用MySQL函數建立幾何值

註釋:MySQL未實施本節所列的函數。

MySQL為建立幾何WKB資料表達式提供了有用的函數集合。本節介紹的函數是對OpenGIS規範的MySQL延伸。這些函數的結果是包含幾何值(無SRID)的BLOB值。這些函數的結果可被GeomFromWKB()函數系列中任意函數的第1個參量取代。
  • GeometryCollection(g1,g2,...)

    構造WKB GeometryCollection。如果任何參量不是構造良好的幾何對像WKB資料表達式,返回值為NULL

  • LineString(pt1,pt2,...)

    從多個WKB Point參量構造WKB LineString。如果任何參量不是WKB Point,返回值為NULL。如果Point參量的數目小於2,返回值為NULL

  • MultiLineString(ls1,ls2,...)

    使用WKB LineString參量構造WKB MultiLineString。如果任何參量不是WKB LineString,返回值為NULL

  • MultiPoint(pt1,pt2,...)

    使用WKB Point參量構造WKB MultiPoint值。如果任何參量不是WKB Point,返回值為NULL

  • MultiPolygon(poly1,poly2,...)

    從一組WKB Polygon參量構造WKB MultiPolygon值。如果任何參量不是WKB Polygon,返回值為NULL

  • Point(x,y)

    使用其坐標構造WKB Point

  • Polygon(ls1,ls2,...)

    從多個WKB LineString參量構造WKB Polygon值。如果任何參量未資料表示為LinearRingWKB形式(即,非封閉和簡單LineString,返回值為NULL

19.4.3. 建立空間列

MySQL提供了為幾何類型建立空間列的標準方法,例如,使用CREATE TABLEALTER TABLE。目前,僅對MyISAM標支援空間列。

·         使用CREATE TABLE語句建立具有空間列的資料表:

·                mysql> CREATE TABLE geom (g GEOMETRY);
·                Query OK, 0 rows affected (0.02 sec)

·         使用ALTER TABLE語句在已有資料表中增加空間列,或將空間列從已有資料表中刪除:

·                mysql> ALTER TABLE geom ADD pt POINT;
·                Query OK, 0 rows affected (0.00 sec)
·                Records: 0  Duplicates: 0  Warnings: 0
·                mysql> ALTER TABLE geom DROP pt;
·                Query OK, 0 rows affected (0.00 sec)
·                Records: 0  Duplicates: 0  Warnings: 0

19.4.4. 填充空間列

建立了空間列後,可用空間數據填充它們。

值應以內部幾何格式保存,但您也能將其從WKTWKB格式轉換為內部幾何格式。在下面的示範中,介紹了通過將WKT值轉換為內部幾何格式以便將幾何值插入資料表中的方法。

您可以在INSERT語句中執行直接轉換操作:

INSERT INTO geom VALUES (GeomFromText('POINT(1 1)'));
 
SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (GeomFromText(@g));

也可以在INSERT之前執行轉換操作:

SET @g = GeomFromText('POINT(1 1)');
INSERT INTO geom VALUES (@g);

在下面的示範中,將多個複雜的幾何值插入到了資料表中:

SET @g = 'LINESTRING(0 0,1 1,2 2)';
INSERT INTO geom VALUES (GeomFromText(@g));
 
SET @g = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))';
INSERT INTO geom VALUES (GeomFromText(@g));
 
SET @g =
'GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
INSERT INTO geom VALUES (GeomFromText(@g));

在前面的所有示範中,均採用了GeomFromText()來建立幾何值。您也可以使用與類型相關的函數:

SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (PointFromText(@g));
 
SET @g = 'LINESTRING(0 0,1 1,2 2)';
INSERT INTO geom VALUES (LineStringFromText(@g));
 
SET @g = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))';
INSERT INTO geom VALUES (PolygonFromText(@g));
 
SET @g =
'GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
INSERT INTO geom VALUES (GeomCollFromText(@g));

注意,如果客戶端應用程式打算使用幾何值的WKB資料表示,它需要在隊列中將正確構造的WKB發送至伺服器。但是,存在數種滿足該要求的方法。例如:

·         用十六進制文字語法插入POINT(1 1)值:

·                mysql> INSERT INTO geom VALUES
·                    -> (GeomFromWKB(0x0101000000000000000000F03F000000000000F03F));

·         ODBC應用程式能夠發送WKB資料表達式,並使用具有BLOB類型的參量將其綁定到佔位符:

·                INSERT INTO geom VALUES (GeomFromWKB(?))

其他編程接口或許也支援類似的佔位符機制。

C程式中,可以使用mysql_real_escape_string()轉義二進制值,並將結果包含在將發送至伺服器的查詢字串。請參見25.2.3.52節,「mysql_real_escape_string()」

19.4.5. 獲取空間數據

對於資料表中保存的幾何值,能夠以內部格式獲取。您也能將其轉換為WKTWKB格式。

19.4.5.1. 以內部格式獲取空間數據

在資料表對資料表傳輸中,使用內部格式來獲取幾何值可能是有用的。
CREATE TABLE geom2 (g GEOMETRY) SELECT g FROM geom;

19.4.5.2. 以WKT格式獲取空間數據

AsText()函數能夠將幾何值從內部格式轉換為WKT字串。
SELECT AsText(g) FROM geom;

19.4.5.3. 以格式獲取空間數據

AsBinary()函數能夠將幾何值從內部格式轉換為包含WKB值的BLOB
SELECT AsBinary(g) FROM geom;

19.5. 分析空間訊息

用值填充了空間列後,即可查詢和分析它們。MySQL提供了一組在空間數據上執行各種操作的函數。根據它們所執行的操作類型,可以將這些函數分為四種主要類別:

·         用於在各種格式間轉換幾何值的函數。

·         用於訪問幾何值定性或定量屬性的函數。

·         描述兩種幾何值之間關係的函數。

·         從已有Geometry建立新Geometry的函數

空間分析函數可用於很多場合下,如:

·         任何交互式SQL程式,如mysqlMySQLCC

·         以任何語言編寫的、支援MySQL客戶端API的應用程式。

19.5.1. Geometry格式轉換函數

MySQL支援下述用於在內部格式和WKTWKB格式間轉換幾何值的函數:

  • AsBinary(g)

    將採用內部幾何格式的值轉換為其WKB資料表示,並返回二進制結果。

    SELECT AsBinary(g) FROM geom;
    
  • AsText(g)

    將採用內部幾何格式的值轉換為其WKT資料表示,並返回字串結果。

    mysql> SET @g = 'LineString(1 1,2 2,3 3)';
    mysql> SELECT AsText(GeomFromText(@g));
    +--------------------------+
    | AsText(GeomFromText(@g)) |
    +--------------------------+
    | LINESTRING(1 1,2 2,3 3)  |
    +--------------------------+
    
  • GeomFromText(wkt[,srid])

    將字串值從其WKT資料表示轉換為內部幾何格式,並返回結果。也支援多種與類型相關的函數,如PointFromText()LineFromText()請參見19.4.2.1節,「使用WKT函數建立Geometry(幾何)值」

  • GeomFromWKB(wkb[,srid])

    將二進制值從其WKB資料表示轉換為內部幾何格式,並返回結果。也支援多種與類型相關的函數,如PointFromWKB()LineFromWKB(),請參見19.4.2.2節,「使用WKB函數建立Geometry(幾何)值」

19.5.2. Geometry函數

屬於該組的每個函數均將幾何值作為其參量,並返回幾何值的定性或定量屬性。某些函數限制了其參量類型。如果參量是不正確的幾何類型,這類函數將返回NULL。例如,如果對像類型既不是Polygon也不是MultiPolygonArea()將返回NULL

19.5.2.1. 通用幾何函數

本節列出的函數不限制其參量,可接受任何類型的幾何值。

  • Dimension(g)

    返回幾何值g的固有維數。結果可以是-1012。(關於這些值的含義,請參見19.2.2節,「類Geometry」)。

    mysql> SELECT Dimension(GeomFromText('LineString(1 1,2 2)'));
    +------------------------------------------------+
    | Dimension(GeomFromText('LineString(1 1,2 2)')) |
    +------------------------------------------------+
    |                                              1 |
    +------------------------------------------------+
    
  • Envelope(g)

    返回幾何值g的最小邊界矩形(MBR)。結果以Polygon值的形式返回。

    多邊形(polygon)是由邊界框的頂點定義的:
    POLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
    
    mysql> SELECT AsText(Envelope(GeomFromText('LineString(1 1,2 2)')));
    +-------------------------------------------------------+
    | AsText(Envelope(GeomFromText('LineString(1 1,2 2)'))) |
    +-------------------------------------------------------+
    | POLYGON((1 1,2 1,2 2,1 2,1 1))                        |
    +-------------------------------------------------------+
    
  • GeometryType(g)

    以字串形式返回幾何類型的名稱,幾何實例g是幾何類型的成員。該名稱與可實例化幾何子類之一對應。

    mysql> SELECT GeometryType(GeomFromText('POINT(1 1)'));
    +------------------------------------------+
    | GeometryType(GeomFromText('POINT(1 1)')) |
    +------------------------------------------+
    | POINT                                    |
    +------------------------------------------+
    
  • SRID(g)

    返回指明了幾何值g的空間參考系統ID的整數。

    MySQL中,SRID值僅是與幾何值相關的整數。所有計算均是在歐幾里得(平面)幾何中進行的。

    mysql> SELECT SRID(GeomFromText('LineString(1 1,2 2)',101));
    +-----------------------------------------------+
    | SRID(GeomFromText('LineString(1 1,2 2)',101)) |
    +-----------------------------------------------+
    |                                           101 |
    +-----------------------------------------------+
    

OpenGIS規範還定義了下述函數,MySQL未實施這類函數:

  • Boundary(g)

    返回幾何值g的組合邊界的閉包的幾何對象。

  • IsEmpty(g)

    如果幾何值g為空的幾何對象,返回1,如果非空,返回0,如果參量為NULL,返回-1。如果幾何對象是空的,它資料表示空的點集合。

  • IsSimple(g)

    目前該函數是佔位符,不應使用它。如果實施了它,其行為與下段所給出的描述類似。

    如果幾何值g沒有異常的幾何點(如自相交或自相切),返回1。如果參量不是簡單參量,IsSimple()返回0,如果參量是NULL,返回-1。

    對於本章前面介紹的每個可實例化幾何類,均包含特定的條件,這類條件會使類實例被分類為非簡單的。

19.5.2.2. Point函數
 

PointXY坐標構成,可使用下述函數獲得它們:

  • X(p)

    以雙精度數值返回點pX坐標值。

    mysql> SELECT X(GeomFromText('Point(56.7 53.34)'));
    +--------------------------------------+
    | X(GeomFromText('Point(56.7 53.34)')) |
    +--------------------------------------+
    |                                 56.7 |
    +--------------------------------------+
    
  • Y(p)

    以雙精度數值返回點pY坐標值。

    mysql> SELECT Y(GeomFromText('Point(56.7 53.34)'));
    +--------------------------------------+
    | Y(GeomFromText('Point(56.7 53.34)')) |
    +--------------------------------------+
    |                                53.34 |
    +--------------------------------------+
    

19.5.2.3. LineString函數

LineStringPoint值組成。您可以提取LineString的特定點,計數它所包含的點數,或獲取其長度。

  • EndPoint(ls)

    返回LineString1s的最後一個點的Point

    mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
    mysql> SELECT AsText(EndPoint(GeomFromText(@ls)));
    +-------------------------------------+
    | AsText(EndPoint(GeomFromText(@ls))) |
    +-------------------------------------+
    | POINT(3 3)                          |
    +-------------------------------------+
    
  • GLength(ls)

    以雙精度數值返回LineString1s在相關的空間參考系中的長度。

    mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
    mysql> SELECT GLength(GeomFromText(@ls));
    +----------------------------+
    | GLength(GeomFromText(@ls)) |
    +----------------------------+
    |            2.8284271247462 |
    +----------------------------+
    
  • NumPoints(ls)

    返回LineString1s中的點數。

    mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
    mysql> SELECT NumPoints(GeomFromText(@ls));
    +------------------------------+
    | NumPoints(GeomFromText(@ls)) |
    +------------------------------+
    |                            3 |
    +------------------------------+
    
  • PointN(ls,n)

    返回LineString1s中的第n個點。點編號從1開始。

    mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
    mysql> SELECT AsText(PointN(GeomFromText(@ls),2));
    +-------------------------------------+
    | AsText(PointN(GeomFromText(@ls),2)) |
    +-------------------------------------+
    | POINT(2 2)                          |
    +-------------------------------------+
    
  • StartPoint(ls)

    返回LineString1s的第一個點的Point

    mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
    mysql> SELECT AsText(StartPoint(GeomFromText(@ls)));
    +---------------------------------------+
    | AsText(StartPoint(GeomFromText(@ls))) |
    +---------------------------------------+
    | POINT(1 1)                            |
    +---------------------------------------+
    

OpenGIS規範還定義了下述函數,MySQL尚未實施這些函數:

  • IsRing(ls)

    如果LineStringls是封閉的(即其StartPoint()EndPoint()值相同)和簡單的(未通過相同的點1次以上)返回1。如果ls不是環,返回0,如果它是NULL,返回-1

19.5.2.4. MultiLineString函數

  • GLength(mls)

    以雙精度數值形式返回MultiLineStringm1s的長度。mls的長度等於其元素的長度之和。

    mysql> SET @mls = 'MultiLineString((1 1,2 2,3 3),(4 4,5 5))';
    mysql> SELECT GLength(GeomFromText(@mls));
    +-----------------------------+
    | GLength(GeomFromText(@mls)) |
    +-----------------------------+
    |             4.2426406871193 |
    +-----------------------------+
    
  • IsClosed(mls)

    如果MultiLineStringm1s是封閉的(即StartPoint()EndPoint()值對m1s中的每個LineString是相同的)返回1。如果mls是非封閉的,返回0,如果它是NULL,返回-1

    mysql> SET @mls = 'MultiLineString((1 1,2 2,3 3),(4 4,5 5))';
    mysql> SELECT IsClosed(GeomFromText(@mls));
    +------------------------------+
    | IsClosed(GeomFromText(@mls)) |
    +------------------------------+
    |                            0 |
    +------------------------------+
    

19.5.2.5. Polygon函數

  • Area(poly)

    以雙精度數值形式返回Polygonpoly的面積,根據在其空間參考系中的測量值。

    mysql> SET @poly = 'Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))';
    mysql> SELECT Area(GeomFromText(@poly));
    +---------------------------+
    | Area(GeomFromText(@poly)) |
    +---------------------------+
    |                         4 |
    +---------------------------+
    
  • ExteriorRing(poly)

    LineString形式返回Polygonpoly的外環。

    mysql> SET @poly =
        -> 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
    mysql> SELECT AsText(ExteriorRing(GeomFromText(@poly)));
    +-------------------------------------------+
    | AsText(ExteriorRing(GeomFromText(@poly))) |
    +-------------------------------------------+
    | LINESTRING(0 0,0 3,3 3,3 0,0 0)           |
    +-------------------------------------------+
    
  • InteriorRingN(poly,n)

    LineString形式返回Polygonpoly的第n個內環。環編號從1開始。

    mysql> SET @poly =
        -> 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
    mysql> SELECT AsText(InteriorRingN(GeomFromText(@poly),1));
    +----------------------------------------------+
    | AsText(InteriorRingN(GeomFromText(@poly),1)) |
    +----------------------------------------------+
    | LINESTRING(1 1,1 2,2 2,2 1,1 1)              |
    +----------------------------------------------+
    
  • NumInteriorRings(poly)

    返回Polygonpoly的內環的數目。

    mysql> SET @poly =
        -> 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
    mysql> SELECT NumInteriorRings(GeomFromText(@poly));
    +---------------------------------------+
    | NumInteriorRings(GeomFromText(@poly)) |
    +---------------------------------------+
    |                                     1 |
    +---------------------------------------+
    

19.5.2.6. MultiPolygon函數

  • Area(mpoly)

    以雙精度數值形式返回MultiPolygonmpoly的面積,根據在其空間參考系中的測量結果。

    mysql> SET @mpoly =
        -> 'MultiPolygon(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))';
    mysql> SELECT Area(GeomFromText(@mpoly));
    +----------------------------+
    | Area(GeomFromText(@mpoly)) |
    +----------------------------+
    |                          8 |
    +----------------------------+
    

OpenGIS規範還定義了下述函數,MySQL未實施這類函數:

  • Centroid(mpoly)

    Point形式返回用於MultiPolygonmpoly的數學質心。不保證結果位於MultiPolygon上。

  • PointOnSurface(mpoly)

    返回Point值,保證該值位於MultiPolygonmpoly上。

19.5.2.7. GeometryCollection函數

  • GeometryN(gc,n)

    返回GeometryCollectiongc中第n個幾何對象。幾何對象的編號從1開始。

    mysql> SET @gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))';
    mysql> SELECT AsText(GeometryN(GeomFromText(@gc),1));
    +----------------------------------------+
    | AsText(GeometryN(GeomFromText(@gc),1)) |
    +----------------------------------------+
    | POINT(1 1)                             |
    +----------------------------------------+
    
  • NumGeometries(gc)

    返回GeometryCollectiongc中幾何對象的數目。

    mysql> SET @gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))';
    mysql> SELECT NumGeometries(GeomFromText(@gc));
    +----------------------------------+
    | NumGeometries(GeomFromText(@gc)) |
    +----------------------------------+
    |                                2 |
    +----------------------------------+
    

19.5.3. 從已有Geometry建立新Geometry的函數

19.5.3.1. 生成新Geometry的Geometry函數

19.5.2節,「Geometry函數」中,我們討論了一些可從已有幾何對像構造新幾何對象的函數:

  • Envelope(g)

  • StartPoint(ls)

  • EndPoint(ls)

  • PointN(ls,n)

  • ExteriorRing(poly)

  • InteriorRingN(poly,n)

  • GeometryN(gc,n)

19.5.3.2. 空間操作符

OpenGIS建議了很多可生成幾何對象的其他函數。它們是為實施空間操作符而設計的。

MySQL中未實施這些函數。它們或許會在未來的版本中出現。

  • Buffer(g,d)

    返回幾何對象,該對像代資料表所有距幾何值g的距離小於或等於d的所有點。

  • ConvexHull(g)

    返回幾何對象,該對像代資料表幾何值g的凸包。

  • Difference(g1,g2)

    返回幾何對象,該對像資料表示了幾何值g1g2的點集合差異。

  • Intersection(g1,g2)

    返回幾何對象,該對像資料表示了幾何值g1g2的點集合交集。

  • SymDifference(g1,g2)

    返回幾何對象,該對像資料表示了幾何值g1g2的點集合對稱差。

  • Union(g1,g2)

    返回幾何對象,該對像資料表示了幾何值g1g2的點集合聯合。

19.5.4. 測試幾何對像間空間關係的函數

這些節中所介紹的函數以2個幾何對像作為輸入參數,並返回它們之間的定量或定性關係。

19.5.5. 關於幾何最小邊界矩形(MBR)的關係

MySQL提供了一些可測試兩個幾何對像g1g2最小邊界矩形之間關係的函數。它們包括:

  • MBRContains(g1,g2)

    返回10以指明g1的最小邊界矩形是否包含g2的最小邊界矩形。

    mysql> SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
    mysql> SET @g2 = GeomFromText('Point(1 1)');
    mysql> SELECT MBRContains(@g1,@g2), MBRContains(@g2,@g1);
    ----------------------+----------------------+
    | MBRContains(@g1,@g2) | MBRContains(@g2,@g1) |
    +----------------------+----------------------+
    |                    1 |                    0 |
    +----------------------+----------------------+
    
  • MBRDisjoint(g1,g2)

    返回10以指明兩個幾何變數g1g2的最小邊界矩形是否不相交。

  • MBREqual(g1,g2)

    返回10以指明兩個幾何變數g1g2的最小邊界矩形是否相同。

  • MBRIntersects(g1,g2)

    返回10以指明兩個幾何變數g1g2的最小邊界矩形是否相交。

  • MBROverlaps(g1,g2)

    返回10以指明兩個幾何變數g1g2的最小邊界矩形是否交迭。

  • MBRTouches(g1,g2)

    返回10以指明兩個幾何變數g1g2的最小邊界矩形是否接觸。

  • MBRWithin(g1,g2)

    返回10以指明g1的最小邊界矩形是否位於g2的最小邊界矩形內。

    mysql> SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
    mysql> SET @g2 = GeomFromText('Polygon((0 0,0 5,5 5,5 0,0 0))');
    mysql> SELECT MBRWithin(@g1,@g2), MBRWithin(@g2,@g1);
    +--------------------+--------------------+
    | MBRWithin(@g1,@g2) | MBRWithin(@g2,@g1) |
    +--------------------+--------------------+
    |                  1 |                  0 |
    +--------------------+--------------------+
    

19.5.6. 測試幾何類之間空間關係的函數

OpenGIS規範定義了下述函數。目前在MySQL尚未按照規範實施它們。對於那些已實施的函數,它們返回的結果與對應的基於MBR的函數返回的相同。包括下面列出的函數,但Distance()Related()除外。

在未來的版本中,可能會實施這些函數,為空間分析提供全部支援,而不僅僅是基於MBR的支援。

這些函數作用在2個幾何值g1g2上。

  • Contains(g1,g2)

    返回10以指明g1是否完全包含g2

  • Crosses(g1,g2)

    如果g1在空間上與g2相交,返回1。如果g1為PolygonMultiPolygon,返回NULL,或如果g2PointMultiPoint返回NULL。否則,返回0。

    術語「空間上交叉」指的是2個給定幾何對像之間的空間關係,它具有下述屬性:

    o        2個結合對像交叉。

    o        其交叉結果將導致其維數小於兩個給定幾何對像最大維數的幾何對象。

    o        其交叉不等於兩個幾何對像中的任何1個。

  • Disjoint(g1,g2)

    返回10以指明g1是否與g2從空間上不相交。

  • Distance(g1,g2)

    以雙精度數值形式返回2個幾何對像中2點間的最短距離。

  • Equals(g1,g2)

    返回10以指明g1是否從空間上等同於g2

  • Intersects(g1,g2)

    返回10以指明g1是否從空間上與g2相交。

  • Overlaps(g1,g2)

    返回10以指明g1是否從空間上與g2交迭。如果2個幾何對像交叉而且其交叉將導致具有相同維數但並不等同於任一幾何對象的幾何對象,將使用術語「空間交迭」。

  • Related(g1,g2,pattern_matrix)

    返回10以指明由pattern_matrix指定的空間關係是否在g1g2間存在。如果參量為NULL返回-1。模式矩形為字串。如果實施了該函數,其規範將在此給出。

  • Touches(g1,g2)

    返回10以指明g1是否從空間上與g2接觸。如果幾何對象的內部不交叉,但1個幾何對象的邊界與另一個的邊界或內部交叉,這兩個幾何對象是從空間上接觸的。

  • Within(g1,g2)

    返回10以指明g1是否從空間上位於g2內。

19.6. 最佳化空間分析

可以使用索引對2個非空間資料庫中的搜索操作進行最佳化。對於空間資料庫,這同樣成立。有了以前設計的大量多維索引功能的幫助,能夠對空間搜索進行最佳化。最典型的情況如下:

·         搜索包含給定點的所有對象的Point查詢。

·         搜索與給定地區交迭的所有對象的地區查詢。

MySQL採用了具有2次分裂特性的R-Trees來為空間列編製索引。使用幾何對象的MBR來建立空間索引。對於大多數幾何對象,MBR是包圍幾何對象的最小矩形。對於水平或垂直linestringMBR退化為linestring的矩形。對於點,MBR是退化為點的矩形。

此外,還能在空間列上建立正常索引。需要為除POINT列之外的空間列上的任何索引(非空間)聲明前綴。

19.6.1. 建立空間索引

MySQL能夠使用與建立正規索引類似的語法建立空間索引,但使用了SPATIAL關鍵字進行了延伸。對於目前編製了索引的空間列,必須將其聲明為NOT NULL。在下面的示範中,介紹了建立空間索引的方法。

·         對於CREATE TABLE

·                mysql> CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g));

·         對於ALTER TABLE

·                mysql> ALTER TABLE geom ADD SPATIAL INDEX(g);

·         對於CREATE INDEX

·                mysql> CREATE SPATIAL INDEX sp_index ON geom (g);

對於MyISAM資料表,SPATIAL INDEX負責建立R-tree索引。對於支援空間索引的其他儲存引擎,SPATIAL INDEX能夠建立B-tree索引。對於準確的值搜尋而不是範圍掃瞄,作用在空間值上的B-tree索引很有用。

要想撤銷空間索引,可使用ALTER TABLEDROP INDEX

·         對於ALTER TABLE

·                mysql> ALTER TABLE geom DROP INDEX g;

·         對於DROP INDEX

·                mysql> DROP INDEX sp_index ON geom;

示範:假定資料表geom包含32000以上的幾何對象,它們保存在類型為GEOMETRY的列g中。該資料表還有用於保存對像ID值的AUTO_INCREMENT列。

mysql> DESCRIBE geom;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| fid   | int(11)  |      | PRI | NULL    | auto_increment |
| g     | geometry |      |     |         |                |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> SELECT COUNT(*) FROM geom;
+----------+
| count(*) |
+----------+
|    32376 |
+----------+
1 row in set (0.00 sec)

要想在列g上新增空間索引,可使用下述語句:

mysql> ALTER TABLE geom ADD SPATIAL INDEX(g);
Query OK, 32376 rows affected (4.05 sec)
Records: 32376  Duplicates: 0  Warnings: 0

19.6.2. 使用空間索引

最佳化程式將調查可用的空間索引是否能包含在使用某些函數的查詢搜索中,如WHERE子句中的MBRContains()MBRWithin()函數。例如,假定我們打算找出位於給定矩形中的所有對象:

mysql> SELECT fid,AsText(g) FROM geom WHERE
mysql> MBRContains(GeomFromText('Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))'),g);
+-----+-----------------------------------------------------------------------------+
| fid | AsText(g)                                                                   |
+-----+-----------------------------------------------------------------------------+
|  21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30333.8 15828.8)     |
|  22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8,30334 15871.4)     |
|  23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4,30334 15914.2)     |
|  24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4,30273.4 15823)     |
|  25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882.4,30274.8 15866.2) |
|  26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4,30275 15918.2)     |
| 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946.8,30320.4 15938.4) |
|   1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136.4,30240 15127.2)   |
|   2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136,30210.4 15121)     |
|   3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,30169 15113)           |
|   4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30157 15111.6)       |
|   5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4,30194.2 15075.2)   |
|   6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,30244.6 15077)         |
|   7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8,30201.2 15049.4)   |
|  10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6,30189.6 15019)     |
|  11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2,30151.2 15009.8)   |
|  13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,30114.6 15067.8)       |
| 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30278 15134)         |
| 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30259 15083.4)       |
| 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4,30128.8 15001)     |
+-----+-----------------------------------------------------------------------------+
20 rows in set (0.00 sec)

我們使用EXPLAIN來檢查該查詢的執行方式(ID列已被刪除,以便輸出能更好地與頁匹配)

mysql> EXPLAIN SELECT fid,AsText(g) FROM geom WHERE
mysql> MBRContains(GeomFromText('Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))'),g);
+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| SIMPLE      | geom  | range | g             | g    |      32 | NULL |   50 | Using where |
+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

讓我們檢查一下在沒有空間索引的情況下會出現什麼:

mysql> EXPLAIN SELECT fid,AsText(g) FROM g IGNORE INDEX (g) WHERE
mysql> MBRContains(GeomFromText('Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))'),g);
+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| select_type | table | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| SIMPLE      | geom  | ALL  | NULL          | NULL |    NULL | NULL | 32376 | Using where |
+-------------+-------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)

執行SELECT語句,忽略空間鍵:

mysql> SELECT fid,AsText(g) FROM geom IGNORE INDEX (g) WHERE
mysql> MBRContains(GeomFromText('Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))'),g);
+-----+-----------------------------------------------------------------------------+
| fid | AsText(g)                                                                   |
+-----+-----------------------------------------------------------------------------+
|   1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136.4,30240 15127.2)   |
|   2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136,30210.4 15121)     |
|   3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,30169 15113)           |
|   4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30157 15111.6)       |
|   5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4,30194.2 15075.2)   |
|   6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,30244.6 15077)         |
|   7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8,30201.2 15049.4)   |
|  10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6,30189.6 15019)     |
|  11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2,30151.2 15009.8)   |
|  13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,30114.6 15067.8)       |
|  21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30333.8 15828.8)     |
|  22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8,30334 15871.4)     |
|  23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4,30334 15914.2)     |
|  24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4,30273.4 15823)     |
|  25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882.4,30274.8 15866.2) |
|  26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4,30275 15918.2)     |
| 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30278 15134)         |
| 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30259 15083.4)       |
| 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4,30128.8 15001)     |
| 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946.8,30320.4 15938.4) |
+-----+-----------------------------------------------------------------------------+
20 rows in set (0.46 sec)

未使用索引時,該查詢的執行時間將從0.00秒上升到0.46秒。

在未來的版本中,空間索引也可能會用於最佳化其他函數。請參見19.5.4節,「測試幾何對像間空間關係的函數」

19.7. MySQL的一致性和相容性

19.7.1. 尚未實施的GIS特性

  • 額外的元數據視圖

    OpenGIS規範建議了數種額外的元數據視圖。例如,包含幾何列的描述的名為GEOMETRY_COLUMNS的系統視圖,對於資料庫中的每列有1行相關內容。

  • 作用在LineStringMultiLineString上的OpenGIS函數Length()目前應在MySQL中以GLength()的方式使用。

    問題在於存在1個用於計算字串值長度的已有SQL函數Length(),而且在某些情況下無法判斷函數是在文本場景下還是空間場景下使用的。我們需要以某種方式解決該問題,或確定另一個函數名。


這是MySQL參考手冊的翻譯版本,關於MySQL參考手冊,請訪問dev.mysql.com。原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。