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
объектов обратитесь к руководству 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
модель используется в GeoDjango Model API ):
>>> 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
объект растровым объектом, или и то и другое. Чтобы указать индекс канала входного растра с правой стороны, 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 [5] | SpatiaLite | PGRaster |
---|---|---|---|---|---|---|
bbcontains |
Икс | Икс | Икс | Икс | N | |
bboverlaps |
Икс | Икс | Икс | Икс | N | |
contained |
Икс | Икс | Икс | Икс | N | |
contains |
Икс | Икс | Икс | Икс | Икс | B |
contains_properly |
Икс | B | ||||
coveredby |
Икс | Икс | Икс | B | ||
covers |
Икс | Икс | Икс | B | ||
crosses |
Икс | Икс | Икс | Икс | C | |
disjoint |
Икс | Икс | Икс | Икс | Икс | B |
distance_gt |
Икс | Икс | Икс | Икс | Икс | N |
distance_gte |
Икс | Икс | Икс | Икс | Икс | N |
distance_lt |
Икс | Икс | Икс | Икс | Икс | N |
distance_lte |
Икс | Икс | Икс | Икс | Икс | N |
dwithin |
Икс | Икс | Икс | B | ||
equals |
Икс | Икс | Икс | Икс | Икс | C |
exact |
Икс | Икс | Икс | Икс | Икс | B |
intersects |
Икс | Икс | Икс | Икс | Икс | B |
isvalid |
Икс | Икс | Х (≥ 5.7.5) | X (LWGEOM) | ||
overlaps |
Икс | Икс | Икс | Икс | Икс | B |
relate |
Икс | Икс | Икс | Икс | C | |
same_as |
Икс | Икс | Икс | Икс | Икс | B |
touches |
Икс | Икс | Икс | Икс | Икс | B |
within |
Икс | Икс | Икс | Икс | Икс | B |
left |
Икс | C | ||||
right |
Икс | C | ||||
overlaps_left |
Икс | B | ||||
overlaps_right |
Икс | B | ||||
overlaps_above |
Икс | C | ||||
overlaps_below |
Икс | C | ||||
strictly_above |
Икс | C | ||||
strictly_below |
Икс | C |
Функции базы данных ¶
В следующей таблице приведены сводные данные о том, какие функции базы данных для конкретных географических регионов доступны на каждом пространственном сервере.
Функция | PostGIS | Oracle | 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 | Oracle | 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 для получения более подробной информации. |