Spec-Zone.ru › Django 5.1

GeoDjango База данных API

Пространственные бэкенды

GeoDjango в настоящее время предоставляет следующие пространственные бэкенды базы данных:

  • django.contrib.gis.db.backends.postgis
  • django.contrib.gis.db.backends.mysql
  • django.contrib.gis.db.backends.oracle
  • django.contrib.gis.db.backends.spatialite

Ограничения пространственных возможностей MySQL

Django поддерживает пространственные функции, работающие с реальными геометриями, доступными в современных версиях MySQL. Однако, пространственные функции не так богаты, как в других бэкендах, таких как PostGIS.

Поддержка растровых данных

RasterField в настоящее время реализована только для бэкенда PostGIS. Доступны пространственные запросы к растровым полям, но пространственные функции и агрегации для растровых полей не реализованы.

Создание и сохранение моделей с геометрическими полями

Вот пример создания геометрического объекта (предполагая модель Zipcode):

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

GEOSGeometry объекты также могут использоваться для сохранения геометрических моделей:

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

Кроме того, если GEOSGeometry находится в другой системе координат (имеет другое значение SRID), чем поле, то оно будет неявно преобразовано в SRID поля модели с использованием процедуры преобразования пространственной базы данных:

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

Таким образом, параметры геометрии можно передавать, используя объект GEOSGeometry, WKT (Хорошо Известный Текст [1]), HEXEWKB (специфичный для PostGIS – геометрия WKB в шестнадцатеричном формате [2]) и GeoJSON (см. RFC 7946). По существу, если вход не является объектом GEOSGeometry, поле геометрии попытается создать экземпляр GEOSGeometry из ввода.

Для получения более подробной информации о создании объектов GEOSGeometry, обратитесь к руководству по GEOS.

Создание и сохранение моделей с растровыми полями

При создании растровых моделей растровое поле неявно преобразует вход в GDALRaster с использованием отложенной оценки. Таким образом, растровое поле примет любой вход, который принимается конструктором GDALRaster.

Вот пример создания растрового объекта из растрового файла volcano.tif (предполагая модель Elevation):

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

GDALRaster объекты также могут использоваться для сохранения растровых моделей:

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

Обратите внимание, что это эквивалентно:

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

Пространственные запросы

Типы запросов GeoDjango могут использоваться с любым методом менеджера, например filter(), exclude(), и т. д. Однако, уникальные для GeoDjango типы запросов доступны только для пространственных полей.

Фильтры по «обычным» полям (например, CharField) могут быть объединены с фильтрами по географическим полям. Географические запросы принимают геометрию и растровые данные с обеих сторон, а типы данных могут свободно смешиваться.

Общая структура географических запросов описана ниже. Полная справка находится в справочнике по пространственным запросам.

Геометрические запросы

Географические запросы с геометриями имеют следующий общий вид (предполагая модель Zipcode , используемую в API моделей GeoDjango):

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

Например:

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

В этом случае poly — это географическое поле, contains — тип пространственного запроса, pnt — параметр (который может быть объектом GEOSGeometry или строкой GeoJSON, WKT или HEXEWKB), а rst — объект GDALRaster.

Запросы к растровым данным

Синтаксис запросов к растровым данным аналогичен синтаксису для геометрий. Единственное отличие заключается в том, что можно указать индекс полосы в качестве дополнительного ввода. Если индекс полосы не указан, используется первая полоса по умолчанию (индекс 0). В этом случае синтаксис идентичен синтаксису запросов к геометриям.

Для указания индекса полосы можно указать дополнительный параметр с обеих сторон запроса. С левой стороны для передачи индекса полосы используется синтаксис с двойным подчеркиванием. С правой стороны можно указать кортеж из растра и индекса полосы.

Это приводит к следующему общему виду запросов, включающих растры (предполагая модель Elevation , используемую в API моделей 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>)

Например:

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

С левой стороны примера rast — это географическое растровое поле, а contains — тип пространственного запроса. С правой стороны geom — вход геометрии, а rst — объект GDALRaster. Индекс полосы по умолчанию равен 0 в первых двух запросах и равен 1 в остальных.

Хотя все пространственные запросы могут использоваться с растровыми объектами с обеих сторон, не все базовые операторы напрямую поддерживают растровый ввод. В случаях, когда оператор ожидает ввода геометрии, растр автоматически преобразуется в геометрию. Важно помнить об этом при интерпретации результатов запроса.

