Installing GeoDjango with PostgreSQL and zc.buildout
I've been wanting to play with GeoDjango for a while, since my database of choice (PostgreSQL) has excellent spatial support. However, getting all the dependencies up and running is pretty complicated.
I've been working on a buildout to get at least most of the steps done for you. There are a couple of manual steps at the end, which I hope to automate when I next have time to work on this.
The buildout installs the following items:
- PostgreSQL
- PostGIS
- GDAL
- Proj
- GEOS
- psycopg2
- Django
It should also perform initial setup of the PostGIS database template, loading some sample SQL files, and sets up some convenience symlinks for the PostgreSQL command-line programs.
It's not finished - in particular, it just assumes that the user running the buildout is to be used as the database owner and such like. Anyway, here it is:
[buildout]
parts =
postgresql
postgis
gdal
init-pgsql
pgsql-symlinks
django
eggs =
psycopg2
[postgresql]
recipe = zc.recipe.cmmi
url = http://wwwmaster.postgresql.org/redir/198/h/source/v8.3.7/postgresql-8.3.7.tar.gz
extra_options =
--with-readline
--enable-thread-safety
[postgis]
recipe = hexagonit.recipe.cmmi
url = http://postgis.refractions.net/download/postgis-1.3.5.tar.gz
configure-options =
--with-pgsql=${postgresql:location}/bin/pg_config
--with-geos=${geos:location}/bin/geos-config
--with-proj=${proj:location}
[proj]
recipe = zc.recipe.cmmi
url = http://download.osgeo.org/proj/proj-4.6.1.tar.gz
[geos]
recipe = zc.recipe.cmmi
url = http://download.osgeo.org/geos/geos-3.0.3.tar.bz2
[gdal]
recipe = zc.recipe.cmmi
url = http://download.osgeo.org/gdal/gdal-1.6.0.tar.gz
extra_options =
--with-python
--with-geos=${geos:location}/bin/geos-config
[init-pgsql]
recipe = iw.recipe.cmd
on_install = true
on_update = false
cmds =
${postgresql:location}/bin/initdb -D ${postgresql:location}/var/data -E UNICODE
${postgresql:location}/bin/pg_ctl -D ${postgresql:location}/var/data start
sleep 30
${postgresql:location}/bin/createdb -E UTF8 template_postgis
${postgresql:location}/bin/createlang -d template_postgis plpgsql
${postgresql:location}/bin/psql -d template_postgis -f ${postgis:location}/share/lwpostgis.sql
${postgresql:location}/bin/psql -d template_postgis -f ${postgis:location}/share/spatial_ref_sys.sql
${postgresql:location}/bin/psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;"
${postgresql:location}/bin/psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;"
${postgresql:location}/bin/pg_ctl -D ${postgresql:location}/var/data stop
[pgsql-symlinks]
recipe = cns.recipe.symlink
symlink_target = ${buildout:directory}/bin
symlink_base = ${postgresql:location}/bin
symlink =
clusterdb
createdb
createlang
createuser
dropdb
droplang
dropuser
ecpg
initdb
ipcclean
pg_config
pg_controldata
pg_ctl
pg_dump
pg_dumpall
pg_resetxlog
pg_restore
postgres
postmaster
psql
reindexdb
vacuumdb
[django]
recipe = djangorecipe
version = 1.0.2
project = project
eggs =
${buildout:eggs}
Note that running this will actually attempt to start up and shut down the database server, as it needs to be running in order for some of the initialisation scripts to run. That 'sleep 30' in the middle is to allow the database server to start, and (if you're on OS X and running it) to give you a change to enter your username and password for the firewall!
There are still some manual steps to be taken (which I'd like to automate in due course). These are the fairly standard things that you do when starting any Django project, plus an extra step for bootstrapping PostGIS.
Create your database
From the command line, you'll need to create the database for you application. You need to specify the PostGIS template, so use something like:
$ bin/createdb -T template_postgis <db name>
Change the settings for your application
Edit the settings.py for your application, and make sure that you're using 'postgresql_psycopg2' as the database engine. Set the database name as appropriate for your application. You should also add 'django.contrib.gis' to your INSTALLED_APPS setting, and you'll also need to add the following two lines to your settings.py:
GDAL_LIBRARY_PATH = '/path/to/buildout/parts/gdal/lib/libgdal.dylib'
GEOS_LIBRARY_PATH = '/path/to/buildout/parts/geos/lib/libgeos_c.dylib'
Add Google projection
I'll confess: I'm only doing this because the GeoDjango docs say you should! I don't know enough about GeoDjango yet to understand why. But you should do the following:
$ bin/django shell
>>> from django.contrib.gis.utils import add_postgis_srs
>>> add_postgis_srs(900913)
>>> ^D
$
If you get an error when importing add_postgis_srs, then double check you got the GDAL_LIBRARY_PATH and GEOS_LIBRARY_PATH correct, and that the files specified were built. (I'm on Mac OS X - I suspect the exact file name may change depending on platform.)
Done!
Once all that's done, you should hopefully be able to bin/django syncdb, start a new app (using fez.djangoskel, of course!) and start using GeoDjango.
I shall refine the above process over time (in particular, there are some modifications I'd like to make to djangorecipe to remove the manual steps at the end), and I'll post extra parts when I've done that.

Great write up!
Ben