# Documentation Django 5.2.8

# 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

Django prend en charge les fonctions spatiales opérant sur des géométries réelles disponibles dans les versions modernes de MySQL. Cependant, ces fonctions ne sont pas aussi riches que pour d’autres bases telles que PostGIS.

### Données matricielles

`RasterField` n’est actuellement implémenté que pour le moteur PostGIS. Les requêtes spatiales sont disponibles pour les champs matriciels, mais pas les fonctions de base de données spatiales ni les agrégats.

## 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` 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 (voir la RFC 7946). 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`, consultez le tutoriel GEOSl.

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

Lors de la création de modèles matriciels, le champ matriciel convertira implicitement la donnée d’entrée en un objet `GDALRaster` par évaluation différée. Ce champ accepte donc les mêmes données que le constructeur `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` 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

GeoDjango’s lookup types may be used with any manager method like `filter()`, `exclude()`, etc. However, the lookup types unique to GeoDjango are only available on spatial fields.

Les filtres pour les champs « normaux » (par ex. `CharField`) peuvent s’enchaîner avec des filtres sur des champs géographiques. Les requêtes géographiques acceptent des entrées géométriques et matricielles des deux côtés et les types d’entrées peuvent être librement mélangés.

La structure générale des requêtes géographiques est décrite ci-dessous. Une référence complète peut être consultée dans la référence sur les recherches spatiales.

### Recherches géométriques

Geographic queries with geometries take the following general form (assuming the `Zipcode` model used in the API de modèle de GeoDjango):

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

Par exemple :

    >>> qs = Zipcode.objects.filter(poly__contains=pnt)
    >>> qs = Elevation.objects.filter(poly__contains=rst)

Dans ce cas, `poly` est le champ géographique, `contains` est le type de recherche spatiale, `pnt` est le paramètre (qui pourrait être un objet `GEOSGeometry` ou une chaîne GeoJSON , WKT ou HEXEWKB) et `rst` est un objet `GDALRaster`.

### Recherches matricielles

La syntaxe des requêtes matricielles est semblable à celle pour les géométries. La seule différence est qu’un indice de bande peut être indiqué en supplément. Si aucun indice de bande n’est indiqué, c’est la première bande (indice `0`) qui est utilisée par défaut. Dans ce cas, la syntaxe est identique à la syntaxe des requêtes géométriques.

Pour indiquer l’indice de bande, un paramètre supplémentaire peut être ajouté des deux côtés de la requête. Du côté gauche, c’est la syntaxe de double soulignement qui est utilisée pour transmettre l’indice de bande. Du côté droit, un tuple contenant la matrice et l’indice de bande peut être utilisé.

