space, → | next slide |
← | previous slide |
d | debug mode |
## <ret> | go to slide # |
c | table of contents (vi) |
f | toggle footer |
r | reload slides |
z | toggle help (this) |
Way to represent the curved surface on a flat surface
Compromises on distortion
Started by Justin Bronn in 2006-2007
Merged into Django in 2008
django.contrib.gis
Geographic Admin
GEOS / GDAL
DataSource / LayerMapping
Serialization (KML, GeoJSON, GeoRSS…)
INSTALLED_APPS += (
'django.contrib.gis',
)
DATABASES = {'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
# '...' ...,
}}
$ createdb -T template_postgis -E UTF8 europythongame
$ ./manage.py startapp countries
$ ./manage.py ogrinspect WORLD_BORDERS.shp Country \
--srid=4326 --mapping --multi-geom > coutries/models.py
from django.contrib.gis.db import models
class Country(models.Model):
fips = models.CharField('FIPS Code', max_length=2)
iso2 = models.CharField('2 Digit ISO', max_length=2)
iso3 = models.CharField('3 Digit ISO', max_length=3)
un = models.IntegerField('United Nations Code')
name = models.CharField('Name', max_length=50)
area = models.IntegerField()
pop2005 = models.IntegerField('Population in 2005')
region = models.IntegerField('Region Code')
subregion = models.IntegerField('Sub-Region Code')
lon = models.FloatField()
lat = models.FloatField()
geom = models.MultiPolygonField(srid=4326)
objects = models.GeoManager()
from django.contrib.gis.db import models
class Country(models.Model):
# ...
geom = models.MultiPolygonField(srid=4326)
objects = models.GeoManager()
country_mapping = {
'fips': 'FIPS',
'iso2': 'ISO2',
'iso3': 'ISO3',
'un': 'UN',
'name': 'NAME',
'area': 'AREA',
'pop2005': 'POP2005',
'region': 'REGION',
'subregion': 'SUBREGION',
'lon': 'LON',
'lat': 'LAT',
'geom': 'MULTIPOLYGON',
}
from django.contrib.gis.utils import LayerMapping
lm = LayerMapping(Country, 'TM_WORLD_BORDERS-0.3.shp',
country_mapping,
encoding='iso-8859-1')
lm.save(verbose=True)
from django.contrib.gis import admin
from coutries.models import Country
admin.site.register(Country, admin.GeoModelAdmin)
admin.site.register(Country, admin.OSMGeoAdmin)
pip install django-floppyforms
INSTALLED_APPS += ('floppyforms',)
import floppyforms as forms
Base widgets: map backends (OSM, GMaps, ...)
Geometry-specific widgets
Inherit from both
import floppyforms as forms
class MultiPolygonWidget(forms.gis.MultiPolygonWidget,
forms.gis.BaseOsmWidget):
pass
from countries.models import Country
class CountryForm(forms.ModelForm):
class Meta:
model = Country
widgets = {
'geom': MultiPolygonWidget,
}
from django.contrib import admin
class CountryAdmin(admin.ModelAdmin):
form = CountryForm
admin.site.register(Country, CountryAdmin)
>>> from django.contrib.gis.geos import Point
>>> from countries.models import Country
>>> p = Point(11.27, 43.77)
>>> Country.objects.filter(mpoly__contains=p)
[<Country: Italy>]
>>> Country.objects.distance(p).order_by('distance')[:5]
[<Country: Italy>, <Country: San Marino>, <Country: France>,
<Country: Holy See (Vatican City)>, <Country: Croatia>]
it = Country.objects.get(name='Italy')
# This is expensive
>>> Country.objects.distance(it.mpoly).order_by('distance')[:5]
[<Country: France>, <Country: San Marino>, <Country: Austria>,
<Country: Slovenia>, <Country: Italy>]
ct = Country.objects.order_by('?')
<script type="text/javascript"
src="OpenLayers.js"></script>
<div id="map"></div>
<textarea class="hidden">
{{ ct.geom.geojson|safe }}
</textarea>
var map = new OpenLayers.Map({
div: "map",
projection: "EPSG:900913",
maxExtent: new OpenLayers.Bounds(-20037508,
-20037508,20037508,20037508),
maxResolution: 156543.0339,
units: 'm',
controls: []
}),
parser = new OpenLayers.Format.GeoJSON();
features = parser.read($('textarea').innerHTML);
vector = new OpenLayers.Layer.Vector('Country'),
map.addLayer(vector);
map.setBaseLayer(vector);
var src = new OpenLayers.Projection('EPSG:4326');
var dst = map.getProjectionObject();
for (var i=0; i<features.length; i++) {
feature = features[i];
features.geometry.transform(src, dst);
}
vector.addFeatures(features);
map.zoomToExtent(vector.getDataExtent());
import floppyforms as forms
class ReadOnlyWidget(forms.gis.MultiPolygonWidget,
forms.gis.BaseOsmWidget):
template_name = 'questions/widget.html'
class CountryForm(forms.Form):
country = forms.gis.MultiPolygonField(
widget=ReadOnlyWidget,
)
{% extends "floppyforms/gis/osm.html" %}
{% block options %}{{ block.super }}
options['modifiable'] = false;
{% endblock %}
form = CountryForm(
initial={
'country': previous.country.geom,
},
)
{{ form.media }}
{{ form }}
Game mechanics
Twitter authentication
GeoDjango docs / source code
#geodjango on freenode
OSM talk