Extensions for Spatial Data

http://dev.mysql.com/worklog/task/?spm=5176.100239.blogcont4270.8.j3asa7&id=6609

前文:

  这两天因为项目原因看了一下MySQL的空间索引,发现网上的资料不多,查了一下官方文档,为了强化记忆做了一个简单的翻译。基本上理解了mysql空间索引的要点。谨以此纪。

 

Extensions for Spatial Data

Open Geospatial Consortium (OGC) 是一个由超过两百五十个公司,机构,大学组成的致力于发展管理空间数据的解决方案的组织。
 
OGC 发布了OpenGIS® Implementation Standard for Geographic information - Simple feature access - Part 2: SQL option , 这个文档建议了几种方法扩展RDBMS来支持空间数据。文档查看: http://www.opengeospatial.org/standards/sfs.
 
遵循OGC文档,MySQL以 SQL with Geometry Types (几何类型SQL)环境的一个子集实现了空间扩展。这个环境是指SQL环境扩展的一系列几何类型。一个 geometry-valued(几何-值)列由一个带有几何类型的列实现。规格文档描述了一系列的SQL 几何类型,以及用于创建,分析几何数值的方法。
 
MySQL spatial extensions实现了空间特性的生成,存储和分析。
 
  • 用于表示空间值得数据类型 Data types for representing spatial values

  • 用于操作空间值得方法Functions for manipulating spatial values

  • 提高访问空间列速度的空间索引Spatial indexing for improved access times to spatial columns 

 
数据类型和方法在MyISAM, InnoDB, NDB, and ARCHIVE中可用。至于空间索引, MyISAM and InnoDB支持空间和非空间索引,其他引擎支持非空间索引
 
geographic feature(地理特性)  是指世界上的所有东西都有一个location(位置)。这个特性可以是:
 
        
  • 一个实体,例如一座山,一个池塘,一个城市 An entity. For example, a mountain, a pond, a city.

  • 一个空间,例如城区,热带地区A space. For example, town district, the tropics.

  • 一个确定的位置。例如一个特定两条街交叉的十字路口A definable location. For example, a crossroad, as a particular place where two streets intersect. 

 
地理定义为一个点point,或者由点聚合起来表示的任意东西的位置
 

MySQL GIS Conformance(一致性) and Compatibility(兼容性)

Mysql 没有实现以下GIS特性:
   
     额外的Metadata Views
    
     OpenGIS中LineString and MultiLineString的方法length() 应该使用ST_Length()
 

Additional Resources

Spatial Data Types

    MySQL包含OpenGIS 类相对应的数据类型,其中一些类型保存单一几何值
  • GEOMETRY 几何体

  • POINT 点

  • LINESTRING 线

  • POLYGON 多边形

     

GEOMETRY可以存储任意几何类型。其他的类型需要特定的几何类型
其他类型用于保存集合
    
  • MULTIPOINT 多点

  • MULTILINESTRING 多线

  • MULTIPOLYGON 多个多边形

  • GEOMETRYCOLLECTION 几何集合

 
GEOMETRYCOLLECTION可以存放任意类型的集合。其他类型需要特定几何类型
 

12.5.2 The OpenGIS Geometry Model

OGC's SQL with Geometry Types推荐的几何类型基于OpenGIS Geometry Model.在这个模型中每个几何包含以下通用的属性:
    
  • 它由一个空间关系系统关联起来,这个系统描述了对象定义的坐标空间。

  • 他属于一些几何类

12.5.2.1 The Geometry Class Hierarchy几何类层级

  • Geometry (noninstantiable)几何

    • Point (instantiable)点

    • Curve (noninstantiable)曲线

      • LineString (instantiable)线串

        • Line线

        • LinearRing线圈

    • Surface (noninstantiable) 面

      • Polygon (instantiable)多边形

    • GeometryCollection (instantiable)几何集合

      • MultiPoint (instantiable)多点

      • MultiCurve (noninstantiable)多曲线

        • MultiLineString (instantiable)多线串

      • MultiSurface (noninstantiable)多面

        • MultiPolygon (instantiable) 多个多边形

 
所有的noninstantiable不可创建,instantiable可创建,所有的类有属性,可实例化类还包含认证(判断有效的类实例的规则)
 
Geometry是基本类,他是一个虚拟类。Geometry可实例化子类限制在0、1/2维几何对象,这个对象存在于一个二维坐标空间。所有可实例化几何类被定义可以判断几何类型实例是否是 topologically closed(拓扑闭,也就是说所有的几何类型包含他们的边界)
 
