Справочник по API GIS QuerySet

Пространственные поиски

Пространственный поиск в этом разделе доступен для GeometryField и RasterField.

Введение см. в spatial lookups introduction. Обзор того, какие поисковые запросы совместимы с конкретным пространственным бэкендом, приведен в spatial lookup compatibility table.

Поиск с помощью растров

Все примеры, приведенные ниже, даны для геометрических полей и входов, но поиск можно использовать одинаково с растровыми изображениями с обеих сторон. Если поиск не поддерживает растровый ввод, то при необходимости ввод автоматически преобразуется в геометрию с помощью функции ST_Polygon. См. также introduction to raster lookups.

Операторы базы данных, используемые при поиске, можно разделить на три категории:

  • Поддержка нативных растров N: оператор принимает растры нативно с обеих сторон поиска, и растровый ввод может быть смешан с геометрическим вводом.
  • Двусторонняя поддержка растров B: оператор поддерживает растры, только если обе стороны поиска получают растровые данные. Растровые данные автоматически преобразуются в геометрию для смешанного поиска.
  • Поддержка преобразования геометрии C. Поиск не имеет встроенной поддержки растров, все растровые данные автоматически преобразуются в геометрию.

Приведенные ниже примеры показывают эквивалент SQL для поиска в различных типах растровой поддержки. Аналогичная схема применима ко всем пространственным поискам.

Дело Поиск Эквивалент SQL
N, B rast__contains=rst ST_Contains(rast, rst)
N, B rast__1__contains=(rst, 2) ST_Contains(rast, 1, rst, 2)
B, C rast__contains=geom ST_Contains(ST_Polygon(rast), geom)
B, C rast__1__contains=geom ST_Contains(ST_Polygon(rast, 1), geom)
B, C poly__contains=rst ST_Contains(poly, ST_Polygon(rst))
B, C poly__contains=(rst, 1) ST_Contains(poly, ST_Polygon(rst, 1))
C rast__crosses=rst ST_Crosses(ST_Polygon(rast), ST_Polygon(rst))
C rast__1__crosses=(rst, 2) ST_Crosses(ST_Polygon(rast, 1), ST_Polygon(rst, 2))
C rast__crosses=geom ST_Crosses(ST_Polygon(rast), geom)
C poly__crosses=rst ST_Crosses(poly, ST_Polygon(rst))

Пространственный поиск с помощью растров поддерживается только для бэкендов PostGIS (обозначаемых в данном разделе как PGRaster).

bbcontains

Доступность: PostGIS, MySQL, SpatiaLite, PGRaster (Native)

Проверяет, полностью ли граничная область геометрии или растрового поля содержит граничную область геометрии поиска.

Пример:

Zipcode.objects.filter(poly__bbcontains=geom)
Бэкэнд Эквивалент SQL
ПостГИС poly ~ geom
MySQL MBRContains(poly, geom)
SpatiaLite MbrContains(poly, geom)

bboverlaps

Доступность: PostGIS, MySQL, SpatiaLite, PGRaster (Native)

Проверяет, перекрывает ли граница поля геометрии границу поля геометрии поиска.

Пример:

Zipcode.objects.filter(poly__bboverlaps=geom)
Бэкэнд Эквивалент SQL
ПостГИС poly && geom
MySQL MBROverlaps(poly, geom)
SpatiaLite MbrOverlaps(poly, geom)

contained

Доступность: PostGIS, MySQL, SpatiaLite, PGRaster (Native)

Проверяет, полностью ли граничная область поля геометрии содержится в граничной области геометрии поиска.

Пример:

Zipcode.objects.filter(poly__contained=geom)
Бэкэнд Эквивалент SQL
ПостГИС poly @ geom
MySQL MBRWithin(poly, geom)
SpatiaLite MbrWithin(poly, geom)

contains

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

Проверяет, содержит ли поле геометрии пространственно геометрию поиска.

Пример:

Zipcode.objects.filter(poly__contains=geom)
Бэкэнд Эквивалент SQL
ПостГИС ST_Contains(poly, geom)
Oracle SDO_CONTAINS(poly, geom)
MySQL MBRContains(poly, geom)
SpatiaLite Contains(poly, geom)

contains_properly

Доступность: PostGIS, PGRaster (двусторонний)

Возвращает true, если геометрия поиска пересекает внутреннюю часть геометрического поля, но не границу (или внешнюю часть).

Пример:

