Утилита импорта данных LayerMapping¶
Класс LayerMapping предоставляет способ сопоставления содержимого векторных файлов пространственных данных (например, шейп-файлов) с моделями GeoDjango.
Эта утилита возникла из личных потребностей автора, направленных на устранение повторения кода, необходимого для извлечения геометрии и полей из векторного слоя, преобразования в другую систему координат (например, WGS84) и последующей вставки в модель GeoDjango.
Примечание
Для использования LayerMapping требуется GDAL.
Предупреждение
Источники данных ГИС, например шейп-файлы, могут быть очень большими. Если вы обнаружите, что LayerMapping использует слишком много памяти, установите для DEBUG значение False в настройках. Когда для DEBUG установлено значение True, Django автоматически регистрирует каждый SQL-запрос - и когда операторы SQL содержат геометрии, это может потреблять больше памяти, чем обычно.
Пример¶
Вам понадобится источник данных, поддерживаемый GDAL, например шейп-файл (здесь мы используем простой шейп-файл многоугольника
test_poly.shpс тремя функциями):
>>> from django.contrib.gis.gdal import DataSource
>>> ds = DataSource("test_poly.shp")
>>> layer = ds[0]
>>> print(layer.fields) # Exploring the fields in the layer, we only want the 'str' field.
['float', 'int', 'str']
>>> print(len(layer)) # getting the number of features in the layer (should be 3)
3
>>> print(layer.geom_type) # Should be 'Polygon'
Polygon
>>> print(layer.srs) # WGS84 in WKT
GEOGCS["GCS_WGS_1984",
DATUM["WGS_1984",
SPHEROID["WGS_1984",6378137,298.257223563]],
PRIMEM["Greenwich",0],
UNIT["Degree",0.017453292519943295]]
Теперь мы определяем соответствующую модель Django (обязательно используйте
migrate):from django.contrib.gis.db import models class TestGeo(models.Model): name = models.CharField(max_length=25) # corresponds to the 'str' field poly = models.PolygonField(srid=4269) # we want our model in a different SRID def __str__(self): return "Name: %s" % self.name
Используйте
LayerMapping, чтобы извлечь все объекты и поместить их в базу данных:
>>> from django.contrib.gis.utils import LayerMapping
>>> from geoapp.models import TestGeo
>>> mapping = {
... "name": "str", # The 'name' model field maps to the 'str' layer field.
... "poly": "POLYGON", # For geometry fields use OGC name.
... } # The mapping is a dictionary
>>> lm = LayerMapping(TestGeo, "test_poly.shp", mapping)
>>> lm.save(verbose=True) # Save the layermap, imports the data.
Saved: Name: 1
Saved: Name: 2
Saved: Name: 3
Здесь LayerMapping преобразовал три геометрии из шейп-файла в их исходной системе пространственной привязки (WGS84) в систему пространственной привязки модели GeoDjango (NAD83). Если для слоя не определена система пространственной привязки, используйте ключевое слово source_srs с объектом SpatialReference, чтобы указать ее.
LayerMapping API¶
- class LayerMapping(model, data_source, mapping, layer=0, source_srs=None, encoding=None, transaction_mode='commit_on_success', transform=True, unique=True, using='default')¶
Ниже приведены аргументы и ключевые слова, которые можно использовать во время создания экземпляров объектов LayerMapping.
Аргумент |
Описание |
|---|---|
|
Географическая модель, а не экземпляр. |
|
Путь к файлу источника данных, поддерживаемому OGR (например, шейп-файлу). Также принимает экземпляры |
|
Словарь: ключи — это строки, соответствующие полю модели, а значения соответствуют именам строковых полей для объекта OGR, или, если поле модели является географическим, то оно должно соответствовать типу геометрии OGR, например, |
Аргументы ключевых слов |
|
|---|---|
|
Индекс слоя, который будет использоваться из источника данных (по умолчанию 0). |
|
Используйте это, чтобы указать исходный SRS вручную (например, некоторые шейп-файлы не поставляются с файлом |
|
Указывает кодировку набора символов для строк в источнике данных OGR. Например, |
|
Может быть |
|
Установка значения False отключит преобразования координат. Другими словами, геометрии будут вставлены в базу данных без изменений по сравнению с их исходным состоянием в источнике данных. |
|
Если задать это имя или кортеж имен из данной модели, будут созданы модели, уникальные только для данного имени(й). Геометрии каждого объекта будут добавлены в коллекцию, связанную с уникальной моделью. Устанавливает режим транзакции |
|
Устанавливает базу данных, которая будет использоваться при импорте пространственных данных. По умолчанию установлено |
save() Аргументы ключевых слов¶
- LayerMapping.save(verbose=False, fid_range=False, step=False, progress=False, silent=False, stream=sys.stdout, strict=False)¶
Метод save() также принимает ключевые слова. Эти ключевые слова используются для управления журналированием выходных данных, обработки ошибок и для импорта определенных диапазонов функций.
Сохранить аргументы ключевого слова |
Описание |
|---|---|
|
Может быть установлен с помощью фрагмента или кортежа идентификаторов объектов (начала и конца) для сопоставления из источника данных. Другими словами, это ключевое слово позволяет пользователю выборочно импортировать подмножество объектов в источнике географических данных. |
|
Если это ключевое слово установлено, будет напечатана информация о состоянии с указанием количества обработанных и успешно сохраненных объектов. По умолчанию информация о ходе выполнения будет печататься через каждые 1000 обработанных объектов, однако это значение по умолчанию можно переопределить, задав для этого ключевого слова целое число для желаемого интервала. |
|
По умолчанию уведомления о нефатальных ошибках выводятся в |
|
Если установлено целое число, транзакции будут происходить на каждом интервале шага. Например, если |
|
Информация о состоянии будет записана в этот дескриптор файла. По умолчанию используется |
|
Выполнение сопоставления модели прекратится при первой обнаруженной ошибке. Значение по умолчанию («False») — попытка продолжить. |
|
Если установлено, информация будет распечатана после каждого сохранения модели в базе данных. |
Решение проблем¶
Недостаточно памяти¶
Как отмечено в предупреждении в начале этого раздела, Django сохраняет все SQL-запросы, когда DEBUG=True. Установите DEBUG=False в своих настройках, и это должно остановить чрезмерное использование памяти при запуске сценариев LayerMapping.
MySQL: ошибка max_allowed_packet¶
Если вы столкнулись со следующей ошибкой при использовании LayerMapping и MySQL:
OperationalError: (1153, "Got a packet bigger than 'max_allowed_packet' bytes")
Тогда решение состоит в том, чтобы увеличить значение параметра max_allowed_packet в вашей конфигурации MySQL. Например, значение по умолчанию может быть чем-то небольшим, например один мегабайт. Этот параметр можно изменить в файле конфигурации MySQL (my.cnf) в разделе [mysqld]:
max_allowed_packet = 10M