Учебник по GeoDjango
Введение
GeoDjango — это модуль contrib для Django, который превращает его в полнофункциональный географический веб-фреймворк. GeoDjango стремится максимально упростить создание географических веб-приложений, таких как сервисы на основе местоположения. Его возможности включают:
- Поля модели Django для геометрий OGC и растровых данных.
- Расширения ORM Django для запросов и манипуляций пространственными данными.
- Гибкие, высокоуровневые Python-интерфейсы для операций с геометрией GIS, растровыми операциями и обработкой данных в различных форматах.
- Редактирование полей геометрии в админке.
В этом учебнике предполагается знакомство с Django; поэтому, если вы новичок в Django, пожалуйста, сначала изучите обычный учебник, чтобы ознакомиться с Django.
Примечание
GeoDjango имеет дополнительные требования помимо требований Django — для получения более подробной информации обратитесь к документации по установке.
Этот учебник проведет вас через создание географического веб-приложения для отображения мирных границ. [1] Часть кода, используемого в этом учебнике, взята из проекта GeoDjango basic apps или вдохновлена им. [2]
Примечание
Для пошаговых инструкций следуйте разделам учебника последовательно.
Настройка
Создание пространственной базы данных
Обычно никакой специальной настройки не требуется, поэтому вы можете создать базу данных так же, как и для любого другого проекта. Мы предоставляем несколько советов для выбранных баз данных:
Создание нового проекта
Используйте стандартную django-admin команду для создания проекта под названием geodjango:
$ django-admin startproject geodjango
...\> django-admin startproject geodjango
Это инициализирует новый проект. Теперь создайте приложение Django world внутри проекта geodjango:
$ cd geodjango $ python manage.py startapp world
...\> cd geodjango
...\> py manage.py startapp world
Настройка settings.py
Настройки проекта geodjango хранятся в файле geodjango/settings.py. Измените настройки подключения к базе данных, чтобы они соответствовали вашей настройке:
DATABASES = {
"default": {
"ENGINE": "django.contrib.gis.db.backends.postgis",
"NAME": "geodjango",
"USER": "geo",
},
}
Кроме того, измените настройку INSTALLED_APPS, чтобы добавить django.contrib.admin, django.contrib.gis и world (ваше недавно созданное приложение):
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django.contrib.gis",
"world",
]
Географические данные
Границы стран
Данные границ стран доступны в этом архиве ZIP. Создайте директорию data в приложении world, загрузите данные границ стран и распакуйте их. На платформах GNU/Linux используйте следующие команды:
$ mkdir world/data $ cd world/data $ wget https://web.archive.org/web/20231220150759/https://thematicmapping.org/downloads/TM_WORLD_BORDERS-0.3.zip $ unzip TM_WORLD_BORDERS-0.3.zip $ cd ../..
...\> mkdir world\data
...\> cd world\data
...\> wget https://web.archive.org/web/20231220150759/https://thematicmapping.org/downloads/TM_WORLD_BORDERS-0.3.zip
...\> unzip TM_WORLD_BORDERS-0.3.zip
...\> cd ..\..
Архив ZIP с границами стран содержит набор файлов данных, коллективно известных как ESRI Shapefile — один из самых популярных форматов пространственных данных. После распаковки набор данных границ стран содержит файлы со следующими расширениями:
-
.shp: Содержит векторные данные для геометрий границ стран. -
.shx: Файл пространственного индекса для геометрий, хранящихся в.shp. -
.dbf: Файл базы данных для хранения данных атрибутов, не являющихся геометрическими (например, целочисленных и символьных полей). -
.prj: Содержит информацию о пространственной ссылке для географических данных, хранящихся в shapefile.
Использование ogrinfo для проверки пространственных данных
Утилита GDAL ogrinfo позволяет проверять метаданные shapefile или других источников векторных данных:
$ ogrinfo world/data/TM_WORLD_BORDERS-0.3.shp
INFO: Open of `world/data/TM_WORLD_BORDERS-0.3.shp'
using driver `ESRI Shapefile' successful.
1: TM_WORLD_BORDERS-0.3 (Polygon)
...\> ogrinfo world\data\TM_WORLD_BORDERS-0.3.shp
INFO: Open of `world/data/TM_WORLD_BORDERS-0.3.shp'
using driver `ESRI Shapefile' successful.
1: TM_WORLD_BORDERS-0.3 (Polygon)
ogrinfo указывает, что shapefile имеет один слой, и что этот слой содержит полигональные данные. Для получения более подробной информации укажем имя слоя и используем параметр -so, чтобы получить только важную сводную информацию:
$ ogrinfo -so world/data/TM_WORLD_BORDERS-0.3.shp TM_WORLD_BORDERS-0.3
INFO: Open of `world/data/TM_WORLD_BORDERS-0.3.shp'
using driver `ESRI Shapefile' successful.
Layer name: TM_WORLD_BORDERS-0.3
Geometry: Polygon
Feature Count: 246
Extent: (-180.000000, -90.000000) - (180.000000, 83.623596)
Layer SRS WKT:
GEOGCS["GCS_WGS_1984",
DATUM["WGS_1984",
SPHEROID["WGS_1984",6378137.0,298.257223563]],
PRIMEM["Greenwich",0.0],
UNIT["Degree",0.0174532925199433]]
FIPS: String (2.0)
ISO2: String (2.0)
ISO3: String (3.0)
UN: Integer (3.0)
NAME: String (50.0)
AREA: Integer (7.0)
POP2005: Integer (10.0)
REGION: Integer (3.0)
SUBREGION: Integer (3.0)
LON: Real (8.3)
LAT: Real (7.3)
...\> ogrinfo -so world\data\TM_WORLD_BORDERS-0.3.shp TM_WORLD_BORDERS-0.3
INFO: Open of `world/data/TM_WORLD_BORDERS-0.3.shp'
using driver `ESRI Shapefile' successful.
Layer name: TM_WORLD_BORDERS-0.3
Geometry: Polygon
Feature Count: 246
Extent: (-180.000000, -90.000000) - (180.000000, 83.623596)
Layer SRS WKT:
GEOGCS["GCS_WGS_1984",
DATUM["WGS_1984",
SPHEROID["WGS_1984",6378137.0,298.257223563]],
PRIMEM["Greenwich",0.0],
UNIT["Degree",0.0174532925199433]]
FIPS: String (2.0)
ISO2: String (2.0)
ISO3: String (3.0)
UN: Integer (3.0)
NAME: String (50.0)
AREA: Integer (7.0)
POP2005: Integer (10.0)
REGION: Integer (3.0)
SUBREGION: Integer (3.0)
LON: Real (8.3)
LAT: Real (7.3)
Эта подробная сводная информация сообщает о количестве объектов в слое (246), географических границах данных, пространственной системе координат («SRS WKT»), а также информации о типе каждого поля атрибута. Например, FIPS: String (2.0) указывает, что поле FIPS символьного типа имеет максимальную длину 2. Аналогично, LON: Real (8.3) — поле с плавающей точкой, хранящее максимум 8 цифр до трёх десятичных знаков.
Географические модели
Определение географической модели
Теперь, когда вы изучили свой набор данных с помощью ogrinfo, создайте модель GeoDjango для представления этих данных:
from django.contrib.gis.db import models
class WorldBorder(models.Model):
# Regular Django fields corresponding to the attributes in the
# world borders shapefile.
name = models.CharField(max_length=50)
area = models.IntegerField()
pop2005 = models.IntegerField("Population 2005")
fips = models.CharField("FIPS Code", max_length=2, null=True)
iso2 = models.CharField("2 Digit ISO", max_length=2)
iso3 = models.CharField("3 Digit ISO", max_length=3)
un = models.IntegerField("United Nations Code")
region = models.IntegerField("Region Code")
subregion = models.IntegerField("Sub-Region Code")
lon = models.FloatField()
lat = models.FloatField()
# GeoDjango-specific: a geometry field (MultiPolygonField)
mpoly = models.MultiPolygonField()
# Returns the string representation of the model.
def __str__(self):
return self.name
Обратите внимание, что модуль models импортирован из django.contrib.gis.db.
По умолчанию пространственная система координат для полей геометрии — WGS84 (т.е. SRID равен 4326) — другими словами, координаты поля представляют собой пары долготы и широты в градусах. Для использования другой системы координат установите SRID поля геометрии с помощью параметра srid. Используйте целое число, представляющее код EPSG системы координат.
Выполнение migrate
После определения модели необходимо синхронизировать её с базой данных. Сначала создайте миграцию базы данных:
$ python manage.py makemigrations
Migrations for 'world':
world/migrations/0001_initial.py:
+ Create model WorldBorder
...\> py manage.py makemigrations
Migrations for 'world':
world/migrations/0001_initial.py:
+ Create model WorldBorder
Давайте посмотрим на SQL, который сгенерирует таблицу для модели WorldBorder:
$ python manage.py sqlmigrate world 0001
...\> py manage.py sqlmigrate world 0001
Эта команда должна вывести следующий результат:
BEGIN;
--
-- Create model WorldBorder
--
CREATE TABLE "world_worldborder" (
"id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
"name" varchar(50) NOT NULL,
"area" integer NOT NULL,
"pop2005" integer NOT NULL,
"fips" varchar(2) NOT NULL,
"iso2" varchar(2) NOT NULL,
"iso3" varchar(3) NOT NULL,
"un" integer NOT NULL,
"region" integer NOT NULL,
"subregion" integer NOT NULL,
"lon" double precision NOT NULL,
"lat" double precision NOT NULL
"mpoly" geometry(MULTIPOLYGON,4326) NOT NULL
)
;
CREATE INDEX "world_worldborder_mpoly_id" ON "world_worldborder" USING GIST ("mpoly");
COMMIT;
Если это выглядит правильно, выполните migrate, чтобы создать эту таблицу в базе данных:
$ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions, world Running migrations: ... Applying world.0001_initial... OK
...\> py manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, world
Running migrations:
...
Applying world.0001_initial... OK
Импорт пространственных данных
В этом разделе вы узнаете, как импортировать данные о границах мира в базу данных с помощью моделей GeoDjango, используя утилиту импорта данных LayerMapping.
Существует множество способов импорта данных в пространственную базу данных – помимо инструментов, включённых в GeoDjango, вы можете также использовать следующие:
- ogr2ogr: утилита командной строки, включённая в GDAL, которая может импортировать множество форматов векторных данных в базы данных PostGIS, MySQL и Oracle.
- shp2pgsql: эта утилита, включённая в PostGIS, импортирует ESRI-shape файлы в PostGIS.
Интерфейс GDAL
Ранее вы использовали ogrinfo для просмотра содержимого файла shape с границами мира. GeoDjango также включает питонический интерфейс к мощной библиотеке OGR GDAL, который может работать со всеми источниками векторных данных, поддерживаемыми OGR.
Сначала вызовите оболочку Django:
$ python manage.py shell
...\> py manage.py shell
Если вы загрузили данные Границы мира ранее в ходе учебника, то вы можете определить его путь, используя pathlib.Path из Python:
>>> from pathlib import Path >>> import world >>> world_shp = Path(world.__file__).resolve().parent / "data" / "TM_WORLD_BORDERS-0.3.shp"
Теперь откройте файл shape с границами мира, используя интерфейс DataSource GeoDjango:
>>> from django.contrib.gis.gdal import DataSource >>> ds = DataSource(world_shp) >>> print(ds) / ... /geodjango/world/data/TM_WORLD_BORDERS-0.3.shp (ESRI Shapefile)
Объекты источника данных могут иметь разные слои географических объектов; однако, shape-файлы разрешают иметь только один слой:
>>> print(len(ds)) 1 >>> lyr = ds[0] >>> print(lyr) TM_WORLD_BORDERS-0.3
Вы можете увидеть тип геометрии слоя и количество содержащихся в нём объектов:
>>> print(lyr.geom_type) Polygon >>> print(len(lyr)) 246
Примечание
К сожалению, формат данных shapefile не позволяет большей специфичности в отношении типов геометрии. Этот shapefile, как и многие другие, на самом деле содержит MultiPolygon геометрии, а не Многоугольники. Важно использовать более общий тип поля в моделях: GeoDjango MultiPolygonField будет принимать Polygon геометрию, но PolygonField не будет принимать MultiPolygon тип геометрии. Вот почему модель WorldBorder, определённая выше, использует MultiPolygonField.
У Layer также может быть связанная с ним система пространственной привязки. Если это так, то атрибут srs вернёт объект SpatialReference:
>>> srs = lyr.srs
>>> print(srs)
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,
AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0,
AUTHORITY["EPSG","8901"]],
UNIT["degree",0.0174532925199433,
AUTHORITY["EPSG","9122"]],
AXIS["Latitude",NORTH],
AXIS["Longitude",EAST],
AUTHORITY["EPSG","4326"]]
>>> srs.proj # PROJ representation
'+proj=longlat +datum=WGS84 +no_defs'
Этот shapefile находится в популярной системе пространственной привязки WGS84 – другими словами, данные используют пары долготы, широты в градусах.
Кроме того, shape-файлы также поддерживают атрибутивные поля, которые могут содержать дополнительные данные. Вот поля слоя Границы мира:
>>> print(lyr.fields) ['FIPS', 'ISO2', 'ISO3', 'UN', 'NAME', 'AREA', 'POP2005', 'REGION', 'SUBREGION', 'LON', 'LAT']
Следующий код позволит вам изучить типы OGR (например, целое число или строка), связанные с каждым из полей:
>>> [fld.__name__ for fld in lyr.field_types] ['OFTString', 'OFTString', 'OFTString', 'OFTInteger', 'OFTString', 'OFTInteger', 'OFTInteger64', 'OFTInteger', 'OFTInteger', 'OFTReal', 'OFTReal']
Вы можете перебирать каждый объект в слое и извлекать информацию как из геометрии объекта (доступ к которой осуществляется через атрибут geom), так и из атрибутивных полей объекта (к значениям которых вы можете обратиться с помощью метода get()):
>>> for feat in lyr:
... print(feat.get("NAME"), feat.geom.num_points)
...
Guernsey 18
Jersey 26
South Georgia South Sandwich Islands 338
Taiwan 363
Объекты Layer могут быть разрезаны:
>>> lyr[0:2] [<django.contrib.gis.gdal.feature.Feature object at 0x2f47690>, <django.contrib.gis.gdal.feature.Feature object at 0x2f47650>]
И отдельные объекты могут быть получены по их идентификатору:
>>> feat = lyr[234]
>>> print(feat.get("NAME"))
San Marino
Геометрии границ могут быть экспортированы в WKT и GeoJSON:
>>> geom = feat.geom
>>> print(geom.wkt)
POLYGON ((12.415798 43.957954,12.450554 ...
>>> print(geom.json)
{ "type": "Polygon", "coordinates": [ [ [ 12.415798, 43.957954 ], [ 12.450554, 43.979721 ], ...
LayerMapping
Для импорта данных используйте утилиту LayerMapping в скрипте Python. Создайте файл, названный load.py в приложении world, с указанным кодом:
from pathlib import Path
from django.contrib.gis.utils import LayerMapping
from .models import WorldBorder
world_mapping = {
"fips": "FIPS",
"iso2": "ISO2",
"iso3": "ISO3",
"un": "UN",
"name": "NAME",
"area": "AREA",
"pop2005": "POP2005",
"region": "REGION",
"subregion": "SUBREGION",
"lon": "LON",
"lat": "LAT",
"mpoly": "MULTIPOLYGON",
}
world_shp = Path(__file__).resolve().parent / "data" / "TM_WORLD_BORDERS-0.3.shp"
def run(verbose=True):
lm = LayerMapping(WorldBorder, world_shp, world_mapping, transform=False)
lm.save(strict=True, verbose=verbose)
Несколько примечаний о происходящем:
- Каждый ключ в словаре
world_mappingсоответствует полю в моделиWorldBorder. Значение – имя поля shape-файла, из которого будут загружены данные. - Ключ
mpolyдля поля геометрии – этоMULTIPOLYGON, тип геометрии, который GeoDjango будет импортировать в качестве поля. Даже простые многоугольники в shape-файле будут автоматически преобразованы в коллекции перед вставкой в базу данных. - Путь к shape-файлу не абсолютный – другими словами, если вы переместите приложение
world(с подкаталогомdata) в другое место, скрипт всё равно будет работать. - Ключевое слово
transformустановлено вFalse, так как данные в shape-файле не нуждаются в преобразовании – они уже находятся в WGS84 (SRID=4326).
После этого вызовите оболочку Django из каталога проекта geodjango:
$ python manage.py shell
...\> py manage.py shell
Затем импортируйте модуль load, вызовите функцию run и понаблюдайте, как LayerMapping выполнит работу:
>>> from world import load >>> load.run()
Попробуйте ogrinspect
Теперь, когда вы увидели, как определить географические модели и импортировать данные с помощью LayerMapping, можно далее автоматизировать этот процесс с помощью команды управления ogrinspect. Команда ogrinspect инспектирует источник векторных данных, поддерживаемых GDAL (например, shapefile), и автоматически генерирует определение модели и словарь LayerMapping.
Общее использование команды следующее:
$ python manage.py ogrinspect [options] <data_source> <model_name> [options]
...\> py manage.py ogrinspect [options] <data_source> <model_name> [options]
data_source – путь к источнику данных, поддерживаемому GDAL, а model_name – имя, используемое для модели. Для дальнейшего определения того, как генерируется модель, могут быть использованы параметры командной строки.
Например, следующая команда почти воспроизводит модель WorldBorder и словарь сопоставления, созданный выше, автоматически:
$ python manage.py ogrinspect world/data/TM_WORLD_BORDERS-0.3.shp WorldBorder \
--srid=4326 --mapping --multi
...\> py manage.py ogrinspect world\data\TM_WORLD_BORDERS-0.3.shp WorldBorder \
--srid=4326 --mapping --multi
Несколько примечаний о параметрах командной строки, указанных выше:
- Параметр
--srid=4326задаёт SRID для географического поля. - Параметр
--mappingуказываетogrinspectтакже сгенерировать словарь сопоставления для использования сLayerMapping. - Параметр
--multiзадаётся, чтобы географическое поле былоMultiPolygonField, а не простоPolygonField.
Команда генерирует следующий вывод, который можно скопировать непосредственно в models.py приложения GeoDjango:
# This is an auto-generated Django model module created by ogrinspect.
from django.contrib.gis.db import models
class WorldBorder(models.Model):
fips = models.CharField(max_length=2)
iso2 = models.CharField(max_length=2)
iso3 = models.CharField(max_length=3)
un = models.IntegerField()
name = models.CharField(max_length=50)
area = models.IntegerField()
pop2005 = models.IntegerField()
region = models.IntegerField()
subregion = models.IntegerField()
lon = models.FloatField()
lat = models.FloatField()
geom = models.MultiPolygonField(srid=4326)
# Auto-generated `LayerMapping` dictionary for WorldBorder model
worldborders_mapping = {
"fips": "FIPS",
"iso2": "ISO2",
"iso3": "ISO3",
"un": "UN",
"name": "NAME",
"area": "AREA",
"pop2005": "POP2005",
"region": "REGION",
"subregion": "SUBREGION",
"lon": "LON",
"lat": "LAT",
"geom": "MULTIPOLYGON",
}
Пространственные запросы
Пространственные запросы
GeoDjango добавляет пространственные запросы к Django ORM. Например, вы можете найти страну в таблице WorldBorder, которая содержит определённую точку. Сначала запустите оболочку управления:
$ python manage.py shell
...\> py manage.py shell
Теперь определите точку интереса [3]:
>>> pnt_wkt = "POINT(-95.3385 29.7245)"
Строка pnt_wkt представляет точку с долготой -95.3385 градусов и широтой 29.7245 градусов. Геометрия представлена в формате Well Known Text (WKT), стандарт, выпущенный Open Geospatial Consortium (OGC). [4] Импортируйте модель WorldBorder и выполните запрос contains, используя pnt_wkt в качестве параметра:
>>> from world.models import WorldBorder >>> WorldBorder.objects.filter(mpoly__contains=pnt_wkt) <QuerySet [<WorldBorder: United States>]>
Здесь вы получили QuerySet, содержащую только одну модель: границу Соединенных Штатов (точно то, чего вы ожидали).
Аналогично, вы также можете использовать объект геометрии GEOS. Здесь вы можете объединить пространственный запрос intersects с методом get, чтобы получить только экземпляр WorldBorder для Сан-Марино вместо набора результатов:
>>> from django.contrib.gis.geos import Point >>> pnt = Point(12.4604, 43.9420) >>> WorldBorder.objects.get(mpoly__intersects=pnt) <WorldBorder: San Marino>
Запросы contains и intersects — это лишь подмножество доступных запросов. Более подробную информацию см. в документации GeoDjango API базы данных.
Автоматические пространственные преобразования
При выполнении пространственных запросов GeoDjango автоматически преобразует геометрии, если они находятся в другой системе координат. В следующем примере координаты будут выражены в системе координат EPSG SRID 32140, специфичной для южного Техаса только и в единицах метров, а не градусов:
>>> from django.contrib.gis.geos import GEOSGeometry, Point >>> pnt = Point(954158.1, 4215137.1, srid=32140)
Обратите внимание, что pnt также может быть создан с помощью EWKT, «расширенной» формы WKT, которая включает SRID:
>>> pnt = GEOSGeometry("SRID=32140;POINT(954158.1 4215137.1)")
ORM GeoDjango автоматически обернёт геометрические значения в SQL-преобразования, что позволит разработчику работать на более высоком уровне абстракции:
>>> qs = WorldBorder.objects.filter(mpoly__intersects=pnt)
>>> print(qs.query) # Generating the SQL
SELECT "world_worldborder"."id", "world_worldborder"."name", "world_worldborder"."area",
"world_worldborder"."pop2005", "world_worldborder"."fips", "world_worldborder"."iso2",
"world_worldborder"."iso3", "world_worldborder"."un", "world_worldborder"."region",
"world_worldborder"."subregion", "world_worldborder"."lon", "world_worldborder"."lat",
"world_worldborder"."mpoly" FROM "world_worldborder"
WHERE ST_Intersects("world_worldborder"."mpoly", ST_Transform(%s, 4326))
>>> qs # printing evaluates the queryset
<QuerySet [<WorldBorder: United States>]>
Прямые запросы
При использовании прямых запросов необходимо обернуть ваши геометрические поля, чтобы значение поля могло быть распознано GEOS:
>>> from django.db import connection >>> # or if you're querying a non-default database: >>> from django.db import connections >>> connection = connections["your_gis_db_alias"] >>> City.objects.raw( ... "SELECT id, name, %s as point from myapp_city" % (connection.ops.select % "point") ... )
Прямые запросы следует использовать только в том случае, если вы точно знаете, что делаете.
Ленивые геометрии
GeoDjango загружает геометрии в стандартном текстовом представлении. При первом обращении к полю геометрии GeoDjango создаёт объект GEOSGeometry, предоставляя мощные функции, такие как свойства сериализации для популярных форматов геопространственных данных:
>>> sm = WorldBorder.objects.get(name="San Marino")
>>> sm.mpoly
<MultiPolygon object at 0x24c6798>
>>> sm.mpoly.wkt # WKT
MULTIPOLYGON (((12.4157980000000006 43.9579540000000009, 12.4505540000000003 43.9797209999999978, ...
>>> sm.mpoly.wkb # WKB (as Python binary buffer)
<read-only buffer for 0x1fe2c70, size -1, offset 0 at 0x2564c40>
>>> sm.mpoly.geojson # GeoJSON
'{ "type": "MultiPolygon", "coordinates": [ [ [ [ 12.415798, 43.957954 ], [ 12.450554, 43.979721 ], ...
Это включает доступ ко всем расширенным геометрическим операциям, предоставляемым библиотекой GEOS:
>>> pnt = Point(12.4604, 43.9420) >>> sm.mpoly.contains(pnt) True >>> pnt.contains(sm.mpoly) False
Географические аннотации
GeoDjango также предоставляет набор географических аннотаций для вычисления расстояний и нескольких других операций (пересечение, разность и т. д.). См. документацию по Географическим функциям базы данных.
Отображение данных на карте
Географический администратор
Приложения администратора Django поддерживает редактирование геометрических полей.
Основы
Приложение администратора Django позволяет пользователям создавать и изменять геометрии на интерактивной JavaScript-карте (на основе OpenLayers).
Давайте приступим. Создайте файл admin.py в приложении world со следующим кодом:
from django.contrib.gis import admin from .models import WorldBorder admin.site.register(WorldBorder, admin.ModelAdmin)
Далее отредактируйте urls.py в папке приложения geodjango следующим образом:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("admin/", admin.site.urls),
]
Создайте пользователя администратора:
$ python manage.py createsuperuser
...\> py manage.py createsuperuser
Далее запустите сервер разработки Django:
$ python manage.py runserver
...\> py manage.py runserver
Наконец, перейдите на http://localhost:8000/admin/ и войдите в систему с только что созданным пользователем. Перейдите к любой из записей WorldBorder — границы можно редактировать, нажав на многоугольник и перетащив вершины в нужное положение.
GISModelAdmin
С помощью GISModelAdmin GeoDjango использует слой OpenStreetMap в админ-панели. Это обеспечивает больший контекст (включая улицы и другие детали), чем доступно с ModelAdmin (который использует набор данных WMS Vector Map Level 0, размещённый на OSGeo).
Файлы смещения DATUM PROJ необходимо установить (подробнее см. в инструкции по установке PROJ).
Если это условие выполнено, используйте класс GISModelAdmin в файле admin.py:
admin.site.register(WorldBorder, admin.GISModelAdmin)
Примечания
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.2/ref/contrib/gis/tutorial/