Spec-Zone.ru › Django 4.2

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 (Well Known Text [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 (Native)

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

  • 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 растровым объектом, или оба. Для указания индекса полосы растрового ввода справа можно передать кортеж из трех элементов в запрос следующим образом:

>>> 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
Centroid X X X 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

Функции агрегирования

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

Агрегация PostGIS Oracle SpatiaLite
Collect X 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.
[3] См. документацию PostGIS по ST_DistanceSphere.
END_OF_DOCUMENT_MARKER
[4] См. раздел Ограничения MySQL Spatial для получения более подробной информации.

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

Spec-Zone.ru

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