LayerMapping утилита импорта данных

Класс LayerMapping предоставляет способ отображения содержимого векторных файлов пространственных данных (например, шейп-файлов) в модели GeoDjango.

Эта утилита выросла из личной потребности автора устранить повторение кода, который использовался для извлечения геометрии и полей из векторного слоя, преобразования в другую систему координат (например, WGS84), а затем вставки в модель GeoDjango.

Примечание

Использование LayerMapping требует наличия GDAL.

Предупреждение

Источники данных ГИС, такие как шейп-файлы, могут быть очень большими. Если вы обнаружите, что LayerMapping использует слишком много памяти, установите DEBUG на False в настройках. Когда DEBUG установлено значение True, Django automatically logs каждый SQL запрос - и когда SQL запросы содержат геометрию, это может потреблять больше памяти, чем обычно.

Пример

  1. Вам нужен источник данных с поддержкой 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]]
    
  2. Теперь мы определяем нашу соответствующую модель 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
    
  3. Используйте 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.

Аргумент Описание
model Географическая модель, не экземпляр.
data_source Путь к файлу источника данных, поддерживаемому OGR (например, шейп-файл). Также принимает экземпляры django.contrib.gis.gdal.DataSource.
mapping Словарь: ключи - строки, соответствующие полю модели, а значения - строковые имена полей для характеристики OGR, или если поле модели является географическим, то оно должно соответствовать типу геометрии OGR, например, 'POINT', 'LINESTRING', 'POLYGON'.
Аргументы по ключевым словам  
layer Индекс слоя, который будет использоваться из источника данных (по умолчанию равен 0).
source_srs Используйте этот параметр для указания источника SRS вручную (например, некоторые шейпфайлы не поставляются с файлом '.prj'). Принимаются целочисленные SRID, строки WKT или PROJ, а также объекты django.contrib.gis.gdal.SpatialReference.
encoding Определяет кодировку набора символов строк в источнике данных OGR. Например, 'latin-1', 'utf-8' и 'cp437' - все это допустимые параметры кодировки.
transaction_mode Может быть 'commit_on_success' (по умолчанию) или 'autocommit'.
transform Установка значения False отключает преобразование координат. Другими словами, геометрии будут вставляться в базу данных без изменений по сравнению с их исходным состоянием в источнике данных.
unique Установка этого параметра на имя или кортеж имен из данной модели создаст модели, уникальные только для данного имени (имен). Геометрии из каждого объекта будут добавлены в коллекцию, связанную с уникальной моделью. Заставляет режим транзакции быть 'autocommit'.
using Устанавливает базу данных, которую следует использовать при импорте пространственных данных. По умолчанию 'default'.
Changed in Django 3.2:

Добавлена поддержка pathlib.Path data_source.

save() Аргументы ключевых слов

LayerMapping.save(verbose=False, fid_range=False, step=False, progress=False, silent=False, stream=sys.stdout, strict=False)

Метод save() также принимает ключевые слова. Эти ключевые слова используются для управления протоколированием вывода, обработкой ошибок и для импорта определенных диапазонов функций.

Сохранить аргументы ключевых слов Описание
fid_range Может быть задано фрагментом или кортежем (начало, конец) идентификаторов признаков для отображения из источника данных. Другими словами, это ключевое слово позволяет пользователю выборочно импортировать подмножество ряда признаков из источника географических данных.
progress Когда это ключевое слово установлено, будет печататься информация о состоянии, указывающая количество обработанных и успешно сохраненных признаков. По умолчанию информация о ходе обработки будет печататься через каждые 1000 обработанных признаков, однако это значение можно изменить, задав в этом ключевом слове целое число для нужного интервала.
silent По умолчанию уведомления о нефатальных ошибках выводятся в sys.stdout, но это ключевое слово может быть установлено для отключения этих уведомлений.
step Если задано целое число, транзакции будут происходить через каждый интервал шагов. Например, если step=1000, фиксация произойдет после 1 000-й функции, 2 000-й функции и т.д.
stream Информация о статусе будет записана в этот файл-хэндл. По умолчанию используется sys.stdout, но поддерживается любой объект с методом write.
strict Выполнение отображения модели прекращается при первой возникшей ошибке. Значение по умолчанию (False) означает попытку продолжения.
verbose Если установлено, то информация будет печататься после каждого сохранения модели в базе данных.

Устранение неполадок

Нехватка памяти

Как отмечено в предупреждении в верхней части этого раздела, 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
Вернуться на верх