In this tutorial we’re going to build the foundations of an application that tracks animals in natural reserves.
Note
This tutorial assumes familiarity with Django; thus, if you’re brand new to Django, please read through the regular tutorial to familiarize yourself with Django first.
GeoDjango has additional requirements beyond what Django requires –
please consult the installation documentation
for more details.
Use the standard django-admin
script to create a project called
geodjango
:
$ django-admin startproject geodjango
This will initialize a new project. Now, create a tracking
Django application
within the geodjango
project:
$ cd geodjango
$ python manage.py startapp tracking
settings.py
¶The geodjango
project settings are stored in the geodjango/settings.py
file. Edit the database connection settings to match your setup:
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
...
}
}
In addition, modify the INSTALLED_APPS
setting to include
django.contrib.admin
, django.contrib.gis
,
and tracking
(your newly created application):
INSTALLED_APPS = [
'tracking',
'django.contrib.gis',
...
]
Edit tracking/models.py
to look like the following:
from django.contrib.gis.db import models
class Animal(models.Model):
species = models.CharField(max_length=50)
name = models.CharField(max_length=50)
position = models.PointField()
def __unicode__(self):
return '%s (%s)' % (self.name, self.species)
class Reserve(models.Model):
name = models.CharField(max_length=50)
boundaries = models.PolygonField()
def __unicode__(self):
return self.name
As you can see, all Django models are available through GeoDjango’s models. We
used a new model type, provided by GeoDjango, named PointField
.
Note
The default spatial reference system for geometry fields is WGS84 (meaning
the SRID is 4326) – in other words, the field coordinates are in
longitude, latitude pairs in units of degrees. To use a different
coordinate system, set the SRID of the geometry field with the srid
argument. Use an integer representing the coordinate system’s EPSG code.
After defining your model, we need to sync it with the database. First, create a database migration:
$ python manage.py makemigrations
Migrations for 'tracking':
0001_initial.py:
- Create model Animal
- Create model Reserve
Next, run migrate
to create this table in the database:
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, tracking, contenttypes, auth, sessions
Running migrations:
...
Applying tracking.0001_initial... OK
Let’s create some objects and see what we can do with them.
$ python manage.py shell
Let’s see how it works:
>>> from tracking.models import Animal
>>> from django.contrib.gis.geos import Point
>>> Animal(name='Hobbes', species='tiger', position=Point(0, 0)).save()
>>> Animal(name='Marcel', species='elephant', position=Point(10, 10)).save()
>>> Animal(name='Bob', species='elephant', position=Point(10, 12)).save()
Note
You might wonder what these coordinates mean. Actually they don’t mean anything, they’re just examples. You’ll rarely have to enter this kind of data manually, usually it will come from a map, an external service, or something similar.
We can easily calculate the distance between Hobbes the tiger and Marcel the elephant using the _distance-queries distance method:
>>> marcel = Animal.objects.get('Marcel')
>>> hobbes = Animal.objects.get(name='Hobbes').annotate(
... distance=Distance('position', marcel.position)
... )
>>> hobbes.distance
Distance(m=1568522.71629)
>>> # Distance objects can easily be converted to various units
>>> hobbes.distance.km
1568.52271629392
We can get the list of all individuals ordered by their distance from the only tiger in the reserve:
>>> Animal.objects.distance(Animal.objects.get(species='tiger').position).order_by('distance')
We can even search for elephants that are less than 500 km away from the tiger:
>>> from django.contrib.gis.measure import D
>>> hobbes = Animal.objects.get(name='Hobbes')
>>> Animal.objects.filter(species='elephant', position__distance_lt=(hobbes.position, D(km=500)))
[<Animal: Marcel (elephant)>, <Animal: Bob (elephant)>]
At this point we have defined geographic models and we can already add/edit data and do distance calculations. Chances are you’ll want a better interface to enter the data though, and this is where the admin interface comes into play. Head over the part 2 of this tutorial to start working with the admin.
Apr 03, 2016