Geometry有以下子类; Point, Curve, Surface, and GeometryCollection
        
  • 点表示0维对象 Point represents zero-dimensional objects.

  • Curve曲线代表一维对象,他有LineString线串子类(子-子类=》Line 线,LinearRing线圈)

  • 面Surface表示一个二 维对象,他有Polygon多边形这个子类

  • GeometryCollection几何集合有专门的0/1/2维集合类叫做MultiPoint, MultiLineString, and MultiPolygon 来建立PointsLineStrings, and Polygons集合相应的几何模型, .MultiCurve and MultiSurface 是做为处理 Curves and Surfaces几何的接口引进的虚拟父类。

 

12.5.2.2 Geometry Class

Geometry是层级中的root class,他是不可实例化类,但是包含一些属性,这些属性是所有Geometry子类共有的。
    Geometry Properties
            
  •  Its type. 每一个geometry属于层级中的某一个可实例化类。

  • Its SRID, or Spatial Reference Identifier.空间关系标示,这个值标识了geometr关联的空间关系系统,系统描述了几何对象在其中定义的坐标空间。

    In MySQL, the SRID value是一个整数关联到几何value.所有的计算通过欧几里得(平面)几何所得.  SRID最大值是232−1. 如果提供了一个更大值只会取其低32位。

  • Its coordinates 在他的空间关系系统中的坐标。由双精度(8-byte)数据表示. 所有的非空几何体包含至少一对(X,Y)坐标.空几何体不包含任何坐标.

    坐标Coordinates和SRID相关 .例如,在不同的坐标系统,两个对象即使这两个对象有相同的坐标但是距离可能会不同,,因为在平面 planar 坐标系统的距离和在地理测量geodetic 系统(地球表面上的系统坐标)的距离是不同的东西.

  • Its interior内部, boundary边界, and exterior外部.

    每一个几何占据了一些空间中的位置。 几何体的外部是指所有没有被几何体占用的空间.内部是指几何体占据的空间。边界是指内部和外部间的交接处

  • Its MBR (最小边框矩形minimum bounding rectangle), 或者envelope封闭线. 这个是边界几何体,由最大的坐标和最小的坐标组成(X,Y):

    ((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
    
  • Whether the value is simple or nonsimple.  (LineStringMultiPointMultiLineString) 类型的几何值既不是simple 也不是 nonsimple.每个类型自行决定自己是simple or nonsimple.

  • Whether the value is closed or not closed. (LineStringMultiString) 的Geometry values 既不是closed 也不是 not closed. .每个类型自行决定自己是 closed or not closed.

  • Whether the value is empty or nonempty 如果一个几何体不包含任何点则为empty. empty几何体的内部外部和边界都没有定义 ( 用 NULL 表示).一个空几何体总是simple的包含的区域为0。

  • Its dimension维度. 维度有 −1, 0, 1, or 2:

    • −1 空几何体

    • 0  没有长度没有空间的几何体

    • 1 非零长度但是0空间的几何体

    • 2 非零空间的几何体

    Point 是zero. LineString 是 1. Polygon 是 2. MultiPoint, MultiLineString, and MultiPolygon由他们包含的组件维度决定

12.5.2.3 Point Class

           A Point 是指在坐标系统中单一的位置的几何体

Point Examples

  • 想象一个大比例尺的世界地图,一个点可以用来表示一个城市

  • 在一个城市地图,一个点可以用来表示一个公交站

Point Properties

  • X-coordinate value.

  • Y-coordinate value.

  • 维度为0

  • 边界为空

 

12.5.2.4 Curve Class

A Curve 是一维几何体, 通常表示一个序列的点. 其子类定义了点和点之间的插入类型 。Curve  是一个不可实例化的类。

Curve Properties

  • 包含他的所有点的坐标

  • 1维度的几何体

  • 如果不通过同一个点两次则为simple, 例外的情况是它的开始和结束是同一个点

  • 起始点和终结点相同的话为closed

  • closed的边界为空

  • nonclosed 的边界视为他的两个端点

  • 如果既是simple又是closed的则为LinearRing

12.5.2.5 LineString Class

A LineString 是两点之间的线.

LineString Examples

  • 世界地图上,LineString 可以表示河流

  • 城市地图上,可以表示街道

LineString Properties

  • A LineString has coordinates of segments, defined by each consecutive pair of points.

  • A LineString is a Line if it consists of exactly two points.

  • A LineString is a LinearRing if it is both closed and simple. 

 
 

12.5.2.6 Surface Class

A Surface 是二维几何体。不可实例化. 他的可实例化子类是Polygon.

Surface Properties

  • 二维几何体.

  • The OpenGIS specification定义一个简单的Surface是由单一的“patch”组成,这个 “patch”是由一个外部边界和零个或多个内部边界关联起来

  • simple Surface 的边界是由一系列的closed curves对应的外部和内部边界

 

12.5.2.7 Polygon Class

A Polygon是一个平面Surface 表示一个多边的几何体。 由一个外部边界和0个或者多个内部边界组成,每一个内部边界表示几何体中的一个孔

Polygon Examples

  • On a region map, Polygon objects could represent forests, districts, and so on.

Polygon Assertions

  • 边界由一系列的LinearRing对象组成它的外部和内部边界

  • 没有交叉的圈. 圈可能会相交在一点,但是只能是切点。

  • A Polygon has no lines, spikes, or punctures.

  • A Polygon has an interior that is a connected point set.

  • 可能有孔. The exterior of a Polygon with holes is not connected. Each hole defines a connected component of the exterior.

前面的判断使得Polygon成为simple几何体. 

 

12.5.2.8 GeometryCollection Class

A GeometryCollection 是一个任意数量几何体的集合

所有的子项必须在同一个空间关系系统(相同的坐标空间). 除此之外没有其他额外约束, 但是GeometryCollection的子类可能限制子项资格. 限制条件基于:

  • 子项类型 (for example, a MultiPoint may contain only Point elements)

  • 维度

  • 约束元素之间的空间重叠的程度

 

12.5.2.9 MultiPoint Class

A MultiPoint是一个由Point 子项组成的集合. 这些点无论如何没有联系或者顺序.

MultiPoint Examples

  • 世界地图上,可以表示一列的小岛屿

  • 城市地图上,可以表示售票网店

MultiPoint Properties

  • 零维度

  • 如果没有两点是相同的则为simple。

  • 边界为空

 

12.5.2.10 MultiCurve Class

A MultiCurve 是有Curve 组成的一个集合。 MultiCurve 不可实例化。

MultiCurve Properties

  • 一维度

  • 当且仅当他的子项都是simple他为simple。任意两个子项之间唯一的交叉发生在两个子项的边界点上

  • A MultiCurve boundary is obtained by applying the “mod 2 union rule” (also known as the “odd-even rule”): A point is in the boundary of a MultiCurve if it is in the boundaries of an odd number of Curve elements.

  • A MultiCurve is closed if all of its elements are closed.

  • The boundary of a closed MultiCurve is always empty.

12.5.2.11 MultiLineString Class

A MultiLineString is a MultiCurve geometry collection composed of LineString elements.

MultiLineString Examples

  • 在一个地区地图上,可以用来表示河流系统或者铁路系统

 

12.5.2.12 MultiSurface Class

A MultiSurface is a geometry collection composed of surface elements. 不可实例化.唯一可实例化的子类是 MultiPolygon.

MultiSurface Assertions

  • 其中的Surfaces没有内部相交

  • 其中的Surface相交点数有限.

12.5.2.13 MultiPolygon Class

A MultiPolygon is a MultiSurface object composed of Polygon elements.

MultiPolygon Examples

  • 可以用来表示地区湖系统

MultiPolygon Assertions

  • 没有两个Polygon内部相交。

  • 两个Polygon不可以相交(相交也是在前面一个条件中禁止的)或者接触无限个点

  • 一个MultiPolygon可能没有切线,spikes,或者穿孔.  MultiPolygon 是 一个规则的,closed的点集合

  • A MultiPolygon有不止一个Polygon有不连接的内部. The number of connected components of the interior of a MultiPolygon is equal to the number of Polygon values in theMultiPolygon.

MultiPolygon Properties

  • 二维

  • A MultiPolygon的边界是一系列的closed curves (LineString values) corresponding to the boundaries of its Polygon elements.

  • Each Curve in the boundary of the MultiPolygon is in the boundary of exactly one Polygon element.

  • Every Curve in the boundary of an Polygon element is in the boundary of the MultiPolygon

 
 

12.5.3 Using Spatial Data

这个章节描述如何创建包含空间数据类型列的表,以及如何操作空间信息.
 

12.5.3.1 Supported Spatial Data Formats

有两个标准的空间数据格式被用来表示集合对象Two standard spatial data formats are used to represent geometry objects in queries:

  • Well-Known Text (WKT) format

  • Well-Known Binary (WKB) format

在内部,MySQL存储几何值到一个既不是WKT也不是WKB的格式。

 

12.5.3.1.1 Well-Known Text (WKT) Format
    The Well-Known Text (WKT) 用来表示将ASCII表格中的几何数据换成几何值。OpenGIS规格提供了一个巴科斯范式语法来定义写入WKT值得规则。

Examples of WKT representations of geometry objects:

  • A Point:

    POINT(15 20)
    

    点坐标之间没有用逗号分隔。这个和  SQL Point() 方法不同,后者需要用逗号隔开坐标.注意使用适当的语法到给定空间操作的上下文。例如下面的语句都是从Point对象中取出X坐标。第一个直接使用Point() 函数,第二个使用WKT的GeomFormText()转换Point
    The first produces the object directly using the Point() function. The second uses a WKT representation converted to a Point with GeomFromText().

    mysql> SELECT ST_X(Point(15, 20));
    +---------------------+
    | ST_X(POINT(15, 20)) |
    +---------------------+
    |                  15 |
    +---------------------+
    
    mysql> SELECT ST_X(ST_GeomFromText('POINT(15 20)'));
    +---------------------------------------+
    | ST_X(ST_GeomFromText('POINT(15 20)')) |
    +---------------------------------------+
    |                                    15 |
    +---------------------------------------+
    
  • A LineString有四个点:

    LINESTRING(0 0, 10 10, 20 25, 50 60)
    

    点和点直接由逗号分开

  • A 带有一个外部圈和一个内部圈的Polygon

    POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))
    
  • 多点:

    MULTIPOINT(0 0, 20 20, 60 60)
    

    在5.7.9中,空间函数例如 ST_MPointFromText() and ST_GeomFromText() 接受WKT格式化的MutilPoint数值中使用圆括号把点包裹起来.例如下面两个函数调用都是有效的。但是,在5.7.9之前的版本,第二种方式会产生错误:

    ST_MPointFromText('MULTIPOINT (1 1, 2 2, 3 3)')
    ST_MPointFromText('MULTIPOINT ((1 1), (2 2), (3 3))')
    

    在5.7.9中,输出的MultiPoint值会使用圆括号把每个点包裹起来

    mysql> SET @mp = 'MULTIPOINT(1 1, 2 2, 3 3)';
    mysql> SELECT ST_AsText(ST_GeomFromText(@mp));
    +---------------------------------+
    | ST_AsText(ST_GeomFromText(@mp)) |
    +---------------------------------+
    | MULTIPOINT((1 1),(2 2),(3 3))   |
    +---------------------------------+
    

    5.7.9之前的输出不会带有括号

    mysql> SET @mp = 'MULTIPOINT(1 1, 2 2, 3 3)';
    mysql> SELECT ST_AsText(ST_GeomFromText(@mp));
    +---------------------------------+
    | ST_AsText(ST_GeomFromText(@mp)) |
    +---------------------------------+
    | MULTIPOINT(1 1,2 2,3 3)         |
    +---------------------------------+
    
  • A MultiLineString with two LineString values:

    MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
    
  • A MultiPolygon with two Polygon values:

    MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))
    
  • A GeometryCollection consisting of two Point values and one LineString:

    GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
    
