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.
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()
.
Returns 1 or 0 to indicate whether
g1
completely contains
g2
. This tests the opposite
relationship as Within()
.
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
Returns 1 or 0 to indicate whether
g1
is spatially disjoint from
(does not intersect) g2
.
Returns as a double-precision number the shortest distance between any two points in the two geometries.
Returns 1 or 0 to indicate whether
g1
is spatially equal to
g2
.
Returns 1 or 0 to indicate whether
g1
spatially intersects
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.
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.
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.
Returns 1 or 0 to indicate whether
g1
is spatially within
g2
. This tests the opposite
relationship as Contains()
.
User Comments
people (including the author) have been known to have spent a lot of time 'working' with features that weren't working in the first place.
so read this sentence very, very carefully (taken from above):
"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."
"Those that are implemented return the same result as the corresponding MBR-based functions."
The lack of the real implementation to those functions can be for now worked around by passing the result of the query to an appropriate function.
For example, a "within" condition query results with the MBRWithin-function and must then be passed to a "true-Within-function" like those explained by Paul Bourke at http://local.wasp.uwa.edu.au/~pbourke/geometry/.
More specifically:
You have a query:
SELECT AsText(theGeom) AS myPolygon FROM spatialTable WHERE Within(GeomFromText('POINT(463937.596407 4531626.73719)'), theGeom);
You whill loop the MBRWithin-like function result to the specific php function myWithin($row[myPolygon ],"POINT(463937.596407 4531626.73719)") to verify if "really" it is Within.
And here you are:
/******************************************************************************
*
* Purpose: Inside/outside polygon test of a point
* by calculating the number of time an horizontal ray
emanating from a point to the rigth intersects the lines
segments making up the polygon (even=no, odd=yes)
* Author: Paul Bourke, php adaptation: Roger Boily
* return boolean
*
******************************************************************************/
function myWithin($myPolygon,$point) {
$counter = 0;
// get rid of unnecessary stuff
$myPolygon = str_replace("POLYGON","",$myPolygon);
$myPolygon = str_replace("(","",$myPolygon);
$myPolygon = str_replace(")","",$myPolygon);
$point = str_replace("POINT","",$point);
$point = str_replace("(","",$point);
$point = str_replace(")","",$point);
// make an array of points of the polygon
$polygon = explode(",",$myPolygon);
// get the x and y coordinate of the point
$p = explode(" ",$point);
$px = $p[0];
$py = $p[1];
// number of points in the polygon
$n = count($polygon);
$poly1 = $polygon[0];
for ($i=1; $i <= $n; $i++) {
$poly1XY = explode(" ",$poly1);
$poly1x = $poly1XY[0];
$poly1y = $poly1XY[1];
$poly2 = $polygon[$i % $n];
$poly2XY = explode(" ",$poly2);
$poly2x = $poly2XY[0];
$poly2y = $poly2XY[1];
if ($py > min($poly1y,$poly2y)) {
if ($py <= max($poly1y,$poly2y)) {
if ($px <= max($poly1x,$poly2x)) {
if ($poly1y != $poly2y) {
$xinters = ($py-$poly1y)*($poly2x-$poly1x)/($poly2y-$poly1y)+$poly1x;
if ($poly1x == $poly2x || $px <= $xinters) {
$counter++;
}
}
}
}
}
$poly1 = $poly2;
} // end of While each polygon
if ($counter % 2 == 0) {
return(false); // outside
} else {
return(true); // inside
}
}
*******************************
Roger Boily, Gis Consulant [boily at bsw dot org ]
*******************************
Some of the functions mentioned above have now been implemented using non-MBR geometry - take a look at http://forge.mysql.com/wiki/GIS_Functions for more details.
Add your own comment.