第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[,<