վÄÚËÑË÷: ÇëÊäÈëËÑË÷¹ؼü´Ê
µ±ǰҳÃæ: ÔÚÏßÎĵµÊ×ҳ > MySQL 5.1²ο¼ÊֲáÖÐÎİæ

Chapter 19. Spatial Extensions in MySQL - MySQL 5.1²ο¼ÊֲáÖÐÎİæ

ç¬�19章:MySQL中的空间扩展

MySQL支持空间扩展,允许生成、保存和分析地理特征。这些特征可用于MyISAMã€�InnoDBã€�NDBã€�BDBå’�ARCHIVE表(但是ï¼�ARCHIVE引擎不支æŒ�索引功能,因此,不能ä¸�ARCHIVE列中的空间列编制索引)ã€�

本章介绍了下述议题:

·         OpenGIS几何模型中这些空间扩展的基础ã€�

·         用于表示空间数据的数据格式ã€�

·         如何åœ�MySQL中使用空间数据ã€�

·         使用关于空间数据的索引功能ã€�

·         MySQLä¸�OpenGIS规范的差异ã€�

如果åœ�MySQL空间扩展的使用方面有任何问题,可在我们网站的GIS论坛中讨论ã€�

19.1. 前言

遵从OpenGIS联盟ï¼�OGC)的规范ï¼�MySQL实施了空间扩展ã€�OGC是一个由250多家公司、代理机构和大学参与的国际联盟,负责开发公开的概念解决方案,这类解决方案对所有用来管理空间数据的应用都是有用的ã€�OGC的网站是http://www.opengis.org/ã€�

1997年,OpenGIS联盟ï¼�OGC)发布了针对SQLçš�OpenGIS®简单特征规èŒ�,在该文档中,提出了扩展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维坐标空间中存在çš�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定义为非实例化类。它们为其子类定义了公用方法集合,而且是为扩展而包含在内的ã€�

Pointã€�LineStringã€�Polygonã€�GeometryCollectionã€�MultiPointã€�MultiLineStringå’�MultiPolygon定义为可实例化类ã€�

19.2.2. 类Geometry

Geometry是层次结构的根类。它是一种非实例化类,但具有很多属性,这些属性对由任ä½�Geometry子类创建的所有几何值来说是共同的。下面介绍了这些属性(尤其是具有自己特殊属性的子类)ã€�

Geometry属æ€�

Geometry值具有下述属性:

·         å…�type(类型)。每ä¸�geometry属于层次结构中可实例化类之一ã€�

·         å…�SRID,或空间参è€�ID。该值确定了用于描述定义几何对象的坐标空间的空间坐标系统ã€�

åœ�MySQL中,SRID值仅是与geometry值相关的整数值。所有计算均是在欧几里得几何系(平面)中进行的ã€�

·         它在其空间坐标系统中çš�coordinates(坐标),表示为双精度数值(8字节)。所有的非空几何对象至少包含一对坐标(Xã€�Y)。空几何对象不含坐标ã€�

坐标ä¸�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值表示)。空的几何对象定义为总是简单的,面积为0ã€�

·         å…�dimension(维数)。几何对象的维数ä¸�âˆ�1ã€�0ã€�1æˆ�2ï¼�

o        âˆ�1用于空几何对象ã€�

o        0用于无长度、无面积的几何对象ã€�

o        1用于具有é��0长度å’�0面积的几何对象ã€�

o        2用于具有é��0面积的几何对象ã€�

Point对象的维数为0ã€�LineString对象的维数为1ã€�Polygon对象的维数为2ã€�MultiPointã€�MultiLineStringå’�MultiPolygon对象的维数与构成它们的元素的维数相同ã€�

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的边界由其两个端点构成ã€�

·         简单且封闭çš�Curveæ˜�LinearRingã€�

19.2.5. 类LineString

LineString是具有点之间线性内插特性的Curveã€�

LineString示例

·         在世界地图上ï¼�LineString对象可表示河流ã€�

·         在城市地图上ï¼�LineString对象可表示街道ã€�

LineString属æ€�

·         LineString具有线段的坐标,由每个连续的点对(两点)定义ã€�

·         如果仅包含两点,LineStringä¸�Lineã€�

·         如果它既是简单的也是封闭的,LineStringä¸�LinearRingã€�

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属æ€�

·         MultiPointæ˜�0维几何对象ã€�

·         如果没有两个Point是相同的(具有等同的坐标值)ï¼�MultiPoint是简单的ã€�

·         MultiPoint的边界为空集合ã€�

19.2.10. 类MultiCurve

MultiCurve是一种由Curve元素构成的几何对象集合ã€�MultiCurve是一种非实例化类ã€�

MultiCurve属æ€�

·         MultiCurveæ˜�1维几何对象ã€�

·         当且仅当其所有元素均是简单的时,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声明

·         2ä¸�MultiSurface面没有相交的内部ã€�

·         2ä¸�MultiSurface元素具有最多在有限点上相交的边界ã€�

19.2.13. 类MultiPolygon

MultiPolygon是一种由Polygon元素构成的几何对象集合ã€�

MultiPolygon示例

·         在地区地图上ï¼�MultiPolygon可表示湖泊系统ã€�

MultiPolygon声明

·         MultiPolygon没有内部相交的的2ä¸�Polygon元素ã€�

·         MultiPolygon没有2个交叉的Polygon元素(前述声明也禁止交叉),也没有在无数点处相接触的2ä¸�Polugon元素ã€�

·         MultiPolygon不能含有有断开的线、尖峰或穿孔ã€�MultiPolygon是一种正常的封闭点集合ã€�

·         对于æœ�1个以ä¸�Polygon元素çš�MultiPolygonï¼�具有不连接的内部ã€�MultiPolygon内部已连接部件的数目等于MultiPolygonä¸�Polygon值的数目ã€�

MultiPolygon属æ€�

·         MultiPolygonæ˜�2维几何对象ã€�

·         MultiPolygon边界是与å…�Polygon元素的边界对应的封闭曲线集合ï¼�LineString值)ã€�

·         MultiPolygon边界中的每个Curve准确位于1ä¸�Polygon元素的边界内ã€�

·         Polygon元素边界中的每个Curve位于MultiPolygon的边界中ã€�

19.3. 支持的空间数据格å¼�

在本节中,介绍了用于表示查询中几何对象的标准空间数据格式。它们是ï¼�

·         著名的文æœ�(WKT)格式

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

从其内部看,MySQL以不完全等同äº�WKTæˆ�WKB的格式保存几何对象值ã€�

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)

·         具有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规范文档中,可找到相应的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)可以是0æˆ�1,分别表æ˜�little-endianæˆ�big-endian存储ã€�little-endianå’�big-endian字节顺序也分别称为网络数据表示(NDR)和外部数据表示ï¼�XDR)ã€�

·         â€�WKB type”(WKB类型)是指明几何类型的代码。取值从1åˆ�7,分别表ç¤�Pointã€�LineStringã€�Polygonã€�MultiPointã€�MultiLineStringã€�MultiPolygon、和GeometryCollectionã€�

·         Point值具æœ�Xå’�Y坐标,每个值均用双精度值表示ã€�

对于更复杂几何值的WKB值,它们是由更复杂的数据结构表示的,详情请参è§�OpenGIS规范ã€�

19.4. 创建具备空间功能的MySQL数据åº�

本节介绍了可用于表示MySQL中空间数据的数据类型,以及用于创建和检索空间值的函数ã€�

19.4.1. MySQL空间数据类型

MySQL具有ä¸�OpenGIS类对应的数据类型。某些类型只能保存单个几何值:

·         GEOMETRY

·         POINT

·         LINESTRING

·         POLYGON

GEOMETRY能够保存任何类型的几何值。其他的单值类åž�POINTã€�LINESTRING以及POLYGON只能保存特定几何类型çš�值ã€�

其他数据类型能保存多个值:

·         MULTIPOINT

·         MULTILINESTRING

·         MULTIPOLYGON

·         GEOMETRYCOLLECTION

GEOMETRYCOLLECTION能保存任意类型的对象集合。对于其他集合类型,MULTIPOINTã€�MULTILINESTRINGã€�MULTIPOLYGONå’�GEOMETRYCOLLECTION,仅限于具有特定几何类型的集合成员ã€�

19.4.2. 创建空间å€�

在本节中,介绍了使用OpenGIS标准中定义的WKTå’�WKB函数创建空间值的方法,以及使用相åº�MySQL函数的方法ã€�

19.4.2.1. 使用WKT函数创建Geometry(几何)å€�

MySQL提供了众多以WKT表达式、以及可选的空间参考系IDï¼�SRID)为输入参数的函数。它们将返回对应的几何对象ã€�

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规范还介绍了用于构é€�Polygonæˆ�MultiPolygon值的可选函数,这些值基于环和封é—�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表达式、或可选的空间参考系ç»�IDï¼�SRID)的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规范还介绍了用于构é€�Polygonæˆ�MultiPolygon值的可选函数,这些值基于环和封é—�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值。如果任何参量未表示ä¸�LinearRingçš�WKB形式(即,非封闭和简å��LineStringï¼�,返回值为NULLã€�

19.4.3. 创建空间åˆ�

MySQL提供了为几何类型创建空间列的标准方法,例如,使用CREATE TABLEæˆ�ALTER 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. 填充空间åˆ�

创建了空间列后,可用空间数据填充它们ã€�

值应以内部几何格式保存,但你也能将其ä»�WKTæˆ�WKB格式转换为内部几何格式。在下面的示例中,介绍了通过å°�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. 获取空间数据

对于表中保存的几何值,能够以内部格式获取。你也能将其转换ä¸�WKTæˆ�WKB格式ã€�

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程序,如mysqlæˆ�MySQLCCã€�

·         以任何语言编写的、支æŒ�MySQL客户ç«�API的应用程序ã€�

19.5.1. Geometry格式转换函数

MySQL支持下述用于在内部格式和WKTæˆ�WKB格式间转换几何值的函数ï¼�

  • 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也不æ˜�MultiPolygonï¼�Area()将返å›�NULLã€�

19.5.2.1. 通用几何函数

本节列出的函数不限制其参量,可接受任何类型的几何值ã€�

  • Dimension(g)

    返回几何å€�g的固有维数。结果可以是-1ã€�0ã€�1æˆ�2。(关于这些值的含义,请参见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函数
 

Pointç”�Xå’�Y坐标构成,可使用下述函数获得它们ï¼�

  • X(p)

    以双精度数值返回点pçš�X坐标值ã€�

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

    以双精度数值返回点pçš�Y坐标值ã€�

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

19.5.2.3. LineString函数

LineStringç”�Point值组成。你可以提取LineString的特定点,计数它所包含的点数,或获取其长度ã€�

  • EndPoint(ls)

    返回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)                          |
    +-------------------------------------+
    
  • GLength(ls)

    以双精度数值返å›�LineStringå€�1s在相关的空间参考系中的长度ã€�

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

    返回LineStringå€�1s中的点数ã€�

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

    返回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)                          |
    +-------------------------------------+
    
  • StartPoint(ls)

    返回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规范还定义了下述函数ï¼�MySQL尚未实施这些函数ï¼�

  • IsRing(ls)

    如果LineStringå€�ls是封闭的(即å…�StartPoint()å’�EndPoint()值相å��)和简单的(未通过相同的点1次以上)返回1。如æž�ls不是环,返回0,如果它æ˜�NULL,返å›�-1ã€�

19.5.2.4. MultiLineString函数

  • GLength(mls)

    以双精度数值形式返å›�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 |
    +-----------------------------+
    
  • IsClosed(mls)

    如果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 |
    +------------------------------+
    

19.5.2.5. Polygon函数

  • Area(poly)

    以双精度数值形式返å›�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 |
    +---------------------------+
    
  • ExteriorRing(poly)

    ä»�LineString形式返回Polygonå€�poly的外环ã€�

    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形式返回Polygonå€�poly的第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)

    返回Polygonå€�poly的内环的数目ã€�

    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)

    以双精度数值形式返å›�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规范还定义了下述函数ï¼�MySQL未实施这类函数:

  • Centroid(mpoly)

    ä»�Point形式返回用于MultiPolygonå€�mpoly的数学质心。不保证结果位于MultiPolygon上ã€�

  • PointOnSurface(mpoly)

    返回Point值,保证该值位äº�MultiPolygonå€�mpoly上ã€�

19.5.2.7. GeometryCollection函数

  • GeometryN(gc,n)

    返回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)                             |
    +----------------------------------------+
    
  • NumGeometries(gc)

    返回GeometryCollectionå€�gc中几何对象的数目ã€�

    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)

    返回几何对象,该对象表示了几何å€�g1ä¸�g2的点集合差异ã€�

  • Intersection(g1,g2)

    返回几何对象,该对象表示了几何å€�g1ä¸�g2的点集合交集ã€�

  • SymDifference(g1,g2)

    返回几何对象,该对象表示了几何å€�g1ä¸�g2的点集合对称差ã€�

  • Union(g1,g2)

    返回几何对象,该对象表示了几何å€�g1ä¸�g2的点集合联合ã€�

19.5.4. 测试几何对象间空间关系的函数

这些节中所介绍的函数以2个几何对象作为输入参数,并返回它们之间的定量或定性关系ã€�

19.5.5. 关于几何最小边界矩形(MBR)的关系