12.5.3.1.2 Well-Known Binary (WKB) Format

The Well-Known Binary (WKB) 使用转换几何数据成二进制流representation of geometric values is used for exchanging geometry data as binary streams represented by BLOB values containing geometric WKB information. WKB 使用1-byte 无符号整数,4-byte无符号整数,和8-byte 双精度数字。一个byte是8bit。例如,一个WKB值表示POINT(1,1)用21byte组成这个序列,每一个由两个十六进制表示。

0101000000000000000000F03F000000000000F03F

这个序列由以下组件组成:

Byte order:   01
WKB type:     01000000
X coordinate: 000000000000F03F
Y coordinate: 000000000000F03F

Component representation is as follows:

  • byte是由0/1表示低位高位存储。 这种方法也被称为Network Data Representation (NDR) and External Data Representation (XDR), respectively.

  • The WKB type是用来表明几何体类型. 值从1到7分别表示 Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, and GeometryCollection.

  • 一个Point值有X,Y坐标。每个坐标由一个双精度数值表示

 

12.5.3.2 Creating Spatial Columns

MySQL 提供了一个标准的方法去为几何类型创建空间列。例如, 在 CREATE TABLE or ALTER TABLE. 空间列在 MyISAM, InnoDB, NDB, and ARCHIVE tables 中支持. 

  • 使用 CREATE TABLE 语法创建一个带有空间列的表

    CREATE TABLE geom (g GEOMETRY);
    
  • 使用 ALTER TABLE 语法添加或者删除一个表中的空间列

    ALTER TABLE geom ADD pt POINT;
    ALTER TABLE geom DROP pt;
    
 

