2010-03-27 04:14:53 +08:00
===================
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
2015-06-19 23:46:03 +08:00
section, we'll be using the following geographic model of a `ZIP code`__ and
of a `Digital Elevation Model`__ as our examples::
2010-03-27 04:14:53 +08:00
from django.contrib.gis.db import models
2010-08-20 03:27:44 +08:00
2010-03-27 04:14:53 +08:00
class Zipcode(models.Model):
code = models.CharField(max_length=5)
poly = models.PolygonField()
2015-06-19 23:46:03 +08:00
class Elevation(models.Model):
name = models.CharField(max_length=100)
rast = models.RasterField()
2015-08-08 18:02:32 +08:00
__ https://en.wikipedia.org/wiki/ZIP_code
2015-06-19 23:46:03 +08:00
__ https://en.wikipedia.org/wiki/Digital_elevation_model
2010-03-27 04:14:53 +08:00
2015-06-19 23:46:03 +08:00
Spatial Field Types
===================
2010-03-27 04:14:53 +08:00
2015-06-19 23:46:03 +08:00
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.
2010-03-27 04:14:53 +08:00
``GeometryField``
-----------------
.. class:: GeometryField
``PointField``
--------------
.. class:: PointField
``LineStringField``
-------------------
.. class:: LineStringField
``PolygonField``
----------------
.. class:: PolygonField
``MultiPointField``
-------------------
.. class:: MultiPointField
``MultiLineStringField``
------------------------
.. class:: MultiLineStringField
``MultiPolygonField``
---------------------
.. class:: MultiPolygonField
``GeometryCollectionField``
---------------------------
.. class:: GeometryCollectionField
2015-06-19 23:46:03 +08:00
``RasterField``
---------------
2010-03-27 04:14:53 +08:00
2015-06-19 23:46:03 +08:00
.. 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``.
2010-03-27 04:14:53 +08:00
In addition to the regular :ref:`common-model-field-options` available for
2015-06-19 23:46:03 +08:00
Django model fields, spatial fields have the following additional options.
2010-03-27 04:14:53 +08:00
All are optional.
``srid``
--------
2015-06-19 23:46:03 +08:00
.. attribute:: BaseSpatialField.srid
2010-03-27 04:14:53 +08:00
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).
2015-08-08 18:02:32 +08:00
__ https://en.wikipedia.org/wiki/WGS84
2010-03-27 04:14:53 +08:00
.. _selecting-an-srid:
Selecting an SRID
^^^^^^^^^^^^^^^^^
Choosing an appropriate SRID for your model is an important decision that the
2010-08-20 03:27:44 +08:00
developer should consider carefully. The SRID is an integer specifier that
2010-03-27 04:14:53 +08:00
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
2010-10-09 16:12:50 +08:00
is spherical and representations of the earth (e.g., paper maps, Web maps)
2010-03-27 04:14:53 +08:00
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,
2015-08-08 19:56:37 +08:00
not distances. In other words, while the shortest path between two points on
2010-03-27 04:14:53 +08:00
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,
2010-08-20 03:27:44 +08:00
additional computation is required to obtain distances in planar units (e.g.,
2010-03-27 04:14:53 +08:00
kilometers and miles). Using a geographic coordinate system may introduce
2014-11-13 21:38:19 +08:00
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.
2010-03-31 07:15:43 +08:00
[#fndist]_
2010-03-27 04:14:53 +08:00
2010-08-20 03:27:44 +08:00
Portions of the earth's surface may projected onto a two-dimensional, or
2010-03-27 04:14:53 +08:00
Cartesian, plane. Projected coordinate systems are especially convenient
for region-specific applications, e.g., if you know that your database will
2010-08-20 03:27:44 +08:00
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
2010-03-27 04:14:53 +08:00
calculations.
.. note::
2014-02-23 01:30:28 +08:00
If you wish to perform arbitrary distance queries using non-point
2014-11-13 21:38:19 +08:00
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.
2010-03-27 04:14:53 +08:00
Additional Resources:
2010-08-20 03:27:44 +08:00
* `spatialreference.org`__: A Django-powered database of spatial reference
2010-03-27 04:14:53 +08:00
systems.
2015-11-15 20:05:15 +08:00
* `The State Plane Coordinate System`__: A website covering the various
2010-03-27 04:14:53 +08:00
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.
2015-08-08 18:02:32 +08:00
__ https://en.wikipedia.org/wiki/Geodesy
__ https://en.wikipedia.org/wiki/Great_circle
2010-03-27 04:14:53 +08:00
__ http://www.spatialreference.org/ref/epsg/2796/
__ http://spatialreference.org/
2015-11-30 00:29:46 +08:00
__ https://web.archive.org/web/20080302095452/http://welcome.warnercnr.colostate.edu/class_info/nr502/lg3/datums_coordinates/spcs.html
2010-03-27 04:14:53 +08:00
``spatial_index``
-----------------
2015-06-19 23:46:03 +08:00
.. attribute:: BaseSpatialField.spatial_index
2010-03-27 04:14:53 +08:00
Defaults to ``True``. Creates a spatial index for the given geometry
2010-08-20 03:27:44 +08:00
field.
2010-03-27 04:14:53 +08:00
.. 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.
2015-06-19 23:46:03 +08:00
.. _geometry-field-options:
Geometry Field Options
======================
There are additional options available for Geometry fields. All the following
options are optional.
2010-03-27 04:14:53 +08:00
``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
2014-02-15 18:36:53 +08:00
three-dimensional support.
2010-03-27 04:14:53 +08:00
.. note::
2013-12-24 22:57:13 +08:00
At this time 3D support is limited to the PostGIS spatial backend.
2010-03-27 04:14:53 +08:00
``geography``
-------------
.. attribute:: GeometryField.geography
2010-03-31 07:15:43 +08:00
If set to ``True``, this option will create a database column of
2010-08-20 03:27:44 +08:00
type geography, rather than geometry. Please refer to the
2010-03-27 04:14:53 +08:00
:ref:`geography type <geography-type>` section below for more
details.
.. note::
2015-03-18 06:34:15 +08:00
Geography support is limited to PostGIS and will force the SRID to be 4326.
2010-03-27 04:14:53 +08:00
.. _geography-type:
Geography Type
^^^^^^^^^^^^^^
2015-03-18 06:34:15 +08:00
The geography type provides native support for spatial features represented
with geographic coordinates (e.g., WGS84 longitude/latitude). [#fngeography]_
2010-03-27 04:14:53 +08:00
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>`
2010-08-20 03:27:44 +08:00
only the following additional :ref:`spatial lookups <spatial-lookups>` are
2010-03-27 04:14:53 +08:00
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
2015-03-18 06:34:15 +08:00
<http://postgis.net/docs/manual-2.1/using_postgis_dbmanagement.html#PostGIS_GeographyVSGeometry>`_.
2010-03-27 04:14:53 +08:00
``GeoManager``
==============
.. currentmodule:: django.contrib.gis.db.models
.. class:: GeoManager
2015-05-09 01:52:15 +08:00
The ``GeoManager`` is required in order to use the legacy
:ref:`geoqueryset-methods`.
2015-06-19 23:46:03 +08:00
2015-05-09 01:52:15 +08:00
.. deprecated:: 1.9
2015-06-19 23:46:03 +08:00
2015-05-09 01:52:15 +08:00
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.
2015-06-19 23:46:03 +08:00
2015-05-09 01:52:15 +08:00
.. versionchanged:: 1.9
2010-03-27 04:14:53 +08:00
2015-05-09 01:52:15 +08:00
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
2010-03-27 04:14:53 +08:00
2015-05-09 01:52:15 +08:00
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()
2010-03-27 04:14:53 +08:00
2015-05-09 01:52:15 +08:00
The geographic manager was needed to do spatial queries on related
``Zipcode`` objects, for example::
2010-03-27 04:14:53 +08:00
2015-05-09 01:52:15 +08:00
qs = Address.objects.filter(zipcode__poly__contains='POINT(-104.590948 38.319914)')
2010-03-27 04:14:53 +08:00
.. rubric:: Footnotes
2012-06-28 16:49:07 +08:00
.. [#fnogc] OpenGIS Consortium, Inc., `Simple Feature Specification For SQL <http://www.opengeospatial.org/standards/sfs>`_.
2010-03-27 04:14:53 +08:00
.. [#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.
2015-03-18 06:34:15 +08:00
.. [#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.