?
本文檔使用 php中文網手冊 發(fā)布
目錄
MySQL支持空間擴展,允許生成、保存和分析地理特征。這些特征可用于MyISAM、InnoDB、NDB、BDB和ARCHIVE表(但是,ARCHIVE引擎不支持索引功能,因此,不能為ARCHIVE列中的空間列編制索引)。
本章介紹了下述議題:
·???????? OpenGIS幾何模型中這些空間擴展的基礎。
·???????? 用于表示空間數(shù)據的數(shù)據格式。
·???????? 如何在MySQL中使用空間數(shù)據。
·???????? 使用關于空間數(shù)據的索引功能。
·???????? MySQL與OpenGIS規(guī)范的差異。
如果在MySQL空間擴展的使用方面有任何問題,可在我們網站的GIS論壇 中討論。
遵從OpenGIS聯(lián)盟(OGC)的規(guī)范,MySQL實施了空間擴展。OGC是一個由250多家公司、代理機構和大學參與的國際聯(lián)盟,負責開發(fā)公開的概念解決方案,這類解決方案對所有用來管理空間數(shù)據的應用都是有用的。OGC的網站是http://www.opengis.org/。
1997年,OpenGIS聯(lián)盟(OGC)發(fā)布了針對SQL的OpenGIS?簡單特征規(guī)范,在該文檔中,提出了擴展SQL RDBMS以支持空間數(shù)據的一些概念性方法。該規(guī)范可從OpenGIS網站上獲得http://www.opengis.org/docs/99-049.pdf。其中包含與本章有關的額外信息。
MySQL實施了OGC建議的具有Geometry類型的SQL環(huán)境的一個子集。該術語指的是用一組集合類型擴展的環(huán)境。具有幾何值的SQL列是作為擁有集合類型的列實施的。該規(guī)范描述了SQL幾何類型集合,以及作用在這些類型上用于創(chuàng)建和分析幾何值的函數(shù)。
地理特征指的是世界上具有地理位置的任何事物。它可以是:
·???????? 實體,如山、池溏、城市。
·???????? 空間,如郵政區(qū)域、熱帶。
·???????? 可定義的位置,如兩條街道相交的十字路口。
有些文件采用術語地理空間特征來指代地理特征。
幾何是另一個表示地理特征的術語。最初,單詞幾何表示的是對大地的測量。來自制圖學的另一個含義指的是制圖人員用于繪制世界地圖的地理特征。
本章將所有這些術語當作同義詞對待:地理特征、地理空間特征、或幾何。最常使用的術語是幾何。
我們將幾何定義為世界上具有地理位置的點或點的集合。
OGC具有幾何類型的SQL環(huán)境建議的幾何類型集合,基于OpenGIS幾何模型。在本模型中,每個幾何對象均具有下述一般屬性:
·???????? 與空間參考系統(tǒng)相關,其中介紹了定義對象的坐標空間。
·???????? 屬于某種幾何類。
幾何類定義了下述層次:
·???????? Geometry(非實例化)
o??????? Point(可實例化的)
o??????? Curve(非實例化)
§???????? LineString(可實例化的)
·???????? Line
·???????? LinearRing
o??????? Surface(非實例化)
§???????? Polygon(可實例化的)
o??????? GeometryCollection(可實例化的)
§???????? MultiPoint(可實例化的)
§???????? MultiCurve(非實例化)
·???????? MultiLineString(可實例化的)
§???????? MultiSurface(非實例化)
·???????? MultiPolygon(可實例化的)
不能在非實例化類中創(chuàng)建對象。能夠在可實例化類中創(chuàng)建對象。所有類均有屬性,可實例化類還可以包含聲明(定義有效類實例的規(guī)則)。
Geometry是一種基本類。它是一種抽象類。Geometry的可實例化子類限制為可在2維坐標空間中存在的0、1、2維幾何對象。所有的可實例化幾何類是這樣定義的,從而使得幾何類的實例從拓撲意義上講是閉合的(也就是說,所有定義的幾何類包含其邊界)。
基本Geometry類具有關于Point、Curve、Surface和GeometryCollection的子類:
·???????? Point表示0維對象。
·???????? Curve表示1維對象,具有子類LineString,以及次級子類Line和LinearRing。
·???????? Surface是為2維對象設計的,具有子類Polygon。
·???????? GeometryCollection具有特殊的0維、1維和2維類集合,名為MultiPoint、MultiLineString和MultiPolygon,分別用于為對應的Points、LineStrings和Polygons集合進行幾何建模。MultiCurve和MultiSurface是作為抽象超類引入的,它們歸納了用于處理Curves和Surfaces的集合接口。
Geometry、Curve、Surface、MultiCurve和MultiSurface定義為非實例化類。它們?yōu)槠渥宇惗x了公用方法集合,而且是為擴展而包含在內的。
Point、LineString、Polygon、GeometryCollection、MultiPoint、MultiLineString和MultiPolygon定義為可實例化類。
Geometry是層次結構的根類。它是一種非實例化類,但具有很多屬性,這些屬性對由任何Geometry子類創(chuàng)建的所有幾何值來說是共同的。下面介紹了這些屬性(尤其是具有自己特殊屬性的子類)。
Geometry屬性
Geometry值具有下述屬性:
·???????? 其type(類型)。每個geometry屬于層次結構中可實例化類之一。
·???????? 其SRID,或空間參考ID。該值確定了用于描述定義幾何對象的坐標空間的空間坐標系統(tǒng)。
在MySQL中,SRID值僅是與geometry值相關的整數(shù)值。所有計算均是在歐幾里得幾何系(平面)中進行的。
·???????? 它在其空間坐標系統(tǒng)中的coordinates(坐標),表示為雙精度數(shù)值(8字節(jié))。所有的非空幾何對象至少包含一對坐標(X、Y)??諑缀螌ο蟛缓鴺恕?/p>
坐標與SRID相關。例如,在不同的坐標系內,兩個對象之間的距離會有所不同,即使這兩個對象具有相同的坐標也同樣。這是因為,平面坐標系中的距離和地心坐標系(地球表面上的坐標)中的距離是不同的事項。
·???????? 其interior(內部)、boundary(邊界)和exterior(外部)。
每個幾何對象均占據空間中的某一位置。幾何對象的exterior(外部)指的是未被該對象占據的所有空間。其interior(內部)指的是被該對象占據的空間。其boundary(邊界)指的是幾何對象內部和外部之間的界面。
·???????? 其MBR(最小邊界矩形)或包絡面。這是一種邊界幾何值,由最小和最大坐標(X,Y)構成。
·??????????????? ((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
·???????? 無論值是簡單的或非簡單的。類型(LineString、MultiPoint、MultiLineString)的幾何值或是簡單的,或是非簡單的。每個類型決定了其自己的簡單或非簡單聲明。
·???????? 無論值是封閉的或非封閉的。類型(LineString、MultiPoint)的幾何值或是封閉的,或是非封閉的。每個類型決定了其自己的封閉或非封閉聲明。
·???????? 無論值是空的或非空的。如果沒有任何點,幾何對象是空的。空幾何對象的內部、外部和邊界未定義(也就是說,它們由Null值表示)??盏膸缀螌ο蠖x為總是簡單的,面積為0。
·???????? 其dimension(維數(shù))。幾何對象的維數(shù)為?1、0、1或2:
o??????? ?1用于空幾何對象。
o??????? 0用于無長度、無面積的幾何對象。
o??????? 1用于具有非0長度和0面積的幾何對象。
o??????? 2用于具有非0面積的幾何對象。
Point對象的維數(shù)為0。LineString對象的維數(shù)為1。Polygon對象的維數(shù)為2。MultiPoint、MultiLineString和MultiPolygon對象的維數(shù)與構成它們的元素的維數(shù)相同。
Point(點)指的是代表坐標空間中單個位置的幾何類。
Point示例
·???????? 想像一張具有眾多城市的大世界地圖。每個Point對象可代表1個城市。
·???????? 在城市地圖上,Point對象可代表1個公共汽車站。
Point屬性
·???????? X-坐標值。
·???????? Y-坐標值。
·???????? Point定義為0維幾何對象。
·???????? Point的邊界為空集合。
Curve(曲線)是一種1維幾何對象,通常由一系列點表示。Curve的特殊子類定義了點之間的內插類型。Curve是一種非實例化類。
Curve屬性
·???????? Curve具有其點的坐標。
·???????? Curve定義為1維幾何對象。
·???????? 如果未通過相同的點兩次,Curve就是簡單的。
·???????? 如果其起點等于其終點,Curve就是封閉的。
·???????? 封閉Curve的邊界為空。
·???????? 非封閉Curve的邊界由其兩個端點構成。
·???????? 簡單且封閉的Curve是LinearRing。
LineString是具有點之間線性內插特性的Curve。
LineString示例
·???????? 在世界地圖上,LineString對象可表示河流。
·???????? 在城市地圖上,LineString對象可表示街道。
LineString屬性
·???????? LineString具有線段的坐標,由每個連續(xù)的點對(兩點)定義。
·???????? 如果僅包含兩點,LineString為Line。
·???????? 如果它既是簡單的也是封閉的,LineString為LinearRing。
Surface是一種2維幾何對象。它是一種非實例化類。其唯一的可實例化子類是Polygon.
Surface屬性
·???????? Surface定義為2維幾何對象。
·???????? 在OpenGIS規(guī)范中,將簡單的Surface定義為由單一“patch”構成的幾何對象,它與單個外部邊界以及0或多個內部邊界有關。
·???????? 簡單Surface的邊界是一組與其內部和外部邊界對應的封閉曲線的集合。
Polygon是代表多邊幾何對象的平面Surface。它由單個外部邊界以及0或多個內部邊界定義,其中,每個內部邊界定義為Polygon中的1個孔。
Polygon示例
·???????? 在地區(qū)地圖上,Polygon對象可表示森林、區(qū)等。
Polygon聲明
·???????? Polygon的邊界由一組構成其外部邊界和比內部邊界的LinearRing歸向集合構成(即,簡單且封閉的LineString對象)。
·???????? Polygon沒有交叉的環(huán)。Polygon邊界中的環(huán)可能會在Point處相交,但僅以切線方式相交。
·???????? Polygon沒有線、尖峰或穿孔。
·???????? Polygon有由連接點集合構成的內部。
·???????? Polygon可能包含孔。對于具有孔的Polygon,其外部不連接。每個孔定義了連接的外部部件。
前述聲明使得Polygon成為簡單的幾何對象。
MultiCurve屬性
·???????? MultiCurve是1維幾何對象。
·???????? 當且僅當其所有元素均是簡單的時,MultiCurve才是簡單的。任意兩元素的唯一交叉僅出現(xiàn)在兩元素邊界的點上。
·???????? MultiCurve邊界是通過采用“模2聯(lián)合規(guī)則”(也稱為奇偶規(guī)則)獲得的:如果某一點位于奇數(shù)編號MultiCurve元素的邊界內,它將位于MultiCurve的邊界內。
·???????? 如果其所有元素均是封閉的,則MultiCurve為封閉的。
·???????? 封閉MultiCurve的邊界總為空。
MultiPolygon示例
·???????? 在地區(qū)地圖上,MultiPolygon可表示湖泊系統(tǒng)。
MultiPolygon聲明
·???????? MultiPolygon沒有內部相交的的2個Polygon元素。
·???????? MultiPolygon沒有2個交叉的Polygon元素(前述聲明也禁止交叉),也沒有在無數(shù)點處相接觸的2個Polugon元素。
·???????? MultiPolygon不能含有有斷開的線、尖峰或穿孔。MultiPolygon是一種正常的封閉點集合。
·???????? 對于有1個以上Polygon元素的MultiPolygon,具有不連接的內部。MultiPolygon內部已連接部件的數(shù)目等于MultiPolygon中Polygon值的數(shù)目。
MultiPolygon屬性
·???????? MultiPolygon是2維幾何對象。
·???????? MultiPolygon邊界是與其Polygon元素的邊界對應的封閉曲線集合(LineString值)。
·???????? MultiPolygon邊界中的每個Curve準確位于1個Polygon元素的邊界內。
·???????? Polygon元素邊界中的每個Curve位于MultiPolygon的邊界中。
幾何對象WKT表示的示例:
·???????? Point:
·??????????????? POINT(15 20)
注意,指定點坐標時不使用分隔用逗號。
·???????? 具有4個點的LineString:
·??????????????? LINESTRING(0 0, 10 10, 20 25, 50 60)
注意,點坐標對采用逗號隔開。
·???????? 具有1個外部環(huán)和1個內部環(huán)的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)
·???????? 具有2個LineString值的MultiLineString:
·??????????????? MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
·???????? 具有2個Polygon值的MultiPolygon:
·??????????????? MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))
·???????? 由2個Point值和1個LineString構成的GeometryCollection:
·??????????????? GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
在本章開始處給出的OGC規(guī)范文檔中,可找到相應的Backus-Naur語法,它指定了用于編寫WKT值的正式生產規(guī)則。
WKB用于以二進制流的形式交換幾何數(shù)據,二進制流由含幾何WKB信息的BLOB值表示。
WKB使用1字節(jié)無符號整數(shù)、4字節(jié)無符號整數(shù)、以及8字節(jié)雙精度數(shù)(IEEE 754格式)。1字節(jié)等于8比特。
例如,與POINT(1 1)對應的WKB值由下述21字節(jié)序列構成(在此,每個字節(jié)由2個十六進制數(shù)值表示):
0101000000000000000000F03F000000000000F03F
該序列可分為下述部分:
Byte order : 01
WKB type?? : 01000000
X????????? : 000000000000F03F
Y????????? : 000000000000F03F
表示如下:
·???????? 字節(jié)順序(Byte order)可以是0或1,分別表明little-endian或big-endian存儲。little-endian和big-endian字節(jié)順序也分別稱為網絡數(shù)據表示(NDR)和外部數(shù)據表示(XDR)。
·???????? “WKB type”(WKB類型)是指明幾何類型的代碼。取值從1到7,分別表示Point、LineString、Polygon、MultiPoint、MultiLineString、MultiPolygon、和GeometryCollection。
·???????? Point值具有X和Y坐標,每個值均用雙精度值表示。
對于更復雜幾何值的WKB值,它們是由更復雜的數(shù)據結構表示的,詳情請參見OpenGIS規(guī)范。
·???????? GEOMETRY
·???????? POINT
·???????? LINESTRING
·???????? POLYGON
GEOMETRY能夠保存任何類型的幾何值。其他的單值類型POINT、LINESTRING以及POLYGON只能保存特定幾何類型的值。
其他數(shù)據類型能保存多個值:
·???????? MULTIPOINT
·???????? MULTILINESTRING
·???????? MULTIPOLYGON
·???????? GEOMETRYCOLLECTION
GEOMETRYCOLLECTION能保存任意類型的對象集合。對于其他集合類型,MULTIPOINT、MULTILINESTRING、MULTIPOLYGON和GEOMETRYCOLLECTION,僅限于具有特定幾何類型的集合成員。
MySQL提供了眾多以WKT表達式、以及可選的空間參考系ID(SRID)為輸入參數(shù)的函數(shù)。它們將返回對應的幾何對象。
GeomFromText()接受任何幾何類型的WKT作為其第1個參量。在實施方案中也提供了與類型相關的構造函數(shù),用于構造每一種幾何類型的幾何值。
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值。
使用其WKT表示和SRID構造POINT值。
PolyFromText(wkt[,srid]) , PolygonFromText(wkt[,srid])
使用其WKT表示和SRID構造POLYGON值。
OpenGIS規(guī)范還介紹了用于構造Polygon或MultiPolygon值的可選函數(shù),這些值基于環(huán)和封閉LineString值集合的WKT表達式。這些值可以相交。MySQL未實施下述函數(shù):
MySQL提供了眾多函數(shù),它們將包含WKT表達式、或可選的空間參考系統(tǒng)ID(SRID)的BLOB作為輸入參數(shù)。它們返回對應的幾何對象。
GeomFromWKB()接受任何幾何類型的WKB作為其第1個參量。在實施方案中也提供了與類型相關的構造函數(shù),用于構造每一種幾何類型的幾何值。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值。
使用其WKB表示和SRID構造POINT值。
PolyFromWKB(wkb[,srid]) , PolygonFromWKB(wkb[,srid])
使用其WKB表示和SRID構造POLYGON值。
OpenGIS規(guī)范還介紹了用于構造Polygon或MultiPolygon值的可選函數(shù),這些值基于環(huán)和封閉LineString值集合的WKB表達式。這些值可以相交。MySQL未實施下述函數(shù):
注釋:MySQL未實施本節(jié)所列的函數(shù)。
MySQL為創(chuàng)建幾何WKB表達式提供了有用的函數(shù)集合。本節(jié)介紹的函數(shù)是對OpenGIS規(guī)范的MySQL擴展。這些函數(shù)的結果是包含幾何值(無SRID)的BLOB值。這些函數(shù)的結果可被GeomFromWKB()函數(shù)系列中任意函數(shù)的第1個參量取代。構造WKB GeometryCollection。如果任何參量不是構造良好的幾何對象WKB表達式,返回值為NULL。
從多個WKB Point參量構造WKB LineString值。如果任何參量不是WKB Point,返回值為NULL。如果Point參量的數(shù)目小于2,返回值為NULL。
使用WKB LineString參量構造WKB MultiLineString值。如果任何參量不是WKB LineString,返回值為NULL。
使用WKB Point參量構造WKB MultiPoint值。如果任何參量不是WKB Point,返回值為NULL。
從一組WKB Polygon參量構造WKB MultiPolygon值。如果任何參量不是WKB Polygon,返回值為NULL。
使用其坐標構造WKB Point。
從多個WKB LineString參量構造WKB Polygon值。如果任何參量未表示為LinearRing的WKB形式(即,非封閉和簡單LineString),返回值為NULL。
·???????? 使用CREATE TABLE語句創(chuàng)建具有空間列的表:
·??????????????? 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
創(chuàng)建了空間列后,可用空間數(shù)據填充它們。
值應以內部幾何格式保存,但你也能將其從WKT或WKB格式轉換為內部幾何格式。在下面的示例中,介紹了通過將WKT值轉換為內部幾何格式以便將幾何值插入表中的方法。
你可以在INSERT語句中執(zhí)行直接轉換操作:
INSERT INTO geom VALUES (GeomFromText('POINT(1 1)'));
?
SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (GeomFromText(@g));
也可以在INSERT之前執(zhí)行轉換操作:
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()來創(chuàng)建幾何值。你也可以使用與類型相關的函數(shù):
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發(fā)送至服務器。但是,存在數(shù)種滿足該要求的方法。例如:
·???????? 用十六進制文字語法插入POINT(1 1)值:
·??????????????? mysql> INSERT INTO geom VALUES
·??????????????? ????-> (GeomFromWKB(0x0101000000000000000000F03F000000000000F03F));
·???????? ODBC應用程序能夠發(fā)送WKB表達式,并使用具有BLOB類型的參量將其綁定到占位符:
·??????????????? INSERT INTO geom VALUES (GeomFromWKB(?))
其他編程接口或許也支持類似的占位符機制。
在C程序中,可以使用mysql_real_escape_string()轉義二進制值,并將結果包含在將發(fā)送至服務器的查詢字符串。請參見25.2.3.52節(jié),“mysql_real_escape_string()”·???????? 用于在各種格式間轉換幾何值的函數(shù)。
·???????? 用于訪問幾何值定性或定量屬性的函數(shù)。
·???????? 描述兩種幾何值之間關系的函數(shù)。
·???????? 從已有Geometry創(chuàng)建新Geometry的函數(shù)
空間分析函數(shù)可用于很多場合下,如:
·???????? 任何交互式SQL程序,如mysql或MySQLCC。
·???????? 以任何語言編寫的、支持MySQL客戶端API的應用程序。
MySQL支持下述用于在內部格式和WKT或WKB格式間轉換幾何值的函數(shù):
將采用內部幾何格式的值轉換為其WKB表示,并返回二進制結果。
SELECT AsBinary(g) FROM geom;
將采用內部幾何格式的值轉換為其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) | +--------------------------+
將字符串值從其WKT表示轉換為內部幾何格式,并返回結果。也支持多種與類型相關的函數(shù),如PointFromText()和LineFromText(),請參見19.4.2.1節(jié),“使用WKT函數(shù)創(chuàng)建Geometry(幾何)值”。
將二進制值從其WKB表示轉換為內部幾何格式,并返回結果。也支持多種與類型相關的函數(shù),如PointFromWKB()和LineFromWKB(),請參見19.4.2.2節(jié),“使用WKB函數(shù)創(chuàng)建Geometry(幾何)值”。
本節(jié)列出的函數(shù)不限制其參量,可接受任何類型的幾何值。
返回幾何值g的固有維數(shù)。結果可以是-1、0、1或2。(關于這些值的含義,請參見19.2.2節(jié),“類Geometry”)。
mysql> SELECT Dimension(GeomFromText('LineString(1 1,2 2)')); +------------------------------------------------+ | Dimension(GeomFromText('LineString(1 1,2 2)')) | +------------------------------------------------+ | 1 | +------------------------------------------------+
返回幾何值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)) | +-------------------------------------------------------+
以字符串形式返回幾何類型的名稱,幾何實例g是幾何類型的成員。該名稱與可實例化幾何子類之一對應。
mysql> SELECT GeometryType(GeomFromText('POINT(1 1)')); +------------------------------------------+ | GeometryType(GeomFromText('POINT(1 1)')) | +------------------------------------------+ | POINT | +------------------------------------------+
返回指明了幾何值g的空間參考系統(tǒng)ID的整數(shù)。
在MySQL中,SRID值僅是與幾何值相關的整數(shù)。所有計算均是在歐幾里得(平面)幾何中進行的。
mysql> SELECT SRID(GeomFromText('LineString(1 1,2 2)',101)); +-----------------------------------------------+ | SRID(GeomFromText('LineString(1 1,2 2)',101)) | +-----------------------------------------------+ | 101 | +-----------------------------------------------+
OpenGIS規(guī)范還定義了下述函數(shù),MySQL未實施這類函數(shù):
Point由X和Y坐標構成,可使用下述函數(shù)獲得它們:
以雙精度數(shù)值返回點p的X坐標值。
mysql> SELECT X(GeomFromText('Point(56.7 53.34)')); +--------------------------------------+ | X(GeomFromText('Point(56.7 53.34)')) | +--------------------------------------+ | 56.7 | +--------------------------------------+
以雙精度數(shù)值返回點p的Y坐標值。
mysql> SELECT Y(GeomFromText('Point(56.7 53.34)')); +--------------------------------------+ | Y(GeomFromText('Point(56.7 53.34)')) | +--------------------------------------+ | 53.34 | +--------------------------------------+
LineString由Point值組成。你可以提取LineString的特定點,計數(shù)它所包含的點數(shù),或獲取其長度。
返回LineString值1s的最后一個點的Point。
mysql> SET @ls = 'LineString(1 1,2 2,3 3)'; mysql> SELECT AsText(EndPoint(GeomFromText(@ls))); +-------------------------------------+ | AsText(EndPoint(GeomFromText(@ls))) | +-------------------------------------+ | POINT(3 3) | +-------------------------------------+
以雙精度數(shù)值返回LineString值1s在相關的空間參考系中的長度。
mysql> SET @ls = 'LineString(1 1,2 2,3 3)'; mysql> SELECT GLength(GeomFromText(@ls)); +----------------------------+ | GLength(GeomFromText(@ls)) | +----------------------------+ | 2.8284271247462 | +----------------------------+
返回LineString值1s中的點數(shù)。
mysql> SET @ls = 'LineString(1 1,2 2,3 3)'; mysql> SELECT NumPoints(GeomFromText(@ls)); +------------------------------+ | NumPoints(GeomFromText(@ls)) | +------------------------------+ | 3 | +------------------------------+
返回LineString值1s中的第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) | +-------------------------------------+
返回LineString值1s的第一個點的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規(guī)范還定義了下述函數(shù),MySQL尚未實施這些函數(shù):
以雙精度數(shù)值形式返回MultiLineString值m1s的長度。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 | +-----------------------------+
如果MultiLineString值m1s是封閉的(即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 | +------------------------------+
以雙精度數(shù)值形式返回Polygon值poly的面積,根據在其空間參考系中的測量值。
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 | +---------------------------+
以LineString形式返回Polygon值poly的外環(huán)。
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) | +-------------------------------------------+
以LineString形式返回Polygon值poly的第n個內環(huán)。環(huá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) | +----------------------------------------------+
返回Polygon值poly的內環(huán)的數(shù)目。
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 | +---------------------------------------+
以雙精度數(shù)值形式返回MultiPolygon值mpoly的面積,根據在其空間參考系中的測量結果。
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規(guī)范還定義了下述函數(shù),MySQL未實施這類函數(shù):
返回GeometryCollection值gc中第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) | +----------------------------------------+
返回GeometryCollection值gc中幾何對象的數(shù)目。
mysql> SET @gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))'; mysql> SELECT NumGeometries(GeomFromText(@gc)); +----------------------------------+ | NumGeometries(GeomFromText(@gc)) | +----------------------------------+ | 2 | +----------------------------------+
在19.5.2節(jié),“Geometry函數(shù)”中,我們討論了一些可從已有幾何對象構造新幾何對象的函數(shù):
Envelope(g)
StartPoint(ls)
EndPoint(ls)
PointN(ls,n)
ExteriorRing(poly)
InteriorRingN(poly,n)
GeometryN(gc,n)
OpenGIS建議了很多可生成幾何對象的其他函數(shù)。它們是為實施空間操作符而設計的。
在MySQL中未實施這些函數(shù)。它們或許會在未來的版本中出現(xiàn)。
MySQL提供了一些可測試兩個幾何對象g1和g2最小邊界矩形之間關系的函數(shù)。它們包括:
返回1或0以指明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 | +----------------------+----------------------+
返回1或0以指明兩個幾何變量g1和g2的最小邊界矩形是否不相交。
返回1或0以指明兩個幾何變量g1和g2的最小邊界矩形是否相同。
返回1或0以指明兩個幾何變量g1和g2的最小邊界矩形是否相交。
返回1或0以指明兩個幾何變量g1和g2的最小邊界矩形是否交迭。
返回1或0以指明兩個幾何變量g1和g2的最小邊界矩形是否接觸。
返回1或0以指明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 | +--------------------+--------------------+
OpenGIS規(guī)范定義了下述函數(shù)。目前在MySQL尚未按照規(guī)范實施它們。對于那些已實施的函數(shù),它們返回的結果與對應的基于MBR的函數(shù)返回的相同。包括下面列出的函數(shù),但Distance()和Related()除外。
在未來的版本中,可能會實施這些函數(shù),為空間分析提供全部支持,而不僅僅是基于MBR的支持。
這些函數(shù)作用在2個幾何值g1和g2上。
返回1或0以指明g1是否完全包含g2。
如果g1在空間上與g2相交,返回1。如果g1為Polygon或MultiPolygon,返回NULL,或如果g2為Point或MultiPoint返回NULL。否則,返回0。
術語“空間上交叉”指的是2個給定幾何對象之間的空間關系,它具有下述屬性:
o??????? 2個結合對象交叉。
o??????? 其交叉結果將導致其維數(shù)小于兩個給定幾何對象最大維數(shù)的幾何對象。
o??????? 其交叉不等于兩個幾何對象中的任何1個。
返回1或0以指明g1是否與g2從空間上不相交。
以雙精度數(shù)值形式返回2個幾何對象中2點間的最短距離。
返回1或0以指明g1是否從空間上等同于g2。
返回1或0以指明g1是否從空間上與g2相交。
返回1或0以指明g1是否從空間上與g2交迭。如果2個幾何對象交叉而且其交叉將導致具有相同維數(shù)但并不等同于任一幾何對象的幾何對象,將使用術語“空間交迭”。
返回1或0以指明由pattern_matrix指定的空間關系是否在g1和g2間存在。如果參量為NULL返回-1。模式矩形為字符串。如果實施了該函數(shù),其規(guī)范將在此給出。
返回1或0以指明g1是否從空間上與g2接觸。如果幾何對象的內部不交叉,但1個幾何對象的邊界與另一個的邊界或內部交叉,這兩個幾何對象是從空間上接觸的。
返回1或0以指明g1是否從空間上位于g2內。
·???????? 搜索包含給定點的所有對象的Point查詢。
·???????? 搜索與給定地區(qū)交迭的所有對象的地區(qū)查詢。
MySQL采用了具有2次分裂特性的R-Trees來為空間列編制索引。使用幾何對象的MBR來創(chuàng)建空間索引。對于大多數(shù)幾何對象,MBR是包圍幾何對象的最小矩形。對于水平或垂直linestring,MBR退化為linestring的矩形。對于點,MBR是退化為點的矩形。
此外,還能在空間列上創(chuàng)建正常索引。需要為除POINT列之外的空間列上的任何索引(非空間)聲明前綴。
MySQL能夠使用與創(chuàng)建正規(guī)索引類似的語法創(chuàng)建空間索引,但使用了SPATIAL關鍵字進行了擴展。對于目前編制了索引的空間列,必須將其聲明為NOT NULL。在下面的示例中,介紹了創(chuàng)建空間索引的方法。
·???????? 對于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負責創(chuàng)建R-tree索引。對于支持空間索引的其他存儲引擎,SPATIAL INDEX能夠創(chuàng)建B-tree索引。對于準確的值查找而不是范圍掃描,作用在空間值上的B-tree索引很有用。
要想撤銷空間索引,可使用ALTER TABLE或DROP 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
優(yōu)化程序將調查可用的空間索引是否能包含在使用某些函數(shù)的查詢搜索中,如WHERE子句中的MBRContains()或MBRWithin()函數(shù)。例如,假定我們打算找出位于給定矩形中的所有對象:
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來檢查該查詢的執(zhí)行方式(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)
讓我們檢查一下在沒有空間索引的情況下會出現(xiàn)什么:
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)
執(zhí)行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)
未使用索引時,該查詢的執(zhí)行時間將從0.00秒上升到0.46秒。
在未來的版本中,空間索引也可能會用于優(yōu)化其他函數(shù)。請參見19.5.4節(jié),“測試幾何對象間空間關系的函數(shù)”。
額外的元數(shù)據視圖
OpenGIS規(guī)范建議了數(shù)種額外的元數(shù)據視圖。例如,包含幾何列的描述的名為GEOMETRY_COLUMNS的系統(tǒng)視圖,對于數(shù)據庫中的每列有1行相關內容。
作用在LineString和MultiLineString上的OpenGIS函數(shù)Length()目前應在MySQL中以GLength()的方式調用。
問題在于存在1個用于計算字符串值長度的已有SQL函數(shù)Length(),而且在某些情況下無法判斷函數(shù)是在文本場景下還是空間場景下調用的。我們需要以某種方式解決該問題,或確定另一個函數(shù)名。
這是MySQL參考手冊的翻譯版本,關于MySQL參考手冊,請訪問dev.mysql.com。原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。