12.5.3.3 填充Populating Spatial Columns

创建空间列之后,你可以填充进去空间数据。数值必须存储为内部几何格式的值。但是你可以转换成 Well-Known Text (WKT) or Well-Known Binary (WKB) 格式。下面例子展示如何插入几何值到一个表中。使用WKT转换成内部几何格式:

  • 直接在 INSERT  语句中执行转换

    INSERT INTO geom VALUES (ST_GeomFromText('POINT(1 1)'));
    
    SET @g = 'POINT(1 1)';
    INSERT INTO geom VALUES (ST_GeomFromText(@g));
    
  • INSERT 之前执行转换

    SET @g = ST_GeomFromText('POINT(1 1)');
    INSERT INTO geom VALUES (@g);
    

下面的例子插入了更加复杂的几何数据到表中

    SET @g = 'LINESTRING(0 0,1 1,2 2)';
   INSERT INTO geom VALUES (ST_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 (ST_GeomFromText(@g));

  SET @g ='GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
  INSERT INTO geom VALUES (ST_GeomFromText(@g));

前面的语句使用了ST_GeomFromText() 来创建几何值。你可以使用type-specific(类型定义)函数//这里留有疑义,下面的例子和前面的相同都是使用ST_GeomFromText() 但是我感觉更像是要使用类似POINT() 函数:

SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (ST_PointFromText(@g));

SET @g = 'LINESTRING(0 0,1 1,2 2)';
INSERT INTO geom VALUES (ST_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 (ST_PolygonFromText(@g));

SET @g =
'GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
INSERT INTO geom VALUES (ST_GeomCollFromText(@g));

一个应用程序想要在查询服务器的时候使用WKB 表示几何数值.下面有几个方法实现这个需求。例如

  • 插入一个POINT(1 1)使用二进制语法:

    mysql> INSERT INTO geom VALUES
        -> (ST_GeomFromWKB(0x0101000000000000000000F03F000000000000F03F));
    
  • 一个ODBC应用可以发送一个WKB表达式,并把他绑定到一个占位符上,使用BLOB 类型:

    INSERT INTO geom VALUES (ST_GeomFromWKB(?))
    

    其他程序接口可能支持类似的占位符机制

  • C 语言中,你可以使用 mysql_real_escape_string() 跳过一个二进制数值,包含结果到一个查询字符串中

 

12.5.3.4 读取Fetching Spatial Data

Geometry数值存储在表格中可以读取到内部格式,你可以转换成WKT或者WKB格式

  • 读取空间数据到内部格式:

    读出来的内部格式在表和表之间传递很有用

    CREATE TABLE geom2 (g GEOMETRY) SELECT g FROM geom;
    
  • 读取到WKT格式:

     ST_AsText() 方法将内部格式转换成WKT字符串

    SELECT ST_AsText(g) FROM geom;
    
  • 读取到WKB格式:

    ST_AsBinary() 方法将内部格式转换到一个 包含WKB值得 BLOB

    SELECT ST_AsBinary(g) FROM geom;
    

12.5.3.5 优化空间分析Optimizing Spatial Analysis

对于MyISAM and (as of MySQL 5.7.5) InnoDB tables,在包含空间数据的列中执行搜索操作 可以通过使用SPATIAL indexes(空间索引)进行优化. 典型的操作是:

  • Point 搜索:搜索包含一个给定的点的所有对象

  • 地区搜索:搜索与给定区域重叠的所有对象

MySQL使用 R-Trees with quadratic splitting(二次分割) 来创建空间索引到空间列上.一个空间索引是使用minimum bounding rectangle (最小外包矩形MBR)建立的.对于大多数几何体来说, the MBR 是一个最小的可以包含这个几何体的矩形.对于一个水平或者垂直的linestring, the MBR是一个变化的linestring内部 的矩形。对于一个point, the MBR是一个变化的点内的矩形.

同样也可能创建普通索引到空间列上,在一个非空间索引, you must declare a prefix for any spatial column except for POINT columns.

MyISAM and InnoDB 都支持 SPATIAL and non-SPATIAL indexes.

 
12.5.3.6 Creating Spatial Indexes
 
For MyISAM and (as of MySQL 5.7.5) InnoDB tables, MySQL可以使用类似普通索引的语法创建空间索引, 但是需要使用 SPATIAL关键字.索引项必须是非空。下面的例子展示如何创建空间索引
 
    With CREATE TABLE:
 
    CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g)) ENGINE=MyISAM;
 
    With ALTER TABLE:
 
    ALTER TABLE geom ADD SPATIAL INDEX(g);
 
    With CREATE INDEX:
 
    CREATE SPATIAL INDEX sp_index ON geom (g);
 
