diff options
| author | Daniel Wiesmann <daniel.wiesmann@gmail.com> | 2016-04-21 17:03:14 +0100 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2016-05-06 09:17:18 -0400 |
| commit | bbfad84dd980a97174c3b061a3d1b5f1373c380d (patch) | |
| tree | 29bf6823cec3f141ab72cdd6034d70c6aa32f9d3 /docs/ref | |
| parent | 03efa304bce5ef0924948a74ae01cdf817dd416a (diff) | |
Fixed #25588 -- Added spatial lookups to RasterField.
Thanks Tim Graham for the review.
Diffstat (limited to 'docs/ref')
| -rw-r--r-- | docs/ref/contrib/gis/db-api.txt | 165 | ||||
| -rw-r--r-- | docs/ref/contrib/gis/geoquerysets.txt | 132 |
2 files changed, 216 insertions, 81 deletions
diff --git a/docs/ref/contrib/gis/db-api.txt b/docs/ref/contrib/gis/db-api.txt index ef26f8f75e..4403fff392 100644 --- a/docs/ref/contrib/gis/db-api.txt +++ b/docs/ref/contrib/gis/db-api.txt @@ -53,7 +53,12 @@ Raster Support -------------- ``RasterField`` is currently only implemented for the PostGIS backend. Spatial -queries (such as lookups and distance) are not yet available for raster fields. +lookups are available for raster fields, but spatial database functions and +aggregates aren't implemented for raster fields. + +.. versionchanged:: 1.10 + + ``RasterField`` now supports spatial lookups. Creating and Saving Models with Geometry Fields =============================================== @@ -136,11 +141,20 @@ Spatial Lookups GeoDjango's lookup types may be used with any manager method like ``filter()``, ``exclude()``, etc. However, the lookup types unique to -GeoDjango are only available on geometry fields. +GeoDjango are only available on spatial fields. + Filters on 'normal' fields (e.g. :class:`~django.db.models.CharField`) -may be chained with those on geographic fields. Thus, geographic queries -take the following general form (assuming the ``Zipcode`` model used in the -:doc:`model-api`):: +may be chained with those on geographic fields. Geographic lookups accept +geometry and raster input on both sides and input types can be mixed freely. + +The general structure of geographic lookups is described below. A complete +reference can be found in the :ref:`spatial lookup reference<spatial-lookups>`. + +Geometry Lookups +---------------- + +Geographic queries with geometries take the following general form (assuming +the ``Zipcode`` model used in the :doc:`model-api`):: >>> qs = Zipcode.objects.filter(<field>__<lookup_type>=<parameter>) >>> qs = Zipcode.objects.exclude(...) @@ -148,14 +162,60 @@ take the following general form (assuming the ``Zipcode`` model used in the For example:: >>> qs = Zipcode.objects.filter(poly__contains=pnt) + >>> qs = Elevation.objects.filter(poly__contains=rst) In this case, ``poly`` is the geographic field, :lookup:`contains <gis-contains>` -is the spatial lookup type, and ``pnt`` is the parameter (which may be a +is the spatial lookup type, ``pnt`` is the parameter (which may be a :class:`~django.contrib.gis.geos.GEOSGeometry` object or a string of -GeoJSON , WKT, or HEXEWKB). +GeoJSON , WKT, or HEXEWKB), and ``rst`` is a +:class:`~django.contrib.gis.gdal.GDALRaster` object. + +.. _spatial-lookup-raster: + +Raster Lookups +-------------- + +.. versionadded:: 1.10 -A complete reference can be found in the :ref:`spatial lookup reference -<spatial-lookups>`. +The raster lookup syntax is similar to the syntax for geometries. The only +difference is that a band index can specified as additional input. If no band +index is specified, the first band is used by default (index ``0``). In that +case the syntax is identical to the syntax for geometry lookups. + +To specify the band index, an additional parameter can be specified on both +sides of the lookup. On the left hand side, the double underscore syntax is +used to pass a band index. On the right hand side, a tuple of the raster and +band index can be specified. + +This results in the following general form for lookups involving rasters +(assuming the ``Elevation`` model used in the :doc:`model-api`):: + + >>> qs = Elevation.objects.filter(<field>__<lookup_type>=<parameter>) + >>> qs = Elevation.objects.filter(<field>__<band_index>__<lookup_type>=<parameter>) + >>> qs = Elevation.objects.filter(<field>__<lookup_type>=(<raster_input, <band_index>) + +Fore example:: + + >>> qs = Elevation.objects.filter(rast__contains=geom) + >>> qs = Elevation.objects.filter(rast__contains=rst) + >>> qs = Elevation.objects.filter(rast__1__contains=geom) + >>> qs = Elevation.objects.filter(rast__contains=(rst, 1)) + >>> qs = Elevation.objects.filter(rast__1__contains=(rst, 1)) + +On the left hand side of the example, ``rast`` is the geographic raster field +and :lookup:`contains <gis-contains>` is the spatial lookup type. On the right +hand side, ``geom`` is a geometry input and ``rst`` is a +:class:`~django.contrib.gis.gdal.GDALRaster` object. The band index defaults to +``0`` in the first two queries and is set to ``1`` on the others. + +While all spatial lookups can be used with raster objects on both sides, not all +underlying operators natively accept raster input. For cases where the operator +expects geometry input, the raster is automatically converted to a geometry. +It's important to keep this in mind when interpreting the lookup results. + +The type of raster support is listed for all lookups in the :ref:`compatibility +table <spatial-lookup-compatibility>`. Lookups involving rasters are currently +only available for the PostGIS backend. .. _distance-queries: @@ -176,7 +236,7 @@ in the :doc:`model-api` documentation for more details. Distance Lookups ---------------- -*Availability*: PostGIS, Oracle, SpatiaLite +*Availability*: PostGIS, Oracle, SpatiaLite, PGRaster (Native) The following distance lookups are available: @@ -193,7 +253,7 @@ The following distance lookups are available: Distance lookups take a tuple parameter comprising: -#. A geometry to base calculations from; and +#. A geometry or raster to base calculations from; and #. A number or :class:`~django.contrib.gis.measure.Distance` object containing the distance. If a :class:`~django.contrib.gis.measure.Distance` object is used, @@ -241,6 +301,16 @@ Then distance queries may be performed as follows:: >>> qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(mi=20))) >>> qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(chain=100))) +Raster queries work the same way by simply replacing the geometry field +``point`` with a raster field, or the ``pnt`` object with a raster object, or +both. To specify the band index of a raster input on the right hand side, a +3-tuple can be passed to the lookup as follows:: + + >>> qs = SouthTexasCity.objects.filter(point__distance_gte=(rst, 2, D(km=7))) + +Where the band with index 2 (the third band) of the raster ``rst`` would be +used for the lookup. + __ https://github.com/django/django/blob/master/tests/gis_tests/distapp/models.py .. _compatibility-table: @@ -254,43 +324,46 @@ Spatial Lookups --------------- The following table provides a summary of what spatial lookups are available -for each spatial database backend. +for each spatial database backend. The PostGIS Raster (PGRaster) lookups are +divided into the three categories described in the :ref:`raster lookup details +<spatial-lookup-raster>`: native support ``N``, bilateral native support ``B``, +and geometry conversion support ``C``. -================================= ========= ======== ============ ========== -Lookup Type PostGIS Oracle MySQL [#]_ SpatiaLite -================================= ========= ======== ============ ========== -:lookup:`bbcontains` X X X -:lookup:`bboverlaps` X X X -:lookup:`contained` X X X -:lookup:`contains <gis-contains>` X X X X -:lookup:`contains_properly` X -:lookup:`coveredby` X X -:lookup:`covers` X X -:lookup:`crosses` X X -:lookup:`disjoint` X X X X -:lookup:`distance_gt` X X X -:lookup:`distance_gte` X X X -:lookup:`distance_lt` X X X -:lookup:`distance_lte` X X X -:lookup:`dwithin` X X -:lookup:`equals` X X X X -:lookup:`exact` X X X X -:lookup:`intersects` X X X X +================================= ========= ======== ============ ========== ======== +Lookup Type PostGIS Oracle MySQL [#]_ SpatiaLite PGRaster +================================= ========= ======== ============ ========== ======== +:lookup:`bbcontains` X X X N +:lookup:`bboverlaps` X X X N +:lookup:`contained` X X X N +:lookup:`contains <gis-contains>` X X X X B +:lookup:`contains_properly` X B +:lookup:`coveredby` X X B +:lookup:`covers` X X B +:lookup:`crosses` X X C +:lookup:`disjoint` X X X X B +:lookup:`distance_gt` X X X N +:lookup:`distance_gte` X X X N +:lookup:`distance_lt` X X X N +:lookup:`distance_lte` X X X N +:lookup:`dwithin` X X B +:lookup:`equals` X X X X C +:lookup:`exact` X X X X B +:lookup:`intersects` X X X X B :lookup:`isvalid` X -:lookup:`overlaps` X X X X -:lookup:`relate` X X X -:lookup:`same_as` X X X X -:lookup:`touches` X X X X -:lookup:`within` X X X X -:lookup:`left` X -:lookup:`right` X -:lookup:`overlaps_left` X -:lookup:`overlaps_right` X -:lookup:`overlaps_above` X -:lookup:`overlaps_below` X -:lookup:`strictly_above` X -:lookup:`strictly_below` X -================================= ========= ======== ============ ========== +:lookup:`overlaps` X X X X B +:lookup:`relate` X X X C +:lookup:`same_as` X X X X B +:lookup:`touches` X X X X B +:lookup:`within` X X X X B +:lookup:`left` X C +:lookup:`right` X C +:lookup:`overlaps_left` X B +:lookup:`overlaps_right` X B +:lookup:`overlaps_above` X C +:lookup:`overlaps_below` X C +:lookup:`strictly_above` X C +:lookup:`strictly_below` X C +================================= ========= ======== ============ ========== ======== .. _database-functions-compatibility: diff --git a/docs/ref/contrib/gis/geoquerysets.txt b/docs/ref/contrib/gis/geoquerysets.txt index 6b12c07a57..1c9d13df85 100644 --- a/docs/ref/contrib/gis/geoquerysets.txt +++ b/docs/ref/contrib/gis/geoquerysets.txt @@ -11,22 +11,70 @@ GeoQuerySet API Reference Spatial Lookups =============== -The spatial lookups in this section are available for :class:`GeometryField`. +The spatial lookups in this section are available for :class:`GeometryField` +and :class:`RasterField`. For an introduction, see the :ref:`spatial lookups introduction <spatial-lookups-intro>`. For an overview of what lookups are compatible with a particular spatial backend, refer to the :ref:`spatial lookup compatibility table <spatial-lookup-compatibility>`. +.. versionchanged:: 1.10 + + Spatial lookups now support raster input. + +Lookups with rasters +-------------------- + +All examples in the reference below are given for geometry fields and inputs, +but the lookups can be used the same way with rasters on both sides. Whenever +a lookup doesn't support raster input, the input is automatically +converted to a geometry where necessary using the `ST_Polygon +<http://postgis.net/docs/RT_ST_Polygon.html>`_ function. See also the +:ref:`introduction to raster lookups <spatial-lookup-raster>`. + +The database operators used by the lookups can be divided into three categories: + +- Native raster support ``N``: the operator accepts rasters natively on both + sides of the lookup, and raster input can be mixed with geometry inputs. + +- Bilateral raster support ``B``: the operator supports rasters only if both + sides of the lookup receive raster inputs. Raster data is automatically + converted to geometries for mixed lookups. + +- Geometry conversion support ``C``. The lookup does not have native raster + support, all raster data is automatically converted to geometries. + +The examples below show the SQL equivalent for the lookups in the different +types of raster support. The same pattern applies to all spatial lookups. + +==== ============================== ======================================================= +Case Lookup SQL Equivalent +==== ============================== ======================================================= +N, B ``rast__contains=rst`` ``ST_Contains(rast, rst)`` +N, B ``rast__1__contains=(rst, 2)`` ``ST_Contains(rast, 1, rst, 2)`` +B, C ``rast__contains=geom`` ``ST_Contains(ST_Polygon(rast), geom)`` +B, C ``rast__1__contains=geom`` ``ST_Contains(ST_Polygon(rast, 1), geom)`` +B, C ``poly__contains=rst`` ``ST_Contains(poly, ST_Polygon(rst))`` +B, C ``poly__contains=(rst, 1)`` ``ST_Contains(poly, ST_Polygon(rst, 1))`` +C ``rast__crosses=rst`` ``ST_Crosses(ST_Polygon(rast), ST_Polygon(rst))`` +C ``rast__1__crosses=(rst, 2)`` ``ST_Crosses(ST_Polygon(rast, 1), ST_Polygon(rst, 2))`` +C ``rast__crosses=geom`` ``ST_Crosses(ST_Polygon(rast), geom)`` +C ``poly__crosses=rst`` ``ST_Crosses(poly, ST_Polygon(rst))`` +==== ============================== ======================================================= + +Spatial lookups with rasters are only supported for PostGIS backends +(denominated as PGRaster in this section). + .. fieldlookup:: bbcontains ``bbcontains`` -------------- -*Availability*: PostGIS, MySQL, SpatiaLite +*Availability*: PostGIS, MySQL, SpatiaLite, PGRaster (Native) -Tests if the geometry field's bounding box completely contains the lookup -geometry's bounding box. +Tests if the geometry or raster field's bounding box completely contains the +lookup geometry's bounding box. Example:: @@ -45,7 +93,7 @@ SpatiaLite ``MbrContains(poly, geom)`` ``bboverlaps`` -------------- -*Availability*: PostGIS, MySQL, SpatiaLite +*Availability*: PostGIS, MySQL, SpatiaLite, PGRaster (Native) Tests if the geometry field's bounding box overlaps the lookup geometry's bounding box. @@ -67,7 +115,7 @@ SpatiaLite ``MbrOverlaps(poly, geom)`` ``contained`` ------------- -*Availability*: PostGIS, MySQL, SpatiaLite +*Availability*: PostGIS, MySQL, SpatiaLite, PGRaster (Native) Tests if the geometry field's bounding box is completely contained by the lookup geometry's bounding box. @@ -89,7 +137,7 @@ SpatiaLite ``MbrWithin(poly, geom)`` ``contains`` ------------ -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite +*Availability*: PostGIS, Oracle, MySQL, SpatiaLite, PGRaster (Bilateral) Tests if the geometry field spatially contains the lookup geometry. @@ -111,7 +159,7 @@ SpatiaLite ``Contains(poly, geom)`` ``contains_properly`` --------------------- -*Availability*: PostGIS +*Availability*: PostGIS, PGRaster (Bilateral) Returns true if the lookup geometry intersects the interior of the geometry field, but not the boundary (or exterior). [#fncontainsproperly]_ @@ -131,7 +179,7 @@ PostGIS ``ST_ContainsProperly(poly, geom)`` ``coveredby`` ------------- -*Availability*: PostGIS, Oracle +*Availability*: PostGIS, Oracle, PGRaster (Bilateral) Tests if no point in the geometry field is outside the lookup geometry. [#fncovers]_ @@ -152,7 +200,7 @@ Oracle ``SDO_COVEREDBY(poly, geom)`` ``covers`` ---------- -*Availability*: PostGIS, Oracle +*Availability*: PostGIS, Oracle, PGRaster (Bilateral) Tests if no point in the lookup geometry is outside the geometry field. [#fncovers]_ @@ -173,7 +221,7 @@ Oracle ``SDO_COVERS(poly, geom)`` ``crosses`` ----------- -*Availability*: PostGIS, SpatiaLite +*Availability*: PostGIS, SpatiaLite, PGRaster (Conversion) Tests if the geometry field spatially crosses the lookup geometry. @@ -193,7 +241,7 @@ SpatiaLite ``Crosses(poly, geom)`` ``disjoint`` ------------ -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite +*Availability*: PostGIS, Oracle, MySQL, SpatiaLite, PGRaster (Bilateral) Tests if the geometry field is spatially disjoint from the lookup geometry. @@ -215,7 +263,7 @@ SpatiaLite ``Disjoint(poly, geom)`` ``equals`` ---------- -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite +*Availability*: PostGIS, Oracle, MySQL, SpatiaLite, PGRaster (Conversion) .. fieldlookup:: exact .. fieldlookup:: same_as @@ -223,14 +271,14 @@ SpatiaLite ``Disjoint(poly, geom)`` ``exact``, ``same_as`` ---------------------- -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite +*Availability*: PostGIS, Oracle, MySQL, SpatiaLite, PGRaster (Bilateral) .. fieldlookup:: intersects ``intersects`` -------------- -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite +*Availability*: PostGIS, Oracle, MySQL, SpatiaLite, PGRaster (Bilateral) Tests if the geometry field spatially intersects the lookup geometry. @@ -271,14 +319,14 @@ PostGIS equivalent:: ``overlaps`` ------------ -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite +*Availability*: PostGIS, Oracle, MySQL, SpatiaLite, PGRaster (Bilateral) .. fieldlookup:: relate ``relate`` ---------- -*Availability*: PostGIS, Oracle, SpatiaLite +*Availability*: PostGIS, Oracle, SpatiaLite, PGRaster (Conversion) Tests if the geometry field is spatially related to the lookup geometry by the values given in the given pattern. This lookup requires a tuple parameter, @@ -293,7 +341,7 @@ 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. [#fnde9im]_ -Example:: +Geometry example:: # A tuple lookup parameter is used to specify the geometry and # the intersection pattern (the pattern here is for 'contains'). @@ -307,6 +355,16 @@ SpatiaLite SQL equivalent:: SELECT ... WHERE Relate(poly, geom, 'T*T***FF*') +Raster example:: + + Zipcode.objects.filter(poly__relate=(rast, 1, 'T*T***FF*')) + Zipcode.objects.filter(rast__2__relate=(rast, 1, 'T*T***FF*')) + +PostGIS SQL equivalent:: + + SELECT ... WHERE ST_Relate(poly, ST_Polygon(rast, 1), 'T*T***FF*') + SELECT ... WHERE ST_Relate(ST_Polygon(rast, 2), ST_Polygon(rast, 1), 'T*T***FF*') + Oracle ~~~~~~ @@ -352,7 +410,7 @@ SpatiaLite ``Touches(poly, geom)`` ``within`` ---------- -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite +*Availability*: PostGIS, Oracle, MySQL, SpatiaLite, PGRaster (Bilateral) Tests if the geometry field is spatially within the lookup geometry. @@ -374,7 +432,7 @@ SpatiaLite ``Within(poly, geom)`` ``left`` -------- -*Availability*: PostGIS +*Availability*: PostGIS, PGRaster (Conversion) Tests if the geometry field's bounding box is strictly to the left of the lookup geometry's bounding box. @@ -392,7 +450,7 @@ PostGIS equivalent:: ``right`` --------- -*Availability*: PostGIS +*Availability*: PostGIS, PGRaster (Conversion) Tests if the geometry field's bounding box is strictly to the right of the lookup geometry's bounding box. @@ -410,7 +468,7 @@ PostGIS equivalent:: ``overlaps_left`` ----------------- -*Availability*: PostGIS +*Availability*: PostGIS, PGRaster (Bilateral) Tests if the geometry field's bounding box overlaps or is to the left of the lookup geometry's bounding box. @@ -429,7 +487,7 @@ PostGIS equivalent:: ``overlaps_right`` ------------------ -*Availability*: PostGIS +*Availability*: PostGIS, PGRaster (Bilateral) Tests if the geometry field's bounding box overlaps or is to the right of the lookup geometry's bounding box. @@ -447,7 +505,7 @@ PostGIS equivalent:: ``overlaps_above`` ------------------ -*Availability*: PostGIS +*Availability*: PostGIS, PGRaster (Conversion) Tests if the geometry field's bounding box overlaps or is above the lookup geometry's bounding box. @@ -465,7 +523,7 @@ PostGIS equivalent:: ``overlaps_below`` ------------------ -*Availability*: PostGIS +*Availability*: PostGIS, PGRaster (Conversion) Tests if the geometry field's bounding box overlaps or is below the lookup geometry's bounding box. @@ -483,7 +541,7 @@ PostGIS equivalent:: ``strictly_above`` ------------------ -*Availability*: PostGIS +*Availability*: PostGIS, PGRaster (Conversion) Tests if the geometry field's bounding box is strictly above the lookup geometry's bounding box. @@ -501,7 +559,7 @@ PostGIS equivalent:: ``strictly_below`` ------------------ -*Availability*: PostGIS +*Availability*: PostGIS, PGRaster (Conversion) Tests if the geometry field's bounding box is strictly below the lookup geometry's bounding box. @@ -520,27 +578,31 @@ PostGIS equivalent:: Distance Lookups ================ -*Availability*: PostGIS, Oracle, SpatiaLite +*Availability*: PostGIS, Oracle, SpatiaLite, PGRaster (Native) For an overview on performing distance queries, please refer to the :ref:`distance queries introduction <distance-queries>`. Distance lookups take the following form:: - <field>__<distance lookup>=(<geometry>, <distance value>[, 'spheroid']) + <field>__<distance lookup>=(<geometry/raster>, <distance value>[, 'spheroid']) + <field>__<distance lookup>=(<raster>, <band_index>, <distance value>[, 'spheroid']) + <field>__<band_index>__<distance lookup>=(<raster>, <band_index>, <distance value>[, 'spheroid']) The value passed into a distance lookup is a tuple; the first two values are mandatory, and are the geometry to calculate distances to, and a distance value (either a number in units of the field, a :class:`~django.contrib.gis.measure.Distance` object, or a `query expression -<ref/models/expressions>`). +<ref/models/expressions>`). To pass a band index to the lookup, use a 3-tuple +where the second entry is the band index. With PostGIS, on every distance lookup but :lookup:`dwithin`, an optional -third element, ``'spheroid'``, may be included to tell GeoDjango -to use the more accurate spheroid distance calculation functions on -fields with a geodetic coordinate system (e.g., ``ST_Distance_Spheroid`` -would be used instead of ``ST_Distance_Sphere``). The simpler ``ST_Distance`` -function is used with projected coordinate systems. +element, ``'spheroid'``, may be included to tell GeoDjango to use the more +accurate spheroid distance calculation functions on fields with a geodetic +coordinate system (e.g., ``ST_Distance_Spheroid`` would be used instead of +``ST_Distance_Sphere``). The simpler ``ST_Distance`` function is used with +projected coordinate systems. Rasters are converted to geometries for spheroid +based lookups. .. versionadded:: 1.10 |
