1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

[4.2.x] Refs #34140 -- Applied rst code-block to non-Python examples.

Thanks to J.V. Zammit, Paolo Melchiorre, and Mariusz Felisiak for
reviews.

Backport of 534ac48297 from main.
This commit is contained in:
Carlton Gibson
2023-02-09 16:48:46 +01:00
committed by Mariusz Felisiak
parent 4a89aa25c9
commit b784768eef
120 changed files with 3998 additions and 1397 deletions

View File

@@ -37,13 +37,17 @@ Creating and Saving Models with Geometry Fields
===============================================
Here is an example of how to create a geometry object (assuming the ``Zipcode``
model)::
model):
.. code-block:: pycon
>>> from zipcode.models import Zipcode
>>> z = Zipcode(code=77096, poly='POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))')
>>> z.save()
:class:`~django.contrib.gis.geos.GEOSGeometry` objects may also be used to save geometric models::
:class:`~django.contrib.gis.geos.GEOSGeometry` objects may also be used to save geometric models:
.. code-block:: pycon
>>> from django.contrib.gis.geos import GEOSGeometry
>>> poly = GEOSGeometry('POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))')
@@ -53,7 +57,9 @@ model)::
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::
transform procedure:
.. code-block:: pycon
>>> 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)
@@ -82,14 +88,18 @@ The raster field will therefore accept any input that is accepted by the
:class:`~django.contrib.gis.gdal.GDALRaster` constructor.
Here is an example of how to create a raster object from a raster file
``volcano.tif`` (assuming the ``Elevation`` model)::
``volcano.tif`` (assuming the ``Elevation`` model):
.. code-block:: pycon
>>> from elevation.models import Elevation
>>> dem = Elevation(name='Volcano', rast='/path/to/raster/volcano.tif')
>>> dem.save()
:class:`~django.contrib.gis.gdal.GDALRaster` objects may also be used to save
raster models::
raster models:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import GDALRaster
>>> rast = GDALRaster({'width': 10, 'height': 10, 'name': 'Canyon', 'srid': 4326,
@@ -97,7 +107,9 @@ raster models::
>>> dem = Elevation(name='Canyon', rast=rast)
>>> dem.save()
Note that this equivalent to::
Note that this equivalent to:
.. code-block:: pycon
>>> dem = Elevation.objects.create(
... name='Canyon',
@@ -125,12 +137,16 @@ Geometry Lookups
----------------
Geographic queries with geometries take the following general form (assuming
the ``Zipcode`` model used in the :doc:`model-api`)::
the ``Zipcode`` model used in the :doc:`model-api`):
.. code-block:: pycon
>>> qs = Zipcode.objects.filter(<field>__<lookup_type>=<parameter>)
>>> qs = Zipcode.objects.exclude(...)
For example::
For example:
.. code-block:: pycon
>>> qs = Zipcode.objects.filter(poly__contains=pnt)
>>> qs = Elevation.objects.filter(poly__contains=rst)
@@ -157,13 +173,17 @@ 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`)::
(assuming the ``Elevation`` model used in the :doc:`model-api`):
.. code-block:: pycon
>>> 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>)
For example::
For example:
.. code-block:: pycon
>>> qs = Elevation.objects.filter(rast__contains=geom)
>>> qs = Elevation.objects.filter(rast__contains=rst)
@@ -256,7 +276,9 @@ For example, let's say we have a ``SouthTexasCity`` model (from the
# is used, units are in meters.
point = models.PointField(srid=32140)
Then distance queries may be performed as follows::
Then distance queries may be performed as follows:
.. code-block:: pycon
>>> from django.contrib.gis.geos import GEOSGeometry
>>> from django.contrib.gis.measure import D # ``D`` is a shortcut for ``Distance``
@@ -273,7 +295,9 @@ Then distance queries may be performed as follows::
Raster queries work the same way by 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::
passed to the lookup as follows:
.. code-block:: pycon
>>> qs = SouthTexasCity.objects.filter(point__distance_gte=(rst, 2, D(km=7)))

View File

@@ -8,7 +8,9 @@ Geographic Database Functions
The functions documented on this page allow users to access geographic database
functions to be used in annotations, aggregations, or filters in Django.
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.db.models.functions import Length
>>> Track.objects.annotate(length=Length('line')).filter(length__gt=100)
@@ -61,7 +63,9 @@ Accepts a single geographic field or expression and returns a `GeoJSON
is not a complete GeoJSON structure but only the ``geometry`` key content of a
GeoJSON structure. See also :doc:`/ref/contrib/gis/serializers`.
Example::
Example:
.. code-block:: pycon
>>> City.objects.annotate(json=AsGeoJSON('point')).get(name='Chicago').json
{"type":"Point","coordinates":[-87.65018,41.85039]}
@@ -94,7 +98,9 @@ SpatiaLite
Accepts a single geographic field or expression and returns a `Geographic Markup
Language (GML)`__ representation of the geometry.
Example::
Example:
.. code-block:: pycon
>>> qs = Zipcode.objects.annotate(gml=AsGML('poly'))
>>> print(qs[0].gml)
@@ -123,7 +129,9 @@ __ https://en.wikipedia.org/wiki/Geography_Markup_Language
Accepts a single geographic field or expression and returns a `Keyhole Markup
Language (KML)`__ representation of the geometry.
Example::
Example:
.. code-block:: pycon
>>> qs = Zipcode.objects.annotate(kml=AsKML('poly'))
>>> print(qs[0].kml)
@@ -176,7 +184,9 @@ Oracle, `PostGIS <https://postgis.net/docs/ST_AsBinary.html>`__, SpatiaLite
Accepts a single geographic field or expression and returns a `Well-known
binary (WKB)`_ representation of the geometry.
Example::
Example:
.. code-block:: pycon
>>> bytes(City.objects.annotate(wkb=AsWKB('point')).get(name='Chelyabinsk').wkb)
b'\x01\x01\x00\x00\x00]3\xf9f\x9b\x91K@\x00X\x1d9\xd2\xb9N@'
@@ -193,7 +203,9 @@ Oracle, `PostGIS <https://postgis.net/docs/ST_AsText.html>`__, SpatiaLite
Accepts a single geographic field or expression and returns a `Well-known text
(WKT)`_ representation of the geometry.
Example::
Example:
.. code-block:: pycon
>>> City.objects.annotate(wkt=AsWKT('point')).get(name='Chelyabinsk').wkt
'POINT (55.137555 61.451728)'
@@ -276,7 +288,9 @@ resource-intensive).
In the following example, the distance from the city of Hobart to every other
:class:`~django.contrib.gis.db.models.PointField` in the ``AustraliaCity``
queryset is calculated::
queryset is calculated:
.. code-block:: pycon
>>> from django.contrib.gis.db.models.functions import Distance
>>> pnt = AustraliaCity.objects.get(name='Hobart').point

View File

@@ -36,7 +36,9 @@ The GDAL/OGR tools described here are designed to help you read in
your geospatial data, in order for most of them to be useful you have
to have some data to work with. If you're starting out and don't yet
have any data of your own to use, GeoDjango tests contain a number of
data sets that you can use for testing. You can download them here::
data sets that you can use for testing. You can download them here:
.. code-block:: shell
$ wget https://raw.githubusercontent.com/django/django/main/tests/gis_tests/data/cities/cities.{shp,prj,shx,dbf}
$ wget https://raw.githubusercontent.com/django/django/main/tests/gis_tests/data/rasters/raster.tif
@@ -75,7 +77,9 @@ each feature in that layer.
Once you've created your ``DataSource``, you can find out how many layers
of data it contains by accessing the :attr:`layer_count` property, or
(equivalently) by using the ``len()`` function. For information on
accessing the layers of data themselves, see the next section::
accessing the layers of data themselves, see the next section:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import DataSource
>>> ds = DataSource('/path/to/your/cities.shp')
@@ -110,7 +114,9 @@ __ https://gdal.org/drivers/vector/
Typically, all the features in a given layer have the same geometry type.
The :attr:`geom_type` property of a layer is an :class:`OGRGeomType` that
identifies the feature type. We can use it to print out some basic
information about each layer in a :class:`DataSource`::
information about each layer in a :class:`DataSource`:
.. code-block:: pycon
>>> for layer in ds:
... print('Layer "%s": %i %ss' % (layer.name, len(layer), layer.geom_type.name))
@@ -120,7 +126,9 @@ __ https://gdal.org/drivers/vector/
The example output is from the cities data source, loaded above, which
evidently contains one layer, called ``"cities"``, which contains three
point features. For simplicity, the examples below assume that you've
stored that layer in the variable ``layer``::
stored that layer in the variable ``layer``:
.. code-block:: pycon
>>> layer = ds[0]
@@ -128,19 +136,25 @@ __ https://gdal.org/drivers/vector/
Returns the name of this layer in the data source.
.. code-block:: pycon
>>> layer.name
'cities'
.. attribute:: num_feat
Returns the number of features in the layer. Same as ``len(layer)``::
Returns the number of features in the layer. Same as ``len(layer)``:
.. code-block:: pycon
>>> layer.num_feat
3
.. attribute:: geom_type
Returns the geometry type of the layer, as an :class:`OGRGeomType` object::
Returns the geometry type of the layer, as an :class:`OGRGeomType` object:
.. code-block:: pycon
>>> layer.geom_type.name
'Point'
@@ -148,14 +162,18 @@ __ https://gdal.org/drivers/vector/
.. attribute:: num_fields
Returns the number of fields in the layer, i.e the number of fields of
data associated with each feature in the layer::
data associated with each feature in the layer:
.. code-block:: pycon
>>> layer.num_fields
4
.. attribute:: fields
Returns a list of the names of each of the fields in this layer::
Returns a list of the names of each of the fields in this layer:
.. code-block:: pycon
>>> layer.fields
['Name', 'Population', 'Density', 'Created']
@@ -163,7 +181,9 @@ __ https://gdal.org/drivers/vector/
.. attribute field_types
Returns a list of the data types of each of the fields in this layer. These
are subclasses of ``Field``, discussed below::
are subclasses of ``Field``, discussed below:
.. code-block:: pycon
>>> [ft.__name__ for ft in layer.field_types]
['OFTString', 'OFTReal', 'OFTReal', 'OFTDate']
@@ -171,7 +191,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: field_widths
Returns a list of the maximum field widths for each of the fields in this
layer::
layer:
.. code-block:: pycon
>>> layer.field_widths
[80, 11, 24, 10]
@@ -179,14 +201,18 @@ __ https://gdal.org/drivers/vector/
.. attribute:: field_precisions
Returns a list of the numeric precisions for each of the fields in this
layer. This is meaningless (and set to zero) for non-numeric fields::
layer. This is meaningless (and set to zero) for non-numeric fields:
.. code-block:: pycon
>>> layer.field_precisions
[0, 0, 15, 0]
.. attribute:: extent
Returns the spatial extent of this layer, as an :class:`Envelope` object::
Returns the spatial extent of this layer, as an :class:`Envelope` object:
.. code-block:: pycon
>>> layer.extent.tuple
(-104.609252, 29.763374, -95.23506, 38.971823)
@@ -194,7 +220,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: srs
Property that returns the :class:`SpatialReference` associated with this
layer::
layer:
.. code-block:: pycon
>>> print(layer.srs)
GEOGCS["GCS_WGS_1984",
@@ -212,7 +240,9 @@ __ https://gdal.org/drivers/vector/
layer. A spatial filter can only be set with an :class:`OGRGeometry`
instance, a 4-tuple extent, or ``None``. When set with something other than
``None``, only features that intersect the filter will be returned when
iterating over the layer::
iterating over the layer:
.. code-block:: pycon
>>> print(layer.spatial_filter)
None
@@ -233,7 +263,9 @@ __ https://gdal.org/drivers/vector/
.. method:: get_fields()
A method that returns a list of the values of a given field for each
feature in the layer::
feature in the layer:
.. code-block:: pycon
>>> layer.get_fields('Name')
['Pueblo', 'Lawrence', 'Houston']
@@ -243,7 +275,9 @@ __ https://gdal.org/drivers/vector/
A method that returns a list containing the geometry of each feature in the
layer. If the optional argument ``geos`` is set to ``True`` then the
geometries are converted to :class:`~django.contrib.gis.geos.GEOSGeometry`
objects. Otherwise, they are returned as :class:`OGRGeometry` objects::
objects. Otherwise, they are returned as :class:`OGRGeometry` objects:
.. code-block:: pycon
>>> [pt.tuple for pt in layer.get_geoms()]
[(-104.609252, 38.255001), (-95.23506, 38.971823), (-95.363151, 29.763374)]
@@ -273,7 +307,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: geom
Returns the geometry for this feature, as an ``OGRGeometry`` object::
Returns the geometry for this feature, as an ``OGRGeometry`` object:
.. code-block:: pycon
>>> city.geom.tuple
(-104.609252, 38.255001)
@@ -281,7 +317,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: get
A method that returns the value of the given field (specified by name)
for this feature, **not** a ``Field`` wrapper object::
for this feature, **not** a ``Field`` wrapper object:
.. code-block:: pycon
>>> city.get('Population')
102121
@@ -309,7 +347,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: fid
Returns the feature identifier within the layer::
Returns the feature identifier within the layer:
.. code-block:: pycon
>>> city.fid
0
@@ -317,7 +357,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: layer_name
Returns the name of the :class:`Layer` that the feature came from. This
will be the same for all features in a given layer::
will be the same for all features in a given layer:
.. code-block:: pycon
>>> city.layer_name
'cities'
@@ -325,7 +367,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: index
A method that returns the index of the given field name. This will be the
same for all features in a given layer::
same for all features in a given layer:
.. code-block:: pycon
>>> city.index('Population')
1
@@ -337,7 +381,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: name
Returns the name of this field::
Returns the name of this field:
.. code-block:: pycon
>>> city['Name'].name
'Name'
@@ -345,14 +391,18 @@ __ https://gdal.org/drivers/vector/
.. attribute:: type
Returns the OGR type of this field, as an integer. The ``FIELD_CLASSES``
dictionary maps these values onto subclasses of ``Field``::
dictionary maps these values onto subclasses of ``Field``:
.. code-block:: pycon
>>> city['Density'].type
2
.. attribute:: type_name
Returns a string with the name of the data type of this field::
Returns a string with the name of the data type of this field:
.. code-block:: pycon
>>> city['Name'].type_name
'String'
@@ -361,14 +411,18 @@ __ https://gdal.org/drivers/vector/
Returns the value of this field. The ``Field`` class itself returns the
value as a string, but each subclass returns the value in the most
appropriate form::
appropriate form:
.. code-block:: pycon
>>> city['Population'].value
102121
.. attribute:: width
Returns the width of this field::
Returns the width of this field:
.. code-block:: pycon
>>> city['Name'].width
80
@@ -376,35 +430,45 @@ __ https://gdal.org/drivers/vector/
.. attribute:: precision
Returns the numeric precision of this field. This is meaningless (and set
to zero) for non-numeric fields::
to zero) for non-numeric fields:
.. code-block:: pycon
>>> city['Density'].precision
15
.. method:: as_double()
Returns the value of the field as a double (float)::
Returns the value of the field as a double (float):
.. code-block:: pycon
>>> city['Density'].as_double()
874.7
.. method:: as_int()
Returns the value of the field as an integer::
Returns the value of the field as an integer:
.. code-block:: pycon
>>> city['Population'].as_int()
102121
.. method:: as_string()
Returns the value of the field as a string::
Returns the value of the field as a string:
.. code-block:: pycon
>>> city['Name'].as_string()
'Pueblo'
.. method:: as_datetime()
Returns the value of the field as a tuple of date and time components::
Returns the value of the field as a tuple of date and time components:
.. code-block:: pycon
>>> city['Created'].as_datetime()
(c_long(1999), c_long(5), c_long(23), c_long(0), c_long(0), c_long(0), c_long(0))
@@ -432,7 +496,9 @@ OGR Geometries
around OGR's internal geometry representation. Thus, they allow for more
efficient access to data when using :class:`DataSource`. Unlike its GEOS
counterpart, :class:`OGRGeometry` supports spatial reference systems and
coordinate transformation::
coordinate transformation:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import OGRGeometry
>>> polygon = OGRGeometry('POLYGON((0 0, 5 0, 5 5, 0 5))')
@@ -478,7 +544,9 @@ coordinate transformation::
.. attribute:: dimension
Returns the number of coordinated dimensions of the geometry, i.e. 0
for points, 1 for lines, and so forth::
for points, 1 for lines, and so forth:
.. code-block:: pycon
>> polygon.dimension
2
@@ -490,14 +558,18 @@ coordinate transformation::
.. attribute:: geom_count
Returns the number of elements in this geometry::
Returns the number of elements in this geometry:
.. code-block:: pycon
>>> polygon.geom_count
1
.. attribute:: point_count
Returns the number of points used to describe this geometry::
Returns the number of points used to describe this geometry:
.. code-block:: pycon
>>> polygon.point_count
4
@@ -516,7 +588,9 @@ coordinate transformation::
.. attribute:: geom_name
Returns the name of the type of this geometry::
Returns the name of the type of this geometry:
.. code-block:: pycon
>>> polygon.geom_name
'POLYGON'
@@ -524,7 +598,9 @@ coordinate transformation::
.. attribute:: area
Returns the area of this geometry, or 0 for geometries that do not contain
an area::
an area:
.. code-block:: pycon
>>> polygon.area
25.0
@@ -536,7 +612,9 @@ coordinate transformation::
.. attribute:: extent
Returns the envelope of this geometry as a 4-tuple, instead of as an
:class:`Envelope` object::
:class:`Envelope` object:
.. code-block:: pycon
>>> point.extent
(0.0, 0.0, 5.0, 5.0)
@@ -547,7 +625,9 @@ coordinate transformation::
``None`` if no spatial reference system has been assigned to it.
If assigned, accessing this property returns a :class:`SpatialReference`
object. It may be set with another :class:`SpatialReference` object,
or any input that :class:`SpatialReference` accepts. Example::
or any input that :class:`SpatialReference` accepts. Example:
.. code-block:: pycon
>>> city.geom.srs.name
'GCS_WGS_1984'
@@ -566,21 +646,27 @@ coordinate transformation::
.. attribute:: gml
Returns a string representation of this geometry in GML format::
Returns a string representation of this geometry in GML format:
.. code-block:: pycon
>>> OGRGeometry('POINT(1 2)').gml
'<gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point>'
.. attribute:: hex
Returns a string representation of this geometry in HEX WKB format::
Returns a string representation of this geometry in HEX WKB format:
.. code-block:: pycon
>>> OGRGeometry('POINT(1 2)').hex
'0101000000000000000000F03F0000000000000040'
.. attribute:: json
Returns a string representation of this geometry in JSON format::
Returns a string representation of this geometry in JSON format:
.. code-block:: pycon
>>> OGRGeometry('POINT(1 2)').json
'{ "type": "Point", "coordinates": [ 1.000000, 2.000000 ] }'
@@ -592,7 +678,9 @@ coordinate transformation::
.. attribute:: wkb_size
Returns the size of the WKB buffer needed to hold a WKB representation
of this geometry::
of this geometry:
.. code-block:: pycon
>>> OGRGeometry('POINT(1 2)').wkb_size
21
@@ -616,7 +704,9 @@ coordinate transformation::
.. method:: close_rings()
If there are any rings within this geometry that have not been closed,
this routine will do so by adding the starting point to the end::
this routine will do so by adding the starting point to the end:
.. code-block:: pycon
>>> triangle = OGRGeometry('LINEARRING (0 0,0 1,1 0)')
>>> triangle.close_rings()
@@ -706,7 +796,9 @@ coordinate transformation::
.. attribute:: tuple
Returns the coordinates of a point geometry as a tuple, the
coordinates of a line geometry as a tuple of tuples, and so forth::
coordinates of a line geometry as a tuple of tuples, and so forth:
.. code-block:: pycon
>>> OGRGeometry('POINT (1 2)').tuple
(1.0, 2.0)
@@ -721,14 +813,18 @@ coordinate transformation::
.. attribute:: x
Returns the X coordinate of this point::
Returns the X coordinate of this point:
.. code-block:: pycon
>>> OGRGeometry('POINT (1 2)').x
1.0
.. attribute:: y
Returns the Y coordinate of this point::
Returns the Y coordinate of this point:
.. code-block:: pycon
>>> OGRGeometry('POINT (1 2)').y
2.0
@@ -736,7 +832,9 @@ coordinate transformation::
.. attribute:: z
Returns the Z coordinate of this point, or ``None`` if the point does not
have a Z coordinate::
have a Z coordinate:
.. code-block:: pycon
>>> OGRGeometry('POINT (1 2 3)').z
3.0
@@ -745,14 +843,18 @@ coordinate transformation::
.. attribute:: x
Returns a list of X coordinates in this line::
Returns a list of X coordinates in this line:
.. code-block:: pycon
>>> OGRGeometry('LINESTRING (1 2,3 4)').x
[1.0, 3.0]
.. attribute:: y
Returns a list of Y coordinates in this line::
Returns a list of Y coordinates in this line:
.. code-block:: pycon
>>> OGRGeometry('LINESTRING (1 2,3 4)').y
[2.0, 4.0]
@@ -760,7 +862,9 @@ coordinate transformation::
.. attribute:: z
Returns a list of Z coordinates in this line, or ``None`` if the line does
not have Z coordinates::
not have Z coordinates:
.. code-block:: pycon
>>> OGRGeometry('LINESTRING (1 2 3,4 5 6)').z
[3.0, 6.0]
@@ -794,7 +898,9 @@ coordinate transformation::
.. class:: OGRGeomType(type_input)
This class allows for the representation of an OGR geometry type
in any of several ways::
in any of several ways:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import OGRGeomType
>>> gt1 = OGRGeomType(3) # Using an integer for the type
@@ -805,14 +911,18 @@ coordinate transformation::
.. attribute:: name
Returns a short-hand string form of the OGR Geometry type::
Returns a short-hand string form of the OGR Geometry type:
.. code-block:: pycon
>>> gt1.name
'Polygon'
.. attribute:: num
Returns the number corresponding to the OGR geometry type::
Returns the number corresponding to the OGR geometry type:
.. code-block:: pycon
>>> gt1.num
3
@@ -820,7 +930,9 @@ coordinate transformation::
.. attribute:: django
Returns the Django field type (a subclass of GeometryField) to use for
storing this OGR type, or ``None`` if there is no appropriate Django type::
storing this OGR type, or ``None`` if there is no appropriate Django type:
.. code-block:: pycon
>>> gt1.django
'PolygonField'
@@ -885,7 +997,9 @@ Coordinate System Objects
* A shorthand string for well-known standards (``'WGS84'``, ``'WGS72'``,
``'NAD27'``, ``'NAD83'``)
Example::
Example:
.. code-block:: pycon
>>> wgs84 = SpatialReference('WGS84') # shorthand string
>>> wgs84 = SpatialReference(4326) # EPSG code
@@ -907,7 +1021,9 @@ Coordinate System Objects
Returns the value of the given string attribute node, ``None`` if the node
doesn't exist. Can also take a tuple as a parameter, (target, child), where
child is the index of the attribute in the WKT. For example::
child is the index of the attribute in the WKT. For example:
.. code-block:: pycon
>>> wkt = 'GEOGCS["WGS 84", DATUM["WGS_1984, ... AUTHORITY["EPSG","4326"]]')
>>> srs = SpatialReference(wkt) # could also use 'WGS84', or 4326
@@ -1068,7 +1184,9 @@ Coordinate System Objects
Represents a coordinate system transform. It is initialized with two
:class:`SpatialReference`, representing the source and target coordinate
systems, respectively. These objects should be used when performing the same
coordinate transformation repeatedly on different geometries::
coordinate transformation repeatedly on different geometries:
.. code-block:: pycon
>>> ct = CoordTransform(SpatialReference('WGS84'), SpatialReference('NAD83'))
>>> for feat in layer:
@@ -1721,7 +1839,9 @@ Key Default Usage
The following example uses some of the options available for the
`GTiff driver`__. The result is a compressed signed byte raster with an
internal tiling scheme. The internal tiles have a block size of 23 by 23::
internal tiling scheme. The internal tiles have a block size of 23 by 23:
.. code-block:: pycon
>>> GDALRaster({
... 'driver': 'GTiff',
@@ -1787,7 +1907,9 @@ from a remote storage or returned from a view without being written to disk.
``/vsimem/``.
Input provided as ``bytes`` has to be a full binary representation of a file.
For instance::
For instance:
.. code-block:: pycon
# Read a raster as a file object from a remote source.
>>> from urllib.request import urlopen
@@ -1807,7 +1929,9 @@ dictionary representation and provide a ``name`` argument that starts with
of the raster.
Here's how to create a raster and return it as a file in an
:class:`~django.http.HttpResponse`::
:class:`~django.http.HttpResponse`:
.. code-block:: pycon
>>> from django.http import HttpResponse
>>> rst = GDALRaster({
@@ -1838,7 +1962,9 @@ Compressed rasters
Instead decompressing the file and instantiating the resulting raster, GDAL can
directly access compressed files using the ``/vsizip/``, ``/vsigzip/``, or
``/vsitar/`` virtual filesystems::
``/vsitar/`` virtual filesystems:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import GDALRaster
>>> rst = GDALRaster('/vsizip/path/to/your/file.zip/path/to/raster.tif')
@@ -1852,7 +1978,9 @@ GDAL can support online resources and storage providers transparently. As long
as it's built with such capabilities.
To access a public raster file with no authentication, you can use
``/vsicurl/``::
``/vsicurl/``:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import GDALRaster
>>> rst = GDALRaster('/vsicurl/https://example.com/raster.tif')

View File

@@ -31,7 +31,9 @@ __ https://github.com/maxmind/libmaxminddb/
Example
=======
Here is an example of its usage::
Here is an example of its usage:
.. code-block:: pycon
>>> from django.contrib.gis.geoip2 import GeoIP2
>>> g = GeoIP2()

View File

@@ -856,7 +856,9 @@ Keyword Argument Description
__ https://docs.oracle.com/en/database/oracle/oracle-database/21/spatl/
spatial-concepts.html#GUID-CE10AB14-D5EA-43BA-A647-DAC9EEF41EE6
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.db.models import Extent, Union
>>> WorldBorder.objects.aggregate(Extent('mpoly'), Union('mpoly'))
@@ -886,7 +888,9 @@ Oracle, SpatiaLite
Returns the extent of all ``geo_field`` in the ``QuerySet`` as a four-tuple,
comprising the lower left coordinate and the upper right coordinate.
Example::
Example:
.. code-block:: pycon
>>> qs = City.objects.filter(name__in=('Houston', 'Dallas')).aggregate(Extent('poly'))
>>> print(qs['poly__extent'])
@@ -903,7 +907,9 @@ Returns the 3D extent of all ``geo_field`` in the ``QuerySet`` as a six-tuple,
comprising the lower left coordinate and upper right coordinate (each with x, y,
and z coordinates).
Example::
Example:
.. code-block:: pycon
>>> qs = City.objects.filter(name__in=('Houston', 'Dallas')).aggregate(Extent3D('poly'))
>>> print(qs['poly__extent3d'])
@@ -920,7 +926,9 @@ SpatiaLite
Returns a ``LineString`` constructed from the point field geometries in the
``QuerySet``. Currently, ordering the queryset has no effect.
Example::
Example:
.. code-block:: pycon
>>> qs = City.objects.filter(name__in=('Houston', 'Dallas')).aggregate(MakeLine('poly'))
>>> print(qs['poly__makeline'])
@@ -944,7 +952,9 @@ large querysets.
If the computation time for using this method is too expensive, consider
using :class:`Collect` instead.
Example::
Example:
.. code-block:: pycon
>>> u = Zipcode.objects.aggregate(Union(poly)) # This may take a long time.
>>> u = Zipcode.objects.filter(poly__within=bbox).aggregate(Union(poly)) # A more sensible approach.

View File

@@ -50,7 +50,9 @@ Creating a Geometry
:class:`GEOSGeometry` objects may be created in a few ways. The first is
to simply instantiate the object on some spatial input -- the following
are examples of creating the same geometry from WKT, HEX, WKB, and GeoJSON::
are examples of creating the same geometry from WKT, HEX, WKB, and GeoJSON:
.. code-block:: pycon
>>> from django.contrib.gis.geos import GEOSGeometry
>>> pnt = GEOSGeometry('POINT(5 23)') # WKT
@@ -60,12 +62,16 @@ are examples of creating the same geometry from WKT, HEX, WKB, and GeoJSON::
Another option is to use the constructor for the specific geometry type
that you wish to create. For example, a :class:`Point` object may be
created by passing in the X and Y coordinates into its constructor::
created by passing in the X and Y coordinates into its constructor:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point
>>> pnt = Point(5, 23)
All these constructors take the keyword argument ``srid``. For example::
All these constructors take the keyword argument ``srid``. For example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import GEOSGeometry, LineString, Point
>>> print(GEOSGeometry('POINT (0 0)', srid=4326))
@@ -76,7 +82,9 @@ All these constructors take the keyword argument ``srid``. For example::
SRID=32140;POINT (0 0)
Finally, there is the :func:`fromfile` factory method which returns a
:class:`GEOSGeometry` object from a file::
:class:`GEOSGeometry` object from a file:
.. code-block:: pycon
>>> from django.contrib.gis.geos import fromfile
>>> pnt = fromfile('/path/to/pnt.wkt')
@@ -97,14 +105,18 @@ Geometries are Pythonic
-----------------------
:class:`GEOSGeometry` objects are 'Pythonic', in other words components may
be accessed, modified, and iterated over using standard Python conventions.
For example, you can iterate over the coordinates in a :class:`Point`::
For example, you can iterate over the coordinates in a :class:`Point`:
.. code-block:: pycon
>>> pnt = Point(5, 23)
>>> [coord for coord in pnt]
[5.0, 23.0]
With any geometry object, the :attr:`GEOSGeometry.coords` property
may be used to get the geometry coordinates as a Python tuple::
may be used to get the geometry coordinates as a Python tuple:
.. code-block:: pycon
>>> pnt.coords
(5.0, 23.0)
@@ -112,7 +124,9 @@ may be used to get the geometry coordinates as a Python tuple::
You can get/set geometry components using standard Python indexing
techniques. However, what is returned depends on the geometry type
of the object. For example, indexing on a :class:`LineString`
returns a coordinate tuple::
returns a coordinate tuple:
.. code-block:: pycon
>>> from django.contrib.gis.geos import LineString
>>> line = LineString((0, 0), (0, 50), (50, 50), (50, 0), (0, 0))
@@ -122,7 +136,9 @@ returns a coordinate tuple::
(50.0, 0.0)
Whereas indexing on a :class:`Polygon` will return the ring
(a :class:`LinearRing` object) corresponding to the index::
(a :class:`LinearRing` object) corresponding to the index:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Polygon
>>> poly = Polygon( ((0.0, 0.0), (0.0, 50.0), (50.0, 50.0), (50.0, 0.0), (0.0, 0.0)) )
@@ -132,7 +148,9 @@ Whereas indexing on a :class:`Polygon` will return the ring
(50.0, 0.0)
In addition, coordinates/components of the geometry may added or modified,
just like a Python list::
just like a Python list:
.. code-block:: pycon
>>> line[0] = (1.0, 1.0)
>>> line.pop()
@@ -141,7 +159,9 @@ just like a Python list::
>>> line.coords
((1.0, 1.0), (0.0, 50.0), (50.0, 50.0), (50.0, 0.0), (1.0, 1.0))
Geometries support set-like operators::
Geometries support set-like operators:
.. code-block:: pycon
>>> from django.contrib.gis.geos import LineString
>>> ls1 = LineString((0, 0), (2, 2))
@@ -160,7 +180,9 @@ Geometries support set-like operators::
The :class:`~GEOSGeometry` equality operator uses
:meth:`~GEOSGeometry.equals_exact`, not :meth:`~GEOSGeometry.equals`, i.e.
it requires the compared geometries to have the same coordinates in the
same positions with the same SRIDs::
same positions with the same SRIDs:
.. code-block:: pycon
>>> from django.contrib.gis.geos import LineString
>>> ls1 = LineString((0, 0), (1, 1))
@@ -191,7 +213,9 @@ given ``geo_input`` argument, and then assumes the proper geometry subclass
The ``srid`` parameter, if given, is set as the SRID of the created geometry if
``geo_input`` doesn't have an SRID. If different SRIDs are provided through the
``geo_input`` and ``srid`` parameters, ``ValueError`` is raised::
``geo_input`` and ``srid`` parameters, ``ValueError`` is raised:
.. code-block:: pycon
>>> from django.contrib.gis.geos import GEOSGeometry
>>> GEOSGeometry('POINT EMPTY', srid=4326).ewkt
@@ -246,7 +270,9 @@ Properties
.. attribute:: GEOSGeometry.geom_type
Returns a string corresponding to the type of geometry. For example::
Returns a string corresponding to the type of geometry. For example:
.. code-block:: pycon
>>> pnt = GEOSGeometry('POINT(5 23)')
>>> pnt.geom_type
@@ -307,7 +333,9 @@ Properties
.. attribute:: GEOSGeometry.srid
Property that may be used to retrieve or set the SRID associated with the
geometry. For example::
geometry. For example:
.. code-block:: pycon
>>> pnt = Point(5, 23)
>>> print(pnt.srid)
@@ -671,7 +699,9 @@ Other Properties & Methods
Converts this geometry to canonical form. If the ``clone`` keyword is set,
then the geometry is not modified and a normalized clone of the geometry is
returned instead::
returned instead:
.. code-block:: pycon
>>> g = MultiPoint(Point(0, 0), Point(2, 2), Point(1, 1))
>>> print(g)
@@ -691,13 +721,17 @@ Other Properties & Methods
``Point`` objects are instantiated using arguments that represent the
component coordinates of the point or with a single sequence coordinates.
For example, the following are equivalent::
For example, the following are equivalent:
.. code-block:: pycon
>>> pnt = Point(5, 23)
>>> pnt = Point([5, 23])
Empty ``Point`` objects may be instantiated by passing no arguments or an
empty sequence. The following are equivalent::
empty sequence. The following are equivalent:
.. code-block:: pycon
>>> pnt = Point()
>>> pnt = Point([])
@@ -709,19 +743,25 @@ Other Properties & Methods
``LineString`` objects are instantiated using arguments that are either a
sequence of coordinates or :class:`Point` objects. For example, the
following are equivalent::
following are equivalent:
.. code-block:: pycon
>>> ls = LineString((0, 0), (1, 1))
>>> ls = LineString(Point(0, 0), Point(1, 1))
In addition, ``LineString`` objects may also be created by passing in a
single sequence of coordinate or :class:`Point` objects::
single sequence of coordinate or :class:`Point` objects:
.. code-block:: pycon
>>> ls = LineString( ((0, 0), (1, 1)) )
>>> ls = LineString( [Point(0, 0), Point(1, 1)] )
Empty ``LineString`` objects may be instantiated by passing no arguments
or an empty sequence. The following are equivalent::
or an empty sequence. The following are equivalent:
.. code-block:: pycon
>>> ls = LineString()
>>> ls = LineString([])
@@ -738,7 +778,9 @@ Other Properties & Methods
``LinearRing`` objects are constructed in the exact same way as
:class:`LineString` objects, however the coordinates must be *closed*, in
other words, the first coordinates must be the same as the last
coordinates. For example::
coordinates. For example:
.. code-block:: pycon
>>> ls = LinearRing((0, 0), (0, 1), (1, 1), (0, 0))
@@ -757,7 +799,9 @@ Other Properties & Methods
``Polygon`` objects may be instantiated by passing in parameters that
represent the rings of the polygon. The parameters must either be
:class:`LinearRing` instances, or a sequence that may be used to construct a
:class:`LinearRing`::
:class:`LinearRing`:
.. code-block:: pycon
>>> ext_coords = ((0, 0), (0, 1), (1, 1), (1, 0), (0, 0))
>>> int_coords = ((0.4, 0.4), (0.4, 0.6), (0.6, 0.6), (0.6, 0.4), (0.4, 0.4))
@@ -779,7 +823,9 @@ Other Properties & Methods
or ``>``, but as the comparison is made through Polygon's
:class:`LineString`, it does not mean much (but is consistent and quick).
You can always force the comparison with the :attr:`~GEOSGeometry.area`
property::
property:
.. code-block:: pycon
>>> if poly_1.area > poly_2.area:
>>> pass
@@ -795,7 +841,9 @@ Geometry Collections
.. class:: MultiPoint(*args, **kwargs)
``MultiPoint`` objects may be instantiated by passing in :class:`Point`
objects as arguments, or a single sequence of :class:`Point` objects::
objects as arguments, or a single sequence of :class:`Point` objects:
.. code-block:: pycon
>>> mp = MultiPoint(Point(0, 0), Point(1, 1))
>>> mp = MultiPoint( (Point(0, 0), Point(1, 1)) )
@@ -807,7 +855,9 @@ Geometry Collections
``MultiLineString`` objects may be instantiated by passing in
:class:`LineString` objects as arguments, or a single sequence of
:class:`LineString` objects::
:class:`LineString` objects:
.. code-block:: pycon
>>> ls1 = LineString((0, 0), (1, 1))
>>> ls2 = LineString((2, 2), (3, 3))
@@ -829,7 +879,9 @@ Geometry Collections
.. class:: MultiPolygon(*args, **kwargs)
``MultiPolygon`` objects may be instantiated by passing :class:`Polygon`
objects as arguments, or a single sequence of :class:`Polygon` objects::
objects as arguments, or a single sequence of :class:`Polygon` objects:
.. code-block:: pycon
>>> p1 = Polygon( ((0, 0), (0, 1), (1, 1), (0, 0)) )
>>> p2 = Polygon( ((1, 1), (1, 2), (2, 2), (1, 1)) )
@@ -843,7 +895,9 @@ Geometry Collections
``GeometryCollection`` objects may be instantiated by passing in other
:class:`GEOSGeometry` as arguments, or a single sequence of
:class:`GEOSGeometry` objects::
:class:`GEOSGeometry` objects:
.. code-block:: pycon
>>> poly = Polygon( ((0, 0), (0, 1), (1, 1), (0, 0)) )
>>> gc = GeometryCollection(Point(0, 0), MultiPoint(Point(0, 0), Point(1, 1)), poly)
@@ -862,7 +916,9 @@ geometry can be orders of magnitude faster -- the more complex the geometry
that is prepared, the larger the speedup in the operation. For more information,
please consult the `GEOS wiki page on prepared geometries <https://trac.osgeo.org/geos/wiki/PreparedGeometry>`_.
For example::
For example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, Polygon
>>> poly = Polygon.from_bbox((0, 0, 5, 5))
@@ -905,7 +961,9 @@ Geometry Factories
:type file_h: a Python ``file`` object or a string path to the file
:rtype: a :class:`GEOSGeometry` corresponding to the spatial data in the file
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import fromfile
>>> g = fromfile('/home/bob/geom.wkt')
@@ -921,7 +979,9 @@ Geometry Factories
``fromstr(string, srid)`` is equivalent to
:class:`GEOSGeometry(string, srid) <GEOSGeometry>`.
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import fromstr
>>> pnt = fromstr('POINT(-90.5 29.5)', srid=4326)
@@ -937,7 +997,9 @@ and/or WKT input given to their ``read(geom)`` method.
.. class:: WKBReader
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import WKBReader
>>> wkb_r = WKBReader()
@@ -946,7 +1008,9 @@ and/or WKT input given to their ``read(geom)`` method.
.. class:: WKTReader
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import WKTReader
>>> wkt_r = WKTReader()
@@ -973,7 +1037,9 @@ include the SRID value (in other words, EWKB).
.. method:: WKBWriter.write(geom)
Returns the WKB of the given geometry as a Python ``buffer`` object.
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> pnt = Point(1, 1)
@@ -983,7 +1049,9 @@ include the SRID value (in other words, EWKB).
.. method:: WKBWriter.write_hex(geom)
Returns WKB of the geometry in hexadecimal. Example::
Returns WKB of the geometry in hexadecimal. Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> pnt = Point(1, 1)
@@ -1003,7 +1071,9 @@ include the SRID value (in other words, EWKB).
1 Little Endian (e.g., compatible with x86 systems)
=============== =================================================
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> wkb_w = WKBWriter()
@@ -1026,7 +1096,9 @@ include the SRID value (in other words, EWKB).
3 Output 3D WKB.
============ ===========================
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> wkb_w = WKBWriter()
@@ -1042,7 +1114,9 @@ include the SRID value (in other words, EWKB).
.. attribute:: WKBWriter.srid
Set this property with a boolean to indicate whether the SRID of the
geometry should be included with the WKB representation. Example::
geometry should be included with the WKB representation. Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> wkb_w = WKBWriter()
@@ -1061,7 +1135,9 @@ include the SRID value (in other words, EWKB).
.. method:: WKTWriter.write(geom)
Returns the WKT of the given geometry. Example::
Returns the WKT of the given geometry. Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKTWriter
>>> pnt = Point(1, 1)
@@ -1078,6 +1154,8 @@ include the SRID value (in other words, EWKB).
This property is used to enable or disable trimming of
unnecessary decimals.
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKTWriter
>>> pnt = Point(1, 1)
>>> wkt_w = WKTWriter()

View File

@@ -85,7 +85,9 @@ is required.
.. note::
On Linux platforms, it may be necessary to run the ``ldconfig`` command
after installing each library. For example::
after installing each library. For example:
.. code-block:: shell
$ sudo make install
$ sudo ldconfig
@@ -106,19 +108,25 @@ internal geometry representation used by GeoDjango (it's behind the "lazy"
geometries). Specifically, the C API library is called (e.g., ``libgeos_c.so``)
directly from Python using ctypes.
First, download GEOS from the GEOS website and untar the source archive::
First, download GEOS from the GEOS website and untar the source archive:
.. code-block:: shell
$ wget https://download.osgeo.org/geos/geos-X.Y.Z.tar.bz2
$ tar xjf geos-X.Y.Z.tar.bz2
Then step into the GEOS directory, create a ``build`` folder, and step into
it::
it:
.. code-block:: shell
$ cd geos-X.Y.Z
$ mkdir build
$ cd build
Then build and install the package::
Then build and install the package:
.. code-block:: shell
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build .
@@ -149,7 +157,9 @@ If using a binary package of GEOS (e.g., on Ubuntu), you may need to :ref:`binut
If your GEOS library is in a non-standard location, or you don't want to
modify the system's library path then the :setting:`GEOS_LIBRARY_PATH`
setting may be added to your Django settings file with the full path to the
GEOS C library. For example::
GEOS C library. For example:
.. code-block:: shell
GEOS_LIBRARY_PATH = '/home/bob/local/lib/libgeos_c.so'
@@ -168,18 +178,24 @@ PROJ
`PROJ`_ is a library for converting geospatial data to different coordinate
reference systems.
First, download the PROJ source code::
First, download the PROJ source code:
.. code-block:: shell
$ wget https://download.osgeo.org/proj/proj-X.Y.Z.tar.gz
... and datum shifting files (download ``proj-datumgrid-X.Y.tar.gz`` for
PROJ < 7.x) [#]_::
PROJ < 7.x) [#]_:
.. code-block:: shell
$ wget https://download.osgeo.org/proj/proj-data-X.Y.tar.gz
Next, untar the source code archive, and extract the datum shifting files in the
``data`` subdirectory (use ``nad`` subdirectory for PROJ < 6.x). This must be
done *prior* to configuration::
done *prior* to configuration:
.. code-block:: shell
$ tar xzf proj-X.Y.Z.tar.gz
$ cd proj-X.Y.Z/data
@@ -190,13 +206,17 @@ For PROJ 9.x and greater, releases only support builds using ``CMake`` (see
`PROJ RFC-7`_).
To build with ``CMake`` ensure your system meets the `build requirements`_.
Then create a ``build`` folder in the PROJ directory, and step into it::
Then create a ``build`` folder in the PROJ directory, and step into it:
.. code-block:: shell
$ cd proj-X.Y.Z
$ mkdir build
$ cd build
Finally, configure, make and install PROJ::
Finally, configure, make and install PROJ:
.. code-block:: shell
$ cmake ..
$ cmake --build .
@@ -215,20 +235,26 @@ reading most vector and raster spatial data formats. Currently, GeoDjango only
supports :doc:`GDAL's vector data <../gdal>` capabilities [#]_.
:ref:`geosbuild` and :ref:`proj4` should be installed prior to building GDAL.
First download the latest GDAL release version and untar the archive::
First download the latest GDAL release version and untar the archive:
.. code-block:: shell
$ wget https://download.osgeo.org/gdal/X.Y.Z/gdal-X.Y.Z.tar.gz
$ tar xzf gdal-X.Y.Z.tar.gz
For GDAL 3.6.x and greater, releases only support builds using ``CMake``. To
build with ``CMake`` create a ``build`` folder in the GDAL directory, and step
into it::
into it:
.. code-block:: shell
$ cd gdal-X.Y.Z
$ mkdir build
$ cd build
Finally, configure, make and install GDAL::
Finally, configure, make and install GDAL:
.. code-block:: shell
$ cmake ..
$ cmake --build .
@@ -258,7 +284,9 @@ When GeoDjango can't find the GDAL library, configure your :ref:`libsettings`
If your GDAL library is in a non-standard location, or you don't want to
modify the system's library path then the :setting:`GDAL_LIBRARY_PATH`
setting may be added to your Django settings file with the full path to
the GDAL library. For example::
the GDAL library. For example:
.. code-block:: shell
GDAL_LIBRARY_PATH = '/home/sue/local/lib/libgdal.so'

View File

@@ -2,8 +2,6 @@
GeoDjango Installation
======================
.. highlight:: console
Overview
========
In general, GeoDjango installation requires:
@@ -141,7 +139,9 @@ A user may set this environment variable to customize the library paths
they want to use. The typical library directory for software
built from source is ``/usr/local/lib``. Thus, ``/usr/local/lib`` needs
to be included in the ``LD_LIBRARY_PATH`` variable. For example, the user
could place the following in their bash profile::
could place the following in their bash profile:
.. code-block:: shell
export LD_LIBRARY_PATH=/usr/local/lib
@@ -151,7 +151,9 @@ Setting system library path
On GNU/Linux systems, there is typically a file in ``/etc/ld.so.conf``, which may include
additional paths from files in another directory, such as ``/etc/ld.so.conf.d``.
As the root user, add the custom library path (like ``/usr/local/lib``) on a
new line in ``ld.so.conf``. This is *one* example of how to do so::
new line in ``ld.so.conf``. This is *one* example of how to do so:
.. code-block:: shell
$ sudo echo /usr/local/lib >> /etc/ld.so.conf
$ sudo ldconfig
@@ -159,7 +161,9 @@ new line in ``ld.so.conf``. This is *one* example of how to do so::
For OpenSolaris users, the system library path may be modified using the
``crle`` utility. Run ``crle`` with no options to see the current configuration
and use ``crle -l`` to set with the new library path. Be *very* careful when
modifying the system library path::
modifying the system library path:
.. code-block:: shell
# crle -l $OLD_PATH:/usr/local/lib
@@ -176,11 +180,15 @@ Linux system then Python's ctypes may not be able to find your library even if
your library path is set correctly and geospatial libraries were built perfectly.
The ``binutils`` package may be installed on Debian and Ubuntu systems using the
following command::
following command:
.. code-block:: shell
$ sudo apt-get install binutils
Similarly, on Red Hat and CentOS systems::
Similarly, on Red Hat and CentOS systems:
.. code-block:: shell
$ sudo yum install binutils
@@ -221,7 +229,9 @@ __ https://www.python.org/ftp/python/
You will need to modify the ``PATH`` environment variable in your
``.profile`` file so that the new version of Python is used when
``python`` is entered at the command-line::
``python`` is entered at the command-line:
.. code-block:: shell
export PATH=/Library/Frameworks/Python.framework/Versions/Current/bin:$PATH
@@ -255,7 +265,9 @@ It provides recipes for the GeoDjango prerequisites on Macintosh computers
running macOS. Because Homebrew still builds the software from source, `Xcode`_
is required.
Summary::
Summary:
.. code-block:: shell
$ brew install postgresql
$ brew install postgis
@@ -287,7 +299,9 @@ MacPorts
running macOS. Because MacPorts still builds the software from source,
`Xcode`_ is required.
Summary::
Summary:
.. code-block:: shell
$ sudo port install postgresql13-server
$ sudo port install geos
@@ -299,12 +313,16 @@ Summary::
.. note::
You will also have to modify the ``PATH`` in your ``.profile`` so
that the MacPorts programs are accessible from the command-line::
that the MacPorts programs are accessible from the command-line:
.. code-block:: shell
export PATH=/opt/local/bin:/opt/local/lib/postgresql13/bin
In addition, add the ``DYLD_FALLBACK_LIBRARY_PATH`` setting so that
the libraries can be found by Python::
the libraries can be found by Python:
.. code-block:: shell
export DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib:/opt/local/lib/postgresql13
@@ -434,7 +452,9 @@ psycopg
The ``psycopg`` Python module provides the interface between Python and the
PostgreSQL database. ``psycopg`` can be installed via pip within your Python
virtual environment::
virtual environment:
.. code-block:: doscon
...\> py -m pip install psycopg

View File

@@ -35,7 +35,9 @@ Creating a spatial database
---------------------------
PostGIS 2 includes an extension for PostgreSQL that's used to enable spatial
functionality::
functionality:
.. code-block:: shell
$ createdb <db name>
$ psql <db name>
@@ -74,7 +76,9 @@ To administer the database, you can either use the pgAdmin III program
(:menuselection:`Start --> PostgreSQL X --> pgAdmin III`) or the SQL Shell
(:menuselection:`Start --> PostgreSQL X --> SQL Shell`). For example, to create
a ``geodjango`` spatial database and user, the following may be executed from
the SQL Shell as the ``postgres`` user::
the SQL Shell as the ``postgres`` user:
.. code-block:: psql
postgres# CREATE USER geodjango PASSWORD 'my_passwd';
postgres# CREATE DATABASE geodjango OWNER geodjango;

View File

@@ -33,7 +33,9 @@ SQLite
------
Check first if SQLite is compiled with the `R*Tree module`__. Run the sqlite3
command line interface and enter the following query::
command line interface and enter the following query:
.. code-block:: sqlite3
sqlite> CREATE VIRTUAL TABLE testrtree USING rtree(id,minX,maxX,minY,maxY);
@@ -41,14 +43,18 @@ If you obtain an error, you will have to recompile SQLite from source. Otherwise
skip this section.
To install from sources, download the latest amalgamation source archive from
the `SQLite download page`__, and extract::
the `SQLite download page`__, and extract:
.. code-block:: shell
$ wget https://www.sqlite.org/YYYY/sqlite-amalgamation-XXX0000.zip
$ unzip sqlite-amalgamation-XXX0000.zip
$ cd sqlite-amalgamation-XXX0000
Next, run the ``configure`` script -- however the ``CFLAGS`` environment variable
needs to be customized so that SQLite knows to build the R*Tree module::
needs to be customized so that SQLite knows to build the R*Tree module:
.. code-block:: shell
$ CFLAGS="-DSQLITE_ENABLE_RTREE=1" ./configure
$ make
@@ -64,7 +70,9 @@ SpatiaLite library (``libspatialite``)
--------------------------------------
Get the latest SpatiaLite library source bundle from the
`download page`__::
`download page`__:
.. code-block:: shell
$ wget https://www.gaia-gis.it/gaia-sins/libspatialite-sources/libspatialite-X.Y.Z.tar.gz
$ tar xaf libspatialite-X.Y.Z.tar.gz
@@ -76,7 +84,9 @@ Get the latest SpatiaLite library source bundle from the
.. note::
For macOS users building from source, the SpatiaLite library *and* tools
need to have their ``target`` configured::
need to have their ``target`` configured:
.. code-block:: shell
$ ./configure --target=macosx
@@ -93,7 +103,9 @@ Homebrew
--------
`Homebrew`_ handles all the SpatiaLite related packages on your behalf,
including SQLite, SpatiaLite, PROJ, and GEOS. Install them like this::
including SQLite, SpatiaLite, PROJ, and GEOS. Install them like this:
.. code-block:: shell
$ brew update
$ brew install spatialite-tools

View File

@@ -32,7 +32,9 @@ Example
=======
#. You need a GDAL-supported data source, like a shapefile (here we're using
a simple polygon shapefile, ``test_poly.shp``, with three features)::
a simple polygon shapefile, ``test_poly.shp``, with three features):
.. code-block:: pycon
>>> from django.contrib.gis.gdal import DataSource
>>> ds = DataSource('test_poly.shp')
@@ -62,7 +64,9 @@ Example
return 'Name: %s' % self.name
#. Use :class:`LayerMapping` to extract all the features and place them in the
database::
database:
.. code-block:: pycon
>>> from django.contrib.gis.utils import LayerMapping
>>> from geoapp.models import TestGeo
@@ -206,13 +210,17 @@ should stop excessive memory use when running ``LayerMapping`` scripts.
MySQL: ``max_allowed_packet`` error
-----------------------------------
If you encounter the following error when using ``LayerMapping`` and MySQL::
If you encounter the following error when using ``LayerMapping`` and MySQL:
.. code-block:: pytb
OperationalError: (1153, "Got a packet bigger than 'max_allowed_packet' bytes")
Then the solution is to increase the value of the ``max_allowed_packet``
setting in your MySQL configuration. For example, the default value may
be something low like one megabyte -- the setting may be modified in MySQL's
configuration file (``my.cnf``) in the ``[mysqld]`` section::
configuration file (``my.cnf``) in the ``[mysqld]`` section:
.. code-block:: ini
max_allowed_packet = 10M

View File

@@ -16,7 +16,9 @@ Example
:class:`Distance` objects may be instantiated using a keyword argument indicating the
context of the units. In the example below, two different distance objects are
instantiated in units of kilometers (``km``) and miles (``mi``)::
instantiated in units of kilometers (``km``) and miles (``mi``):
.. code-block:: pycon
>>> from django.contrib.gis.measure import D, Distance
>>> d1 = Distance(km=5)
@@ -27,7 +29,9 @@ instantiated in units of kilometers (``km``) and miles (``mi``)::
5.0 mi
For conversions, access the preferred unit attribute to get a converted
distance quantity::
distance quantity:
.. code-block:: pycon
>>> print(d1.mi) # Converting 5 kilometers to miles
3.10685596119
@@ -35,7 +39,9 @@ distance quantity::
8.04672
Moreover, arithmetic operations may be performed between the distance
objects::
objects:
.. code-block:: pycon
>>> print(d1 + d2) # Adding 5 miles to 5 kilometers
13.04672 km
@@ -43,14 +49,18 @@ objects::
1.89314403881 mi
Two :class:`Distance` objects multiplied together will yield an :class:`Area`
object, which uses squared units of measure::
object, which uses squared units of measure:
.. code-block:: pycon
>>> a = d1 * d2 # Returns an Area object.
>>> print(a)
40.2336 sq_km
To determine what the attribute abbreviation of a unit is, the ``unit_attname``
class method may be used::
class method may be used:
.. code-block:: pycon
>>> print(Distance.unit_attname('US Survey Foot'))
survey_ft
@@ -117,14 +127,18 @@ Measurement API
To initialize a distance object, pass in a keyword corresponding to the
desired :ref:`unit attribute name <supported_units>` set with desired
value. For example, the following creates a distance object representing 5
miles::
miles:
.. code-block:: pycon
>>> dist = Distance(mi=5)
.. method:: __getattr__(unit_att)
Returns the distance value in units corresponding to the given unit
attribute. For example::
attribute. For example:
.. code-block:: pycon
>>> print(dist.km)
8.04672
@@ -132,7 +146,9 @@ Measurement API
.. classmethod:: unit_attname(unit_name)
Returns the distance unit attribute name for the given full unit name. For
example::
example:
.. code-block:: pycon
>>> Distance.unit_attname('Mile')
'mi'
@@ -149,14 +165,18 @@ Measurement API
To initialize an area object, pass in a keyword corresponding to the
desired :ref:`unit attribute name <supported_units>` set with desired
value. For example, the following creates an area object representing 5
square miles::
square miles:
.. code-block:: pycon
>>> a = Area(sq_mi=5)
.. method:: __getattr__(unit_att)
Returns the area value in units corresponding to the given unit attribute.
For example::
For example:
.. code-block:: pycon
>>> print(a.sq_km)
12.949940551680001
@@ -164,7 +184,9 @@ Measurement API
.. classmethod:: unit_attname(unit_name)
Returns the area unit attribute name for the given full unit name. For
example::
example:
.. code-block:: pycon
>>> Area.unit_attname('Kilometer')
'sq_km'

View File

@@ -46,7 +46,9 @@ Create database user
~~~~~~~~~~~~~~~~~~~~
To make a database user with the ability to create databases, use the
following command::
following command:
.. code-block:: shell
$ createuser --createdb -R -S <user_name>
@@ -54,19 +56,25 @@ The ``-R -S`` flags indicate that we do not want the user to have the ability
to create additional users (roles) or to be a superuser, respectively.
Alternatively, you may alter an existing user's role from the SQL shell
(assuming this is done from an existing superuser account)::
(assuming this is done from an existing superuser account):
.. code-block:: psql
postgres# ALTER ROLE <user_name> CREATEDB NOSUPERUSER NOCREATEROLE;
Create database superuser
~~~~~~~~~~~~~~~~~~~~~~~~~
This may be done at the time the user is created, for example::
This may be done at the time the user is created, for example:
.. code-block:: shell
$ createuser --superuser <user_name>
Or you may alter the user's role from the SQL shell (assuming this
is done from an existing superuser account)::
is done from an existing superuser account):
.. code-block:: psql
postgres# ALTER ROLE <user_name> SUPERUSER;
@@ -114,10 +122,14 @@ in :mod:`django.contrib.gis`::
Assuming the settings above were in a ``postgis.py`` file in the same
directory as ``runtests.py``, then all Django and GeoDjango tests would
be performed when executing the command::
be performed when executing the command:
.. code-block:: shell
$ ./runtests.py --settings=postgis
To run only the GeoDjango test suite, specify ``gis_tests``::
To run only the GeoDjango test suite, specify ``gis_tests``:
.. code-block:: shell
$ ./runtests.py --settings=postgis gis_tests