SPATIAL INDEX 创建了一个R-tree 索引。对于支持非空间索引的存储引擎,引擎创建一个B-tree索引. B-tree 索引在准确值查找上是很有用的,但在范围扫描就不一样了。
 
 
删除spatial indexes, use ALTER TABLE or DROP INDEX:
 
    With ALTER TABLE:
 
    ALTER TABLE geom DROP INDEX g;
 
    With DROP INDEX:
 
    DROP INDEX sp_index ON geom;
 
Example: 假设一个 table geom包含超过32,000 geometries,存放在类型为GEOMETRY 的 g列 .table有一个AUTO_INCREMENT列fid做为对象ID。
 
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) ENGINE=MyISAM;
Query OK, 32376 rows affected (4.05 sec)
Records: 32376  Duplicates: 0  Warnings: 0
 

12.5.3.7 Using Spatial Indexes

 
优化器调查是否可用空间索引参与搜索查询,这个查询在WHERE子句中使用函数如MBRContains()或MBRWithin()。以下查询找到所有对象在给定的矩形:

 
mysql> SET @poly =
    -> 'Polygon((30000 15000,
                 31000 15000,
                 31000 16000,
                 30000 16000,
                 30000 15000))';
mysql> SELECT fid,ST_AsText(g) FROM geom WHERE
    -> MBRContains(ST_GeomFromText(@poly),g);
