GeoDjango’s lookup types can only be used on geographic fields with filter(). Filters on ‘normal’ fields (e.g. CharField) may be chained with those on geographic fields. Thus, geographic queries take the following form (assuming the Zipcode model used in the GeoDjango Model API):
>>> qs = Zipcode.objects.filter(<field>__<lookup_type>=<parameter>)
>>> qs = Zipcode.objects.exclude(...)
For example:
>>> qs = Zipcode.objects.filter(poly__contains=pnt)
In this case, poly is the geographic field, contains is the lookup type, and pnt is the parameter (which may be a GEOSGeometry object or a string of GeoJSON , WKT, or HEXEWKB).
Note: GeoDjango constructs spatial SQL with the GeoQuerySet, a subclass of Django’s QuerySet returned by the GeoManager instance attached to the model.
Here is an example of how to create a geometry object (assuming the Zipcode model):
>>> from zipcode.models import Zipcode
>>> z = Zipcode(code=77096, poly='POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))')
>>> z.save()
GEOSGeometry objects may also be used to save geometric models:
>>> from django.contrib.gis.geos import GEOSGeometry
>>> z = Zipcode(code=77096, poly=GEOSGeometry('POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))'))
>>> z.save()
Moreover, if the GEOSGeometry is in a different coordinate system (has a different SRID value) than that of the field, then it will be implicitly transformed into the SRID of the model’s field, using the spatial database’s transform procedure:
>>> poly_3084 = GEOSGeometry('POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))', srid=3084) # SRID 3084 is 'NAD83(HARN) / Texas Centric Lambert Conformal'
>>> z = Zipcode(code=78212, poly=poly_3084)
>>> z.save()
>>> from django.db import connection
>>> print connection.queries[-1]['sql'] # printing the last SQL statement executed (requires DEBUG=True)
INSERT INTO "geoapp_zipcode" ("code", "poly") VALUES (78212, ST_Transform(ST_GeomFromWKB('\\001 ... ', 3084), 4326))
Thus, geometry parameters may be passed in using the GEOSGeometry object, WKT (Well Known Text [1]), HEXEWKB (PostGIS specific – a WKB geometry in hexadecimal [2]), and GeoJSON [3] (requires GDAL). Essentially, if the input is not a GEOSGeometry object, the geometry field will attempt to create a GEOSGeometry instance from the input.
Below are some examples of GEOS Geometry objects, WKT, and HEXEWKB, and GeoJSON:
GEOS Geometry:
>>> from django.contrib.gis.geos import *
>>> pnt = Point(5, 23)
>>> ls = LineString((0, 0), (5, 23))
>>> poly = GEOSGeometry('POLYGON (( 10 10, 10 20, 20 20, 20 15, 10 10))')
WKT Polygon: 'POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))'
HEXEWKB Polygon : '0103000000010000000 ... 00000000000002440'
GeoJSON Point: { "type": "Point", "coordinates": [100.0, 0.0] }
The following lookup types correspond to PostGIS spatial operators. [4]
Tests if the geometry field’s bounding box completely contains the lookup geometry’s bounding box.
Example:
Zipcode.objects.filter(poly__bbcontains=geom)
PostGIS equivalent:
SELECT ... WHERE poly ~ geom
Tests if the geometry field’s bounding box overlaps the lookup geometry’s bounding box.
Example:
Zipcode.objects.filter(poly__bboverlaps=geom)
PostGIS equivalent:
SELECT ... WHERE poly && geom
Tests if the geometry field’s bounding box is completely contained by the lookup geometry’s bounding box.
Example:
Zipcode.objects.filter(poly__contained=geom)
PostGIS equivalent:
SELECT ... WHERE poly @ geom
Tests actual geometric equality of the geometry field against the the given lookup geometry, vertex-by-vertex.
The following examples are equivalent:
Zipcode.objects.filter(poly__exact=geom)
Zipcode.objects.filter(poly=geom)
Zipcode.objects.filter(poly__same_as=geom)
PostGIS equivalent:
SELECT ... WHERE poly ~= geom
Tests if the geometry field’s bounding box is strictly to the left of the lookup geometry’s bounding box.
Example:
Zipcode.objects.filter(poly__left=geom)
PostGIS equivalent:
SELECT ... WHERE poly << geom
Tests if the geometry field’s bounding box is strictly to the right of the lookup geometry’s bounding box.
Example:
Zipcode.objects.filter(poly__right=geom)
PostGIS equivalent:
SELECT ... WHERE poly >> geom
Tests if the geometry field’s bounding box overlaps or is to the left of the lookup geometry’s bounding box.
Example:
Zipcode.objects.filter(poly__overlaps_left=geom)
PostGIS equivalent:
SELECT ... WHERE poly &< geom
Tests if the geometry field’s bounding box overlaps or is to the right of the lookup geometry’s bounding box.
Example:
Zipcode.objects.filter(poly__overlaps_right=geom)
PostGIS equivalent:
SELECT ... WHERE poly &> geom
Tests if the geometry field’s bounding box overlaps or is above the lookup geometry’s bounding box.
Example:
Zipcode.objects.filter(poly__overlaps_above=geom)
PostGIS equivalent:
SELECT ... WHERE poly |&> geom
Tests if the geometry field’s bounding box overlaps or is below the lookup geometry’s bounding box.
Example:
Zipcode.objects.filter(poly__overlaps_below=geom)
PostGIS equivalent:
SELECT ... WHERE poly &<| geom
Tests if the geometry field’s bounding box is strictly above the lookup geometry’s bounding box.
Example:
Zipcode.objects.filter(poly__strictly_above=geom)
PostGIS equivalent:
SELECT ... WHERE poly |>> geom
Tests if the geometry field’s bounding box is strictly below the lookup geometry’s bounding box.
Example:
Zipcode.objects.filter(poly__strictly_below=geom)
PostGIS equivalent:
SELECT ... WHERE poly <<| geom
The following lookup types correspond to PostGIS geometry relationship functions. [5] Please note that when using PostGIS 1.3.1 and above, index support is automatically “inlined” – in other words, the bounding box equivalent is automatically evaluated prior to calling these, more computationally expensive, functions.
Tests if the geometry field spatially contains the lookup geometry.
Example:
Zipcode.objects.filter(poly__contains=geom)
PostGIS equivalent:
SELECT ... WHERE ST_Contains(poly, geom)
Tests if no point in the geometry field is outside the lookup geometry. [6] Only available in PostGIS 1.3.1 and above.
Example:
Zipcode.objects.filter(poly__coveredby=geom)
PostGIS equivalent:
SELECT ... WHERE ST_CoveredBy(poly, geom)
Tests if no point in the lookup geometry is outside the geometry field. [7] Only available in PostGIS 1.3.1 and above.
Example:
Zipcode.objects.filter(poly__coversy=geom)
PostGIS equivalent:
SELECT ... WHERE ST_Covers(poly, geom)
Tests if the geometry field spatially crosses the lookup geometry.
Example:
Zipcode.objects.filter(poly__crosses=geom)
PostGIS equivalent:
SELECT ... WHERE ST_Crosses(poly, geom)
Tests if the geometry field is spatially disjoint from the lookup geometry.
Example:
Zipcode.objects.filter(poly__disjoint=geom)
PostGIS equivalent:
SELECT ... WHERE ST_Disjoint(poly, geom)
Tests if the geometry field is within the specified distance of the lookup geometry; uses indexes if available. The lookup parameter is a two-element tuple: (geom, distance), where distance is a Distance object or a numeric value in units. Only available in PostGIS versions 1.3.1 and above.
Distance Parameters and Geographic Coordinate Systems
The dwithin lookup is meant for projected coordinate systems because PostGIS uses ST_Distance, which calculates the cartesian distance between geometries. In other words, this will not return accurate results for geographic coordinate systems such as WGS84. Thus, an exception will be raised if a Distance object is used on a geometry field in a geographic coordinate system.
However, a numeric value is allowed for geometry fields in geographic coordinate systems. This advanced usage allows users to limit querysets by distance more efficiently using units of degrees.
Example:
# If Zipcode uses a projected coordinate system, this is allowed.
Zipcode.objects.filter(poly__dwithin=(geom, D(mi=5)))
# If Zipcode uses a geographic coordinate system, then the
# distance unit must be a numeric value in units of degrees.
Zipcode.objects.filter(poly__dwithin=(geom, 0.5))
PostGIS equivalent:
SELECT ... WHERE ST_DWithin(poly, geom, <units value>)
Tests if the geometry field is spatially equal to the lookup geometry.
Example:
Zipcode.objects.filter(poly__equals=geom)
PostGIS equivalent:
SELECT ... WHERE ST_Equals(poly, geom)
Tests if the geometry field spatially intersects the lookup geometry.
Example:
Zipcode.objects.filter(poly__intersects=geom)
PostGIS equivalent:
SELECT ... WHERE ST_Intersects(poly, geom)
Tests if the geometry field spatially overlaps the lookup geometry.
Example:
Zipcode.objects.filter(poly__overlaps=geom)
PostGIS equivalent:
SELECT ... WHERE ST_Overlaps(poly, geom)
Tests if the geometry field is spatially related to the the lookup geometry by the values given in the intersection pattern matrix. The intersection pattern matrix is a string comprising nine characters, which define intersections between the interior, boundary, and exterior of the geometry field and the lookup geometry. The intersection pattern matrix may only use the following characters: 1, 2, T, F, or *. This lookup type allows users to “fine tune” a specific geometric relationship consistent with the DE-9IM model. [8]
Example:
# A tuple lookup parameter is used to specify the geometry and
# the intersection pattern (the pattern here is for 'contains').
Zipcode.objects.filter(poly__relate(geom, 'T*T***FF*'))
PostGIS equivalent:
SELECT ... WHERE ST_Relate(poly, geom, 'T*T***FF*')
Tests if the geometry field spatially touches the lookup geometry.
Example:
Zipcode.objects.filter(poly__touches=geom)
PostGIS equivalent:
SELECT ... WHERE ST_Touches(poly, geom)
Tests if the geometry field is spatially within the lookup geometry.
Example:
Zipcode.objects.filter(poly__within=geom)
PostGIS equivalent:
SELECT ... WHERE ST_Within(poly, geom)
For more information, see Oracle’s Spatial Operators documentation. [9]
Tests if the geometry field spatially contains the lookup geometry.
Example:
Zipcode.objects.filter(poly__contains=geom)
Oracle equivalent:
SELECT ... WHERE SDO_CONTAINS(poly, geom)
Tests if no point in the lookup geometry is outside the geometry field.
Oracle equivalent:
SELECT ... WHERE SDO_COVERS(poly, geom)
Tests if no point in the geometry field is outside the lookup geometry.
Oracle equivalent:
SELECT ... WHERE SDO_COVEREDBY(poly, geom)
Tests if the geometry field is spatially disjoint from the lookup geometry.
Oracle equivalent:
SELECT ... WHERE SDO_GEOM.RELATE(poly, 'DISJOINT', geom, 0.05)
Tests if the geometry field is within the specified distance of the lookup geometry; uses indexes if available. The lookup parameter is a two-element tuple: (geom, distance), where distance is a Distance object or a numeric value in units.
Oracle equivalent:
SELECT ... WHERE SDO_WITHIN_DISTANCE(poly, geom, 'distance=distance')
Tests if the geometry field is spatially equal to the lookup geometry. The following examples are equivalent on Oracle:
Zipcode.objects.filter(poly=geom)
Zipcode.objects.filter(poly__exact=geom)
Zipcode.objects.filter(poly__equals=geom)
Zipcode.objects.filter(poly__same_as=geom)
Oracle equivalent:
SELECT ... WHERE SDO_EQUALS(poly, geom)
Tests if the geometry field spatially intersects the lookup geometry.
Oracle equivalent:
SELECT ... WHERE SDO_OVERLAPBDYINTERSECT(poly, geom)
Tests if the geometry field spatially overlaps the lookup geometry.
Oracle equivalent:
SELECT ... WHERE SDO_OVERLAPS(poly, geom)
Tests if the geometry field is spatially related to the the lookup geometry by the given mask component. This lookup requires a tuple parameter, (geom, mask), where mask is at least one of the nine-intersection patterns: TOUCH, OVERLAPBDYDISJOINT, OVERLAPBDYINTERSECT, EQUAL, INSIDE, COVEREDBY, CONTAINS, COVERS, ANYINTERACT, and ON. Multiple masks may be combined with the logical Boolean operator OR, for example, 'inside+touch'. [10] The mask relation strings are case-insensitive.
Example:
# A tuple lookup parameter is used to specify the geometry and
# the mask component.
Zipcode.objects.filter(poly__relate(geom, 'anyinteract'))
Oracle equivalent:
SELECT ... WHERE SDO_RELATE(poly, geom, 'anyinteract')
Tests if the geometry field spatially touches the lookup geometry.
Oracle equivalent:
SELECT ... WHERE SDO_TOUCH(poly, geom)
Tests if the geometry field is spatially within (inside) the lookup geometry.
Oracle equivalent:
SELECT ... WHERE SDO_INSIDE(poly, geom)
For more information, see Relations on Geometry Minimal Bounding Rectangles (MBRs). [11]
Distance calculations with spatial data is tricky because, unfortunately, the Earth is not flat. Some distance queries with fields in a geographic coordinate system may have to be expressed differently because of limitations in PostGIS. Please see the Selecting an SRID section in the model API documentation for more details.
Availability: PostGIS, Oracle
Distance lookups take a tuple parameter comprising:
If a Distance [12] object is used, it may be expressed in any units (the SQL generated will use units converted to those of the field); otherwise, numeric parameters will be assumed to be in the units of the field.
Note: For PostGIS users, the routine ST_distance_sphere is used by default for calculating distances on geographic coordinate systems – which may only be called with point geometries [13]. Thus, geographic distance lookups on PostGIS are only allowed on PointField model fields using points for the geographic parameter.
The following distance lookups are available:
In addition, there’s the distance(geom) GeoQuerySet method.
For example, let’s say we have a SouthTexasCity model (from the GeoDjango distance tests ) on a projected coordinate system valid for cities in southern Texas:
from django.contrib.gis.db import models
class SouthTexasCity(models.Model):
name = models.CharField(max_length=30)
# A projected coordinate system (only valid for South Texas!)
# is used, units are in meters.
point = models.PointField(srid=32140)
objects = models.GeoManager()
Then distance queries may be performed as follows:
>>> from django.contrib.gis.geos import *
>>> from django.contrib.gis.measure import D # ``D`` is a shortcut for ``Distance``
>>> from geoapp import SouthTexasCity
# Distances will be calculated from this point, which does not have to be projected.
>>> pnt = fromstr('POINT(-96.876369 29.905320)', srid=4326)
# If numeric parameter, units of field (meters in this case) are assumed.
>>> qs = SouthTexasCity.objects.filter(point__distance_lte=(pnt, 7000))
# Find all Cities within 7 km, > 20 miles away, and > 100 chains away (an obscure unit)
>>> qs = SouthTexasCity.objects.filter(point__distance_lte=(pnt, D(km=7)))
>>> qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(mi=20)))
>>> qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(chain=100)))
GeoQuerySet methods perform a spatial operation on each geographic field in the queryset and store its output in a new attribute on the model (which is generally the name of the GeoQuerySet method).
There are also aggregate GeoQuerySet methods which return a single value instead of a queryset. This section will describe the API and availablity of every GeoQuerySet method available in GeoDjango.
With a few exceptions, the following keyword arguments may be used with all GeoQuerySet methods:
| Keyword Argument | Description |
|---|---|
| field_name | By default, GeoQuerySet methods use the first geographic field encountered in the model. This keyword should be used to specify another geographic field (e.g., field_name='point2') when there are multiple geographic fields in a model. On PostGIS, the field_name keyword may also be used on geometry fields in models that are related via a ForeignKey relation (e.g., field_name='related__point'). |
| model_att | By default, GeoQuerySet methods typically attach their output in an attribute with the same name as the GeoQuerySet method. Setting this keyword with the desired attribute name will override this default behavior. For example, qs = Zipcode.objects.centroid(model_att='c') will attach the centroid of the Zipcode geometry field in a c attribute on every model rather than in a centroid attribute. This keyword is required if a method name clashes with an existing GeoQuerySet method – if you wanted to use the area() method on model with a PolygonField named area, for example. |
Availability: PostGIS
Returns the extent of the GeoQuerySet as a four-tuple, comprising the lower left coordinate and the upper right coordinate.
Example:
>>> qs = City.objects.filter(name__in=('Houston', 'Dallas'))
>>> print qs.extent()
(-96.8016128540039, 29.7633724212646, -95.3631439208984, 32.782058715820)
Availability: PostGIS
Returns a LineString constructed from the point field geometries in the GeoQuerySet. Currently, ordering the queryset has no effect.
Example:
>>> print City.objects.filter(name__in=('Houston', 'Dallas')).make_line()
LINESTRING (-95.3631510000000020 29.7633739999999989, -96.8016109999999941 32.7820570000000018)
Availability: PostGIS, Oracle
This method returns a GEOSGeometry object comprising the union of every geometry in the queryset. Please note that use of union is processor intensive and may take a significant amount of time on large querysets.
Example:
>>> u = Zipcode.objects.union() # This may take a long time.
>>> u = Zipcode.objects.filter(poly__within=bbox).union() # A more sensible approach.
| Keyword Argument | Description |
|---|---|
| tolerance | This keyword is for Oracle only. It is for the tolerance value used by the SDOAGGRTYPE procedure; the Oracle documentation has more details. |
Availability: PostGIS, Oracle
This method takes a geometry as a parameter, and attaches a distance attribute to every model in the returned queryset that contains the distance (as a Distance object) to the given geometry.
In the following example (taken from the GeoDjango distance tests), the distance from the Tasmanian city of Hobart to every other PointField in the AustraliaCity queryset is calculated:
>>> pnt = AustraliaCity.objects.get(name='Hobart').point
>>> for city in AustraliaCity.objects.distance(pnt): print city.name, city.distance
Wollongong 990071.220408 m
Shellharbour 972804.613941 m
Thirroul 1002334.36351 m
Mittagong 975691.632637 m
Batemans Bay 834342.185561 m
Canberra 598140.268959 m
Melbourne 575337.765042 m
Sydney 1056978.87363 m
Hobart 0.0 m
Adelaide 1162031.83522 m
Hillsdale 1049200.46122 m
Note
Because the distance attribute is a Distance object, you can easily express the value in the units of your choice. For example, city.distance.mi is the distance value in miles and city.distance.km is the distance value in kilometers. See the distance documentation for usage details and the list of supported units.
Returns the length of the geometry field in a length attribute (a Distance object) on each model in the queryset.
Returns the perimeter of the geometry field in a perimeter attribute (a Distance object) on each model in the queryset.
With the exception of transform, all of the following attach geometry objects to each element of the GeoQuerySet that is the result of the method.
Availability: PostGIS, Oracle
Availability: PostGIS
Availability: PostGIS, Oracle
Returns a Point geometry guaranteed to lie on the surface of the Geometry field in a point_on_surface attribute on each element of this GeoQuerySet; otherwise sets with None.
Availability: PostGIS
Availability: PostGIS
Availability: PostGIS, Oracle
The transform method transforms the geometries in a model to the spatial reference system specified by the srid parameter. If no srid is given, then 4326 (WGS84) is used by default.
Note
What spatial reference system an integer SRID corresponds to may depend on the spatial database used. In other words, the SRID numbers used for Oracle are not necessarily the same as those used by PostGIS.
Example:
>>> qs = Zipcode.objects.all().transform() # Transforms to WGS84
>>> qs = Zipcode.objects.all().transform(32140) # Transforming to "NAD83 / Texas South Central"
>>> print qs[0].poly.srid
32140
>>> print qs[0].poly
POLYGON ((234055.1698884720099159 4937796.9232223574072123 ...
Availability: PostGIS, Oracle
The following methods all take a geometry as a parameter and attach a geometry to each element of the GeoQuerySet that is the result of the operation.
The following GeoQuerySet methods will return an attribute that has the value of the geometry field in each model converted to the requested output format.
Availability: PostGIS, Oracle
Attaches a gml attribute to every model in the queryset that contains the Geographic Markup Language (GML) representation of the geometry.
Example:
>>> qs = Zipcode.objects.all().gml()
>>> print qs[0].gml
<gml:Polygon srsName="EPSG:4326"><gml:OuterBoundaryIs>-147.78711,70.245363 ... -147.78711,70.245363</gml:OuterBoundaryIs></gml:Polygon>
| Keyword Argument | Description |
|---|---|
| precision | This keyword is for PostGIS only. It may be used to specify the number of significant digits for the coordinates in the GML representation – the default value is 8. |
| version | This keyword is for PostGIS only. It may be used to specify the GML version used, and may only be values of 2 or 3. The default value is 2. |
Availability: PostGIS
Attaches a kml attribute to every model in the queryset that contains the Keyhole Markup Language (KML) representation of the geometry fields. It should be noted that the contents of the KML are transformed to WGS84 if necessary.
Example:
>>> qs = Zipcode.objects.all().kml()
>>> print qs[0].kml
<Polygon><outerBoundaryIs><LinearRing><coordinates>-103.04135,36.217596,0 ... -103.04135,36.217596,0</coordinates></LinearRing></outerBoundaryIs></Polygon>
| Keyword Argument | Description |
|---|---|
| precision | This keyword may be used to specify the number of significant digits for the coordinates in the KML representation – the default value is 8. |
Availability: PostGIS
Attaches a svg attribute to every model in the queryset that contains the Scalable Vector Graphics (SVG) path data of the geometry fields.
| Keyword Argument | Description |
|---|---|
| relative | If set to True, the path data will be implemented in terms of relative moves. Defaults to False, meaning that absolute moves are used instead. |
| precision | This keyword may be used to specify the number of significant digits for the coordinates in the SVG representation – the default value is 8. |
The following table provides a summary of what lookup types are available on each spatial backend.
| Lookup Type | PostGIS | Oracle | MySQL [14] |
|---|---|---|---|
| bbcontains | X | X | |
| bboverlaps | X | X | |
| contains | X | X | X |
| contained | X | X | |
| coveredby | X | X | |
| covers | X | X | |
| crosses | X | ||
| disjoint | X | X | X |
| distance_gt | X | X | |
| distance_gte | X | X | |
| distance_lt | X | X | |
| distance_lte | X | X | |
| dwithin | X | X | |
| equals | X | X | X |
| exact | X | X | X |
| intersects | X | X | X |
| overlaps | X | X | X |
| relate | X | X | |
| same_as | X | X | X |
| touches | X | X | X |
| within | X | X | X |
| left | X | ||
| right | X | ||
| overlaps_left | X | ||
| overlaps_right | X | ||
| overlaps_above | X | ||
| overlaps_below | X | ||
| strictly_above | X | ||
| strictly_below | X |
The following table provides a summary of what GeoQuerySet methods are availble on each spatial backend. Please note that MySQL does not support any of these methods, and is thus excluded from the table.
| Method | PostGIS | Oracle |
|---|---|---|
| area | X | X |
| centroid | X | X |
| difference | X | X |
| distance | X | X |
| envelope | X | |
| extent | X | |
| gml | X | X |
| intersection | X | X |
| kml | X | |
| length | X | X |
| make_line | X | |
| mem_size | X | |
| num_geom | X | X |
| num_points | X | X |
| perimeter | X | X |
| point_on_surface | X | X |
| scale | X | |
| svg | X | |
| sym_difference | X | X |
| transform | X | X |
| translate | X | |
| union | X | X |
| unionagg | X | X |
Footnotes
| [1] | See Open GIS Consortium, Inc., OpenGIS Simple Feature Specification For SQL, Document 99-049 (May 5, 1999), at Ch. 3.2.5, p. 3-11 (SQL Textual Representation of Geometry). |
| [2] | See PostGIS EWKB, EWKT and Canonical Forms, PostGIS documentation at Ch. 4.1.2. |
| [3] | See Howard Butler, Martin Daly, Allan Doyle, Tim Schaub, & Christopher Schmidt, The GeoJSON Format Specification, Revision 1.0 (June 16, 2008). |
| [4] | See generally, Operators, PostGIS Documentation at Ch. 6.2.2. |
| [5] | See generally, Geometry Relationship Functions PostGIS Dcumentation at Ch. 6.1.2. |
| [6] | For an explanation of this routine, see this entry at the blog of Martin Davis (a PostGIS developer). |
| [7] | See id. |
| [8] | See OpenGIS Simple Feature Specification For SQL, at Ch. 2.1.13.2, p. 2-13 (The Dimensionally Extended Nine-Intersection Model). |
| [9] | Oracle Spatial User’s Guide and Manual, at Ch. 11. |
| [10] | See id. at SDO_RELATE documenation. |
| [11] | MySQL 5.0 Reference Manual, at Ch. 17.5.5. |
| [12] | See ST_distance_sphere in Measurement Functions, PostGIS documentation at Ch. 6.2.3. |
| [13] | See the distance documentation for more information on the Distance object. |
| [14] | MySQL only supports bounding box operations (known as minimum bounding rectangles, or MBR, in MySQL). Thus, spatial lookups such as contains are really equivalent to bbcontains. |