Тип поддержки растровых данных для всех запросов указан в таблице совместимости. Запросы, включающие растры, в настоящее время доступны только для бэкенда PostGIS.

Запросы по расстоянию

Введение

Вычисление расстояний с пространственными данными сложно, так как Земля не плоская. Некоторые запросы по расстоянию с полями в географической системе координат могут потребовать иного выражения из-за ограничений в PostGIS. Дополнительные сведения см. в разделе Выбор SRID документации API моделей GeoDjango.

Запросы по расстоянию

Доступность: PostGIS, MariaDB, MySQL, Oracle, SpatiaLite, PGRaster (Нативный)

Доступны следующие запросы по расстоянию:

  • distance_lt
  • distance_lte
  • distance_gt
  • distance_gte
  • dwithin (кроме MariaDB и MySQL)

Примечание

Для измерения, а не запросов на основе расстояний, используйте функцию Distance.

Запросы по расстоянию принимают кортеж параметров, включающий:

  1. Геометрию или растр, от которой производятся вычисления; и
  2. Число или объект Distance, содержащий расстояние.

Если используется объект Distance, он может быть выражен в любых единицах (сгенерированный SQL будет использовать единицы, преобразованные в единицы поля); в противном случае числовые параметры предполагаются в единицах поля.

Примечание

В PostGIS ST_Distance_Sphere не ограничивает типы геометрий, с которыми выполняются географические запросы на расстоянии. [3] Однако эти запросы могут занимать много времени, так как расстояния по большой окружности должны вычисляться на лету для каждой строки в запросе. Это связано с тем, что пространственный индекс на традиционных геометрических полях не может быть использован.

Для значительно лучшей производительности запросов на расстоянии в системе WGS84 рассмотрите использование географических столбцов в вашей базе данных, так как они могут использовать свой пространственный индекс в запросах на расстоянии. Вы можете указать GeoDjango использовать географический столбец, установив geography=True в определении поля.

Например, предположим, что у нас есть модель SouthTexasCity (из тестов расстояний GeoDjango) в проектированной системе координат, которая действительна для городов южной Техаса:

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)

Затем запросы по расстоянию могут быть выполнены следующим образом:

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

Растровые запросы работают аналогичным образом, заменив геометрическое поле point на растровое поле, или объект pnt на растровый объект, или оба. Чтобы указать индекс полосы растрового ввода с правой стороны, можно передать в запрос 3-кортеж следующим образом:

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

Где используется полоса с индексом 2 (третья полоса) растра rst для запроса.

Таблицы совместимости

Пространственные запросы

В следующей таблице представлен обзор доступных пространственных запросов для каждого пространственного бэкенда базы данных. Запросы PostGIS Raster (PGRaster) разделены на три категории, описанные в подробном описании запросов к растровым данным: собственная поддержка N, двусторонняя собственная поддержка B, и поддержка преобразования геометрии C.

Тип запроса 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 B
covers 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
intersects X X X X X B
isempty X
isvalid X X 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

Функции баз данных

В следующей таблице представлен обзор доступных функций географии в каждой пространственной базе данных.

Функция 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 X (LWGEOM/RTTOPO)
Intersection X X X X X
IsEmpty X
IsValid X X 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
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

Функции агрегации

В следующей таблице представлен обзор доступных функций агрегации для пространственных бэкэндов. Обратите внимание, что MariaDB не поддерживает ни одну из этих агрегатных функций и, следовательно, исключён из таблицы.

Агрегация PostGIS Oracle MySQL SpatiaLite
Collect X X (≥ 8.0.24) X
Extent X X X
Extent3D X
MakeLine X X
Union X X X

Примечания

[1] См. Open Geospatial Consortium, Inc., OpenGIS Simple Feature Specification For SQL, Документ 99-049 (5 мая 1999 г.), в гл. 3.2.5, с. 3-11 (SQL Текстовое представление геометрии).
[2] См. PostGIS EWKB, EWKT и канонические формы, документация PostGIS в гл. 4.1.2.
END_OF_DOCUMENT_MARKER
[3] См. документацию PostGIS по ST_DistanceSphere.
[4] См. раздел Ограничения MySQL Spatial для получения более подробной информации.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.1/ref/contrib/gis/db-api/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API