---
title: "API de base de données GeoDjango"
version: 1.9
locale: fr
source: https://docs.djangoproject.com/fr/1.9/ref/contrib/gis/db-api/
canonical: https://djangodocs.dev/fr/1.9/ref/contrib/gis/db-api/
---
# API de base de données GeoDjango

## Moteurs de base de données spatiales

GeoDjango propose actuellement les moteurs de base de données spatiales suivants :

- `django.contrib.gis.db.backends.postgis`
- `django.contrib.gis.db.backends.mysql`
- `django.contrib.gis.db.backends.oracle`
- `django.contrib.gis.db.backends.spatialite`

### Limitations spatiales de MySQL

Les extensions spatiales de MySQL ne prennent en charge que les opérations de rectangle englobant (ce que MySQL appelle « minimum bounding rectangle » ou MBR). Spécifiquement, [MySQL ne se conforme pas au standard OGC](https://dev.mysql.com/doc/refman/5.6/en/spatial-relation-functions.html) :

> Actuellement, MySQL n’implémente pas ces fonctions \[`Contains`, `Crosses`, `Disjoint`, `Intersects`, `Overlaps`, `Touches`, `Within`\] en accord avec la spécification. Celles qui sont implémentées renvoient le même résultat que les fonctions correspondantes qui agissent sur le MBR.

En d’autres termes, même si les requêtes spatiales telles que [`contains`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-gis-contains) sont disponibles dans GeoDjango en utilisant MySQL, les résultats renvoyés sont tout à fait équivalentes à ce que renverrait [`bbcontains`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-bbcontains) avec un autre moteur spatial.

> **Warning**
>
> Les vrais index spatiaux (R-trees) ne sont pris en charge qu’avec les tables MyISAM de MySQL. [^5] En d’autres termes, lorsque vous utilisez les extensions spatiales de MySQL, vous devez choisir entre des requêtes spatiales rapides et l’intégrité de vos données (les tables MyISAM ne gérant pas les transactions ni les contraintes de clé étrangère).

### Données matricielles

`RasterField` n’est actuellement implémenté que pour le moteur PostGIS. Les requêtes spatiales (recherches, distances, …) ne sont pas encore disponibles pour les champs matriciels.

## Création et enregistrement de modèles avec des champs géométriques

Voici un exemple de la manière dont il faut créer un objet géométrique (en supposant que le modèle `Zipcode` existe) :

```
>>> from zipcode.models import Zipcode
>>> z = Zipcode(code=77096, poly='POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))')
>>> z.save()
```

Les objets [`GEOSGeometry`](/fr/1.9/ref/contrib/gis/geos/#django.contrib.gis.geos.GEOSGeometry) peuvent aussi être utilisés pour enregistrer des modèles géométriques :

```
>>> from django.contrib.gis.geos import GEOSGeometry
>>> poly = GEOSGeometry('POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))')
>>> z = Zipcode(code=77096, poly=poly)
>>> z.save()
```

De plus, si l’objet `GEOSGeometry` est dans un autre système de coordonnées (sa valeur SRID est différente) que celui du champ, il sera implicitement converti dans le SRID du champ du modèle, en utilisant la procédure de transformation de la base de données spatiale :

```
>>> poly_3084 = GEOSGeometry('POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))', srid=3084)  # SRID 3084 is 'NAD83(HARN) / Texas Centric Lambert Conformal'
>>> z = Zipcode(code=78212, poly=poly_3084)
>>> z.save()
>>> from django.db import connection
>>> print(connection.queries[-1]['sql']) # printing the last SQL statement executed (requires DEBUG=True)
INSERT INTO "geoapp_zipcode" ("code", "poly") VALUES (78212, ST_Transform(ST_GeomFromWKB('\\001 ... ', 3084), 4326))
```

Ainsi, les paramètres de géométrie peuvent être transmis en utilisant un objet `GEOSGeometry`, une syntaxe WKT (Well Known Text [^1]), HEXEWKB (spécifique à PostGIS, un objet géométrique WKB en hexadécimal [^2]), et GeoJSON [^3] (nécessite GDAL). En fait, si la donnée n’est pas un objet `GEOSGeometry`, le champ géométrique essaie de créer une instance `GEOSGeometry` à partir des données fournies.

Pour plus d’informations sur la création d’objets [`GEOSGeometry`](/fr/1.9/ref/contrib/gis/geos/#django.contrib.gis.geos.GEOSGeometry), consultez le [tutoriel GEOSl](/fr/1.9/ref/contrib/gis/geos/#geos-tutorial).

## Création et enregistrement de modèles avec des champs matriciels

> **New in Django 1.9**

Lors de la création de modèles matriciels, le champ matriciel convertira implicitement la donnée d’entrée en un objet [`GDALRaster`](/fr/1.9/ref/contrib/gis/gdal/#django.contrib.gis.gdal.GDALRaster) par évaluation différée. Ce champ accepte donc les mêmes données que le constructeur [`GDALRaster`](/fr/1.9/ref/contrib/gis/gdal/#django.contrib.gis.gdal.GDALRaster).

Voici un exemple de la manière dont on peut créer un objet matriciel à partir d’un fichier matriciel `volcano.tif` (en supposant que le modèle `Elevation` existe) :

```
>>> from elevation.models import Elevation
>>> dem = Elevation(name='Volcano', rast='/path/to/raster/volcano.tif')
>>> dem.save()
```

Les objets [`GDALRaster`](/fr/1.9/ref/contrib/gis/gdal/#django.contrib.gis.gdal.GDALRaster) peuvent aussi être utilisés pour enregistrer des modèles matriciels :

```
>>> from django.contrib.gis.gdal import GDALRaster
>>> rast = GDALRaster({'width': 10, 'height': 10, 'name': 'Canyon', 'srid': 4326,
...                    'scale': [0.1, -0.1], 'bands': [{"data": range(100)}]})
>>> dem = Elevation(name='Canyon', rast=rast)
>>> dem.save()
```

Notez que c’est l’équivalent de :

```
>>> dem = Elevation.objects.create(
...     name='Canyon',
...     rast={'width': 10, 'height': 10, 'name': 'Canyon', 'srid': 4326,
...           'scale': [0.1, -0.1], 'bands': [{"data": range(100)}]},
... )
```

## Recherches spatiales

Les types de recherches GeoDjango peuvent être utilisés avec toute méthode de gestionnaire comme `filter()`, `exclude()`, etc. Cependant, les types de recherches spécifiques à GeoDjango ne sont disponibles que pour les champs géométriques. Les filtres sur les champs « normaux » (par ex. [`CharField`](/fr/1.9/ref/models/fields/#django.db.models.CharField)) peuvent être enchaînés avec d’autres sur les champs géographiques. Ainsi, les requêtes géographiques ont la forme générale suivante (en prenant comme exemple le modèle `Zipcode` utilisé dans l”[API de modèle de GeoDjango](/fr/1.9/ref/contrib/gis/model-api/)) :

```
>>> qs = Zipcode.objects.filter(<field>__<lookup_type>=<parameter>)
>>> qs = Zipcode.objects.exclude(...)
```

Par exemple :

```
>>> qs = Zipcode.objects.filter(poly__contains=pnt)
```

Dans ce cas, `poly` est le champ géographique, [`contains`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-gis-contains) est le type de recherche spatiale et `pnt` est le paramètre (qui pourrait être un objet [`GEOSGeometry`](/fr/1.9/ref/contrib/gis/geos/#django.contrib.gis.geos.GEOSGeometry) ou une chaîne GeoJSON , WKT ou HEXEWKB).

Une référence complète peut être consultée dans la [référence sur les recherches spatiales](/fr/1.9/ref/contrib/gis/geoquerysets/#spatial-lookups).

## Requêtes de distance

### Introduction

Les calculs de distance sur des données spatiales sont complexes, parce que malheureusement, la Terre n’est pas plate. Certaines requêtes de distance avec des champs dans un système de coordonnées géographiques doivent parfois être exprimées différemment en raison de limites dans PostGIS. Pour plus de détails, consultez la section [Choix d’un SRID](/fr/1.9/ref/contrib/gis/model-api/#selecting-an-srid) dans la documentation [API de modèle de GeoDjango](/fr/1.9/ref/contrib/gis/model-api/).

### Recherches de distance

*Disponibilité* : PostGIS, Oracle, SpatiaLite

Les recherches de distance suivantes sont disponibles :

- [`distance_lt`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-distance_lt)
- [`distance_lte`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-distance_lte)
- [`distance_gt`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-distance_gt)
- [`distance_gte`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-distance_gte)
- [`dwithin`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-dwithin)

> **Note**
>
> Pour des *mensurations*, au lieu d’interroger sur les distances, utilisez la fonction [`Distance`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Distance).

Les recherches de distance acceptent un paramètre sous forme de tuple comprenant :

1. Un objet géométrique sur lequel baser les calculs ; et
2. Un nombre ou un objet [`Distance`](/fr/1.9/ref/contrib/gis/measure/#django.contrib.gis.measure.Distance) contenant la distance.

Si un objet [`Distance`](/fr/1.9/ref/contrib/gis/measure/#django.contrib.gis.measure.Distance) est utilisé, il peut être exprimé dans n’importe quelle unité (le code SQL généré utilisera des unités converties dans celles du champ) ; sinon, les paramètres numériques sont supposés être dans la même unité que celle du champ.

> **Note**
>
> Dans PostGIS, `ST_Distance_Sphere` ne restreint *plus* les types géométriques sur lesquels les requêtes de distance géographiques sont appliquées [^4]. Cependant, ces requêtes peuvent être très lentes, car les distances de grand cercle doivent être calculées à la volée pour *chaque* ligne de la requête. La raison en est que l’index spatial des champs géométriques traditionnels ne peut pas être exploité.
>
> Pour de bien meilleures performances concernant les requêtes de distance WGS84, évaluez la possibilité d’utiliser plutôt des [colonnes de type géographique](/fr/1.9/ref/contrib/gis/model-api/#geography-type) dans votre base de données car leur index spatial peut être exploité dans les requêtes de distance. Vous pouvez indiquer à GeoDjango de créer des colonnes géographiques en définissant `geography=True` dans la définition du champ.

Par exemple, si l’on dispose d’un modèle `SouthTexasCity` (exemple tiré des [tests de distance de GeoDjango](https://github.com/django/django/blob/master/tests/gis_tests/distapp/models.py)) avec un système de coordonnées *projeté* valide pour les villes du sud du Texas :

```
from django.contrib.gis.db import models

class SouthTexasCity(models.Model):
    name = models.CharField(max_length=30)
    # A projected coordinate system (only valid for South Texas!)
    # is used, units are in meters.
    point = models.PointField(srid=32140)
```

Les requêtes de distance suivantes pourraient être effectuées :

```
>>> from django.contrib.gis.geos import GEOSGeometry
>>> from django.contrib.gis.measure import D # ``D`` is a shortcut for ``Distance``
>>> from geoapp.models import SouthTexasCity
# Distances will be calculated from this point, which does not have to be projected.
>>> pnt = GEOSGeometry('POINT(-96.876369 29.905320)', srid=4326)
# If numeric parameter, units of field (meters in this case) are assumed.
>>> qs = SouthTexasCity.objects.filter(point__distance_lte=(pnt, 7000))
# Find all Cities within 7 km, > 20 miles away, and > 100 chains away (an obscure unit)
>>> qs = SouthTexasCity.objects.filter(point__distance_lte=(pnt, D(km=7)))
>>> qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(mi=20)))
>>> qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(chain=100)))
```

## Tableaux de compatibilité

### Recherches spatiales

Le tableau suivant indique en résumé quelles sont les recherches spatiales disponibles pour chaque moteur de base de données spatiale.

| Type de recherche | PostGIS | Oracle | MySQL [^6] | SpatiaLite |
| --- | --- | --- | --- | --- |
| [`bbcontains`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-bbcontains) | X |  | X | X |
| [`bboverlaps`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-bboverlaps) | X |  | X | X |
| [`contained`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-contained) | X |  | X | X |
| [`contains`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-gis-contains) | X | X | X | X |
| [`contains_properly`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-contains_properly) | X |  |  |  |
| [`coveredby`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-coveredby) | X | X |  |  |
| [`covers`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-covers) | X | X |  |  |
| [`crosses`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-crosses) | X |  |  | X |
| [`disjoint`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-disjoint) | X | X | X | X |
| [`distance_gt`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-distance_gt) | X | X |  | X |
| [`distance_gte`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-distance_gte) | X | X |  | X |
| [`distance_lt`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-distance_lt) | X | X |  | X |
| [`distance_lte`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-distance_lte) | X | X |  | X |
| [`dwithin`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-dwithin) | X | X |  |  |
| [`equals`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-equals) | X | X | X | X |
| [`exact`](/fr/1.9/ref/models/querysets/#std-fieldlookup-exact) | X | X | X | X |
| [`intersects`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-intersects) | X | X | X | X |
| [`overlaps`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-overlaps) | X | X | X | X |
| [`relate`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-relate) | X | X |  | X |
| [`same_as`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-same_as) | X | X | X | X |
| [`touches`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-touches) | X | X | X | X |
| [`within`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-within) | X | X | X | X |
| [`left`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-left) | X |  |  |  |
| [`right`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-right) | X |  |  |  |
| [`overlaps_left`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-overlaps_left) | X |  |  |  |
| [`overlaps_right`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-overlaps_right) | X |  |  |  |
| [`overlaps_above`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-overlaps_above) | X |  |  |  |
| [`overlaps_below`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-overlaps_below) | X |  |  |  |
| [`strictly_above`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-strictly_above) | X |  |  |  |
| [`strictly_below`](/fr/1.9/ref/contrib/gis/geoquerysets/#std-fieldlookup-strictly_below) | X |  |  |  |

### Fonctions de base de données

Le tableau suivant indique en résumé quelles sont les fonctions géométriques de base de données disponibles pour chaque moteur spatial.

| Fonction | PostGIS | Oracle | MySQL | SpatiaLite |
| --- | --- | --- | --- | --- |
| [`Area`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Area) | X | X | X | X |
| [`AsGeoJSON`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.AsGeoJSON) | X |  |  | X |
| [`AsGML`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.AsGML) | X |  |  | X |
| [`AsKML`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.AsKML) | X |  |  | X |
| [`AsSVG`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.AsSVG) | X |  |  | X |
| [`BoundingCircle`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.BoundingCircle) | X |  |  |  |
| [`Centroid`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Centroid) | X | X | X | X |
| [`Difference`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Difference) | X | X |  | X |
| [`Distance`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Distance) | X | X | X (≥ 5.6.1) | X |
| [`Envelope`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Envelope) | X |  | X | X |
| [`ForceRHR`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.ForceRHR) | X |  |  |  |
| [`GeoHash`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.GeoHash) | X |  |  |  |
| [`Intersection`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Intersection) | X | X |  | X |
| [`Length`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Length) | X | X | X | X |
| [`MemSize`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.MemSize) | X |  |  |  |
| [`NumGeometries`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.NumGeometries) | X | X | X | X |
| [`NumPoints`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.NumPoints) | X | X | X | X |
| [`Perimeter`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Perimeter) | X | X |  | X (≥ 4.0) |
| [`PointOnSurface`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.PointOnSurface) | X | X |  | X |
| [`Reverse`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Reverse) | X | X |  | X (≥ 4.0) |
| [`Scale`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Scale) | X |  |  | X |
| [`SnapToGrid`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.SnapToGrid) | X |  |  | X (≥ 3.1) |
| [`SymDifference`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.SymDifference) | X | X |  | X |
| [`Transform`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Transform) | X | X |  | X |
| [`Translate`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Translate) | X |  |  | X |
| [`Union`](/fr/1.9/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Union) | X | X | X (≥ 5.6.1) | X |

### Fonctions d’agrégation

Le tableau suivant indique en résumé quelles fonctions d’agrégation géographiques sont disponibles pour chaque moteur de base de données spatiale. Notez que MySQL n’en prend en charge aucune et qu’il est donc exclu du tableau.

| Méthode d’agrégation | PostGIS | Oracle | SpatiaLite |
| --- | --- | --- | --- |
| [`Collect`](/fr/1.9/ref/contrib/gis/geoquerysets/#django.contrib.gis.db.models.Collect) | X |  | (à partir de la v3.0) |
| [`Extent`](/fr/1.9/ref/contrib/gis/geoquerysets/#django.contrib.gis.db.models.Extent) | X | X | (à partir de la v3.0) |
| [`Extent3D`](/fr/1.9/ref/contrib/gis/geoquerysets/#django.contrib.gis.db.models.Extent3D) | X |  |  |
| [`MakeLine`](/fr/1.9/ref/contrib/gis/geoquerysets/#django.contrib.gis.db.models.MakeLine) | X |  |  |
| [`Union`](/fr/1.9/ref/contrib/gis/geoquerysets/#django.contrib.gis.db.models.Union) | X | X | X |

**Notes de bas de page**

[^1]: *Voir* Open Geospatial Consortium, Inc., [OpenGIS Simple Feature Specification For SQL](http://www.opengis.org/docs/99-049.pdf), Document 99-049 (5 mai 1999), au Ch. 3.2.5, p. 3-11 (SQL Textual Representation of Geometry).

[^2]: *Voir* [PostGIS EWKB, EWKT and Canonical Forms](http://postgis.net/docs/manual-2.1/using_postgis_dbmanagement.html#EWKB_EWKT), documentation de PostGIS au chap. 4.1.2.

[^3]: *Voir* Howard Butler, Martin Daly, Allan Doyle, Tim Schaub, & Christopher Schmidt, [The GeoJSON Format Specification](http://geojson.org/geojson-spec.html), révision 1.0 (16 juin 2008).

[^4]: *Voir* la [documentation de PostGIS](http://postgis.net/docs/manual-2.1/ST_Distance_Sphere.html) pour `ST_distance_sphere`.

[^5]: *Voir* [Création d’index spatiaux](https://dev.mysql.com/doc/refman/5.6/en/creating-spatial-indexes.html) dans le manuel de référence de MySQL :

> Pour les tables MyISAM, `SPATIAL INDEX` crée un index R-tree. Pour les moteurs de stockage qui prennent en charge les index non spatiaux sur les colonnes spatiales, le moteur crée un index B-tree. Un index B-tree sur des valeurs spatiales est utile pour les recherches par valeur exacte, mais pas pour les recherches sur des intervalles.

[^6]: Référez-vous à la section [Limitations spatiales de MySQL](#mysql-spatial-limitations) pour plus de détails.