Zipcode.objects.filter(poly__contains_properly=geom)
Бэкэнд Эквивалент SQL
ПостГИС ST_ContainsProperly(poly, geom)

coveredby

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

Проверяет, не находится ли точка в поле геометрии за пределами геометрии поиска. [3]

Пример:

Zipcode.objects.filter(poly__coveredby=geom)
Changed in Django 2.2:

Добавлена поддержка SpatiaLite.

Бэкэнд Эквивалент SQL
ПостГИС ST_CoveredBy(poly, geom)
Oracle SDO_COVEREDBY(poly, geom)
SpatiaLite CoveredBy(poly, geom)

covers

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

Проверяет, не находится ли точка в геометрии поиска за пределами поля геометрии. [3]

Пример:

Zipcode.objects.filter(poly__covers=geom)
Changed in Django 2.2:

Добавлена поддержка SpatiaLite.

Бэкэнд Эквивалент SQL
ПостГИС ST_Covers(poly, geom)
Oracle SDO_COVERS(poly, geom)
SpatiaLite Covers(poly, geom)

crosses

Доступность: PostGIS, SpatiaLite, PGRaster (конверсия)

Проверяет, пересекает ли поле геометрии пространственно геометрию поиска.

Пример:

Zipcode.objects.filter(poly__crosses=geom)
Бэкэнд Эквивалент SQL
ПостГИС ST_Crosses(poly, geom)
SpatiaLite Crosses(poly, geom)

disjoint

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

Проверяет, является ли поле геометрии пространственно разобщенным с геометрией поиска.

Пример:

Zipcode.objects.filter(poly__disjoint=geom)
Бэкэнд Эквивалент SQL
ПостГИС ST_Disjoint(poly, geom)
Oracle SDO_GEOM.RELATE(poly, 'DISJOINT', geom, 0.05)
MySQL MBRDisjoint(poly, geom)
SpatiaLite Disjoint(poly, geom)

equals

Доступность: PostGIS, Oracle, MySQL, SpatiaLite, PGRaster (конверсия)

Проверяет, является ли поле геометрии пространственно равным геометрии поиска.

Пример:

Zipcode.objects.filter(poly__equals=geom)
Бэкэнд Эквивалент SQL
ПостГИС ST_Equals(poly, geom)
Oracle SDO_EQUAL(poly, geom)
MySQL MBREquals(poly, geom)
SpatiaLite Equals(poly, geom)

exact, same_as

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

Проверяет, является ли поле геометрии «равным» геометрии поиска. В Oracle и SpatiaLite проверяется пространственное равенство, а в MySQL и PostGIS - равенство ограничительных рамок.

Пример:

Zipcode.objects.filter(poly=geom)
Бэкэнд Эквивалент SQL
ПостГИС poly ~= geom
Oracle SDO_EQUAL(poly, geom)
MySQL MBREquals(poly, geom)
SpatiaLite Equals(poly, geom)

intersects

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

Проверяет, пересекает ли поле геометрии пространственно геометрию поиска.

Пример:

Zipcode.objects.filter(poly__intersects=geom)
Бэкэнд Эквивалент SQL
ПостГИС ST_Intersects(poly, geom)
Oracle SDO_OVERLAPBDYINTERSECT(poly, geom)
MySQL MBRIntersects(poly, geom)
SpatiaLite Intersects(poly, geom)

isvalid

Доступность: MySQL (≥ 5.7.5), PostGIS, Oracle, SpatiaLite

Проверяет, действительна ли геометрия.

Пример:

Zipcode.objects.filter(poly__isvalid=True)
Бэкэнд Эквивалент SQL
MySQL, PostGIS, SpatiaLite ST_IsValid(poly)
Oracle SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(poly, 0.05) = 'TRUE'

overlaps

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

Проверяет, перекрывает ли поле геометрии пространственно геометрию поиска.

Бэкэнд Эквивалент SQL
ПостГИС ST_Overlaps(poly, geom)
Oracle SDO_OVERLAPS(poly, geom)
MySQL MBROverlaps(poly, geom)
SpatiaLite Overlaps(poly, geom)

relate

Доступность: PostGIS, Oracle, SpatiaLite, PGRaster (конверсия)

Проверяет, связано ли поле геометрии пространственно с геометрией поиска по значениям, указанным в заданном шаблоне. Для этого поиска требуется параметр кортежа (geom, pattern); форма pattern будет зависеть от пространственного бэкенда:

PostGIS & SpatiaLite