This results in the following general form for lookups involving rasters (assuming the `Elevation` model used in the API de modèle de GeoDjango):

    >>> qs = Elevation.objects.filter(<field>__<lookup_type>=<parameter>)
    >>> qs = Elevation.objects.filter(<field>__<band_index>__<lookup_type>=<parameter>)
    >>> qs = Elevation.objects.filter(<field>__<lookup_type>=(<raster_input, <band_index>)

Par exemple :

    >>> qs = Elevation.objects.filter(rast__contains=geom)
    >>> qs = Elevation.objects.filter(rast__contains=rst)
    >>> qs = Elevation.objects.filter(rast__1__contains=geom)
    >>> qs = Elevation.objects.filter(rast__contains=(rst, 1))
    >>> qs = Elevation.objects.filter(rast__1__contains=(rst, 1))

Du côté gauche de l’exemple, `rast` est le champ matriciel géographique et `contains` est le type de requête spatiale. Du côté droit, `geom` est l’entrée géométrique et `rst` est un objet `GDALRaster`. L’indice de bande vaut `0` par défaut dans les deux premières requêtes et est défini à `1` dans les suivantes.

Bien que toutes les requêtes spatiales puissent être utilisées avec des objets matriciels des deux côtés, certains opérateurs ne savent pas gérer des entrées matricielles. Pour les cas où l’opérateur s’attend à une entrée géométrique, la matrice est automatiquement convertie en géométrie. Il est important d’avoir cela à l’esprit lors de l’interprétation des résultats de requête.

Le type de prise en charge matricielle est énuméré pour chaque requête dans la table de compatibilité. Les requêtes impliquant des matrices ne sont actuellement disponibles que pour le moteur PostGIS.

## Requêtes de distance

### Introduction

Distance calculations with spatial data is tricky because, unfortunately, the Earth is not flat. Some distance queries with fields in a geographic coordinate system may have to be expressed differently because of limitations in PostGIS. Please see the Choix d’un SRID section for more details.

### Recherches de distance

Disponibilité : PostGIS, MariaDB, MySQL, Oracle, SpatiaLite, PGRaster (natif)

Les recherches de distance suivantes sont disponibles :

- `distance_lt`

- `distance_lte`

- `distance_gt`

- `distance_gte`

- `dwithin` (sauf MariaDB et MySQL)

Note

Pour des mensurations, au lieu d’interroger sur les distances, utilisez la fonction `Distance`.

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

1. Un objet géométrique ou matriciel sur lequel baser les calculs ; et

2. Un nombre ou un objet `Distance` contenant la distance.

Si un objet `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

In PostGIS, `ST_Distance_Sphere` does not limit the geometry types geographic distance queries are performed with. [3] However, these queries may take a long time, as great-circle distances must be calculated on the fly for every row in the query. This is because the spatial index on traditional geometry fields cannot be used.

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 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) 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)))

Les requêtes matricielles fonctionnent de la même manière en remplaçant le champ géométrique `point` par un champ marticiel, ou l’objet `pnt` par un objet matriciel, ou les deux. Pour indiquer l’indice de bande d’une entrée matricielle dans le côté droit, un tuple ternaire peut être passé à la requête comme ceci :

    >>> qs = SouthTexasCity.objects.filter(point__distance_gte=(rst, 2, D(km=7)))

Où la bande avec indice 2 (troisième bande) de la matrice `rst` serait utilisée pour la requête.

## Tableaux de compatibilité

### Recherches spatiales

Le tableau suivant fournit un résumé des requêtes spatiales disponibles pour chaque moteur de base de données spatial. Les requêtes PostGIS Raster (PGRaster) sont divisées dans les trois catégories décrites dans les détails de requêtes matricielles: prise en charge native `N`, prise en charge native bilatérale `B` et prise en charge par conversion géométrique `C`.

Type de recherche | PostGIS | Oracle | MariaDB | MySQL [4] | SpatiaLite | PGRaster
--- | --- | --- | --- | --- | --- | ---
`bbcontains` | X |  | X | X | X | N
`bboverlaps` | X |  | X | X | X | N
`contained` | X |  | X | X | X | N
`contains` | X | X | X | X | X | B
`contains_properly` | X |  |  |  |  | B
`coveredby` | X | X | X (≥ 12.0.1) | X | X | B
`covers` | X | X |  | X | X | B
`crosses` | X |  | X | X | X | C
`disjoint` | X | X | X | X | X | B
`distance_gt` | X | X | X | X | X | N
`distance_gte` | X | X | X | X | X | N
`distance_lt` | X | X | X | X | X | N
`distance_lte` | X | X | X | X | X | N
`dwithin` | X | X |  |  | X | B
`equals` | X | X | X | X | X | C
`exact` | X | X | X | X | X | B
`geom_type` | X | X (≥ 23c) | X | X | X |
`intersects` | X | X | X | X | X | B
`isempty` | X |  |  |  |  |
`isvalid` | X | X | X (≥ 12.0.1) | X | X |
`overlaps` | X | X | X | X | X | B
`relate` | X | X | X |  | X | C
`same_as` | X | X | X | X | X | B
`touches` | X | X | X | X | X | B
`within` | X | X | X | X | X | B
`left` | X |  |  |  |  | C
`right` | X |  |  |  |  | C
`overlaps_left` | X |  |  |  |  | B
`overlaps_right` | X |  |  |  |  | B
`overlaps_above` | X |  |  |  |  | C
`overlaps_below` | X |  |  |  |  | C
`strictly_above` | X |  |  |  |  | C
`strictly_below` | X |  |  |  |  | C

### 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 | MariaDB | MySQL | SpatiaLite
--- | --- | --- | --- | --- | ---
`Area` | X | X | X | X | X
`AsGeoJSON` | X | X | X | X | X
`AsGML` | X | X |  |  | X
`AsKML` | X |  |  |  | X
`AsSVG` | X |  |  |  | X
`AsWKB` | X | X | X | X | X
`AsWKT` | X | X | X | X | X
`Azimuth` | X |  |  |  | X (LWGEOM/RTTOPO)
`BoundingCircle` | X | X |  |  | X (≥ 5.1)
`Centroid` | X | X | X | X | X
`ClosestPoint` | X |  |  |  | X
`Difference` | X | X | X | X | X
`Distance` | X | X | X | X | X
`Envelope` | X | X | X | X | X
`ForcePolygonCW` | X |  |  |  | X
`FromWKB` | X | X | X | X | X
`FromWKT` | X | X | X | X | X
`GeoHash` | X |  | X (≥ 12.0.1) | X | X (LWGEOM/RTTOPO)
`GeometryDistance` | X |  |  |  |
`GeometryType` | X | X (≥ 23c) | X | X | X
`Intersection` | X | X | X | X | X
`IsEmpty` | X |  |  |  |
`IsValid` | X | X | X (≥ 12.0.1) | X | X
`Length` | X | X | X | X | X
`LineLocatePoint` | X |  |  |  | X
`MakeValid` | X |  |  |  | X (LWGEOM/RTTOPO)
`MemSize` | X |  |  |  |
`NumGeometries` | X | X | X | X | X
`NumPoints` | X | X | X | X | X
`Perimeter` | X | X |  |  | X
`PointOnSurface` | X | X | X |  | X
`Reverse` | X | X |  |  | X
`Rotate` | X |  |  |  |
`Scale` | X |  |  |  | X
`SnapToGrid` | X |  |  |  | X
`SymDifference` | X | X | X | X | X
`Transform` | X | X |  |  | X
`Translate` | X |  |  |  | X
`Union` | X | X | X | X | X

### Fonctions d’agrégation

The following table provides a summary of what GIS-specific aggregate functions are available on each spatial backend.

Méthode d’agrégation | PostGIS | Oracle | MariaDB | MySQL | SpatiaLite
--- | --- | --- | --- | --- | ---
`Collect` | X |  | X (≥ 12.0.1) | X (≥ 8.0.24) | X
`Extent` | X | X |  |  | X
`Extent3D` | X |  |  |  |
`MakeLine` | X |  |  |  | X
`Union` | X | X |  |  | X

Notes de bas de page

[1]

Voir Open Geospatial Consortium, Inc., `OpenGIS Simple Feature Specification For SQL `_, 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, documentation de PostGIS au chap. 4.1.2.

[3]

Voir la documentation de PostGIS pour `ST_DistanceSphere`.

[4]

Référez-vous à la section Limitations spatiales de MySQL pour plus de détails.