- Avoir Django (et donc GeoDjango) d'installé
Introduction
Ce tutoriel fait suite à une première présentation de GeoDjango. Il se veut plus concis et vous permettra d'appréhender ce framework d'une manière plus directe. Nous aborderons également plus en détails l'interrogation des données.
Création du projet
La création d'un nouveau projet se fait via la commande shell startproject (documentation complète sur Django-fr):
$ django-admin startproject geoDjangoBasic
Cette commande a pour effet de construire l'arborescence de fichiers nécessaires. Ces derniers sont (src Django-fr):
- __init__.py : Un fichier vide que dit à Python que ce répertoire doit être considéré comme un paquetage Python
- manage.py : Un outil en ligne de commande que vous permet d'intéragir avec ce projet Django de différentes manières
- settings.py : Fichier de configuration de ce projet Django
- urls.py : Les déclarations d'URLs pour ce projet Django ; il s'agit d'une « table des matières » de votre site géré par Django.
Paramétrage du fichier settings.py
Avant d'aller plus loin, il est nécessaire que nous renseignons un peu notre fichier settings.py et notamment la partie correspondant à la base de données utilisée. Pour une explication complète reportez-vous à ce précédent tutoriel, si la base que vous utilisez est de type PostGis il sera nécessaire que vous réalisiez également cette étape.
N'oublions pas également d'ajouter le package 'django.contrib.gis' dans INSTALLED_APPS. Profitons également pour nous avancer et ajouter toujours dans INSTALLED_APPS l'application que nous allons créer au chapitre suivant : 'geoDjangoBasic.geoData'.
De manière imagée, nous avons construit les fondations de notre bâtiment. Il reste maintenant à monter les murs, c'est ce que nous allons faire en créant notre application.
Création de l'application
La création d'une application se déroule en plusieures étapes. Il sera nécessaire tout d'abord d'initialiser celle-çi à partir de Django, pour ensuite définir le modèle correspondant à nos données pour enfin les importer dans notre base.
Création de l'application
pour créer notre application django dispose d'un utilitaire disponible à partir du fichier manage.py. La commande à réaliser dans un shell est la suivante :
$ python manage.py startapp geoData
Ceci a pour effet de créer à nouveau une nouvelle arborescence de fichier :
- __init__.py : Un fichier vide qui dit à Python que ce répertoire doit être considéré comme un paquetage Python
- models.py : Décrit ou contient les données manipulées par l'application
- views.py : Interface avec laquelle l'utilisateur agit. Sa première tâche est de présenter les résultats renvoyés par le modèle
Nous retrouvons ici l'architecture de Django basée sur une logique Modèle-Vue-Contrôleur (plus de détails dans Wikipedia).
Structuration du modèle de données
Nous utiliserons les données disponibles sur le site thematicmapping.org.
Il existe différentes manières de déterminer le modèle décrivant les données que nous allons importer. Nous utiliserons la manière qui me semble la plus simple, ogrinspect. La commande est la suivante :
$ python manage.py ogrinspect geoData/data/TM_WORLD_BORDERS_SIMPL-0.3.shp GeoModel --srid=4326 --mapping --multi
Celle-çi analyse les données et renvoie le modèle et le dictionnaire de données correspondant :
# This is an auto-generated Django model module created by ogrinspect. from django.contrib.gis.db import models class GeoModel(models.Model): fips = models.CharField(max_length=2) iso2 = models.CharField(max_length=2) iso3 = models.CharField(max_length=3) un = models.IntegerField() name = models.CharField(max_length=50) area = models.IntegerField() pop2005 = models.IntegerField() region = models.IntegerField() subregion = models.IntegerField() lon = models.FloatField() lat = models.FloatField() geom = models.MultiPolygonField(srid=4326) objects = models.GeoManager() # Auto-generated `LayerMapping` dictionary for GeoModel model geomodel_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', }
Copions la classe GeoModel dans le fichier models.py de notre application :
from django.db import models from django.contrib.gis.db import models class GeoModel(models.Model): fips = models.CharField(max_length=2) iso2 = models.CharField(max_length=2) iso3 = models.CharField(max_length=3) un = models.IntegerField() name = models.CharField(max_length=50) area = models.IntegerField() pop2005 = models.IntegerField() region = models.IntegerField() subregion = models.IntegerField() lon = models.FloatField() lat = models.FloatField() geom = models.MultiPolygonField(srid=4326) objects = models.GeoManager()
Lançons maintenant la commande sqlall puis syncdb du fichier manage.py. La première vous permettra de consulter le code SQL qui sera généré tandis que la seconde va créer concrètement les champs dans la base.
BEGIN; CREATE TABLE "geoData_geomodel" ( "id" serial NOT NULL PRIMARY KEY, "fips" varchar(2) NOT NULL, "iso2" varchar(2) NOT NULL, "iso3" varchar(3) NOT NULL, "un" integer NOT NULL, "name" varchar(50) NOT NULL, "area" integer NOT NULL, "pop2005" integer NOT NULL, "region" integer NOT NULL, "subregion" integer NOT NULL, "lon" double precision NOT NULL, "lat" double precision NOT NULL ) ; SELECT AddGeometryColumn('geoData_geomodel', 'geom', 4326, 'MULTIPOLYGON', 2); ALTER TABLE "geoData_geomodel" ALTER "geom" SET NOT NULL; CREATE INDEX "geoData_geomodel_geom_id" ON "geoData_geomodel" USING GIST ( "geom" GIST_GEOMETRY_OPS ); COMMIT;
Creating table geoData_geomodel
Installing custom SQL for geoData.GeoModel modelImport des données dans la base
Maintenant que nous avons préparé notre projet et notre application, structuré notre base il ne nous reste plus qu'à importer nos données. Pour cela nous utiliserons la classe LayerMapping de GeoDjango.
Nous allons donc créer un fichier load.py et y ajouter le code suivant :
import os from django.contrib.gis.utils import LayerMapping from models import GeoModel # Auto-generated "LayerMapping" dictionary for GeoModel model import os from django.contrib.gis.utils import LayerMapping from models import GeoModel # Auto-generated `LayerMapping` dictionary for GeoModel model geomodel_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', } world_shp = os.path.abspath(os.path.join(os.path.dirname(__file__), 'data/TM_WORLD_BORDERS_SIMPL-0.3.shp')) def run(verbose=True): lm = LayerMapping(GeoModel, world_shp, geomodel_mapping, transform=False, encoding='iso-8859-1') lm.save(strict=True, verbose=verbose)
Nous retrouvons ci-dessus le dictionnaire de données que nous avons généré précédemment. Il ne reste plus ensuite qu'à instancier la classe LayerMapping et sa méthode save(). Revenons à notre console shell et appelons notre fichier load.py :
$ python manage.py shell >>> from world import load >>> load.run()
Et voilà, nous avons intégré l'ensemble du fichier shape dans notre base de données. Juste par précaution verifions que l'import s'est bien passé. Cela nous permettra par la même occasion de manipuler l'API de la base de données de Django Et GeoDjango.
interrogation des données
En plus des possibilités offertes par Django, GeoDjango enrichit considérablement l'API initiale concernant la base de données en permettant la réalisation d'interrogations et requêtes spatiales. Explorons un peu nos données. pour cela, ouvrons une console python ($ python manage.py shell) et exécutons les commandes suivantes :
>>> from geoDjangoBasic.geoData.models import GeoModel >>> from django.contrib.gis.gdal import * >>> >>> featz = GeoModel.objects.all() >>> for i in featz : ... print i.name ... Antigua and Barbuda Algeria Azerbaijan Albania [...] Guernsey Jersey South Georgia South Sandwich Islands Taiwan >>> >>> >>>feat = GeoModel.objects.get(name='Algeria') >>>print feat.area 238174 >>> >>> >>> featPopSup = GeoModel.objects.filter(pop2005__gt=1000000000) >>> for i in featPopSup : ... print i.name ... China India >>> >>> >>> gmlfeat = featz.gml() >>> print gmlfeat[0].gml <gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-61.686668,17.0244410000002 -61.887222,17.105274 -61.7944489999999,17.1633300000001 -61.686668,17.0244410000002</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-61.7291719999999,17.608608 -61.853058,17.5830540000001 -61.873062,17.7038880000001 -61.7291719999999,17.608608</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon> >>> >>>
En résumé
Pour finir, ci-dessous est présenté un "road book" des différentes étapes nécessaires à la mise en place d'un projet GeoDjango :
- Création du projet : Cmd django-admin startproject
- Paramétrage du fichier settings.py
- Création de l'application : Cmd manage.py startapp
- Structuration du modèle de données : Cmd manage.py ogrinspect
- Copie du modèle dans le fichier models.py de l'application
- Génération de la table correspondant au modèle dans la BDD : manage.py syncdb
- Import des données SIG dans la base : LayerMapping