В этих пространственных бэкендах шаблон пересечения представляет собой строку, состоящую из девяти символов, которые определяют пересечения между внутренней, граничной и внешней частями геометрического поля и геометрией поиска. В матрице шаблона пересечения могут использоваться только следующие символы: 1, 2, T, F или *. Этот тип поиска позволяет пользователям «точно настроить» конкретные геометрические отношения, соответствующие модели DE-9IM. [1]

Пример геометрии:

# A tuple lookup parameter is used to specify the geometry and
# the intersection pattern (the pattern here is for 'contains').
Zipcode.objects.filter(poly__relate=(geom, 'T*T***FF*'))

SQL-эквивалент PostGIS:

SELECT ... WHERE ST_Relate(poly, geom, 'T*T***FF*')

SpatiaLite SQL эквивалент:

SELECT ... WHERE Relate(poly, geom, 'T*T***FF*')

Растровый пример:

Zipcode.objects.filter(poly__relate=(rast, 1, 'T*T***FF*'))
Zipcode.objects.filter(rast__2__relate=(rast, 1, 'T*T***FF*'))

SQL-эквивалент PostGIS:

SELECT ... WHERE ST_Relate(poly, ST_Polygon(rast, 1), 'T*T***FF*')
SELECT ... WHERE ST_Relate(ST_Polygon(rast, 2), ST_Polygon(rast, 1), 'T*T***FF*')

Oracle

Здесь шаблон отношения состоит по крайней мере из одной из девяти строк отношения: TOUCH, OVERLAPBDYDISJOINT, OVERLAPBDYINTERSECT, EQUAL, INSIDE, COVEREDBY, CONTAINS, COVERS, ON и ANYINTERACT. Несколько строк могут быть объединены с помощью логического булева оператора OR, например, 'inside+touch'. [2] Строки отношений не чувствительны к регистру.

Пример:

Zipcode.objects.filter(poly__relate=(geom, 'anyinteract'))

Oracle SQL эквивалент:

SELECT ... WHERE SDO_RELATE(poly, geom, 'anyinteract')

touches

Доступность: PostGIS, Oracle, MySQL, SpatiaLite

Проверяет, касается ли поле геометрии пространственно геометрии поиска.

Пример:

Zipcode.objects.filter(poly__touches=geom)
Бэкэнд Эквивалент SQL
ПостГИС ST_Touches(poly, geom)
MySQL MBRTouches(poly, geom)
Oracle SDO_TOUCH(poly, geom)
SpatiaLite Touches(poly, geom)

within

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

Проверяет, находится ли поле геометрии пространственно в пределах геометрии поиска.

Пример:

Zipcode.objects.filter(poly__within=geom)
Бэкэнд Эквивалент SQL
ПостГИС ST_Within(poly, geom)
MySQL MBRWithin(poly, geom)
Oracle SDO_INSIDE(poly, geom)
SpatiaLite Within(poly, geom)

left

Доступность: PostGIS, PGRaster (преобразование)

Проверяет, находится ли граница поля геометрии строго слева от границы поля геометрии поиска.

Пример:

Zipcode.objects.filter(poly__left=geom)

Эквивалент PostGIS:

SELECT ... WHERE poly << geom

right

Доступность: PostGIS, PGRaster (преобразование)

Проверяет, находится ли граница поля геометрии строго справа от границы поля геометрии поиска.

Пример:

Zipcode.objects.filter(poly__right=geom)

Эквивалент PostGIS:

SELECT ... WHERE poly >> geom

overlaps_left

Доступность: PostGIS, PGRaster (двусторонний)

Проверяет, перекрывает ли граничная область поля геометрии или находится слева от граничной области геометрии поиска.

Пример:

Zipcode.objects.filter(poly__overlaps_left=geom)

Эквивалент PostGIS:

SELECT ... WHERE poly &< geom

overlaps_right

Доступность: PostGIS, PGRaster (двусторонний)

Проверяет, перекрывает ли граничная область поля геометрии или находится справа от граничной области геометрии поиска.

Пример:

Zipcode.objects.filter(poly__overlaps_right=geom)

Эквивалент PostGIS:

SELECT ... WHERE poly &> geom

overlaps_above

Доступность: PostGIS, PGRaster (преобразование)

Проверяет, перекрывает ли граничная область поля геометрии или находится выше граничной области геометрии поиска.

Пример:

Zipcode.objects.filter(poly__overlaps_above=geom)

Эквивалент PostGIS:

SELECT ... WHERE poly |&> geom

