GeoDjango Модель API
В данном документе рассматриваются подробности GeoDjango модели API. В этом разделе мы будем использовать следующие географические модели почтового индекса (ZIP code) и цифровой модели рельефа (Digital Elevation Model) в качестве примеров:
from django.contrib.gis.db import models
class Zipcode(models.Model):
code = models.CharField(max_length=5)
poly = models.PolygonField()
class Elevation(models.Model):
name = models.CharField(max_length=100)
rast = models.RasterField()
Типы пространственных полей
Пространственные поля состоят из ряда типов геометрических полей и одного типа растрового поля. Каждый из типов геометрических полей соответствует спецификации OpenGIS Simple Features [1]. Для растровых данных такого стандарта нет.
GeometryField
-
class GeometryField[source]
PointField
-
class PointField[source]
LineStringField
-
class LineStringField[source]
PolygonField
-
class PolygonField[source]
MultiPointField
-
class MultiPointField[source]
MultiLineStringField
-
class MultiLineStringField[source]
MultiPolygonField
-
class MultiPolygonField[source]
GeometryCollectionField
-
class GeometryCollectionField[source]
RasterField
-
class RasterField[source]
RasterField в настоящее время реализован только для бэкенда PostGIS.
Параметры пространственных полей
Параметры геометрических полей srid и spatial_index теперь совместно используются для GeometryField и RasterField через BaseSpatialField.
В дополнение к стандартным параметрам полей Django моделей, пространственные поля имеют следующие дополнительные параметры. Все они необязательны.
srid
-
BaseSpatialField.srid
Устанавливает SRID [2] (Идентификатор пространственной системы координат) геометрического поля до заданного значения. По умолчанию 4326 (также известный как WGS84, единицы измерения в градусах долготы и широты).
Выбор SRID
Выбор соответствующего SRID для вашей модели является важным решением, которое разработчик должен тщательно обдумать. SRID — это целочисленный идентификатор, который соответствует проекционной системе, используемой для интерпретации данных в пространственной базе данных. [3] Проекционные системы придают контекст координатам, определяющим местоположение. Хотя детали геодезии выходят за рамки этой документации, основная проблема заключается в том, что Земля имеет форму сферы, а представления Земли (например, бумажные карты, веб-карты) не являются таковыми.
Большинство людей знакомы с использованием широты и долготы для ссылки на местоположение на поверхности Земли. Однако широта и долгота представляют собой углы, а не расстояния. Другими словами, в то время как кратчайший путь между двумя точками на плоской поверхности — прямая линия, кратчайший путь между двумя точками на криволинейной поверхности (например, Землей) — дуга большого круга. [4] Таким образом, для получения расстояний в плоских единицах (например, километрах и милях) требуется дополнительное вычисление. Использование географической системы координат может вызвать сложности для разработчика впоследствии. Например, SpatiaLite не имеет возможности выполнять вычисления расстояний между геометриями, использующими географические системы координат, например, построения запроса для поиска всех точек в пределах 5 миль от границ округа, хранящихся как WGS84. [5]
Части поверхности Земли могут быть спроецированы на двумерную или декартову плоскость. Проекционные системы координат особенно удобны для региональных приложений, например, если вам известно, что ваша база данных будет охватывать только геометрии в Северном Канзасе, то вы можете рассмотреть использование проекционной системы, специфичной для этого региона. Кроме того, проекционные системы координат определены в декартовых единицах (таких как метры или футы), что упрощает вычисление расстояний.
Примечание
Если вы хотите выполнять произвольные запросы расстояний с использованием неточечной геометрии в WGS84 в PostGIS и вам нужна хорошая производительность, включите ключевое слово GeometryField.geography, чтобы вместо этого использовался тип данных базы данных география.
Дополнительные ресурсы:
- spatialreference.org: база данных пространственных систем координат, работающая на Django.
- Система координат штата: сайт, посвященный различным проекционным системам, используемым в США. Большая часть пространственных данных США будет в одной из этих систем координат, а не в географической системе координат, например, WGS84.
spatial_index
-
BaseSpatialField.spatial_index
По умолчанию True. Создает пространственный индекс для данного геометрического поля.
Примечание
Это отличается от параметра поля db_index, поскольку пространственные индексы создаются другим способом, чем обычные индексы базы данных. В частности, пространственные индексы обычно создаются с помощью варианта R-дерева, в то время как обычные индексы базы данных обычно используют B-деревья.
Параметры геометрических полей
Доступны дополнительные параметры для геометрических полей. Все следующие параметры являются необязательными.
dim
-
GeometryField.dim
Этот параметр может использоваться для настройки размерности координат геометрического поля. По умолчанию он установлен в 2, для представления двумерных геометрий. Для пространственных бэкэндов, которые его поддерживают, он может быть установлен в 3 для поддержки трехмерных данных.
Примечание
В настоящее время поддержка 3D ограничена пространственным бэкэндом PostGIS.
geography
-
GeometryField.geography
Если установлено значение True, этот параметр создаст столбец базы данных типа география, а не геометрия. Подробнее см. раздел тип географии ниже.
Примечание
Поддержка географии ограничена PostGIS и принудительно установит SRID в 4326.
Тип географии
Тип географии обеспечивает поддержку пространственных объектов, представленных географическими координатами (например, долгота/широта WGS84). [6] В отличие от плоскости, используемой типом геометрии, тип географии использует сферическое представление данных. Операции вычисления расстояний и измерений, выполняемые над столбцом географии, автоматически используют вычисления дуг больших кругов и возвращают линейные единицы. Другими словами, когда ST_Distance вызывается на двух географических объектах, возвращается значение в метрах (в отличие от градусов, если вызывается на столбце геометрии в WGS84).
Поскольку геологические вычисления включают в себя больше математики, для типа geography доступен только подмножество пространственных запросов PostGIS. Практически это означает, что помимо поиска по расстоянию только следующие дополнительные пространственные запросы доступны для гео-колонок:
Если вам нужно использовать пространственный запрос или агрегат, который не поддерживает тип geography в качестве входных данных, вы можете использовать функцию базы данных Cast для преобразования гео-колонки в тип geometry в запросе:
from django.contrib.gis.db.models import PointField
from django.db.models.functions import Cast
Zipcode.objects.annotate(
geom=Cast('geography_field', PointField())
).filter(geom__within=poly)
Для получения дополнительной информации, в документации PostGIS есть полезный раздел о определении когда использовать тип данных geography вместо типа данных geometry.
GeoManager
-
class GeoManager[source]
Менеджер GeoManager требуется для использования устаревших методов GeoQuerySet.
Устарело начиная с версии 1.9: Все GeoQuerySet методы были устаревши и заменены на эквивалентные функции базы данных. Как только устаревшие методы были заменены в вашем коде, вы должны иметь возможность удалить специальный GeoManager из ваших классов с поддержкой ГИС.
В более ранних версиях менеджер был необходим для выполнения географических запросов. Без него все географические фильтры не работали.
GeoManager был необходим даже если у модели не было географического поля, например, в случае ForeignKey связи с моделью с географическим полем. Например, если у нас есть модель Address с ForeignKey на нашу модель %%%CODE_BLOCK_53%%:
from django.contrib.gis.db import models
class Address(models.Model):
num = models.IntegerField()
street = models.CharField(max_length=100)
city = models.CharField(max_length=100)
state = models.CharField(max_length=2)
zipcode = models.ForeignKey(Zipcode, on_delete=models.CASCADE)
objects = models.GeoManager()
Географический менеджер был необходим для выполнения пространственных запросов к связанным Zipcode объектам, например:
qs = Address.objects.filter(zipcode__poly__contains='POINT(-104.590948 38.319914)')
Примечания
| [1] | OpenGIS Consortium, Inc., Спецификация простых объектов для SQL. |
| [2] | См. id. в гл. 2.3.8, стр. 39 (Значения геометрии и системы пространственных ссылок). |
| [3] | Обычно целое число SRID соответствует идентификатору EPSG (Европейская группа по обзору нефтегазовых месторождений). Однако он также может быть связан с пользовательскими проекциями, определёнными в таблице систем пространственных ссылок пространственной базы данных. |
| [4] | Terry A. Slocum, Robert B. McMaster, Fritz C. Kessler, & Hugh H. Howard, Теоматическая картография и визуализация географических данных (Prentice Hall, 2-е издание), в гл. 7.1.3. |
| [5] | Это ограничение не относится к PostGIS. |
| [6] | Для получения более подробной информации см. документацию по типу данных PostGIS Geography. |
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/1.10/ref/contrib/gis/model-api/