MySQL supports spatial extensions to allow the generation, storage,
and analysis of geographic features. Before MySQL 5.0.16, these
features are available for MyISAM tables only. As
of MySQL 5.0.16, InnoDB, NDB,
BDB, and ARCHIVE also support
spatial features.
For spatial columns, MyISAM supports both
SPATIAL and non-SPATIAL
indexes. Other storage engines support
non-SPATIAL indexes, as described in
Section 13.1.4, “CREATE INDEX Syntax”.
This chapter covers the following topics:
The basis of these spatial extensions in the OpenGIS geometry
model
Data formats for representing spatial data
How to use spatial data in MySQL
Use of indexing for spatial data
MySQL differences from the OpenGIS specification
Additional resources
The Open Geospatial Consortium publishes the
OpenGIS® Simple Features Specifications For
SQL, a document that proposes several conceptual
ways for extending an SQL RDBMS to support spatial data. This
specification is available from the OGC Web site at
http://www.opengis.org/docs/99-049.pdf.
If you have questions or concerns about the use of the spatial
extensions to MySQL, you can discuss them in the GIS forum:
http://forums.mysql.com/list.php?23.
16.1. Introduction to MySQL Spatial Support
MySQL implements spatial extensions following the specification of
the Open Geospatial Consortium (OGC). This is an international
consortium of more than 250 companies, agencies, and universities
participating in the development of publicly available conceptual
solutions that can be useful with all kinds of applications that
manage spatial data. The OGC maintains a Web site at
http://www.opengis.org/.
In 1997, the Open Geospatial Consortium published the
OpenGIS® Simple Features Specifications For
SQL, a document that proposes several conceptual ways
for extending an SQL RDBMS to support spatial data. This
specification is available from the OGC Web site at
http://www.opengis.org/docs/99-049.pdf. It contains
additional information relevant to this chapter.
MySQL implements a subset of the SQL with
Geometry Types environment proposed by OGC. This term
refers to an SQL environment that has been extended with a set of
geometry types. A geometry-valued SQL column is implemented as a
column that has a geometry type. The specification describe a set
of SQL geometry types, as well as functions on those types to
create and analyze geometry values.
A geographic feature is anything
in the world that has a location. A feature can be:
An entity. For example, a mountain, a pond, a city.
A space. For example, a postcode area, the tropics.
A definable location. For example, a crossroad, as a
particular place where two streets intersect.
Some documents use the term geospatial
feature to refer to geographic features.
Geometry is another word that
denotes a geographic feature. Originally the word
geometry meant measurement of the
earth. Another meaning comes from cartography, referring to the
geometric features that cartographers use to map the world.
This chapter uses all of these terms synonymously:
geographic feature,
geospatial feature,
feature, or
geometry. Here, the term most
commonly used is geometry,
defined as a point or an aggregate of points
representing anything in the world that has a location.
The set of geometry types proposed by OGC's
SQL with Geometry Types
environment is based on the OpenGIS Geometry
Model. In this model, each geometric object has the
following general properties:
It is associated with a Spatial Reference System, which
describes the coordinate space in which the object is defined.
It belongs to some geometry class.
16.2.1. The Geometry Class Hierarchy
The geometry classes define a hierarchy as follows:
Geometry (non-instantiable)
Point (instantiable)
Curve (non-instantiable)
LineString (instantiable)
Line
LinearRing
Surface (non-instantiable)
Polygon (instantiable)
GeometryCollection (instantiable)
MultiPoint (instantiable)
MultiCurve (non-instantiable)
MultiLineString
(instantiable)
MultiSurface (non-instantiable)
MultiPolygon (instantiable)
It is not possible to create objects in non-instantiable
classes. It is possible to create objects in instantiable
classes. All classes have properties, and instantiable classes
may also have assertions (rules that define valid class
instances).
Geometry is the base class. It is an abstract
class. The instantiable subclasses of
Geometry are restricted to zero-, one-, and
two-dimensional geometric objects that exist in two-dimensional
coordinate space. All instantiable geometry classes are defined
so that valid instances of a geometry class are topologically
closed (that is, all defined geometries include their boundary).
The base Geometry class has subclasses for
Point, Curve,
Surface, and
GeometryCollection:
Point represents zero-dimensional
objects.
Curve represents one-dimensional objects,
and has subclass LineString, with
sub-subclasses Line and
LinearRing.
Surface is designed for two-dimensional
objects and has subclass Polygon.
GeometryCollection has specialized zero-,
one-, and two-dimensional collection classes named
MultiPoint,
MultiLineString, and
MultiPolygon for modeling geometries
corresponding to collections of Points,
LineStrings, and
Polygons, respectively.
MultiCurve and
MultiSurface are introduced as abstract
superclasses that generalize the collection interfaces to
handle Curves and
Surfaces.
Geometry, Curve,
Surface, MultiCurve, and
MultiSurface are defined as non-instantiable
classes. They define a common set of methods for their
subclasses and are included for extensibility.
Point, LineString,
Polygon,
GeometryCollection,
MultiPoint,
MultiLineString, and
MultiPolygon are instantiable classes.
16.2.2. Class Geometry
Geometry is the root class of the hierarchy.
It is a non-instantiable class but has a number of properties
that are common to all geometry values created from any of the
Geometry subclasses. These properties are
described in the following list. Particular subclasses have
their own specific properties, described later.
Geometry Properties
A geometry value has the following properties:
Its type. Each geometry
belongs to one of the instantiable classes in the hierarchy.
Its SRID, or Spatial
Reference Identifier. This value identifies the geometry's
associated Spatial Reference System that describes the
coordinate space in which the geometry object is defined.
In MySQL, the SRID value is just an integer associated with
the geometry value. All calculations are done assuming
Euclidean (planar) geometry.
Its coordinates in its
Spatial Reference System, represented as double-precision
(eight-byte) numbers. All non-empty geometries include at
least one pair of (X,Y) coordinates. Empty geometries
contain no coordinates.
Coordinates are related to the SRID. For example, in
different coordinate systems, the distance between two
objects may differ even when objects have the same
coordinates, because the distance on the
planar coordinate system
and the distance on the
geocentric system
(coordinates on the Earth's surface) are different things.
Its interior,
boundary, and
exterior.
Every geometry occupies some position in space. The exterior
of a geometry is all space not occupied by the geometry. The
interior is the space occupied by the geometry. The boundary
is the interface between the geometry's interior and
exterior.
Its MBR (Minimum Bounding
Rectangle), or Envelope. This is the bounding geometry,
formed by the minimum and maximum (X,Y) coordinates:
Whether the value is simple
or non-simple. Geometry
values of types (LineString,
MultiPoint,
MultiLineString) are either simple or
non-simple. Each type determines its own assertions for
being simple or non-simple.
Whether the value is closed
or not closed. Geometry
values of types (LineString,
MultiString) are either closed or not
closed. Each type determines its own assertions for being
closed or not closed.
Whether the value is empty
or non-empty A geometry is
empty if it does not have any points. Exterior, interior,
and boundary of an empty geometry are not defined (that is,
they are represented by a NULL value). An
empty geometry is defined to be always simple and has an
area of 0.
Its dimension. A geometry
can have a dimension of –1, 0, 1, or 2:
–1 for an empty geometry.
0 for a geometry with no length and no area.
1 for a geometry with non-zero length and zero area.
2 for a geometry with non-zero area.
Point objects have a dimension of zero.
LineString objects have a dimension of 1.
Polygon objects have a dimension of 2.
The dimensions of MultiPoint,
MultiLineString, and
MultiPolygon objects are the same as the
dimensions of the elements they consist of.
16.2.3. Class Point
A Point is a geometry that represents a
single location in coordinate space.
Point
Examples
Imagine a large-scale map of the world with many cities. A
Point object could represent each city.
On a city map, a Point object could
represent a bus stop.
Point
Properties
X-coordinate value.
Y-coordinate value.
Point is defined as a zero-dimensional
geometry.
The boundary of a Point is the empty set.
16.2.4. Class Curve
A Curve is a one-dimensional geometry,
usually represented by a sequence of points. Particular
subclasses of Curve define the type of
interpolation between points. Curve is a
non-instantiable class.
Curve
Properties
A Curve has the coordinates of its
points.
A Curve is defined as a one-dimensional
geometry.
A Curve is simple if it does not pass
through the same point twice.
A Curve is closed if its start point is
equal to its endpoint.
The boundary of a closed Curve is empty.
The boundary of a non-closed Curve
consists of its two endpoints.
A Curve that is simple and closed is a
LinearRing.
16.2.5. Class LineString
A LineString is a Curve
with linear interpolation between points.
LineString
Examples
On a world map, LineString objects could
represent rivers.
In a city map, LineString objects could
represent streets.
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.
16.2.6. Class Surface
A Surface is a two-dimensional geometry. It
is a non-instantiable class. Its only instantiable subclass is
Polygon.
Surface
Properties
A Surface is defined as a two-dimensional
geometry.
The OpenGIS specification defines a simple
Surface as a geometry that consists of a
single “patch” that is associated with a single
exterior boundary and zero or more interior boundaries.
The boundary of a simple Surface is the
set of closed curves corresponding to its exterior and
interior boundaries.
16.2.7. Class Polygon
A Polygon is a planar
Surface representing a multisided geometry.
It is defined by a single exterior boundary and zero or more
interior boundaries, where each interior boundary defines a hole
in the Polygon.
Polygon
Examples
On a region map, Polygon objects could
represent forests, districts, and so on.
Polygon
Assertions
The boundary of a Polygon consists of a
set of LinearRing objects (that is,
LineString objects that are both simple
and closed) that make up its exterior and interior
boundaries.
A Polygon has no rings that cross. The
rings in the boundary of a Polygon may
intersect at a Point, but only as a
tangent.
A Polygon has no lines, spikes, or
punctures.
A Polygon has an interior that is a
connected point set.
A Polygon may have holes. The exterior of
a Polygon with holes is not connected.
Each hole defines a connected component of the exterior.
The preceding assertions make a Polygon a
simple geometry.
16.2.8. Class GeometryCollection
A GeometryCollection is a geometry that is a
collection of one or more geometries of any class.
All the elements in a GeometryCollection must
be in the same Spatial Reference System (that is, in the same
coordinate system). There are no other constraints on the
elements of a GeometryCollection, although
the subclasses of GeometryCollection
described in the following sections may restrict membership.
Restrictions may be based on:
Element type (for example, a MultiPoint
may contain only Point elements)
Dimension
Constraints on the degree of spatial overlap between
elements
16.2.9. Class MultiPoint
A MultiPoint is a geometry collection
composed of Point elements. The points are
not connected or ordered in any way.
MultiPoint
Examples
On a world map, a MultiPoint could
represent a chain of small islands.
On a city map, a MultiPoint could
represent the outlets for a ticket office.
MultiPoint
Properties
A MultiPoint is a zero-dimensional
geometry.
A MultiPoint is simple if no two of its
Point values are equal (have identical
coordinate values).
The boundary of a MultiPoint is the empty
set.
16.2.10. Class MultiCurve
A MultiCurve is a geometry collection
composed of Curve elements.
MultiCurve is a non-instantiable class.
MultiCurve
Properties
A MultiCurve is a one-dimensional
geometry.
A MultiCurve is simple if and only if all
of its elements are simple; the only intersections between
any two elements occur at points that are on the boundaries
of both elements.
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 MultiCurve
elements.
A MultiCurve is closed if all of its
elements are closed.
The boundary of a closed MultiCurve is
always empty.
16.2.11. Class MultiLineString
A MultiLineString is a
MultiCurve geometry collection composed of
LineString elements.
MultiLineString
Examples
On a region map, a MultiLineString could
represent a river system or a highway system.
16.2.12. Class MultiSurface
A MultiSurface is a geometry collection
composed of surface elements. MultiSurface is
a non-instantiable class. Its only instantiable subclass is
MultiPolygon.
MultiSurface
Assertions
Two MultiSurface surfaces have no
interiors that intersect.
Two MultiSurface elements have boundaries
that intersect at most at a finite number of points.
16.2.13. Class MultiPolygon
A MultiPolygon is a
MultiSurface object composed of
Polygon elements.
MultiPolygon
Examples
On a region map, a MultiPolygon could
represent a system of lakes.
MultiPolygon
Assertions
A MultiPolygon has no two
Polygon elements with interiors that
intersect.
A MultiPolygon has no two
Polygon elements that cross (crossing is
also forbidden by the previous assertion), or that touch at
an infinite number of points.
A MultiPolygon may not have cut lines,
spikes, or punctures. A MultiPolygon is a
regular, closed point set.
A MultiPolygon that has more than one
Polygon has an interior that is not
connected. The number of connected components of the
interior of a MultiPolygon is equal to
the number of Polygon values in the
MultiPolygon.
MultiPolygon
Properties
A MultiPolygon is a two-dimensional
geometry.
A MultiPolygon boundary is a set of
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.
A Backus-Naur grammar that specifies the formal production rules
for writing WKT values can be found in the OpenGIS specification
document referenced near the beginning of this chapter.
16.3.2. Well-Known Binary (WKB) Format
The Well-Known Binary (WKB) representation for geometric values
is defined by the OpenGIS specification. It is also defined in
the ISO SQL/MM Part 3: Spatial standard.
WKB is used to exchange geometry data as binary streams
represented by BLOB values containing
geometric WKB information.
WKB uses one-byte unsigned integers, four-byte unsigned
integers, and eight-byte double-precision numbers (IEEE 754
format). A byte is eight bits.
For example, a WKB value that corresponds to POINT(1
1) consists of this sequence of 21 bytes (each
represented here by two hex digits):
0101000000000000000000F03F000000000000F03F
The sequence may be broken down into these components:
Byte order : 01
WKB type : 01000000
X : 000000000000F03F
Y : 000000000000F03F
Component representation is as follows:
The byte order may be either 0 or 1 to indicate
little-endian or big-endian storage. The little-endian and
big-endian byte orders are also known as Network Data
Representation (NDR) and External Data Representation (XDR),
respectively.
The WKB type is a code that indicates the geometry type.
Values from 1 through 7 indicate Point,
LineString, Polygon,
MultiPoint,
MultiLineString,
MultiPolygon, and
GeometryCollection.
A Point value has X and Y coordinates,
each represented as a double-precision value.
WKB values for more complex geometry values are represented by
more complex data structures, as detailed in the OpenGIS
specification.
This section describes the data types you can use for representing
spatial data in MySQL, and the functions available for creating
and retrieving spatial values.
16.4.1. MySQL Spatial Data Types
MySQL has data types that correspond to OpenGIS classes. Some of
these types hold single geometry values:
GEOMETRY
POINT
LINESTRING
POLYGON
GEOMETRY can store geometry values of any
type. The other single-value types (POINT,
LINESTRING, and POLYGON)
restrict their values to a particular geometry type.
The other data types hold collections of values:
MULTIPOINT
MULTILINESTRING
MULTIPOLYGON
GEOMETRYCOLLECTION
GEOMETRYCOLLECTION can store a collection of
objects of any type. The other collection types
(MULTIPOINT,
MULTILINESTRING,
MULTIPOLYGON, and
GEOMETRYCOLLECTION) restrict collection
members to those having a particular geometry type.
This section describes how to create spatial values using
Well-Known Text and Well-Known Binary functions that are defined
in the OpenGIS standard, and using MySQL-specific functions.
16.4.2.1. Creating Geometry Values Using WKT Functions
MySQL provides a number of functions that take as input
parameters a Well-Known Text representation and, optionally, a
spatial reference system identifier (SRID). They return the
corresponding geometry.
GeomFromText() accepts a WKT of any
geometry type as its first argument. An implementation also
provides type-specific construction functions for construction
of geometry values of each geometry type.
Constructs a POLYGON value using its
WKT representation and SRID.
The OpenGIS specification also defines the following optional
functions, which MySQL does not implement. These functions
construct Polygon or
MultiPolygon values based on the WKT
representation of a collection of rings or closed
LineString values. These values may
intersect.
BdMPolyFromText(wkt,srid)
Constructs a MultiPolygon value from a
MultiLineString value in WKT format
containing an arbitrary collection of closed
LineString values.
BdPolyFromText(wkt,srid)
Constructs a Polygon value from a
MultiLineString value in WKT format
containing an arbitrary collection of closed
LineString values.
16.4.2.2. Creating Geometry Values Using WKB Functions
MySQL provides a number of functions that take as input
parameters a BLOB containing a Well-Known
Binary representation and, optionally, a spatial reference
system identifier (SRID). They return the corresponding
geometry.
GeomFromWKB() accepts a WKB of any geometry
type as its first argument. An implementation also provides
type-specific construction functions for construction of
geometry values of each geometry type.
Constructs a POLYGON value using its
WKB representation and SRID.
The OpenGIS specification also describes optional functions
for constructing Polygon or
MultiPolygon values based on the WKB
representation of a collection of rings or closed
LineString values. These values may
intersect. MySQL does not implement these functions:
BdMPolyFromWKB(wkb,srid)
Constructs a MultiPolygon value from a
MultiLineString value in WKB format
containing an arbitrary collection of closed
LineString values.
BdPolyFromWKB(wkb,srid)
Constructs a Polygon value from a
MultiLineString value in WKB format
containing an arbitrary collection of closed
LineString values.
16.4.2.3. Creating Geometry Values Using MySQL-Specific Functions
MySQL provides a set of useful non-standard functions for
creating geometry WKB representations. The functions described
in this section are MySQL extensions to the OpenGIS
specification. The results of these functions are
BLOB values containing WKB representations
of geometry values with no SRID. The results of these
functions can be substituted as the first argument for any
function in the GeomFromWKB() function
family.
GeometryCollection(g1,g2,...)
Constructs a WKB GeometryCollection. If
any argument is not a well-formed WKB representation of a
geometry, the return value is NULL.
LineString(pt1,pt2,...)
Constructs a WKB LineString value from
a number of WKB Point arguments. If any
argument is not a WKB Point, the return
value is NULL. If the number of
Point arguments is less than two, the
return value is NULL.
MultiLineString(ls1,ls2,...)
Constructs a WKB MultiLineString value
using WKB LineString arguments. If any
argument is not a WKB LineString, the
return value is NULL.
MultiPoint(pt1,pt2,...)
Constructs a WKB MultiPoint value using
WKB Point arguments. If any argument is
not a WKB Point, the return value is
NULL.
MultiPolygon(poly1,poly2,...)
Constructs a WKB MultiPolygon value
from a set of WKB Polygon arguments. If
any argument is not a WKB Polygon, the
return value is NULL.
Point(x,y)
Constructs a WKB Point using its
coordinates.
Polygon(ls1,ls2,...)
Constructs a WKB Polygon value from a
number of WKB LineString arguments. If
any argument does not represent the WKB of a
LinearRing (that is, not a closed and
simple LineString) the return value is
NULL.
16.4.3. Creating Spatial Columns
MySQL provides a standard way of creating spatial columns for
geometry types, for example, with CREATE
TABLE or ALTER TABLE. Currently,
spatial columns are supported for MyISAM,
InnoDB, NDB,
BDB, and ARCHIVE tables.
(Support for storage engines other than
MyISAM was added in MySQL 5.0.16.) See also
the annotations about spatial indexes under
Section 16.6.1, “Creating Spatial Indexes”.
Use the CREATE TABLE statement to create
a table with a spatial column:
CREATE TABLE geom (g GEOMETRY);
Use the ALTER TABLE statement to add or
drop a spatial column to or from an existing table:
ALTER TABLE geom ADD pt POINT;
ALTER TABLE geom DROP pt;
16.4.4. Populating Spatial Columns
After you have created spatial columns, you can populate them
with spatial data.
Values should be stored in internal geometry format, but you can
convert them to that format from either Well-Known Text (WKT) or
Well-Known Binary (WKB) format. The following examples
demonstrate how to insert geometry values into a table by
converting WKT values into internal geometry format:
Perform the conversion directly in the
INSERT statement:
INSERT INTO geom VALUES (GeomFromText('POINT(1 1)'));
SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (GeomFromText(@g));
Perform the conversion prior to the
INSERT:
SET @g = GeomFromText('POINT(1 1)');
INSERT INTO geom VALUES (@g);
The following examples insert more complex geometries into the
table:
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));
The preceding examples all use GeomFromText()
to create geometry values. You can also use type-specific
functions:
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));
Note that if a client application program wants to use WKB
representations of geometry values, it is responsible for
sending correctly formed WKB in queries to the server. However,
there are several ways of satisfying this requirement. For
example:
Inserting a POINT(1 1) value with hex
literal syntax:
mysql> INSERT INTO geom VALUES
-> (GeomFromWKB(0x0101000000000000000000F03F000000000000F03F));
An ODBC application can send a WKB representation, binding
it to a placeholder using an argument of
BLOB type:
INSERT INTO geom VALUES (GeomFromWKB(?))
Other programming interfaces may support a similar
placeholder mechanism.
In a C program, you can escape a binary value using
mysql_real_escape_string() and include
the result in a query string that is sent to the server. See
Section 22.2.3.53, “mysql_real_escape_string()”.
16.4.5. Fetching Spatial Data
Geometry values stored in a table can be fetched in internal
format. You can also convert them into WKT or WKB format.
Fetching spatial data in internal format:
Fetching geometry values using internal format can be useful
in table-to-table transfers:
CREATE TABLE geom2 (g GEOMETRY) SELECT g FROM geom;
Fetching spatial data in WKT format:
The AsText() function converts a geometry
from internal format into a WKT string.
SELECT AsText(g) FROM geom;
Fetching spatial data in WKB format:
The AsBinary() function converts a
geometry from internal format into a BLOB
containing the WKB value.
After populating spatial columns with values, you are ready to
query and analyze them. MySQL provides a set of functions to
perform various operations on spatial data. These functions can be
grouped into four major categories according to the type of
operation they perform:
Functions that convert geometries between various formats
Functions that provide access to qualitative or quantitative
properties of a geometry
Functions that describe relations between two geometries
Functions that create new geometries from existing ones
Spatial analysis functions can be used in many contexts, such as:
Any interactive SQL program, such as mysql
or MySQL Query Browser
Application programs written in any language that supports a
MySQL client API
16.5.1. Geometry Format Conversion Functions
MySQL supports the following functions for converting geometry
values between internal format and either WKT or WKB format:
AsBinary(g)
Converts a value in internal geometry format to its WKB
representation and returns the binary result.
SELECT AsBinary(g) FROM geom;
AsText(g)
Converts a value in internal geometry format to its WKT
representation and returns the string result.
Converts a string value from its WKT representation into
internal geometry format and returns the result. A number of
type-specific functions are also supported, such as
PointFromText() and
LineFromText(). See
Section 16.4.2.1, “Creating Geometry Values Using WKT Functions”.
GeomFromWKB(wkb[,srid])
Converts a binary value from its WKB representation into
internal geometry format and returns the result. A number of
type-specific functions are also supported, such as
PointFromWKB() and
LineFromWKB(). See
Section 16.4.2.2, “Creating Geometry Values Using WKB Functions”.
Each function that belongs to this group takes a geometry value
as its argument and returns some quantitative or qualitative
property of the geometry. Some functions restrict their argument
type. Such functions return NULL if the
argument is of an incorrect geometry type. For example,
Area() returns NULL if the
object type is neither Polygon nor
MultiPolygon.
16.5.2.1. General Geometry Functions
The functions listed in this section do not restrict their
argument and accept a geometry value of any type.
Dimension(g)
Returns the inherent dimension of the geometry value
g. The result can be –1,
0, 1, or 2. The meaning of these values is given in
Section 16.2.2, “Class Geometry”.
Returns as a string the name of the geometry type of which
the geometry instance g is a
member. The name corresponds to one of the instantiable
Geometry subclasses.
The OpenGIS specification also defines the following
functions, which MySQL does not implement:
Boundary(g)
Returns a geometry that is the closure of the
combinatorial boundary of the geometry value
g.
IsEmpty(g)
Returns 1 if the geometry value
g is the empty geometry, 0 if
it is not empty, and –1 if the argument is
NULL. If the geometry is empty, it
represents the empty point set.
IsSimple(g)
Currently, this function is a placeholder and should not
be used. If implemented, its behavior will be as described
in the next paragraph.
Returns 1 if the geometry value
g has no anomalous geometric
points, such as self-intersection or self-tangency.
IsSimple() returns 0 if the argument is
not simple, and –1 if it is NULL.
The description of each instantiable geometric class given
earlier in the chapter includes the specific conditions
that cause an instance of that class to be classified as
not simple. (See
Section 16.2.1, “The Geometry Class Hierarchy”.)
16.5.2.2. Point Functions
A Point consists of X and Y coordinates,
which may be obtained using the following functions:
X(p)
Returns the X-coordinate value for the point
p as a double-precision number.
A LineString consists of
Point values. You can extract particular
points of a LineString, count the number of
points that it contains, or obtain its length.
EndPoint(ls)
Returns the Point that is the endpoint
of the LineString value
ls.
The OpenGIS specification also defines the following function,
which MySQL does not implement:
IsRing(ls)
Returns 1 if the LineString value
ls is closed (that is, its
StartPoint() and
EndPoint() values are the same) and is
simple (does not pass through the same point more than
once). Returns 0 if ls is not a
ring, and –1 if it is NULL.
16.5.2.4. MultiLineString Functions
GLength(mls)
Returns as a double-precision number the length of the
MultiLineString value
mls. The length of
mls is equal to the sum of the
lengths of its elements.
GLength() is a non-standard name. It
corresponds to the OpenGIS Length()
function.
IsClosed(mls)
Returns 1 if the MultiLineString value
mls is closed (that is, the
StartPoint() and
EndPoint() values are the same for each
LineString in
mls). Returns 0 if
mls is not closed, and –1
if it is NULL.
16.5.3.1. Geometry Functions That Produce New Geometries
Section 16.5.2, “Geometry Functions”, discusses
several functions that construct new geometries from existing
ones. See that section for descriptions of these functions:
Envelope(g)
StartPoint(ls)
EndPoint(ls)
PointN(ls,N)
ExteriorRing(poly)
InteriorRingN(poly,N)
GeometryN(gc,N)
16.5.3.2. Spatial Operators
OpenGIS proposes a number of other functions that can produce
geometries. They are designed to implement spatial operators.
These functions are not implemented in MySQL. They may appear
in future releases.
Buffer(g,d)
Returns a geometry that represents all points whose
distance from the geometry value
g is less than or equal to a
distance of d.
ConvexHull(g)
Returns a geometry that represents the convex hull of the
geometry value g.
Difference(g1,g2)
Returns a geometry that represents the point set
difference of the geometry value
g1 with
g2.
Intersection(g1,g2)
Returns a geometry that represents the point set
intersection of the geometry values
g1 with
g2.
SymDifference(g1,g2)
Returns a geometry that represents the point set symmetric
difference of the geometry value
g1 with
g2.
Union(g1,g2)
Returns a geometry that represents the point set union of
the geometry values g1 and
g2.
16.5.4. Functions for Testing Spatial Relations Between Geometric Objects
The functions described in these sections take two geometries as
input parameters and return a qualitative or quantitative
relation between them.
16.5.5. Relations on Geometry Minimal Bounding Rectangles (MBRs)
MySQL provides several functions that test relations between
minimal bounding rectangles of two geometries
g1 and g2. The return
values 1 and 0 indicate true and false, respectively.
MBRContains(g1,g2)
Returns 1 or 0 to indicate whether the Minimum Bounding
Rectangle of g1 contains the
Minimum Bounding Rectangle of g2.
This tests the opposite relationship as
MBRWithin().
Returns 1 or 0 to indicate whether the Minimum Bounding
Rectangles of the two geometries
g1 and
g2 are disjoint (do not
intersect).
MBREqual(g1,g2)
Returns 1 or 0 to indicate whether the Minimum Bounding
Rectangles of the two geometries
g1 and
g2 are the same.
MBRIntersects(g1,g2)
Returns 1 or 0 to indicate whether the Minimum Bounding
Rectangles of the two geometries
g1 and
g2 intersect.
MBROverlaps(g1,g2)
Returns 1 or 0 to indicate whether the Minimum Bounding
Rectangles of the two geometries
g1 and
g2 overlap. The term
spatially overlaps is used if two
geometries intersect and their intersection results in a
geometry of the same dimension but not equal to either of
the given geometries.
MBRTouches(g1,g2)
Returns 1 or 0 to indicate whether the Minimum Bounding
Rectangles of the two geometries
g1 and
g2 touch. Two geometries
spatially touch if the interiors of the
geometries do not intersect, but the boundary of one of the
geometries intersects either the boundary or the interior of
the other.
MBRWithin(g1,g2)
Returns 1 or 0 to indicate whether the Minimum Bounding
Rectangle of g1 is within the
Minimum Bounding Rectangle of g2.
This tests the opposite relationship as
MBRWithin().
16.5.6. Functions That Test Spatial Relationships Between Geometries
The OpenGIS specification defines the following functions. They
test the relationship between two geometry values
g1 and g2.
The return values 1 and 0 indicate true and false, respectively.
Note
Currently, MySQL does not implement these functions according
to the specification. Those that are implemented return the
same result as the corresponding MBR-based functions. This
includes functions in the following list other than
Distance() and
Related().
These functions may be implemented in future releases with
full support for spatial analysis, not just MBR-based support.
Contains(g1,g2)
Returns 1 or 0 to indicate whether
g1 completely contains
g2. This tests the opposite
relationship as Within().
Crosses(g1,g2)
Returns 1 if g1 spatially crosses
g2. Returns
NULL if g1 is a
Polygon or a
MultiPolygon, or if
g2 is a Point
or a MultiPoint. Otherwise, returns 0.
The term spatially crosses denotes a
spatial relation between two given geometries that has the
following properties:
The two geometries intersect
Their intersection results in a geometry that has a
dimension that is one less than the maximum dimension of
the two given geometries
Their intersection is not equal to either of the two
given geometries
Disjoint(g1,g2)
Returns 1 or 0 to indicate whether
g1 is spatially disjoint from
(does not intersect) g2.
Distance(g1,g2)
Returns as a double-precision number the shortest distance
between any two points in the two geometries.
Equals(g1,g2)
Returns 1 or 0 to indicate whether
g1 is spatially equal to
g2.
Intersects(g1,g2)
Returns 1 or 0 to indicate whether
g1 spatially intersects
g2.
Overlaps(g1,g2)
Returns 1 or 0 to indicate whether
g1 spatially overlaps
g2. The term spatially
overlaps is used if two geometries intersect and
their intersection results in a geometry of the same
dimension but not equal to either of the given geometries.
Related(g1,g2,pattern_matrix)
Returns 1 or 0 to indicate whether the spatial relationship
specified by pattern_matrix
exists between g1 and
g2. Returns –1 if the
arguments are NULL. The pattern matrix is
a string. Its specification will be noted here if this
function is implemented.
Touches(g1,g2)
Returns 1 or 0 to indicate whether
g1 spatially touches
g2. Two geometries
spatially touch if the interiors of the
geometries do not intersect, but the boundary of one of the
geometries intersects either the boundary or the interior of
the other.
Within(g1,g2)
Returns 1 or 0 to indicate whether
g1 is spatially within
g2. This tests the opposite
relationship as Contains().
Search operations in non-spatial databases can be optimized using
SPATIAL indexes. This is true for spatial
databases as well. With the help of a great variety of
multi-dimensional indexing methods that have previously been
designed, it is possible to optimize spatial searches. The most
typical of these are:
Point queries that search for all objects that contain a given
point
Region queries that search for all objects that overlap a
given region
MySQL uses R-Trees with quadratic
splitting for SPATIAL indexes on
spatial columns. A SPATIAL index is built using
the MBR of a geometry. For most geometries, the MBR is a minimum
rectangle that surrounds the geometries. For a horizontal or a
vertical linestring, the MBR is a rectangle degenerated into the
linestring. For a point, the MBR is a rectangle degenerated into
the point.
It is also possible to create normal indexes on spatial columns.
In a non-SPATIAL index, you must declare a
prefix for any spatial column except for POINT
columns.
MyISAM supports both SPATIAL
and non-SPATIAL indexes. Other storage engines
support non-SPATIAL indexes, as described in
Section 13.1.4, “CREATE INDEX Syntax”.
16.6.1. Creating Spatial Indexes
MySQL can create spatial indexes using syntax similar to that
for creating regular indexes, but extended with the
SPATIAL keyword. Currently, columns in
spatial indexes must be declared NOT NULL.
The following examples demonstrate how to create spatial
indexes:
With CREATE TABLE:
CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g));
With ALTER TABLE:
ALTER TABLE geom ADD SPATIAL INDEX(g);
With CREATE INDEX:
CREATE SPATIAL INDEX sp_index ON geom (g);
For MyISAM tables, SPATIAL
INDEX creates an R-tree index. For storage engines
that support non-spatial indexing of spatial columns, the engine
creates a B-tree index. A B-tree index on spatial values will be
useful for exact-value lookups, but not for range scans.
To drop 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: Suppose that a table geom contains
more than 32,000 geometries, which are stored in the column
g of type GEOMETRY. The
table also has an AUTO_INCREMENT column
fid for storing object ID values.
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)
To add a spatial index on the column g, use
this statement:
The optimizer investigates whether available spatial indexes can
be involved in the search for queries that use a function such
as MBRContains() or
MBRWithin() in the WHERE
clause. The following query finds all objects that are in the
given rectangle:
Use EXPLAIN to check the way this query is
executed:
mysql> SET @poly =
-> 'Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))';
mysql> EXPLAIN SELECT fid,AsText(g) FROM geom WHERE
-> MBRContains(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)
Check what would happen without a spatial index:
mysql> SET @poly =
-> 'Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))';
mysql> EXPLAIN SELECT fid,AsText(g) FROM g IGNORE INDEX (g) WHERE
-> MBRContains(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)
Executing the SELECT statement without the
spatial index yields the same result but causes the execution
time to rise from 0.00 seconds to 0.46 seconds:
MySQL does not yet implement the following GIS features:
Additional Metadata Views
OpenGIS specifications propose several additional metadata
views. For example, a system view named
GEOMETRY_COLUMNS contains a description of
geometry columns, one row for each geometry column in the
database.
The OpenGIS function Length() on
LineString and
MultiLineString currently should be called
in MySQL as GLength()
The problem is that there is an existing SQL function
Length() that calculates the length of
string values, and sometimes it is not possible to distinguish
whether the function is called in a textual or spatial
context. We need either to solve this somehow, or decide on
another function name.