分类: Mysql/postgreSQL
2008-05-11 22:35:43
MySQL支持空间扩展,允许生成、保存和分析地理特征。这些特征可用于MyISAM、InnoDB、NDB、BDB和ARCHIVE表(但是,ARCHIVE引擎不支持索引功能,因此,不能为ARCHIVE列中的空间列编制索引)。
本章介绍了下述议题:
· OpenGIS几何模型中这些空间扩展的基础。
· 用于表示空间数据的数据格式。
· 如何在MySQL中使用空间数据。
· 使用关于空间数据的索引功能。
· MySQL与OpenGIS规范的差异。
如果在MySQL空间扩展的使用方面有任何问题,可在我们网站的中讨论。
遵从OpenGIS联盟(OGC)的规范,MySQL实施了空间扩展。OGC是一个由250多家公司、代理机构和大学参与的国际联盟,负责开发公开的概念解决方案,这类解决方案对所有用来管理空间数据的应用都是有用的。OGC的网站是。
1997年,OpenGIS联盟(OGC)发布了针对SQL的OpenGIS®简单特征规范,在该文档中,提出了扩展SQL RDBMS以支持空间数据的一些概念性方法。该规范可从OpenGIS网站上获得。其中包含与本章有关的额外信息。
MySQL实施了OGC建议的具有Geometry类型的SQL环境的一个子集。该术语指的是用一组集合类型扩展的环境。具有几何值的SQL列是作为拥有集合类型的列实施的。该规范描述了SQL几何类型集合,以及作用在这些类型上用于创建和分析几何值的函数。
地理特征指的是世界上具有地理位置的任何事物。它可以是:
· 实体,如山、池溏、城市。
· 空间,如邮政区域、热带。
· 可定义的位置,如两条街道相交的十字路口。
有些文件采用术语地理空间特征来指代地理特征。
几何是另一个表示地理特征的术语。最初,单词几何表示的是对大地的测量。来自制图学的另一个含义指的是制图人员用于绘制世界地图的地理特征。
本章将所有这些术语当作同义词对待:地理特征、地理空间特征、或几何。最常使用的术语是几何。
我们将几何定义为世界上具有地理位置的点或点的集合。
OGC具有几何类型的SQL环境建议的几何类型集合,基于OpenGIS几何模型。在本模型中,每个几何对象均具有下述一般属性:
· 与空间参考系统相关,其中介绍了定义对象的坐标空间。
· 属于某种几何类。
几何类定义了下述层次:
· 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定义为可实例化类。
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对象的维数与构成它们的元素的维数相同。
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具有线段的坐标,由每个连续的点对(两点)定义。
· 如果仅包含两点,LineString为Line。
· 如果它既是简单的也是封闭的,LineString为LinearRing。
Surface是一种2维几何对象。它是一种非实例化类。其唯一的可实例化子类是Polygon.
Surface属性
· Surface定义为2维几何对象。
· 在OpenGIS规范中,将简单的Surface定义为由单一“patch”构成的几何对象,它与单个外部边界以及0或多个内部边界有关。
· 简单Surface的边界是一组与其内部和外部边界对应的封闭曲线的集合。
Polygon是代表多边几何对象的平面Surface。它由单个外部边界以及0或多个内部边界定义,其中,每个内部边界定义为Polygon中的1个孔。
Polygon示例
· 在地区地图上,Polygon对象可表示森林、区等。
Polygon声明
· Polygon的边界由一组构成其外部边界和比内部边界的LinearRing归向集合构成(即,简单且封闭的LineString对象)。
· Polygon没有交叉的环。Polygon边界中的环可能会在Point处相交,但仅以切线方式相交。
· Polygon没有线、尖峰或穿孔。
· Polygon有由连接点集合构成的内部。
· Polygon可能包含孔。对于具有孔的Polygon,其外部不连接。每个孔定义了连接的外部部件。
前述声明使得Polygon成为简单的几何对象。
GeometryCollection中的所有元素必须具有相同的空间参考系(即相同的坐标系)。对GeometryCollection的元素无任何限制,但下面介绍的GeometryCollection的子类会限制其成员。这类限制可能基于:
· 元素类型(例如,MultiPoint可能仅包含Point元素)。
· 维数。
· 对元素间空间交迭程度的限制。
MultiCurve属性
· MultiCurve是1维几何对象。
· 当且仅当其所有元素均是简单的时,MultiCurve才是简单的。任意两元素的唯一交叉仅出现在两元素边界的点上。
· MultiCurve边界是通过采用“模2联合规则”(也称为奇偶规则)获得的:如果某一点位于奇数编号MultiCurve元素的边界内,它将位于MultiCurve的边界内。
· 如果其所有元素均是封闭的,则MultiCurve为封闭的。
· 封闭MultiCurve的边界总为空。
MultiLineString示例
· 在地区地图上,MultiLineString可表示河流体系或高速路系统。
MultiSurface声明
· 2个MultiSurface面没有相交的内部。
· 2个MultiSurface元素具有最多在有限点上相交的边界。
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的边界中。
· 著名的文本(WKT)格式
· 著名的二进制(WKB)格式
从其内部看,MySQL以不完全等同于WKT或WKB的格式保存几何对象值。
几何对象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值的正式生产规则。
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规范。
· GEOMETRY
· POINT
· LINESTRING
· POLYGON
GEOMETRY能够保存任何类型的几何值。其他的单值类型POINT、LINESTRING以及POLYGON只能保存特定几何类型的值。
其他数据类型能保存多个值:
· MULTIPOINT
· MULTILINESTRING
· MULTIPOLYGON
· GEOMETRYCOLLECTION
GEOMETRYCOLLECTION能保存任意类型的对象集合。对于其他集合类型,MULTIPOINT、MULTILINESTRING、MULTIPOLYGON和GEOMETRYCOLLECTION,仅限于具有特定几何类型的集合成员。
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值。
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值。
注释: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。
· 使用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