+-----+---------------------------------------------------------------+
| fid | ST_AsText(g)                                                  |
+-----+---------------------------------------------------------------+
|  21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30 ... |
|  22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8, ... |
|  23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4, ... |
|  24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4, ... |
|  25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882. ... |
|  26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4, ... |
| 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946. ... |
|   1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136. ... |
|   2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136, ... |
|   3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,3016 ... |
|   4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30 ... |
|   5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4, ... |
|   6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,3024 ... |
|   7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8, ... |
|  10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6, ... |
|  11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2, ... |
|  13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,3011 ... |
| 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30 ... |
| 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30 ... |
| 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4, ... |
+-----+---------------------------------------------------------------+
20 rows in set (0.00 sec)
 
使用EXPLAIN 检查这个查询被执行的方式
 
mysql> SET @poly =
    -> 'Polygon((30000 15000,
                 31000 15000,
                 31000 16000,
                 30000 16000,
                 30000 15000))';
mysql> EXPLAIN SELECT fid,ST_AsText(g) FROM geom WHERE
    -> MBRContains(ST_GeomFromText(@poly),g)\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: geom
         type: range
possible_keys: g
          key: g
      key_len: 32
          ref: NULL
         rows: 50
        Extra: Using where
1 row in set (0.00 sec)
 
如果不使用空间索引的情况:
 
mysql> SET @poly =
    -> 'Polygon((30000 15000,
                 31000 15000,
                 31000 16000,
                 30000 16000,
                 30000 15000))';
mysql> EXPLAIN SELECT fid,ST_AsText(g) FROM g IGNORE INDEX (g) WHERE
    -> MBRContains(ST_GeomFromText(@poly),g)\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: geom
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 32376
        Extra: Using where
1 row in set (0.00 sec)
 
   执行不带空间索引的SELECT语句仍然获得了相同的数据但导致执行时间从0.00 增加到 0.46 秒:
 
mysql> SET @poly =
    -> 'Polygon((30000 15000,
                 31000 15000,
                 31000 16000,
                 30000 16000,
                 30000 15000))';
mysql> SELECT fid,ST_AsText(g) FROM geom IGNORE INDEX (g) WHERE
    -> MBRContains(ST_GeomFromText(@poly),g);
+-----+---------------------------------------------------------------+
| fid | ST_AsText(g)                                                  |
+-----+---------------------------------------------------------------+
|   1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136. ... |
|   2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136, ... |
|   3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,3016 ... |
|   4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30 ... |
|   5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4, ... |
|   6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,3024 ... |
|   7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8, ... |
|  10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6, ... |
|  11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2, ... |
|  13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,3011 ... |
|  21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30 ... |
|  22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8, ... |
|  23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4, ... |
|  24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4, ... |
|  25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882. ... |
|  26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4, ... |
| 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30 ... |
| 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30 ... |
| 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4, ... |
| 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946. ... |
+-----+---------------------------------------------------------------+
20 rows in set (0.46 sec)
 
 

13.15 Spatial Analysis Functions

     

MySQL提供了在空间数据上执行各种操作的函数。根据操作的类型这些函数可以被分成几个大类
  • 创建各种格式几何图形函数 (WKT, WKB, internal)
  • 几何图形格式之间的转换函数
  • 几何的定性或定量属性的访问函数
  • 描述两个图形之间的关系函数
  •  从现有的创建新的几何图形函数

 

13.15.1 Spatial Function Reference

The following table lists each spatial function and provides a short description of each one.

Table 13.19 Spatial Functions

