Utilidad de importación de datos de LayerMapping

La clase LayerMapping proporciona una forma de mapear el contenido de archivos de datos espaciales vectoriales (por ejemplo, shapefiles) a modelos GeoDjango.

Esta utilidad surgió de las necesidades personales del autor para eliminar la repetición de código que se introdujo al extraer geometrías y campos de una capa vectorial, convertirlos a otro sistema de coordenadas (por ejemplo, WGS84) y luego insertarlos en un modelo GeoDjango.

Nota

El uso de LayerMapping requiere GDAL.

Advertencia

Las fuentes de datos GIS, como shapefiles, pueden ser muy grandes. Si encuentras que LayerMapping está utilizando demasiada memoria, establece DEBUG en False en tus configuraciones. Cuando DEBUG se establezca en True, Django registra automáticamente cada consulta SQL – y cuando las sentencias SQL contienen geometrías, esto puede consumir más memoria de lo típico.

Ejemplo

  1. Necesitas una fuente de datos GDAL compatible, como un shapefile (aquí estamos utilizando un simple polígono shapefile, test_poly.shp, con tres características):

>>> 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]]
  1. Ahora definimos nuestro modelo Django correspondiente (asegúrate de utilizar 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
    
  2. Usa la clase LayerMapping para extraer todas las características y colocarlas en la base de datos:

>>> 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

Aquí, la clase LayerMapping transformó las tres geometrías del archivo shapefile en su sistema de referencia espacial original (WGS84) al sistema de referencia espacial del modelo GeoDjango (NAD83). Si no se define un sistema de referencia espacial para el capa, utilice la palabra clave source_srs con un objeto SpatialReference para especificar uno.

API de LayerMapping

class LayerMapping(model, data_source, mapping, layer=0, source_srs=None, encoding=None, transaction_mode='commit_on_success', transform=True, unique=True, using='default')[fuente]

A continuación, se muestran los argumentos y palabras clave que pueden utilizarse durante la instanciación de objetos LayerMapping.

Argumento

Descripción

model

El modelo geográfico, no una instancia.

data_source

La ruta al archivo de origen admitido por OGR (por ejemplo, un archivo shapefile). También acepta instancias de la clase django.contrib.gis.gdal.DataSource.

mapping

Un diccionario: las claves son cadenas que corresponden al campo del modelo, y los valores corresponden a nombres de campos de cadena para la característica OGR, o si el campo del modelo es geográfico entonces debería corresponder al tipo de geometría OGR, por ejemplo, 'POINT', 'LINESTRING', 'POLYGON'.

Palabras Clave de Inicialización

layer

El índice del capa a utilizar desde la Fuente de Datos (por defecto 0)

source_srs

Utiliza esto para especificar manualmente el SRS de origen (por ejemplo, algunas shapefiles no vienen con un archivo '.prj'). Se aceptan SRID enteros, cadenas WKT o PROJ y objetos django.contrib.gis.gdal.SpatialReference.

encoding

Specifica el conjunto de caracteres de codificación de las cadenas en la fuente de datos OGR. Por ejemplo, 'latin-1', 'utf-8', y 'cp437' son todos parámetros de codificación válidos.

transaction_mode

Puede ser 'commit_on_success' (por defecto) o 'autocommit'.

transform

Establecer esto en False deshabilitará las transformaciones de coordenadas. En otras palabras, las geometrías se insertarán en la base de datos sin modificar desde su estado original en la fuente de datos.

único

Estableciendo esto a nombre o una tupla de nombres del modelo dado creará modelos únicos solo para el nombre(s) dado(s). Las geometrías de cada característica se agregarán a la colección asociada con el modelo único. Obliga al modo de transacción a ser 'autocommit'.

usando

Establece la base de datos para utilizar cuando se importan los datos espaciales. Por defecto es 'defecto'.

Palabras clave para save()

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

El método save() también acepta palabras clave. Estas palabras clave se utilizan para controlar la salida de registro, el manejo de errores y para importar rangos específicos de características.

Palabras clave Save

Descripción

fid_range

Puede establecerse con una sección o tupla de (begin, end) ID’s de característica para mapear desde la fuente de datos. En otras palabras, esta palabra clave permite al usuario importar selectivamente un subconjunto rango de características en la fuente de datos geográfica.

progress

Cuando se establece esta palabra clave, se imprimirán información de estado dando el número de características procesadas y guardadas con éxito. Por defecto, la información de progreso se imprimirá cada 1000 características procesadas, aunque este valor por defecto puede ser sobrescrito estableciendo esta palabra clave con un entero para el intervalo deseado.

silent

Por defecto, las notificaciones de errores no fatales se imprimen en sys.stdout, pero esta palabra clave puede estar configurada para deshabilitar estas notificaciones.

step

Si se establece con un entero, se producirán transacciones cada intervalo de paso. Por ejemplo, si step=1000, se realizaría un commit después de la 1,000ª característica, la 2,000ª característica, etc.

stream

La información de estado se escribirá en este manejador de archivo. Por defecto, se utiliza sys.stdout, pero cualquier objeto con un método write está soportado.

strict

La ejecución del mapeo del modelo cesará al primer error encontrado. El valor por defecto (False) es intentar continuar.

verbose

Si está configurado, se imprimirán información posterior a cada modelo guardado en la base de datos.

Solución de problemas

Agotamiento de memoria

Como se indica en la advertencia al principio de esta sección, Django almacena todas las consultas SQL cuando DEBUG=True. Establece DEBUG=False en tus configuraciones y esto debería detener el uso excesivo de memoria cuando ejecutas scripts LayerMapping.

MySQL: error max_allowed_packet

Si encuentras el siguiente error al utilizar LayerMapping y MySQL:

OperationalError: (1153, "Got a packet bigger than 'max_allowed_packet' bytes")

Entonces la solución es aumentar el valor de la configuración max_allowed_packet en tu configuración de MySQL. Por ejemplo, el valor por defecto puede ser algo bajo como un megabyte – la configuración se puede modificar en el archivo de configuración de MySQL (my.cnf) en la sección [mysqld]:

max_allowed_packet = 10M