• 3.1
  • 3.2
  • 6.1
  • Версия документации: 5.0

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

Пространственные серверные части

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) могут быть связаны с фильтрами для географических полей. Географический поиск принимает геометрические и растровые данные с обеих сторон, а типы входных данных можно свободно смешивать.

Общая структура географического поиска описана ниже. Полную ссылку можно найти в ссылке на пространственный поиск <spatial-lookups>.

Поиск по геометрии

Географические запросы с геометрией принимают следующую общую форму (при условии, что модель 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» в остальных.

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

Тип поддержки растра указан для всех поисков в таблице совместимости <spatial-lookup-compatibility>. Поиски с использованием растров в настоящее время доступны только для серверной части PostGIS.

Дистанционные запросы

Введение

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

Дистанционные поиски

Доступность: PostGIS, MariaDB, MySQL, Oracle, SpatiaLite, PGRaster (родной)

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

Примечание

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

Поиск по расстоянию принимает параметр кортежа, содержащий:

  1. Геометрия или растр для базовых вычислений; и

  2. Число или объект Distance, содержащий расстояние.

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

Примечание

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

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

Например, предположим, что у нас есть модель SouthTexasCity (из дистанционных тестов GeoDjango <tests/gis_tests/distapp/models.py>`) в проецируемой системе координат, действующей для городов южного Техаса:

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

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

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

Где для поиска будет использоваться канал с индексом 2 (третий канал) растра «первый».

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

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

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

Тип поиска

ПостГИС

Оракул

МарияДБ

MySQL [4]

SpatiaLite

PGRaster

bbcontains

Х

Х

Х

Х

N

bboverlaps

Х

Х

Х

Х

N

содержится

Х

Х

Х

Х

N

содержит

Х

Х

Х

Х

Х

B

contains_properly

Х

B

coveredby

Х

Х

Х

B

обложки

Х

Х

Х

B

кресты

Х

Х

Х

Х

С

непересекающиеся

Х

Х

Х

Х

Х

B

distance_gt

Х

Х

Х

Х

Х

N

distance_gte

Х

Х

Х

Х

Х

N

distance_lt

Х

Х

Х

Х

Х

N

distance_lte

Х

Х

Х

Х

Х

N

dwithin

Х

Х

Х

B

равно

Х

Х

Х

Х

Х

С

точно

Х

Х

Х

Х

Х

B

пересекается

Х

Х

Х

Х

Х

B

пустой

Х

действительно

Х

Х

Х

Х

перекрывается

Х

Х

Х

Х

Х

B

связать

Х

Х

Х

Х

С

same_as

Х

Х

Х

Х

Х

B

касается

Х

Х

Х

Х

Х

B

внутри

Х

Х

Х

Х

Х

B

слева

Х

С

верно

Х

С

overlaps_left

Х

B

overlaps_right

Х

B

overlaps_above

Х

С

overlaps_below

Х

С

строго_выше

Х

С

строго_ниже

Х

С

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

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

Функция

ПостГИС

Оракул

МарияДБ

MySQL

SpatiaLite

Площадь

Х

Х

Х

Х

Х

AsGeoJSON

Х

Х

Х

Х

Х

AsGML

Х

Х

Х

AsKML

Х

Х

AsSVG

Х

Х

AsWKB

Х

Х

Х

Х

Х

AsWKT

Х

Х

Х

Х

Х

Азимут

Х

X (LWGEOM/RTTOPO)

BoundingCircle

Х

Х

Х (≥ 5,1)

Центроид

Х

Х

Х

Х

Х

ClosestPoint

Х

Х

Разница

Х

Х

Х

Х

Х

Расстояние

Х

Х

Х

Х

Х

Конверт

Х

Х

Х

Х

Х

ForcePolygonCW

Х

Х

FromWKB

Х

Х

Х

Х

Х

FromWKT

Х

Х

Х

Х

Х

GeoHash

Х

Х

X (LWGEOM/RTTOPO)

Пересечение

Х

Х

Х

Х

Х

IsEmpty

Х

Действителен

Х

Х

Х

Х

Длина

Х

Х

Х

Х

Х

LineLocatePoint

Х

Х

MakeValid

Х

X (LWGEOM/RTTOPO)

MemSize

Х

NumGeometries

Х

Х

Х

Х

Х

NumPoints

Х

Х

Х

Х

Х

Периметр

Х

Х

Х

PointOnSurface

Х

Х

Х

Х

Реверс

Х

Х

Х

Масштаб

Х

Х

SnapToGrid

Х

Х

SymDifference

Х

Х

Х

Х

Х

Трансформировать

Х

Х

Х

Перевести

Х

Х

Союз

Х

Х

Х

Х

Х

Агрегатные функции

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

Совокупный

ПостГИС

Оракул

MySQL

SpatiaLite

Собрать

Х

Х (≥ 8.0.24)

Х

Пространство

Х

Х

Х

Extent3D

Х

MakeLine

Х

Х

Союз

Х

Х

Х

Сноски

Back to Top