NameDescription
Area() (弃用 5.7.6) Return Polygon or MultiPolygon area
AsBinary(), AsWKB() (弃用5.7.6) Convert from internal geometry format to WKB
AsText(), AsWKT() (弃用 5.7.6) Convert from internal geometry format to WKT
Buffer() (弃用5.7.6) Return geometry of points within given distance from geometry
Centroid() (弃用5.7.6) Return centroid as a point
Contains() (弃用5.7.6) Whether MBR of one geometry contains MBR of another
ConvexHull() (弃用5.7.6) Return convex hull of geometry
Crosses() (弃用5.7.6) Whether one geometry crosses another
Dimension() (弃用5.7.6) Dimension of geometry
Disjoint() (弃用5.7.6) Whether MBRs of two geometries are disjoint
Distance() (弃用5.7.6) The distance of one geometry from another
EndPoint() (弃用5.7.6) End Point of LineString
Envelope() (弃用 5.7.6) Return MBR of geometry
Equals() (弃用 5.7.6) Whether MBRs of two geometries are equal
ExteriorRing() (弃用5.7.6) Return exterior ring of Polygon
GeomCollFromText(), GeometryCollectionFromText() (弃用5.7.6) Return geometry collection from WKT
GeomCollFromWKB(), GeometryCollectionFromWKB() (弃用5.7.6) Return geometry collection from WKB
GeometryCollection()
从几何图形构造几何图形集合
GeometryN() (弃用5.7.6) Return N-th geometry from geometry collection
GeometryType() (弃用5.7.6) Return name of geometry type
GeomFromText(), GeometryFromText() (弃用5.7.6) Return geometry from WKT
GeomFromWKB(), GeometryFromWKB() (弃用5.7.6) Return geometry from WKB
GLength() (弃用5.7.6) Return length of LineString
InteriorRingN() (弃用5.7.6) Return N-th interior ring of Polygon
Intersects() (弃用5.7.6) Whether MBRs of two geometries intersect
IsClosed() (弃用5.7.6) Whether a geometry is closed and simple
IsEmpty() (弃用5.7.6) Placeholder function
IsSimple() (弃用5.7.6) Whether a geometry is simple
LineFromText(), LineStringFromText() (弃用5.7.6) Construct LineString from WKT
LineFromWKB(), LineStringFromWKB() (弃用5.7.6) Construct LineString from WKB
LineString()

构造 LineString from Point values