View File

@@ -321,14 +321,18 @@ First, invoke the Django shell:
$ python manage.py shell
If you downloaded the :ref:`worldborders` data earlier in the tutorial, then
you can determine its path using Python's :class:`pathlib.Path`::
you can determine its path using Python's :class:`pathlib.Path`:
.. code-block:: pycon
>>> from pathlib import Path
>>> import world
>>> world_shp = Path(world.__file__).resolve().parent / 'data' / 'TM_WORLD_BORDERS-0.3.shp'
Now, open the world borders shapefile using GeoDjango's
:class:`~django.contrib.gis.gdal.DataSource` interface::
:class:`~django.contrib.gis.gdal.DataSource` interface:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import DataSource
>>> ds = DataSource(world_shp)
@@ -336,7 +340,9 @@ Now, open the world borders shapefile using GeoDjango's
/ ... /geodjango/world/data/TM_WORLD_BORDERS-0.3.shp (ESRI Shapefile)
Data source objects can have different layers of geospatial features; however,
shapefiles are only allowed to have one layer::
shapefiles are only allowed to have one layer:
.. code-block:: pycon
>>> print(len(ds))
1
@@ -344,7 +350,9 @@ shapefiles are only allowed to have one layer::
>>> print(lyr)
TM_WORLD_BORDERS-0.3
You can see the layer's geometry type and how many features it contains::
You can see the layer's geometry type and how many features it contains:
.. code-block:: pycon
>>> print(lyr.geom_type)
Polygon
@@ -363,7 +371,9 @@ You can see the layer's geometry type and how many features it contains::
The :class:`~django.contrib.gis.gdal.Layer` may also have a spatial reference
system associated with it. If it does, the ``srs`` attribute will return a
:class:`~django.contrib.gis.gdal.SpatialReference` object::
:class:`~django.contrib.gis.gdal.SpatialReference` object:
.. code-block:: pycon
>>> srs = lyr.srs
>>> print(srs)
@@ -401,7 +411,9 @@ string) associated with each of the fields:
You can iterate over each feature in the layer and extract information from both
the feature's geometry (accessed via the ``geom`` attribute) as well as the
feature's attribute fields (whose **values** are accessed via ``get()``
method)::
method):
.. code-block:: pycon
>>> for feat in lyr:
... print(feat.get('NAME'), feat.geom.num_points)
@@ -411,18 +423,24 @@ method)::
South Georgia South Sandwich Islands 338
Taiwan 363
:class:`~django.contrib.gis.gdal.Layer` objects may be sliced::
:class:`~django.contrib.gis.gdal.Layer` objects may be sliced:
.. code-block:: pycon
>>> lyr[0:2]
[<django.contrib.gis.gdal.feature.Feature object at 0x2f47690>, <django.contrib.gis.gdal.feature.Feature object at 0x2f47650>]
And individual features may be retrieved by their feature ID::
And individual features may be retrieved by their feature ID:
.. code-block:: pycon
>>> feat = lyr[234]
>>> print(feat.get('NAME'))
San Marino
Boundary geometries may be exported as WKT and GeoJSON::
Boundary geometries may be exported as WKT and GeoJSON:
.. code-block:: pycon
>>> geom = feat.geom
>>> print(geom.wkt)
@@ -484,7 +502,9 @@ Afterward, invoke the Django shell from the ``geodjango`` project directory:
$ python manage.py shell
Next, import the ``load`` module, call the ``run`` routine, and watch
``LayerMapping`` do the work::
``LayerMapping`` do the work:
.. code-block:: pycon
>>> from world import load
>>> load.run()
@@ -576,7 +596,9 @@ a particular point. First, fire up the management shell:
$ python manage.py shell
Now, define a point of interest [#]_::
Now, define a point of interest [#]_:
.. code-block:: pycon
>>> pnt_wkt = 'POINT(-95.3385 29.7245)'
@@ -584,7 +606,9 @@ The ``pnt_wkt`` string represents the point at -95.3385 degrees longitude,
29.7245 degrees latitude. The geometry is in a format known as
Well Known Text (WKT), a standard issued by the Open Geospatial
Consortium (OGC). [#]_ Import the ``WorldBorder`` model, and perform
a ``contains`` lookup using the ``pnt_wkt`` as the parameter::
a ``contains`` lookup using the ``pnt_wkt`` as the parameter:
.. code-block:: pycon
>>> from world.models import WorldBorder
>>> WorldBorder.objects.filter(mpoly__contains=pnt_wkt)
@@ -596,7 +620,9 @@ United States (exactly what you would expect).
Similarly, you may also use a :doc:`GEOS geometry object <geos>`.
Here, you can combine the ``intersects`` spatial lookup with the ``get``
method to retrieve only the ``WorldBorder`` instance for San Marino instead
of a queryset::
of a queryset:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point
>>> pnt = Point(12.4604, 43.9420)
@@ -614,19 +640,25 @@ When doing spatial queries, GeoDjango automatically transforms
geometries if they're in a different coordinate system. In the following
example, coordinates will be expressed in `EPSG SRID 32140`__,
a coordinate system specific to south Texas **only** and in units of
**meters**, not degrees::
**meters**, not degrees:
.. code-block:: pycon
>>> from django.contrib.gis.geos import GEOSGeometry, Point
>>> pnt = Point(954158.1, 4215137.1, srid=32140)
Note that ``pnt`` may also be constructed with EWKT, an "extended" form of
WKT that includes the SRID::
WKT that includes the SRID:
.. code-block:: pycon
>>> pnt = GEOSGeometry('SRID=32140;POINT(954158.1 4215137.1)')
GeoDjango's ORM will automatically wrap geometry values
in transformation SQL, allowing the developer to work at a higher level
of abstraction::
of abstraction:
.. code-block:: pycon
>>> qs = WorldBorder.objects.filter(mpoly__intersects=pnt)
>>> print(qs.query) # Generating the SQL
@@ -646,7 +678,9 @@ __ https://spatialreference.org/ref/epsg/32140/
.. admonition:: Raw queries
When using :doc:`raw queries </topics/db/sql>`, you must wrap your geometry
fields so that the field value can be recognized by GEOS::
fields so that the field value can be recognized by GEOS:
.. code-block:: pycon
from django.db import connection
# or if you're querying a non-default database:
@@ -663,7 +697,9 @@ GeoDjango loads geometries in a standardized textual representation. When the
geometry field is first accessed, GeoDjango creates a
:class:`~django.contrib.gis.geos.GEOSGeometry` object, exposing powerful
functionality, such as serialization properties for popular geospatial
formats::
formats:
.. code-block:: pycon
>>> sm = WorldBorder.objects.get(name='San Marino')
>>> sm.mpoly
@@ -676,7 +712,9 @@ formats::
'{ "type": "MultiPolygon", "coordinates": [ [ [ [ 12.415798, 43.957954 ], [ 12.450554, 43.979721 ], ...
This includes access to all of the advanced geometric operations provided by
the GEOS library::
the GEOS library:
.. code-block:: pycon
>>> pnt = Point(12.4604, 43.9420)
>>> sm.mpoly.contains(pnt)