第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)發布了針對SQLOpenGIS?簡單特征規范,在該文檔中,提出了擴展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。原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。

广西11选五走势图彩经网