mirror of https://github.com/django/django.git
Fixed #19243 - Edited GeoDjango Tutorial for consistency and style.
This commit is contained in:
parent
e2b1808196
commit
8e5573e99a
|
@ -5,28 +5,28 @@ GeoDjango Tutorial
|
||||||
Introduction
|
Introduction
|
||||||
============
|
============
|
||||||
|
|
||||||
GeoDjango is an add-on for Django that turns it into a world-class geographic
|
GeoDjango is an included contrib module for Django that turns it into a
|
||||||
Web framework. GeoDjango strives to make it as simple as possible to create
|
world-class geographic Web framework. GeoDjango strives to make it as simple
|
||||||
geographic Web applications, like location-based services. Some features
|
as possible to create geographic Web applications, like location-based services.
|
||||||
include:
|
Its features include:
|
||||||
|
|
||||||
* Django model fields for `OGC`_ geometries.
|
* Django model fields for `OGC`_ geometries.
|
||||||
* Extensions to Django's ORM for the querying and manipulation of spatial data.
|
* Extensions to Django's ORM for querying and manipulating spatial data.
|
||||||
* Loosely-coupled, high-level Python interfaces for GIS geometry operations and
|
* Loosely-coupled, high-level Python interfaces for GIS geometry operations and
|
||||||
data formats.
|
data formats.
|
||||||
* Editing of geometry fields inside the admin.
|
* Editing geometry fields from the admin.
|
||||||
|
|
||||||
This tutorial assumes a familiarity with Django; thus, if you're brand new to
|
This tutorial assumes familiarity with Django; thus, if you're brand new to
|
||||||
Django please read through the :doc:`regular tutorial </intro/tutorial01>` to
|
Django, please read through the :doc:`regular tutorial </intro/tutorial01>` to
|
||||||
introduce yourself with basic Django concepts.
|
familiarize yourself with Django first.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
GeoDjango has special prerequisites overwhat is required by Django --
|
GeoDjango has additional requirements beyond what Django requires --
|
||||||
please consult the :ref:`installation documentation <ref-gis-install>`
|
please consult the :ref:`installation documentation <ref-gis-install>`
|
||||||
for more details.
|
for more details.
|
||||||
|
|
||||||
This tutorial will guide you through the creation of a geographic Web
|
This tutorial will guide you through the creation of a geographic web
|
||||||
application for viewing the `world borders`_. [#]_ Some of the code
|
application for viewing the `world borders`_. [#]_ Some of the code
|
||||||
used in this tutorial is taken from and/or inspired by the `GeoDjango
|
used in this tutorial is taken from and/or inspired by the `GeoDjango
|
||||||
basic apps`_ project. [#]_
|
basic apps`_ project. [#]_
|
||||||
|
@ -51,10 +51,10 @@ Create a Spatial Database
|
||||||
MySQL and Oracle users can skip this section because spatial types
|
MySQL and Oracle users can skip this section because spatial types
|
||||||
are already built into the database.
|
are already built into the database.
|
||||||
|
|
||||||
First, a spatial database needs to be created for our project. If using
|
First, create a spatial database for your project.
|
||||||
PostgreSQL and PostGIS, then the following commands will
|
|
||||||
create the database from a :ref:`spatial database template
|
If you are using PostGIS, create the database from the :ref:`spatial database
|
||||||
<spatialdb_template>`:
|
template <spatialdb_template>`:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
@ -62,9 +62,9 @@ create the database from a :ref:`spatial database template
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
This command must be issued by a database user that has permissions to
|
This command must be issued by a database user with enough privileges to
|
||||||
create a database. Here is an example set of commands to create such
|
create a database. To create a user with ``CREATE DATABASE`` privileges in
|
||||||
a user:
|
PostgreSQL, use the following commands:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
@ -72,25 +72,24 @@ create the database from a :ref:`spatial database template
|
||||||
$ createuser --createdb geo
|
$ createuser --createdb geo
|
||||||
$ exit
|
$ exit
|
||||||
|
|
||||||
Replace ``geo`` with the system login user name that will be
|
Replace ``geo`` with your Postgres database user's username.
|
||||||
connecting to the database. For example, ``johndoe`` if that is the
|
(In PostgreSQL, this user will also be an OS-level user.)
|
||||||
system user that will be running GeoDjango.
|
|
||||||
|
|
||||||
Users of SQLite and SpatiaLite should consult the instructions on how
|
If you are using SQLite and SpatiaLite, consult the instructions on how
|
||||||
to create a :ref:`SpatiaLite database <create_spatialite_db>`.
|
to create a :ref:`SpatiaLite database <create_spatialite_db>`.
|
||||||
|
|
||||||
Create GeoDjango Project
|
Create a New Project
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
Use the ``django-admin.py`` script like normal to create a ``geodjango``
|
Use the standard ``django-admin.py`` script to create a project called
|
||||||
project:
|
``geodjango``:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
$ django-admin.py startproject geodjango
|
$ django-admin.py startproject geodjango
|
||||||
|
|
||||||
With the project initialized, now create a ``world`` Django application within
|
This will initialize a new project. Now, create a ``world`` Django application
|
||||||
the ``geodjango`` project:
|
within the ``geodjango`` project:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
@ -101,7 +100,7 @@ Configure ``settings.py``
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
The ``geodjango`` project settings are stored in the ``geodjango/settings.py``
|
The ``geodjango`` project settings are stored in the ``geodjango/settings.py``
|
||||||
file. Edit the database connection settings appropriately::
|
file. Edit the database connection settings to match your setup::
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
|
@ -113,7 +112,7 @@ file. Edit the database connection settings appropriately::
|
||||||
|
|
||||||
In addition, modify the :setting:`INSTALLED_APPS` setting to include
|
In addition, modify the :setting:`INSTALLED_APPS` setting to include
|
||||||
:mod:`django.contrib.admin`, :mod:`django.contrib.gis`,
|
:mod:`django.contrib.admin`, :mod:`django.contrib.gis`,
|
||||||
and ``world`` (our newly created application)::
|
and ``world`` (your newly created application)::
|
||||||
|
|
||||||
INSTALLED_APPS = (
|
INSTALLED_APPS = (
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
|
@ -135,9 +134,9 @@ Geographic Data
|
||||||
World Borders
|
World Borders
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
The world borders data is available in this `zip file`__. Create a data
|
The world borders data is available in this `zip file`__. Create a ``data``
|
||||||
directory in the ``world`` application, download the world borders data, and
|
directory in the ``world`` application, download the world borders data, and
|
||||||
unzip. On GNU/Linux platforms the following commands should do it:
|
unzip. On GNU/Linux platforms, use the following commands:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
@ -149,7 +148,7 @@ unzip. On GNU/Linux platforms the following commands should do it:
|
||||||
|
|
||||||
The world borders ZIP file contains a set of data files collectively known as
|
The world borders ZIP file contains a set of data files collectively known as
|
||||||
an `ESRI Shapefile`__, one of the most popular geospatial data formats. When
|
an `ESRI Shapefile`__, one of the most popular geospatial data formats. When
|
||||||
unzipped the world borders data set includes files with the following
|
unzipped, the world borders dataset includes files with the following
|
||||||
extensions:
|
extensions:
|
||||||
|
|
||||||
* ``.shp``: Holds the vector data for the world borders geometries.
|
* ``.shp``: Holds the vector data for the world borders geometries.
|
||||||
|
@ -165,8 +164,8 @@ __ http://en.wikipedia.org/wiki/Shapefile
|
||||||
Use ``ogrinfo`` to examine spatial data
|
Use ``ogrinfo`` to examine spatial data
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
The GDAL ``ogrinfo`` utility is excellent for examining metadata about
|
The GDAL ``ogrinfo`` utility allows examining the metadata of shapefiles or
|
||||||
shapefiles (or other vector data sources):
|
other vector data sources:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
@ -175,9 +174,9 @@ shapefiles (or other vector data sources):
|
||||||
using driver `ESRI Shapefile' successful.
|
using driver `ESRI Shapefile' successful.
|
||||||
1: TM_WORLD_BORDERS-0.3 (Polygon)
|
1: TM_WORLD_BORDERS-0.3 (Polygon)
|
||||||
|
|
||||||
Here ``ogrinfo`` is telling us that the shapefile has one layer, and that such
|
``ogrinfo`` tells us that the shapefile has one layer, and that this
|
||||||
layer contains polygon data. To find out more we'll specify the layer name
|
layer contains polygon data. To find out more, we'll specify the layer name
|
||||||
and use the ``-so`` option to get only important summary information:
|
and use the ``-so`` option to get only the important summary information:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
@ -208,14 +207,11 @@ and use the ``-so`` option to get only important summary information:
|
||||||
LAT: Real (7.3)
|
LAT: Real (7.3)
|
||||||
|
|
||||||
This detailed summary information tells us the number of features in the layer
|
This detailed summary information tells us the number of features in the layer
|
||||||
(246), the geographical extent, the spatial reference system ("SRS WKT"),
|
(246), the geographic bounds of the data, the spatial reference system
|
||||||
as well as detailed information for each attribute field. For example,
|
("SRS WKT"), as well as type information for each attribute field. For example,
|
||||||
``FIPS: String (2.0)`` indicates that there's a ``FIPS`` character field
|
``FIPS: String (2.0)`` indicates that the ``FIPS`` character field has
|
||||||
with a maximum length of 2; similarly, ``LON: Real (8.3)`` is a floating-point
|
a maximum length of 2. Similarly, ``LON: Real (8.3)`` is a floating-point
|
||||||
field that holds a maximum of 8 digits up to three decimal places. Although
|
field that holds a maximum of 8 digits up to three decimal places.
|
||||||
this information may be found right on the `world borders`_ Web site, this
|
|
||||||
shows you how to determine this information yourself when such metadata is not
|
|
||||||
provided.
|
|
||||||
|
|
||||||
Geographic Models
|
Geographic Models
|
||||||
=================
|
=================
|
||||||
|
@ -223,8 +219,8 @@ Geographic Models
|
||||||
Defining a Geographic Model
|
Defining a Geographic Model
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
Now that we've examined our world borders data set using ``ogrinfo``, we can
|
Now that you've examined your dataset using ``ogrinfo``, create a GeoDjango
|
||||||
create a GeoDjango model to represent this data::
|
model to represent this data::
|
||||||
|
|
||||||
from django.contrib.gis.db import models
|
from django.contrib.gis.db import models
|
||||||
|
|
||||||
|
@ -252,32 +248,30 @@ create a GeoDjango model to represent this data::
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
Two important things to note:
|
Please note two important things:
|
||||||
|
|
||||||
1. The ``models`` module is imported from :mod:`django.contrib.gis.db`.
|
1. The ``models`` module is imported from :mod:`django.contrib.gis.db`.
|
||||||
2. The model overrides its default manager with
|
2. You must override the model's default manager with
|
||||||
:class:`~django.contrib.gis.db.models.GeoManager`; this is *required*
|
:class:`~django.contrib.gis.db.models.GeoManager` to perform spatial queries.
|
||||||
to perform spatial queries.
|
|
||||||
|
|
||||||
When declaring a geometry field on your model the default spatial reference
|
The default spatial reference system for geometry fields is WGS84 (meaning
|
||||||
system is WGS84 (meaning the `SRID`__ is 4326) -- in other words, the field
|
the `SRID`__ is 4326) -- in other words, the field coordinates are in
|
||||||
coordinates are in longitude/latitude pairs in units of degrees. If you want
|
longitude, latitude pairs in units of degrees. To use a different
|
||||||
the coordinate system to be different, then SRID of the geometry field may be
|
coordinate system, set the SRID of the geometry field with the ``srid``
|
||||||
customized by setting the ``srid`` with an integer corresponding to the
|
argument. Use an integer representing the coordinate system's EPSG code.
|
||||||
coordinate system of your choice.
|
|
||||||
|
|
||||||
__ http://en.wikipedia.org/wiki/SRID
|
__ http://en.wikipedia.org/wiki/SRID
|
||||||
|
|
||||||
Run ``syncdb``
|
Run ``syncdb``
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
After you've defined your model, it needs to be synced with the spatial
|
After defining your model, you need to sync it with the database. First,
|
||||||
database. First, let's look at the SQL that will generate the table for the
|
let's look at the SQL that will generate the table for the
|
||||||
``WorldBorder`` model::
|
``WorldBorder`` model::
|
||||||
|
|
||||||
$ python manage.py sqlall world
|
$ python manage.py sqlall world
|
||||||
|
|
||||||
This management command should produce the following output:
|
This command should produce the following output:
|
||||||
|
|
||||||
.. code-block:: sql
|
.. code-block:: sql
|
||||||
|
|
||||||
|
@ -302,32 +296,28 @@ This management command should produce the following output:
|
||||||
CREATE INDEX "world_worldborder_mpoly_id" ON "world_worldborder" USING GIST ( "mpoly" GIST_GEOMETRY_OPS );
|
CREATE INDEX "world_worldborder_mpoly_id" ON "world_worldborder" USING GIST ( "mpoly" GIST_GEOMETRY_OPS );
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
If satisfied, you may then create this table in the database by running the
|
If this looks correct, run ``syncdb`` to create this table in the database::
|
||||||
``syncdb`` management command::
|
|
||||||
|
|
||||||
$ python manage.py syncdb
|
$ python manage.py syncdb
|
||||||
Creating table world_worldborder
|
Creating table world_worldborder
|
||||||
Installing custom SQL for world.WorldBorder model
|
Installing custom SQL for world.WorldBorder model
|
||||||
|
|
||||||
The ``syncdb`` command may also prompt you to create an admin user; go ahead
|
The ``syncdb`` command may also prompt you to create an admin user. Either
|
||||||
and do so (not required now, may be done at any point in the future using the
|
do so now, or later by running ``django-admin.py createsuperuser``.
|
||||||
``createsuperuser`` management command).
|
|
||||||
|
|
||||||
Importing Spatial Data
|
Importing Spatial Data
|
||||||
======================
|
======================
|
||||||
|
|
||||||
This section will show you how to take the data from the world borders
|
This section will show you how to import the world borders
|
||||||
shapefile and import it into GeoDjango models using the
|
shapefile into the database via GeoDjango models using the
|
||||||
:ref:`ref-layermapping`.
|
:ref:`ref-layermapping`.
|
||||||
There are many different ways to import data in to a spatial database --
|
There are many different ways to import data into a spatial database --
|
||||||
besides the tools included within GeoDjango, you may also use the following to
|
besides the tools included within GeoDjango, you may also use the following:
|
||||||
populate your spatial database:
|
|
||||||
|
|
||||||
* `ogr2ogr`_: Command-line utility, included with GDAL, that
|
* `ogr2ogr`_: A command-line utility included with GDAL that
|
||||||
supports loading a multitude of vector data formats into
|
can import many vector data formats into PostGIS, MySQL, and Oracle databases.
|
||||||
the PostGIS, MySQL, and Oracle spatial databases.
|
* `shp2pgsql`_: This utility included with PostGIS imports ESRI shapefiles into
|
||||||
* `shp2pgsql`_: This utility is included with PostGIS and only supports
|
PostGIS.
|
||||||
ESRI shapefiles.
|
|
||||||
|
|
||||||
.. _ogr2ogr: http://www.gdal.org/ogr2ogr.html
|
.. _ogr2ogr: http://www.gdal.org/ogr2ogr.html
|
||||||
.. _shp2pgsql: http://postgis.refractions.net/documentation/manual-1.5/ch04.html#shp2pgsql_usage
|
.. _shp2pgsql: http://postgis.refractions.net/documentation/manual-1.5/ch04.html#shp2pgsql_usage
|
||||||
|
@ -337,10 +327,9 @@ populate your spatial database:
|
||||||
GDAL Interface
|
GDAL Interface
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Earlier we used the ``ogrinfo`` to explore the contents of the world borders
|
Earlier, you used ``ogrinfo`` to examine the contents of the world borders
|
||||||
shapefile. Included within GeoDjango is an interface to GDAL's powerful OGR
|
shapefile. GeoDjango also includes a Pythonic interface to GDAL's powerful OGR
|
||||||
library -- in other words, you'll be able explore all the vector data sources
|
library that can work with all the vector data sources that OGR supports.
|
||||||
that OGR supports via a Pythonic API.
|
|
||||||
|
|
||||||
First, invoke the Django shell:
|
First, invoke the Django shell:
|
||||||
|
|
||||||
|
@ -348,8 +337,8 @@ First, invoke the Django shell:
|
||||||
|
|
||||||
$ python manage.py shell
|
$ python manage.py shell
|
||||||
|
|
||||||
If the :ref:`worldborders` data was downloaded like earlier in the
|
If you downloaded the :ref:`worldborders` data earlier in the
|
||||||
tutorial, then we can determine the path using Python's built-in
|
tutorial, then you can determine its path using Python's built-in
|
||||||
``os`` module::
|
``os`` module::
|
||||||
|
|
||||||
>>> import os
|
>>> import os
|
||||||
|
@ -357,7 +346,7 @@ tutorial, then we can determine the path using Python's built-in
|
||||||
>>> world_shp = os.path.abspath(os.path.join(os.path.dirname(world.__file__),
|
>>> world_shp = os.path.abspath(os.path.join(os.path.dirname(world.__file__),
|
||||||
... 'data/TM_WORLD_BORDERS-0.3.shp'))
|
... 'data/TM_WORLD_BORDERS-0.3.shp'))
|
||||||
|
|
||||||
Now, the world borders shapefile may be opened using GeoDjango's
|
Now, open the world borders shapefile using GeoDjango's
|
||||||
:class:`~django.contrib.gis.gdal.DataSource` interface::
|
:class:`~django.contrib.gis.gdal.DataSource` interface::
|
||||||
|
|
||||||
>>> from django.contrib.gis.gdal import DataSource
|
>>> from django.contrib.gis.gdal import DataSource
|
||||||
|
@ -374,8 +363,7 @@ shapefiles are only allowed to have one layer::
|
||||||
>>> print(lyr)
|
>>> print(lyr)
|
||||||
TM_WORLD_BORDERS-0.3
|
TM_WORLD_BORDERS-0.3
|
||||||
|
|
||||||
You can see what the geometry type of the layer is and how many features it
|
You can see the layer's geometry type and how many features it contains::
|
||||||
contains::
|
|
||||||
|
|
||||||
>>> print(lyr.geom_type)
|
>>> print(lyr.geom_type)
|
||||||
Polygon
|
Polygon
|
||||||
|
@ -384,16 +372,16 @@ contains::
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Unfortunately the shapefile data format does not allow for greater
|
Unfortunately, the shapefile data format does not allow for greater
|
||||||
specificity with regards to geometry types. This shapefile, like
|
specificity with regards to geometry types. This shapefile, like
|
||||||
many others, actually includes ``MultiPolygon`` geometries in its
|
many others, actually includes ``MultiPolygon`` geometries, not Polygons.
|
||||||
features. You need to watch out for this when creating your models
|
It's important to use a more general field type in models: a
|
||||||
as a GeoDjango ``PolygonField`` will not accept a ``MultiPolygon``
|
GeoDjango ``MultiPolygonField`` will accept a ``Polygon`` geometry, but a
|
||||||
type geometry -- thus a ``MultiPolygonField`` is used in our model's
|
``PolygonField`` will not accept a ``MultiPolygon`` type geometry. This
|
||||||
definition instead.
|
is why the ``WorldBorder`` model defined above uses a ``MultiPolygonField``.
|
||||||
|
|
||||||
The :class:`~django.contrib.gis.gdal.Layer` may also have a spatial reference
|
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
|
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::
|
||||||
|
|
||||||
>>> srs = lyr.srs
|
>>> srs = lyr.srs
|
||||||
|
@ -406,9 +394,9 @@ system associated with it -- if it does, the ``srs`` attribute will return a
|
||||||
>>> srs.proj4 # PROJ.4 representation
|
>>> srs.proj4 # PROJ.4 representation
|
||||||
'+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs '
|
'+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs '
|
||||||
|
|
||||||
Here we've noticed that the shapefile is in the popular WGS84 spatial reference
|
This shapefile is in the popular WGS84 spatial reference
|
||||||
system -- in other words, the data uses units of degrees longitude and
|
system -- in other words, the data uses longitude, latitude pairs in
|
||||||
latitude.
|
units of degrees.
|
||||||
|
|
||||||
In addition, shapefiles also support attribute fields that may contain
|
In addition, shapefiles also support attribute fields that may contain
|
||||||
additional data. Here are the fields on the World Borders layer:
|
additional data. Here are the fields on the World Borders layer:
|
||||||
|
@ -416,8 +404,8 @@ additional data. Here are the fields on the World Borders layer:
|
||||||
>>> print(lyr.fields)
|
>>> print(lyr.fields)
|
||||||
['FIPS', 'ISO2', 'ISO3', 'UN', 'NAME', 'AREA', 'POP2005', 'REGION', 'SUBREGION', 'LON', 'LAT']
|
['FIPS', 'ISO2', 'ISO3', 'UN', 'NAME', 'AREA', 'POP2005', 'REGION', 'SUBREGION', 'LON', 'LAT']
|
||||||
|
|
||||||
Here we are examining the OGR types (e.g., whether a field is an integer or
|
The following code will let you examine the OGR types (e.g. integer or
|
||||||
a string) associated with each of the fields:
|
string) associated with each of the fields:
|
||||||
|
|
||||||
>>> [fld.__name__ for fld in lyr.field_types]
|
>>> [fld.__name__ for fld in lyr.field_types]
|
||||||
['OFTString', 'OFTString', 'OFTString', 'OFTInteger', 'OFTString', 'OFTInteger', 'OFTInteger', 'OFTInteger', 'OFTInteger', 'OFTReal', 'OFTReal']
|
['OFTString', 'OFTString', 'OFTString', 'OFTInteger', 'OFTString', 'OFTInteger', 'OFTInteger', 'OFTInteger', 'OFTInteger', 'OFTReal', 'OFTReal']
|
||||||
|
@ -446,8 +434,7 @@ And individual features may be retrieved by their feature ID::
|
||||||
>>> print(feat.get('NAME'))
|
>>> print(feat.get('NAME'))
|
||||||
San Marino
|
San Marino
|
||||||
|
|
||||||
Here the boundary geometry for San Marino is extracted and looking
|
Boundary geometries may be exported as WKT and GeoJSON::
|
||||||
exported to WKT and GeoJSON::
|
|
||||||
|
|
||||||
>>> geom = feat.geom
|
>>> geom = feat.geom
|
||||||
>>> print(geom.wkt)
|
>>> print(geom.wkt)
|
||||||
|
@ -459,8 +446,9 @@ exported to WKT and GeoJSON::
|
||||||
``LayerMapping``
|
``LayerMapping``
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
We're going to dive right in -- create a file called ``load.py`` inside the
|
To import the data, use a LayerMapping in a Python script.
|
||||||
``world`` application, and insert the following::
|
Create a file called ``load.py`` inside the ``world`` application,
|
||||||
|
with the following code::
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from django.contrib.gis.utils import LayerMapping
|
from django.contrib.gis.utils import LayerMapping
|
||||||
|
@ -492,20 +480,20 @@ We're going to dive right in -- create a file called ``load.py`` inside the
|
||||||
A few notes about what's going on:
|
A few notes about what's going on:
|
||||||
|
|
||||||
* Each key in the ``world_mapping`` dictionary corresponds to a field in the
|
* Each key in the ``world_mapping`` dictionary corresponds to a field in the
|
||||||
``WorldBorder`` model, and the value is the name of the shapefile field
|
``WorldBorder`` model. The value is the name of the shapefile field
|
||||||
that data will be loaded from.
|
that data will be loaded from.
|
||||||
* The key ``mpoly`` for the geometry field is ``MULTIPOLYGON``, the
|
* The key ``mpoly`` for the geometry field is ``MULTIPOLYGON``, the
|
||||||
geometry type we wish to import as. Even if simple polygons are encountered
|
geometry type GeoDjango will import the field as. Even simple polygons in
|
||||||
in the shapefile they will automatically be converted into collections prior
|
the shapefile will automatically be converted into collections prior to
|
||||||
to insertion into the database.
|
insertion into the database.
|
||||||
* The path to the shapefile is not absolute -- in other words, if you move the
|
* The path to the shapefile is not absolute -- in other words, if you move the
|
||||||
``world`` application (with ``data`` subdirectory) to a different location,
|
``world`` application (with ``data`` subdirectory) to a different location,
|
||||||
then the script will still work.
|
the script will still work.
|
||||||
* The ``transform`` keyword is set to ``False`` because the data in the
|
* The ``transform`` keyword is set to ``False`` because the data in the
|
||||||
shapefile does not need to be converted -- it's already in WGS84 (SRID=4326).
|
shapefile does not need to be converted -- it's already in WGS84 (SRID=4326).
|
||||||
* The ``encoding`` keyword is set to the character encoding of string values in
|
* The ``encoding`` keyword is set to the character encoding of the string
|
||||||
the shapefile. This ensures that string values are read and saved correctly
|
values in the shapefile. This ensures that string values are read and saved
|
||||||
from their original encoding system.
|
correctly from their original encoding system.
|
||||||
|
|
||||||
Afterwards, invoke the Django shell from the ``geodjango`` project directory:
|
Afterwards, invoke the Django shell from the ``geodjango`` project directory:
|
||||||
|
|
||||||
|
@ -513,8 +501,8 @@ Afterwards, invoke the Django shell from the ``geodjango`` project directory:
|
||||||
|
|
||||||
$ python manage.py shell
|
$ python manage.py shell
|
||||||
|
|
||||||
Next, import the ``load`` module, call the ``run`` routine, and watch ``LayerMapping``
|
Next, import the ``load`` module, call the ``run`` routine, and watch
|
||||||
do the work::
|
``LayerMapping`` do the work::
|
||||||
|
|
||||||
>>> from world import load
|
>>> from world import load
|
||||||
>>> load.run()
|
>>> load.run()
|
||||||
|
@ -536,7 +524,7 @@ The general usage of the command goes as follows:
|
||||||
|
|
||||||
$ python manage.py ogrinspect [options] <data_source> <model_name> [options]
|
$ python manage.py ogrinspect [options] <data_source> <model_name> [options]
|
||||||
|
|
||||||
Where ``data_source`` is the path to the GDAL-supported data source and
|
``data_source`` is the path to the GDAL-supported data source and
|
||||||
``model_name`` is the name to use for the model. Command-line options may
|
``model_name`` is the name to use for the model. Command-line options may
|
||||||
be used to further define how the model is generated.
|
be used to further define how the model is generated.
|
||||||
|
|
||||||
|
@ -600,9 +588,9 @@ Spatial Queries
|
||||||
|
|
||||||
Spatial Lookups
|
Spatial Lookups
|
||||||
---------------
|
---------------
|
||||||
GeoDjango extends the Django ORM and allows the use of spatial lookups.
|
GeoDjango adds spatial lookups to the Django ORM. For example, you
|
||||||
Let's do an example where we find the ``WorldBorder`` model that contains
|
can find the country in the ``WorldBorder`` table that contains
|
||||||
a point. First, fire up the management shell:
|
a particular point. First, fire up the management shell:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
@ -613,8 +601,8 @@ Now, define a point of interest [#]_::
|
||||||
>>> pnt_wkt = 'POINT(-95.3385 29.7245)'
|
>>> pnt_wkt = 'POINT(-95.3385 29.7245)'
|
||||||
|
|
||||||
The ``pnt_wkt`` string represents the point at -95.3385 degrees longitude,
|
The ``pnt_wkt`` string represents the point at -95.3385 degrees longitude,
|
||||||
and 29.7245 degrees latitude. The geometry is in a format known as
|
29.7245 degrees latitude. The geometry is in a format known as
|
||||||
Well Known Text (WKT), an open standard issued by the Open Geospatial
|
Well Known Text (WKT), a standard issued by the Open Geospatial
|
||||||
Consortium (OGC). [#]_ Import the ``WorldBorder`` model, and perform
|
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::
|
||||||
|
|
||||||
|
@ -623,11 +611,13 @@ a ``contains`` lookup using the ``pnt_wkt`` as the parameter::
|
||||||
>>> qs
|
>>> qs
|
||||||
[<WorldBorder: United States>]
|
[<WorldBorder: United States>]
|
||||||
|
|
||||||
Here we retrieved a ``GeoQuerySet`` that has only one model: the one
|
Here, you retrieved a ``GeoQuerySet`` with only one model: the border of
|
||||||
for the United States (which is what we would expect). Similarly,
|
the United States (exactly what you would expect).
|
||||||
a :ref:`GEOS geometry object <ref-geos>` may also be used -- here the
|
|
||||||
``intersects`` spatial lookup is combined with the ``get`` method to retrieve
|
Similarly, you may also use a :ref:`GEOS geometry object <ref-geos>`.
|
||||||
only the ``WorldBorder`` instance for San Marino instead of a queryset::
|
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::
|
||||||
|
|
||||||
>>> from django.contrib.gis.geos import Point
|
>>> from django.contrib.gis.geos import Point
|
||||||
>>> pnt = Point(12.4604, 43.9420)
|
>>> pnt = Point(12.4604, 43.9420)
|
||||||
|
@ -635,16 +625,16 @@ only the ``WorldBorder`` instance for San Marino instead of a queryset::
|
||||||
>>> sm
|
>>> sm
|
||||||
<WorldBorder: San Marino>
|
<WorldBorder: San Marino>
|
||||||
|
|
||||||
The ``contains`` and ``intersects`` lookups are just a subset of what's
|
The ``contains`` and ``intersects`` lookups are just a subset of the
|
||||||
available -- the :ref:`ref-gis-db-api` documentation has more.
|
available queries -- the :ref:`ref-gis-db-api` documentation has more.
|
||||||
|
|
||||||
Automatic Spatial Transformations
|
Automatic Spatial Transformations
|
||||||
---------------------------------
|
---------------------------------
|
||||||
When querying the spatial database GeoDjango automatically transforms
|
When doing spatial queries, GeoDjango automatically transforms
|
||||||
geometries if they're in a different coordinate system. In the following
|
geometries if they're in a different coordinate system. In the following
|
||||||
example, the coordinate will be expressed in terms of `EPSG SRID 32140`__,
|
example, coordinates will be expressed in `EPSG SRID 32140`__,
|
||||||
a coordinate system specific to south Texas **only** and in units of
|
a coordinate system specific to south Texas **only** and in units of
|
||||||
**meters** and not degrees::
|
**meters**, not degrees::
|
||||||
|
|
||||||
>>> from django.contrib.gis.geos import Point, GEOSGeometry
|
>>> from django.contrib.gis.geos import Point, GEOSGeometry
|
||||||
>>> pnt = Point(954158.1, 4215137.1, srid=32140)
|
>>> pnt = Point(954158.1, 4215137.1, srid=32140)
|
||||||
|
@ -654,7 +644,7 @@ WKT that includes the SRID::
|
||||||
|
|
||||||
>>> pnt = GEOSGeometry('SRID=32140;POINT(954158.1 4215137.1)')
|
>>> pnt = GEOSGeometry('SRID=32140;POINT(954158.1 4215137.1)')
|
||||||
|
|
||||||
When using GeoDjango's ORM, it will automatically wrap geometry values
|
GeoDjango's ORM will automatically wrap geometry values
|
||||||
in transformation SQL, allowing the developer to work at a higher level
|
in transformation SQL, allowing the developer to work at a higher level
|
||||||
of abstraction::
|
of abstraction::
|
||||||
|
|
||||||
|
@ -675,7 +665,7 @@ __ http://spatialreference.org/ref/epsg/32140/
|
||||||
|
|
||||||
When using :doc:`raw queries </topics/db/sql>`, you should generally wrap
|
When using :doc:`raw queries </topics/db/sql>`, you should generally wrap
|
||||||
your geometry fields with the ``asText()`` SQL function (or ``ST_AsText``
|
your geometry fields with the ``asText()`` SQL function (or ``ST_AsText``
|
||||||
for PostGIS) so as the field value will be recognized by GEOS::
|
for PostGIS) so that the field value will be recognized by GEOS::
|
||||||
|
|
||||||
City.objects.raw('SELECT id, name, asText(point) from myapp_city')
|
City.objects.raw('SELECT id, name, asText(point) from myapp_city')
|
||||||
|
|
||||||
|
@ -684,8 +674,8 @@ __ http://spatialreference.org/ref/epsg/32140/
|
||||||
|
|
||||||
Lazy Geometries
|
Lazy Geometries
|
||||||
---------------
|
---------------
|
||||||
Geometries come to GeoDjango in a standardized textual representation. Upon
|
GeoDjango loads geometries in a standardized textual representation. When the
|
||||||
access of the geometry field, GeoDjango creates a `GEOS geometry object
|
geometry field is first accessed, GeoDjango creates a `GEOS geometry object
|
||||||
<ref-geos>`, exposing powerful functionality, such as serialization properties
|
<ref-geos>`, exposing powerful functionality, such as serialization properties
|
||||||
for popular geospatial formats::
|
for popular geospatial formats::
|
||||||
|
|
||||||
|
@ -715,14 +705,11 @@ the GEOS library::
|
||||||
Putting your data on the map
|
Putting your data on the map
|
||||||
============================
|
============================
|
||||||
|
|
||||||
Google
|
|
||||||
------
|
|
||||||
|
|
||||||
Geographic Admin
|
Geographic Admin
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
GeoDjango extends :doc:`Django's admin application </ref/contrib/admin/index>`
|
GeoDjango extends :doc:`Django's admin application </ref/contrib/admin/index>`
|
||||||
to enable support for editing geometry fields.
|
with support for editing geometry fields.
|
||||||
|
|
||||||
Basics
|
Basics
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
@ -730,16 +717,15 @@ Basics
|
||||||
GeoDjango also supplements the Django admin by allowing users to create
|
GeoDjango also supplements the Django admin by allowing users to create
|
||||||
and modify geometries on a JavaScript slippy map (powered by `OpenLayers`_).
|
and modify geometries on a JavaScript slippy map (powered by `OpenLayers`_).
|
||||||
|
|
||||||
Let's dive in again -- create a file called ``admin.py`` inside the
|
Let's dive right in. Create a file called ``admin.py`` inside the
|
||||||
``world`` application, and insert the following::
|
``world`` application with the following code::
|
||||||
|
|
||||||
from django.contrib.gis import admin
|
from django.contrib.gis import admin
|
||||||
from models import WorldBorder
|
from models import WorldBorder
|
||||||
|
|
||||||
admin.site.register(WorldBorder, admin.GeoModelAdmin)
|
admin.site.register(WorldBorder, admin.GeoModelAdmin)
|
||||||
|
|
||||||
Next, edit your ``urls.py`` in the ``geodjango`` application folder to look
|
Next, edit your ``urls.py`` in the ``geodjango`` application folder as follows::
|
||||||
as follows::
|
|
||||||
|
|
||||||
from django.conf.urls import patterns, url, include
|
from django.conf.urls import patterns, url, include
|
||||||
from django.contrib.gis import admin
|
from django.contrib.gis import admin
|
||||||
|
@ -775,9 +761,9 @@ With the :class:`~django.contrib.gis.admin.OSMGeoAdmin`, GeoDjango uses
|
||||||
a `Open Street Map`_ layer in the admin.
|
a `Open Street Map`_ layer in the admin.
|
||||||
This provides more context (including street and thoroughfare details) than
|
This provides more context (including street and thoroughfare details) than
|
||||||
available with the :class:`~django.contrib.gis.admin.GeoModelAdmin`
|
available with the :class:`~django.contrib.gis.admin.GeoModelAdmin`
|
||||||
(which uses the `Vector Map Level 0`_ WMS data set hosted at `OSGeo`_).
|
(which uses the `Vector Map Level 0`_ WMS dataset hosted at `OSGeo`_).
|
||||||
|
|
||||||
First, there are some important requirements and limitations:
|
First, there are some important requirements:
|
||||||
|
|
||||||
* :class:`~django.contrib.gis.admin.OSMGeoAdmin` requires that the
|
* :class:`~django.contrib.gis.admin.OSMGeoAdmin` requires that the
|
||||||
:ref:`spherical mercator projection be added <addgoogleprojection>`
|
:ref:`spherical mercator projection be added <addgoogleprojection>`
|
||||||
|
@ -785,14 +771,19 @@ First, there are some important requirements and limitations:
|
||||||
* The PROJ.4 datum shifting files must be installed (see the
|
* The PROJ.4 datum shifting files must be installed (see the
|
||||||
:ref:`PROJ.4 installation instructions <proj4>` for more details).
|
:ref:`PROJ.4 installation instructions <proj4>` for more details).
|
||||||
|
|
||||||
If you meet these requirements, then just substitute in the ``OSMGeoAdmin``
|
If you meet these requirements, then just substitute the ``OSMGeoAdmin``
|
||||||
option class in your ``admin.py`` file::
|
option class in your ``admin.py`` file::
|
||||||
|
|
||||||
admin.site.register(WorldBorder, admin.OSMGeoAdmin)
|
admin.site.register(WorldBorder, admin.OSMGeoAdmin)
|
||||||
|
|
||||||
.. rubric:: Footnotes
|
.. rubric:: Footnotes
|
||||||
|
|
||||||
.. [#] Special thanks to Bjørn Sandvik of `thematicmapping.org <http://thematicmapping.org>`_ for providing and maintaining this data set.
|
.. [#] Special thanks to Bjørn Sandvik of `thematicmapping.org
|
||||||
.. [#] GeoDjango basic apps was written by Dane Springmeyer, Josh Livni, and Christopher Schmidt.
|
<http://thematicmapping.org>`_ for providing and maintaining this
|
||||||
.. [#] Here the point is for the `University of Houston Law Center <http://www.law.uh.edu/>`_.
|
dataset.
|
||||||
.. [#] Open Geospatial Consortium, Inc., `OpenGIS Simple Feature Specification For SQL <http://www.opengeospatial.org/standards/sfs>`_.
|
.. [#] GeoDjango basic apps was written by Dane Springmeyer, Josh Livni, and
|
||||||
|
Christopher Schmidt.
|
||||||
|
.. [#] This point is the `University of Houston Law Center
|
||||||
|
<http://www.law.uh.edu/>`_.
|
||||||
|
.. [#] Open Geospatial Consortium, Inc., `OpenGIS Simple Feature Specification
|
||||||
|
For SQL <http://www.opengeospatial.org/standards/sfs>`_.
|
||||||
|
|
Loading…
Reference in New Issue