====================================``LayerMapping`` data import utility====================================.. module:: django.contrib.gis.utils.layermapping:synopsis: Spatial data import utility for GeoDjango models... currentmodule:: django.contrib.gis.utilsThe :class:`LayerMapping` class provides a way to map the contents ofvector spatial data files (e.g. shapefiles) into GeoDjango models.This utility grew out of the author's personal needs to eliminatethe code repetition that went into pulling geometries and fields out ofa vector layer, converting to another coordinate system (e.g. WGS84), andthen inserting into a GeoDjango model... note::Use of :class:`LayerMapping` requires GDAL... warning ::GIS data sources, like shapefiles, may be very large. If you findthat :class:`LayerMapping` is using too much memory, set:setting:`DEBUG` to ``False`` in your settings. When :setting:`DEBUG`is set to ``True``, Django :ref:`automatically logs <faq-see-raw-sql-queries>`*every* SQL query -- and when SQL statements contain geometries, this mayconsume more memory than is typical.Example=======#. You need a GDAL-supported data source, like a shapefile (here we're usinga simple polygon shapefile, ``test_poly.shp``, with three features)::>>> 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 WKTGEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]#. Now we define our corresponding Django model (make sure to use :djadmin:`migrate`)::from django.contrib.gis.db import modelsclass TestGeo(models.Model):name = models.CharField(max_length=25) # corresponds to the 'str' fieldpoly = models.PolygonField(srid=4269) # we want our model in a different SRIDdef __str__(self):return 'Name: %s' % self.name#. Use :class:`LayerMapping` to extract all the features and place them in thedatabase::>>> 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: 1Saved: Name: 2Saved: Name: 3Here, :class:`LayerMapping` transformed the three geometries from the shapefilein their original spatial reference system (WGS84) to the spatial referencesystem of the GeoDjango model (NAD83). If no spatial reference system isdefined for the layer, use the ``source_srs`` keyword with a:class:`~django.contrib.gis.gdal.SpatialReference` object to specify one.``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')The following are the arguments and keywords that may be used duringinstantiation of ``LayerMapping`` objects.================= =========================================================Argument Description================= =========================================================``model`` The geographic model, *not* an instance.``data_source`` The path to the OGR-supported data source file(e.g., a shapefile). Also accepts:class:`django.contrib.gis.gdal.DataSource` instances.``mapping`` A dictionary: keys are strings corresponding tothe model field, and values correspond tostring field names for the OGR feature, or if themodel field is a geographic then it shouldcorrespond to the OGR geometry type,e.g., ``'POINT'``, ``'LINESTRING'``, ``'POLYGON'``.================= ============================================================================== =====================================================Keyword Arguments===================== =====================================================``layer`` The index of the layer to use from the Data Source(defaults to 0)``source_srs`` Use this to specify the source SRS manually (forexample, some shapefiles don't come with a ``'.prj'``file). An integer SRID, WKT or PROJ strings, and:class:`django.contrib.gis.gdal.SpatialReference`objects are accepted.``encoding`` Specifies the character set encoding of the stringsin the OGR data source. For example, ``'latin-1'``,``'utf-8'``, and ``'cp437'`` are all valid encodingparameters.``transaction_mode`` May be ``'commit_on_success'`` (default) or``'autocommit'``.``transform`` Setting this to False will disable coordinatetransformations. In other words, geometries willbe inserted into the database unmodified from theiroriginal state in the data source.``unique`` Setting this to the name, or a tuple of names,from the given model will create models uniqueonly to the given name(s). Geometries fromeach feature will be added into the collectionassociated with the unique model. Forcesthe transaction mode to be ``'autocommit'``.``using`` Sets the database to use when importing spatial data.Default is ``'default'``.===================== =====================================================``save()`` Keyword Arguments----------------------------.. method:: LayerMapping.save(verbose=False, fid_range=False, step=False, progress=False, silent=False, stream=sys.stdout, strict=False)The ``save()`` method also accepts keywords. These keywords areused for controlling output logging, error handling, and for importingspecific feature ranges.=========================== =================================================Save Keyword Arguments Description=========================== =================================================``fid_range`` May be set with a slice or tuple of(begin, end) feature ID's to map fromthe data source. In other words, thiskeyword enables the user to selectivelyimport a subset range of features in thegeographic data source.``progress`` When this keyword is set, status informationwill be printed giving the number of featuresprocessed and successfully saved. By default,progress information will be printed every 1000features processed, however, this default maybe overridden by setting this keyword with aninteger for the desired interval.``silent`` By default, non-fatal error notifications areprinted to ``sys.stdout``, but this keyword maybe set to disable these notifications.``step`` If set with an integer, transactions willoccur at every step interval. For example, if``step=1000``, a commit would occur after the1,000th feature, the 2,000th feature etc.``stream`` Status information will be written to this filehandle. Defaults to using ``sys.stdout``, butany object with a ``write`` method is supported.``strict`` Execution of the model mapping will cease uponthe first error encountered. The default value(``False``)behavior is to attempt to continue.``verbose`` If set, information will be printedsubsequent to each model saveexecuted on the database.=========================== =================================================Troubleshooting===============Running out of memory---------------------As noted in the warning at the top of this section, Django stores all SQLqueries when ``DEBUG=True``. Set ``DEBUG=False`` in your settings, and thisshould stop excessive memory use when running ``LayerMapping`` scripts.MySQL: ``max_allowed_packet`` error-----------------------------------If you encounter the following error when using ``LayerMapping`` and MySQL::OperationalError: (1153, "Got a packet bigger than 'max_allowed_packet' bytes")Then the solution is to increase the value of the ``max_allowed_packet``setting in your MySQL configuration. For example, the default value maybe something low like one megabyte -- the setting may be modified in MySQL'sconfiguration file (``my.cnf``) in the ``[mysqld]`` section::max_allowed_packet = 10M