MBRContains() 一个几何的MBR包含了另一个的MBR
MBRCoveredBy() 一个MBR是否被另一个覆盖
MBRCovers() 一个MBR是否覆盖了另一个
MBRDisjoint() 两个几何体的MBR是否分离
MBREqual() (弃用 5.7.6) Whether MBRs of two geometries are equal
MBREquals() 两个几何体的MBR是否相同
MBRIntersects() 两个几何体的MBR是否相交
MBROverlaps() 两个几何体的MBR是否重叠
MBRTouches() 两个几何体的MBR是否触碰
MBRWithin() 一个几何体的MBR是否在另一个的MBR里面
MLineFromText(), MultiLineStringFromText() (deprecated 5.7.6) Construct MultiLineString from WKT
MLineFromWKB(), MultiLineStringFromWKB() (deprecated 5.7.6) Construct MultiLineString from WKB
MPointFromText(), MultiPointFromText() (deprecated 5.7.6) Construct MultiPoint from WKT
MPointFromWKB(), MultiPointFromWKB() (deprecated 5.7.6) Construct MultiPoint from WKB
MPolyFromText(), MultiPolygonFromText() (deprecated 5.7.6) Construct MultiPolygon from WKT
MPolyFromWKB(), MultiPolygonFromWKB() (deprecated 5.7.6) Construct MultiPolygon from WKB
MultiLineString() Contruct MultiLineString from LineString values
MultiPoint() Construct MultiPoint from Point values
MultiPolygon() Construct MultiPolygon from Polygon values
NumGeometries() (deprecated 5.7.6) Return number of geometries in geometry collection
NumInteriorRings() (deprecated 5.7.6) Return number of interior rings in Polygon
NumPoints() (deprecated 5.7.6) Return number of points in LineString
Overlaps() (deprecated 5.7.6) Whether MBRs of two geometries overlap
Point() Construct Point from coordinates
PointFromText() (deprecated 5.7.6) Construct Point from WKT
PointFromWKB() (deprecated 5.7.6) Construct Point from WKB
PointN() (deprecated 5.7.6) Return N-th point from LineString
PolyFromText(), PolygonFromText() (deprecated 5.7.6) Construct Polygon from WKT
PolyFromWKB(), PolygonFromWKB() (deprecated 5.7.6) Construct Polygon from WKB
Polygon() Construct Polygon from LineString arguments
SRID() (deprecated 5.7.6) Return spatial reference system ID for geometry
ST_Area() 返回 Polygon or MultiPolygon 范围
ST_AsBinary(), ST_AsWKB() 将内部格式转换成WKB
ST_AsGeoJSON() 从几何体中生成GeoJSON
ST_AsText(), ST_AsWKT() 将内部格式转换成WKT
ST_Buffer() 返回给定几何体给定距离内的几何体的点
ST_Buffer_Strategy() ST_Buffer()生成策略选项
ST_Centroid() 返回几何中心点
ST_Contains() 是否一个几何体包含另外一个
ST_ConvexHull() Return convex hull of geometry
ST_Crosses() 是否一个几何体和其他的交叉
ST_Difference() 返回两个几何体不同的点集合
ST_Dimension() 几何体维度
ST_Disjoint() 一个几何体是否和另一个分离
ST_Distance() 两个几何体的距离
ST_Distance_Sphere() 两个几何体在地球上的最小距离
ST_EndPoint() 返回LineString的结束点
ST_Envelope() 返回几何体MBR
ST_Equals() 两个几何体是否相等
ST_ExteriorRing() 返回Polygon的外部圈
ST_GeoHash() 生成geohash值
ST_GeomCollFromText(), ST_GeometryCollectionFromText(), ST_GeomCollFromTxt() 返回从 WKT生成的几何体集合
ST_GeomCollFromWKB(), ST_GeometryCollectionFromWKB() 返回从 WKB生成的几何体集合
ST_GeometryN() 返回集合中第N个几何体
ST_GeometryType() 返回几何体类型
ST_GeomFromGeoJSON() 从GeoJSON对象生成几何体
ST_GeomFromText(), ST_GeometryFromText() 从 WKT返回几何体
ST_GeomFromWKB(), ST_GeometryFromWKB() 从WKB返回几何体
ST_InteriorRingN() 返回Polygon的第N个内部环
ST_Intersection() 返回两个几何体的交叉点集合
ST_Intersects() 一个几何体是否和另一个交叉
ST_IsClosed() 一个几何体是否是simple且closed
ST_IsEmpty() Placeholder function
ST_IsSimple() Whether a geometry is simple
ST_IsValid() Whether a geometry is valid
ST_LatFromGeoHash() 从geohash返回纬度
ST_Length() Return length of LineString
ST_LineFromText(), ST_LineStringFromText() Construct LineString from WKT
ST_LineFromWKB(), ST_LineStringFromWKB() Construct LineString from WKB
ST_LongFromGeoHash() 从geohash返回经度
ST_MakeEnvelope() 两点之间的矩形
ST_MLineFromText(), ST_MultiLineStringFromText() Construct MultiLineString from WKT
ST_MLineFromWKB(), ST_MultiLineStringFromWKB() Construct MultiLineString from WKB
ST_MPointFromText(), ST_MultiPointFromText() Construct MultiPoint from WKT
ST_MPointFromWKB(), ST_MultiPointFromWKB() Construct MultiPoint from WKB
ST_MPolyFromText(), ST_MultiPolygonFromText() Construct MultiPolygon from WKT
ST_MPolyFromWKB(), ST_MultiPolygonFromWKB() Construct MultiPolygon from WKB
ST_NumGeometries() 返回集合中的几何体个数
ST_NumInteriorRing(), ST_NumInteriorRings()  返回Polygon内部环的个数
ST_NumPoints() 返回LineString中点的个数
ST_Overlaps() 是否一个几何体和另一个重叠
ST_PointFromGeoHash() 从geohash转换成POINT值
ST_PointFromText() 从WKT生成POINT
ST_PointFromWKB() 从WKB生成POINT
ST_PointN() 返回LineString的第N点
ST_PolyFromText(), ST_PolygonFromText() Construct Polygon from WKT
ST_PolyFromWKB(), ST_PolygonFromWKB() Construct Polygon from WKB
ST_Simplify() 返回简化的几何体
ST_SRID() 返回几何体的空间关系系统ID
ST_StartPoint() LineString的开始点
ST_SymDifference() Return point set symmetric difference of two geometries
ST_Touches() 一个几何体是否触碰到另一个
ST_Union() 返回两个几何体所有点的联合集合
ST_Validate() Return validated geometry
ST_Within() 一个几何体是否在另一个中
ST_X() 返回点的X坐标
ST_Y() 返回点的Y坐标
StartPoint() (deprecated 5.7.6) Start Point of LineString
Touches() (deprecated 5.7.6) Whether one geometry touches another
Within() (deprecated 5.7.6) Whether MBR of one geometry is within MBR of another
X() (deprecated 5.7.6) Return X coordinate of Point
Y() (deprecated 5.7.6) Return Y coordinate of Point 
 
posted @ 2016-07-25 08:47  zengkefu  阅读(280)  评论(0编辑  收藏  举报