overlaps_below

Доступность: PostGIS, PGRaster (преобразование)

Проверяет, перекрывает ли граничная область поля геометрии или находится ниже граничной области геометрии поиска.

Пример:

Zipcode.objects.filter(poly__overlaps_below=geom)

Эквивалент PostGIS:

SELECT ... WHERE poly &<| geom

strictly_above

Доступность: PostGIS, PGRaster (преобразование)

Проверяет, находится ли граница поля геометрии строго над границей геометрии поиска.

Пример:

Zipcode.objects.filter(poly__strictly_above=geom)

Эквивалент PostGIS:

SELECT ... WHERE poly |>> geom

strictly_below

Доступность: PostGIS, PGRaster (преобразование)

Проверяет, находится ли граница поля геометрии строго под границей геометрии поиска.

Пример:

Zipcode.objects.filter(poly__strictly_below=geom)

Эквивалент PostGIS:

SELECT ... WHERE poly <<| geom

Поиск расстояний

Доступность: PostGIS, Oracle, MySQL, SpatiaLite, PGRaster (Native)

Для получения информации о выполнении запросов на расстояние, пожалуйста, обратитесь к distance queries introduction.

Поиск расстояний имеет следующий вид:

<field>__<distance lookup>=(<geometry/raster>, <distance value>[, 'spheroid'])
<field>__<distance lookup>=(<raster>, <band_index>, <distance value>[, 'spheroid'])
<field>__<band_index>__<distance lookup>=(<raster>, <band_index>, <distance value>[, 'spheroid'])

Значение, передаваемое в поиск расстояния, представляет собой кортеж; первые два значения обязательны, это геометрия для расчета расстояния и значение расстояния (либо число в единицах поля, либо объект Distance>, либо выражение запроса <ref/models/expressions>). Чтобы передать индекс диапазона в поиск, используйте 3 кортежа, где второй элемент - индекс диапазона.

При каждом поиске расстояния, кроме dwithin, может быть включен необязательный элемент 'spheroid' для использования более точных функций расчета расстояния до сфероида на полях с геодезической системой координат.

В PostgreSQL опция 'spheroid' использует ST_DistanceSpheroid вместо ST_DistanceSphere. Более простая функция ST_Distance используется с проецируемыми системами координат. Растры преобразуются в геометрию для поиска по сфероиду.

distance_gt

Возвращает модели, в которых расстояние до поля геометрии от геометрии поиска больше заданного значения расстояния.

Пример:

Zipcode.objects.filter(poly__distance_gt=(geom, D(m=5)))
Бэкэнд Эквивалент SQL
ПостГИС ST_Distance/ST_Distance_Sphere(poly, geom) > 5
MySQL ST_Distance(poly, geom) > 5
Oracle SDO_GEOM.SDO_DISTANCE(poly, geom, 0.05) > 5
SpatiaLite Distance(poly, geom) > 5

distance_gte

Возвращает модели, в которых расстояние до поля геометрии от геометрии поиска больше или равно заданному значению расстояния.

Пример:

Zipcode.objects.filter(poly__distance_gte=(geom, D(m=5)))
Бэкэнд Эквивалент SQL
ПостГИС ST_Distance/ST_Distance_Sphere(poly, geom) >= 5
MySQL ST_Distance(poly, geom) >= 5
Oracle SDO_GEOM.SDO_DISTANCE(poly, geom, 0.05) >= 5
SpatiaLite Distance(poly, geom) >= 5

distance_lt

Возвращает модели, в которых расстояние до поля геометрии от геометрии поиска меньше заданного значения расстояния.

Пример:

Zipcode.objects.filter(poly__distance_lt=(geom, D(m=5)))
Бэкэнд Эквивалент SQL
ПостГИС ST_Distance/ST_Distance_Sphere(poly, geom) < 5
MySQL ST_Distance(poly, geom) < 5
Oracle SDO_GEOM.SDO_DISTANCE(poly, geom, 0.05) < 5
SpatiaLite Distance(poly, geom) < 5

distance_lte

Возвращает модели, в которых расстояние до поля геометрии от геометрии поиска меньше или равно заданному значению расстояния.

Пример:

Zipcode.objects.filter(poly__distance_lte=(geom, D(m=5)))
Бэкэнд Эквивалент SQL
ПостГИС ST_Distance/ST_Distance_Sphere(poly, geom) <= 5
MySQL ST_Distance(poly, geom) <= 5
Oracle SDO_GEOM.SDO_DISTANCE(poly, geom, 0.05) <= 5
SpatiaLite Distance(poly, geom) <= 5

