123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- ===================
- GeoDjango Model API
- ===================
- .. module:: django.contrib.gis.db.models
- :synopsis: GeoDjango model and field API.
- This document explores the details of the GeoDjango Model API. Throughout this
- section, we'll be using the following geographic model of a `ZIP code`__ and
- of a `Digital Elevation Model`__ as our examples::
- from django.contrib.gis.db import models
- class Zipcode(models.Model):
- code = models.CharField(max_length=5)
- poly = models.PolygonField()
- class Elevation(models.Model):
- name = models.CharField(max_length=100)
- rast = models.RasterField()
- __ https://en.wikipedia.org/wiki/ZIP_code
- __ https://en.wikipedia.org/wiki/Digital_elevation_model
- Spatial Field Types
- ===================
- Spatial fields consist of a series of geometry field types and one raster field
- type. Each of the geometry field types correspond to the OpenGIS Simple
- Features specification [#fnogc]_. There is no such standard for raster data.
- ``GeometryField``
- -----------------
- .. class:: GeometryField
- ``PointField``
- --------------
- .. class:: PointField
- ``LineStringField``
- -------------------
- .. class:: LineStringField
- ``PolygonField``
- ----------------
- .. class:: PolygonField
- ``MultiPointField``
- -------------------
- .. class:: MultiPointField
- ``MultiLineStringField``
- ------------------------
- .. class:: MultiLineStringField
- ``MultiPolygonField``
- ---------------------
- .. class:: MultiPolygonField
- ``GeometryCollectionField``
- ---------------------------
- .. class:: GeometryCollectionField
- ``RasterField``
- ---------------
- .. versionadded:: 1.9
- .. class:: RasterField
- ``RasterField`` is currently only implemented for the PostGIS backend.
- Spatial Field Options
- =====================
- .. versionchanged:: 1.9
- The geometry field options ``srid`` and ``spatial_index`` are now shared by
- ``GeometryField`` and ``RasterField`` through the ``BaseSpatialField``.
- In addition to the regular :ref:`common-model-field-options` available for
- Django model fields, spatial fields have the following additional options.
- All are optional.
- ``srid``
- --------
- .. attribute:: BaseSpatialField.srid
- Sets the SRID [#fnogcsrid]_ (Spatial Reference System Identity) of the geometry field to
- the given value. Defaults to 4326 (also known as `WGS84`__, units are in degrees
- of longitude and latitude).
- __ https://en.wikipedia.org/wiki/WGS84
- .. _selecting-an-srid:
- Selecting an SRID
- ^^^^^^^^^^^^^^^^^
- Choosing an appropriate SRID for your model is an important decision that the
- developer should consider carefully. The SRID is an integer specifier that
- corresponds to the projection system that will be used to interpret the data
- in the spatial database. [#fnsrid]_ Projection systems give the context to the
- coordinates that specify a location. Although the details of `geodesy`__ are
- beyond the scope of this documentation, the general problem is that the earth
- is spherical and representations of the earth (e.g., paper maps, Web maps)
- are not.
- Most people are familiar with using latitude and longitude to reference a
- location on the earth's surface. However, latitude and longitude are angles,
- not distances. In other words, while the shortest path between two points on
- a flat surface is a straight line, the shortest path between two points on a curved
- surface (such as the earth) is an *arc* of a `great circle`__. [#fnthematic]_ Thus,
- additional computation is required to obtain distances in planar units (e.g.,
- kilometers and miles). Using a geographic coordinate system may introduce
- complications for the developer later on. For example, Spatialite does not have
- the capability to perform distance calculations between geometries using
- geographic coordinate systems, e.g. constructing a query to find all points
- within 5 miles of a county boundary stored as WGS84.
- [#fndist]_
- Portions of the earth's surface may projected onto a two-dimensional, or
- Cartesian, plane. Projected coordinate systems are especially convenient
- for region-specific applications, e.g., if you know that your database will
- only cover geometries in `North Kansas`__, then you may consider using projection
- system specific to that region. Moreover, projected coordinate systems are
- defined in Cartesian units (such as meters or feet), easing distance
- calculations.
- .. note::
- If you wish to perform arbitrary distance queries using non-point
- geometries in WGS84 in PostGIS and you want decent performance, enable the
- :attr:`GeometryField.geography` keyword so that :ref:`geography database
- type <geography-type>` is used instead.
- Additional Resources:
- * `spatialreference.org`__: A Django-powered database of spatial reference
- systems.
- * `The State Plane Coordinate System`__: A Web site covering the various
- projection systems used in the United States. Much of the U.S. spatial
- data encountered will be in one of these coordinate systems rather than
- in a geographic coordinate system such as WGS84.
- __ https://en.wikipedia.org/wiki/Geodesy
- __ https://en.wikipedia.org/wiki/Great_circle
- __ http://www.spatialreference.org/ref/epsg/2796/
- __ http://spatialreference.org/
- __ http://web.archive.org/web/20080302095452/http://welcome.warnercnr.colostate.edu/class_info/nr502/lg3/datums_coordinates/spcs.html
- ``spatial_index``
- -----------------
- .. attribute:: BaseSpatialField.spatial_index
- Defaults to ``True``. Creates a spatial index for the given geometry
- field.
- .. note::
- This is different from the ``db_index`` field option because spatial
- indexes are created in a different manner than regular database
- indexes. Specifically, spatial indexes are typically created using
- a variant of the R-Tree, while regular database indexes typically
- use B-Trees.
- .. _geometry-field-options:
- Geometry Field Options
- ======================
- There are additional options available for Geometry fields. All the following
- options are optional.
- ``dim``
- -------
- .. attribute:: GeometryField.dim
- This option may be used for customizing the coordinate dimension of the
- geometry field. By default, it is set to 2, for representing two-dimensional
- geometries. For spatial backends that support it, it may be set to 3 for
- three-dimensional support.
- .. note::
- At this time 3D support is limited to the PostGIS spatial backend.
- ``geography``
- -------------
- .. attribute:: GeometryField.geography
- If set to ``True``, this option will create a database column of
- type geography, rather than geometry. Please refer to the
- :ref:`geography type <geography-type>` section below for more
- details.
- .. note::
- Geography support is limited to PostGIS and will force the SRID to be 4326.
- .. _geography-type:
- Geography Type
- ^^^^^^^^^^^^^^
- The geography type provides native support for spatial features represented
- with geographic coordinates (e.g., WGS84 longitude/latitude). [#fngeography]_
- Unlike the plane used by a geometry type, the geography type uses a spherical
- representation of its data. Distance and measurement operations
- performed on a geography column automatically employ great circle arc
- calculations and return linear units. In other words, when ``ST_Distance``
- is called on two geographies, a value in meters is returned (as opposed
- to degrees if called on a geometry column in WGS84).
- Because geography calculations involve more mathematics, only a subset of the
- PostGIS spatial lookups are available for the geography type. Practically,
- this means that in addition to the :ref:`distance lookups <distance-lookups>`
- only the following additional :ref:`spatial lookups <spatial-lookups>` are
- available for geography columns:
- * :lookup:`bboverlaps`
- * :lookup:`coveredby`
- * :lookup:`covers`
- * :lookup:`intersects`
- For more information, the PostGIS documentation contains a helpful section on
- determining `when to use geography data type over geometry data type
- <http://postgis.net/docs/manual-2.1/using_postgis_dbmanagement.html#PostGIS_GeographyVSGeometry>`_.
- ``GeoManager``
- ==============
- .. currentmodule:: django.contrib.gis.db.models
- .. class:: GeoManager
- The ``GeoManager`` is required in order to use the legacy
- :ref:`geoqueryset-methods`.
- .. deprecated:: 1.9
- All ``GeoQuerySet`` methods have been deprecated and replaced by
- :doc:`equivalent database functions </ref/contrib/gis/functions>`. As soon
- as the legacy methods have been replaced in your code, you should be able
- to remove the special ``GeoManager`` from your GIS-enabled classes.
- .. versionchanged:: 1.9
- In older versions, the manager was required to conduct geographic queries.
- Without it, all geographic filters failed.
- ``GeoManager`` was required even if the model did not have a geographic
- field itself, e.g., in the case of a ``ForeignKey`` relation to a model
- with a geographic field. For example, if we had an ``Address`` model with
- a ``ForeignKey`` to our ``Zipcode`` model::
- from django.contrib.gis.db import models
- class Address(models.Model):
- num = models.IntegerField()
- street = models.CharField(max_length=100)
- city = models.CharField(max_length=100)
- state = models.CharField(max_length=2)
- zipcode = models.ForeignKey(Zipcode, on_delete=models.CASCADE)
- objects = models.GeoManager()
- The geographic manager was needed to do spatial queries on related
- ``Zipcode`` objects, for example::
- qs = Address.objects.filter(zipcode__poly__contains='POINT(-104.590948 38.319914)')
- .. rubric:: Footnotes
- .. [#fnogc] OpenGIS Consortium, Inc., `Simple Feature Specification For SQL <http://www.opengeospatial.org/standards/sfs>`_.
- .. [#fnogcsrid] *See id.* at Ch. 2.3.8, p. 39 (Geometry Values and Spatial Reference Systems).
- .. [#fnsrid] Typically, SRID integer corresponds to an EPSG (`European Petroleum Survey Group <http://www.epsg.org>`_) identifier. However, it may also be associated with custom projections defined in spatial database's spatial reference systems table.
- .. [#fnthematic] Terry A. Slocum, Robert B. McMaster, Fritz C. Kessler, & Hugh H. Howard, *Thematic Cartography and Geographic Visualization* (Prentice Hall, 2nd edition), at Ch. 7.1.3.
- .. [#fndist] This limitation does not apply to PostGIS.
- .. [#fngeography] Please refer to the `PostGIS Geography Type <http://postgis.net/docs/manual-2.1/using_postgis_dbmanagement.html#PostGIS_Geography>`_ documentation for more details.
|