MySQL提供了一些可测试两个几何对象g1å’�g2最小边界矩形之间关系的函数。它们包括:

  • MBRContains(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('Point(1 1)');
    mysql> SELECT MBRContains(@g1,@g2), MBRContains(@g2,@g1);
    ----------------------+----------------------+
    | MBRContains(@g1,@g2) | MBRContains(@g2,@g1) |
    +----------------------+----------------------+
    |                    1 |                    0 |
    +----------------------+----------------------+
    
  • MBRDisjoint(g1,g2)

    返回1æˆ�0以指明两个几何变é‡�g1å’�g2的最小边界矩形是否不相交ã€�

  • MBREqual(g1,g2)

    返回1æˆ�0以指明两个几何变é‡�g1å’�g2的最小边界矩形是否相同ã€�

  • MBRIntersects(g1,g2)

    返回1æˆ�0以指明两个几何变é‡�g1å’�g2的最小边界矩形是否相交ã€�

  • MBROverlaps(g1,g2)

    返回1æˆ�0以指明两个几何变é‡�g1å’�g2的最小边界矩形是否交迭ã€�

  • MBRTouches(g1,g2)

    返回1æˆ�0以指明两个几何变é‡�g1å’�g2的最小边界矩形是否接触ã€�

  • MBRWithin(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 |
    +--------------------+--------------------+
    

19.5.6. 测试几何类之间空间关系的函数

OpenGIS规范定义了下述函数。目前在MySQL尚未按照规范实施它们。对于那些已实施的函数,它们返回的结果与对应的基äº�MBR的函数返回的相同。包括下面列出的函数,但Distance()å’�Related()除外ã€�

在未来的版本中,可能会实施这些函数,为空间分析提供全部支持,而不仅仅是基äº�MBR的支持ã€�

这些函数作用åœ�2个几何å€�g1å’�g2上ã€�

  • Contains(g1,g2)

    返回1æˆ�0以指æ˜�g1是否完全包含g2ã€�

  • Crosses(g1,g2)

    如果g1在空间上与g2相交,返å›�1。如æž�g1为Polygonæˆ�MultiPolygon,返回NULL,或如果g2ä¸�Pointæˆ�MultiPoint返回NULL。否则,返回0ã€�

    术语“空间上交叉”指的是2个给定几何对象之间的空间关系,它具有下述属性:

    o        2个结合对象交叉ã€�

    o        其交叉结果将导致其维数小于两个给定几何对象最大维数的几何对象ã€�

    o        其交叉不等于两个几何对象中的任何1个ã€�

  • Disjoint(g1,g2)

    返回1æˆ�0以指æ˜�g1是否ä¸�g2从空间上不相交ã€�

  • Distance(g1,g2)

    以双精度数值形式返å›�2个几何对象中2点间的最短距离ã€�

  • Equals(g1,g2)

    返回1æˆ�0以指æ˜�g1是否从空间上等同äº�g2ã€�

  • Intersects(g1,g2)

    返回1æˆ�0以指æ˜�g1是否从空间上ä¸�g2相交ã€�

  • Overlaps(g1,g2)

    返回1æˆ�0以指æ˜�g1是否从空间上ä¸�g2交迭。如æž�2个几何对象交叉而且其交叉将导致具有相同维数但并不等同于任一几何对象的几何对象,将使用术语“空间交迭”ã€�

  • Related(g1,g2,pattern_matrix)

    返回1æˆ�0以指明由pattern_matrix指定的空间关系是否在g1å’�g2间存在。如果参量为NULL返回-1。模式矩形为字符串。如果实施了该函数,其规范将在此给出ã€�

  • Touches(g1,g2)

    返回1æˆ�0以指æ˜�g1是否从空间上ä¸�g2接触。如果几何对象的内部不交叉,ä½�1个几何对象的边界与另一个的边界或内部交叉,这两个几何对象是从空间上接触的ã€�

  • Within(g1,g2)

    返回1æˆ�0以指æ˜�g1是否从空间上位于g2内ã€�

19.6. 优化空间分析

可以使用索引å¯�2个非空间数据库中的搜索操作进行优化。对于空间数据库,这同样成立。有了以前设计的大量多维索引功能的帮助,能够对空间搜索进行优化。最典型的情况如下:

·         搜索包含给定点的所有对象的Point查询ã€�

·         搜索与给定地区交迭的所有对象的地区查询ã€�

MySQL采用äº�具有2次分裂特性的R-Trees来为空间列编制索引。使用几何对象的MBR来创建空间索引。对于大多数几何对象ï¼�MBR是包围几何对象的最小矩彀€‚对于水平或垂直linestringï¼�MBR退化为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 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

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行相关内容ã€�

  • 作用åœ�LineStringå’�MultiLineString上的OpenGIS函数Length()目前应在MySQL中以GLength()的方式调用ã€�

    问题在于存在1个用于计算字符串值长度的已有SQL函数Length(),而且在某些情况下无法判断函数是在文本场景下还是空间场景下调用的。我们需要以某种方式解决该问题,或确定另一个函数名ã€�


这是MySQL参考手册的翻译版本,关于MySQL参考手册,请访é—�dev.mysql.com。原始参考手册为英文版,与英文版参考手册相比,本翻译版可能不是最新的ã€