dwithin

Возвращает модели, в которых расстояние до поля геометрии от геометрии поиска находится в пределах заданного расстояния друг от друга. Обратите внимание, что вы можете предоставить объекты Distance, только если целевые геометрии находятся в проецируемой системе. Для географических геометрий следует использовать единицы геометрического поля (например, градусы для WGS84).

Пример:

Zipcode.objects.filter(poly__dwithin=(geom, D(m=5)))
Бэкэнд Эквивалент SQL
ПостГИС ST_DWithin(poly, geom, 5)
Oracle SDO_WITHIN_DISTANCE(poly, geom, 5)
SpatiaLite PtDistWithin(poly, geom, 5)

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

Django предоставляет некоторые агрегатные функции, специфичные для ГИС. Подробнее о том, как использовать эти агрегатные функции, смотрите the topic guide on aggregation.

Аргумент по ключевому слову Описание
tolerance Это ключевое слово предназначено только для Oracle. Оно предназначено для значения допуска, используемого процедурой SDOAGGRTYPE; в Oracle documentation есть более подробная информация.

Пример:

>>> from django.contrib.gis.db.models import Extent, Union
>>> WorldBorder.objects.aggregate(Extent('mpoly'), Union('mpoly'))

Collect

class Collect(geo_field)

Доступность: PostGIS, SpatiaLite

Возвращает GEOMETRYCOLLECTION или MULTI объект геометрии из столбца geometry. Это аналог упрощенной версии агрегата Union, за исключением того, что он может быть на несколько порядков быстрее, чем выполнение объединения, потому что он просто сворачивает геометрии в коллекцию или мультиобъект, не заботясь о растворении границ.

Extent

class Extent(geo_field)

Доступность: PostGIS, Oracle, SpatiaLite

Возвращает объем всех geo_field в QuerySet в виде кортежа, состоящего из левой нижней координаты и правой верхней координаты.

Пример:

>>> qs = City.objects.filter(name__in=('Houston', 'Dallas')).aggregate(Extent('poly'))
>>> print(qs['poly__extent'])
(-96.8016128540039, 29.7633724212646, -95.3631439208984, 32.782058715820)

Extent3D

class Extent3D(geo_field)

Доступность: PostGIS

Возвращает трехмерную протяженность всех geo_field в QuerySet в виде кортежа, состоящего из левой нижней координаты и правой верхней координаты (каждая с координатами x, y и z).

Пример:

>>> qs = City.objects.filter(name__in=('Houston', 'Dallas')).aggregate(Extent3D('poly'))
>>> print(qs['poly__extent3d'])
(-96.8016128540039, 29.7633724212646, 0, -95.3631439208984, 32.782058715820, 0)

MakeLine

class MakeLine(geo_field)

Доступность: PostGIS, SpatiaLite

Возвращает LineString, построенный из геометрий точечных полей в QuerySet. В настоящее время упорядочивание набора не влияет.

Пример:

>>> qs = City.objects.filter(name__in=('Houston', 'Dallas')).aggregate(MakeLine('poly'))
>>> print(qs['poly__makeline'])
LINESTRING (-95.3631510000000020 29.7633739999999989, -96.8016109999999941 32.7820570000000018)

Union

class Union(geo_field)

Доступность: PostGIS, Oracle, SpatiaLite

Этот метод возвращает объект GEOSGeometry, состоящий из объединения всех геометрий в наборе запросов. Обратите внимание, что использование Union является процессороемким и может занять значительное время на больших наборах запросов.

Примечание

Если время вычислений при использовании этого метода слишком дорого, рассмотрите возможность использования Collect вместо него.

Пример:

>>> u = Zipcode.objects.aggregate(Union(poly))  # This may take a long time.
>>> u = Zipcode.objects.filter(poly__within=bbox).aggregate(Union(poly))  # A more sensible approach.

Сноски

[1]Смотрите OpenGIS Simple Feature Specification For SQL, в гл. 2.1.13.2, стр. 2-13 (Расширенная по размерам модель девяти пересечений).
[2]Смотрите SDO_RELATE documentation, из руководства Oracle Spatial and Graph Developer’s Guide.
[3](1, 2) Для объяснения этой процедуры прочитайте Quirks of the «Contains» Spatial Predicate Мартина Дэвиса (разработчика PostGIS).
Вернуться на верх