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 ¶
До MySQL 5.6.1 пространственные расширения поддерживали только операции с ограничивающим прямоугольником (то, что MySQL называет «минимальным ограничивающим прямоугольником» или MBR). В частности, MySQL не соответствовал стандарту OGC. Django поддерживает пространственные функции, работающие с реальной геометрией, доступной в современных версиях MySQL. Однако пространственные функции не так богаты, как у других движков, таких как PostGIS.
Добавлена поддержка пространственных функций, работающих с реальной геометрией.
Предупреждение
Истинные пространственные индексы (R-деревья) поддерживаются только таблицами MyISAM в MySQL. [4] Другими словами, при использовании пространственных расширений MySQL вы должны выбирать между быстрыми пространственными запросами и целостностью ваших данных (таблицы MyISAM не обрабатывают транзакции или ограничения внешнего ключа).
Матричные данные ¶
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
см. Учебник GEOSI .
Создание и сохранение моделей с матричными полями ¶
При создании матричных моделей поле матрицы неявно преобразует входные данные в объект 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
.
Поиск на расстоянии принимает параметр в виде кортежа, включая:
- Геометрический или матричный объект, на котором основываются вычисления; и
- Число или объект,
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) запросы делятся на три категории , описанные в Matrix Query Детали : Native N
поддержка, Native двусторонней поддержки, B
и поддержка преобразования Геометрическая C
.
Тип исследования | PostGIS | оракул | MariaDB | MySQL [5] | SpatiaLite | PGRaster |
---|---|---|---|---|---|---|
bbcontains |
Икс | Икс | Икс | Икс | НЕ | |
bboverlaps |
Икс | Икс | Икс | Икс | НЕ | |
contained |
Икс | Икс | Икс | Икс | НЕ | |
contains |
Икс | Икс | Икс | Икс | Икс | В |
contains_properly |
Икс | В | ||||
coveredby |
Икс | Икс | Икс | В | ||
covers |
Икс | Икс | Икс | В | ||
crosses |
Икс | Икс | Икс | Икс | В.С. | |
disjoint |
Икс | Икс | Икс | Икс | Икс | В |
distance_gt |
Икс | Икс | Икс | Икс | Икс | НЕ |
distance_gte |
Икс | Икс | Икс | Икс | Икс | НЕ |
distance_lt |
Икс | Икс | Икс | Икс | Икс | НЕ |
distance_lte |
Икс | Икс | Икс | Икс | Икс | НЕ |
dwithin |
Икс | Икс | Икс | В | ||
equals |
Икс | Икс | Икс | Икс | Икс | В.С. |
exact |
Икс | Икс | Икс | Икс | Икс | В |
intersects |
Икс | Икс | Икс | Икс | Икс | В |
isvalid |
Икс | Икс | Х (≥ 5.7.5) | X (LWGEOM) | ||
overlaps |
Икс | Икс | Икс | Икс | Икс | В |
relate |
Икс | Икс | Икс | Икс | В.С. | |
same_as |
Икс | Икс | Икс | Икс | Икс | В |
touches |
Икс | Икс | Икс | Икс | Икс | В |
within |
Икс | Икс | Икс | Икс | Икс | В |
left |
Икс | В.С. | ||||
right |
Икс | В.С. | ||||
overlaps_left |
Икс | В | ||||
overlaps_right |
Икс | В | ||||
overlaps_above |
Икс | В.С. | ||||
overlaps_below |
Икс | В.С. | ||||
strictly_above |
Икс | В.С. | ||||
strictly_below |
Икс | В.С. |
Функции базы данных ¶
В следующей таблице перечислены функции геометрической базы данных, доступные для каждого космического двигателя.
функция | PostGIS | оракул | MariaDB | MySQL | SpatiaLite |
---|---|---|---|---|---|
Area |
Икс | Икс | Икс | Икс | Икс |
AsGeoJSON |
Икс | Икс | Х (≥ 10.2.4) | Х (≥ 5.7.5) | Икс |
AsGML |
Икс | Икс | Икс | ||
AsKML |
Икс | Икс | |||
AsSVG |
Икс | Икс | |||
AsWKB |
Икс | Икс | Икс | Икс | Икс |
AsWKT |
Икс | Икс | Икс | Икс | Икс |
Azimuth |
Икс | X (LWGEOM) | |||
BoundingCircle |
Икс | Икс | |||
Centroid |
Икс | Икс | Икс | Икс | Икс |
Difference |
Икс | Икс | Икс | Икс | Икс |
Distance |
Икс | Икс | Икс | Икс | Икс |
Envelope |
Икс | Икс | Икс | Икс | Икс |
ForcePolygonCW |
Икс | Икс | |||
GeoHash |
Икс | Х (≥ 5.7.5) | X (LWGEOM) | ||
Intersection |
Икс | Икс | Икс | Икс | Икс |
IsValid |
Икс | Икс | Х (≥ 5.7.5) | X (LWGEOM) | |
Length |
Икс | Икс | Икс | Икс | Икс |
LineLocatePoint |
Икс | Икс | |||
MakeValid |
Икс | X (LWGEOM) | |||
MemSize |
Икс | ||||
NumGeometries |
Икс | Икс | Икс | Икс | Икс |
NumPoints |
Икс | Икс | Икс | Икс | Икс |
Perimeter |
Икс | Икс | Икс | ||
PointOnSurface |
Икс | Икс | Икс | Икс | |
Reverse |
Икс | Икс | Икс | ||
Scale |
Икс | Икс | |||
SnapToGrid |
Икс | Икс | |||
SymDifference |
Икс | Икс | Икс | Икс | Икс |
Transform |
Икс | Икс | Икс | ||
Translate |
Икс | Икс | |||
Union |
Икс | Икс | Икс | Икс | Икс |
Функции агрегирования ¶
В следующей таблице перечислены функции географического агрегирования, доступные для каждого механизма пространственной базы данных. Обратите внимание, что MySQL не поддерживает ни одного, поэтому исключен из таблицы.
Метод агрегирования | PostGIS | оракул | SpatiaLite |
---|---|---|---|
Collect |
Икс | Икс | |
Extent |
Икс | Икс | Икс |
Extent3D |
Икс | ||
MakeLine |
Икс | Икс | |
Union |
Икс | Икс | Икс |
Сноски
[1] | См. Open Geospatial Consortium, Inc., OpenGIS Simple Feature Specification for SQL , Document 99-049 (5 мая 1999 г.), в главе 3.2.5, стр. 3-11 (Текстовое представление геометрии в SQL). |
[2] | См. PostGIS EWKB, EWKT и Canonical Forms , документацию PostGIS в гл. 4.1.2. |
[3] | Смотрите в документации PostGIS для ST_DistanceSphere . |
[4] | См. Раздел Создание пространственных индексов в Справочном руководстве MySQL:
|
[5] | Обратитесь к разделу пространственных ограничений MySQL для получения более подробной информации. |