layermapping.txt 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. ====================================
  2. ``LayerMapping`` data import utility
  3. ====================================
  4. .. module:: django.contrib.gis.utils.layermapping
  5. :synopsis: Spatial data import utility for GeoDjango models.
  6. .. currentmodule:: django.contrib.gis.utils
  7. The :class:`LayerMapping` class provides a way to map the contents of
  8. vector spatial data files (e.g. shapefiles) into GeoDjango models.
  9. This utility grew out of the author's personal needs to eliminate
  10. the code repetition that went into pulling geometries and fields out of
  11. a vector layer, converting to another coordinate system (e.g. WGS84), and
  12. then inserting into a GeoDjango model.
  13. .. note::
  14. Use of :class:`LayerMapping` requires GDAL.
  15. .. warning ::
  16. GIS data sources, like shapefiles, may be very large. If you find
  17. that :class:`LayerMapping` is using too much memory, set
  18. :setting:`DEBUG` to ``False`` in your settings. When :setting:`DEBUG`
  19. is set to ``True``, Django :ref:`automatically logs <faq-see-raw-sql-queries>`
  20. *every* SQL query -- and when SQL statements contain geometries, this may
  21. consume more memory than is typical.
  22. Example
  23. =======
  24. #. You need a GDAL-supported data source, like a shapefile (here we're using
  25. a simple polygon shapefile, ``test_poly.shp``, with three features):
  26. .. code-block:: pycon
  27. >>> from django.contrib.gis.gdal import DataSource
  28. >>> ds = DataSource("test_poly.shp")
  29. >>> layer = ds[0]
  30. >>> print(layer.fields) # Exploring the fields in the layer, we only want the 'str' field.
  31. ['float', 'int', 'str']
  32. >>> print(len(layer)) # getting the number of features in the layer (should be 3)
  33. 3
  34. >>> print(layer.geom_type) # Should be 'Polygon'
  35. Polygon
  36. >>> print(layer.srs) # WGS84 in WKT
  37. GEOGCS["GCS_WGS_1984",
  38. DATUM["WGS_1984",
  39. SPHEROID["WGS_1984",6378137,298.257223563]],
  40. PRIMEM["Greenwich",0],
  41. UNIT["Degree",0.017453292519943295]]
  42. #. Now we define our corresponding Django model (make sure to use :djadmin:`migrate`)::
  43. from django.contrib.gis.db import models
  44. class TestGeo(models.Model):
  45. name = models.CharField(max_length=25) # corresponds to the 'str' field
  46. poly = models.PolygonField(srid=4269) # we want our model in a different SRID
  47. def __str__(self):
  48. return "Name: %s" % self.name
  49. #. Use :class:`LayerMapping` to extract all the features and place them in the
  50. database:
  51. .. code-block:: pycon
  52. >>> from django.contrib.gis.utils import LayerMapping
  53. >>> from geoapp.models import TestGeo
  54. >>> mapping = {
  55. ... "name": "str", # The 'name' model field maps to the 'str' layer field.
  56. ... "poly": "POLYGON", # For geometry fields use OGC name.
  57. ... } # The mapping is a dictionary
  58. >>> lm = LayerMapping(TestGeo, "test_poly.shp", mapping)
  59. >>> lm.save(verbose=True) # Save the layermap, imports the data.
  60. Saved: Name: 1
  61. Saved: Name: 2
  62. Saved: Name: 3
  63. Here, :class:`LayerMapping` transformed the three geometries from the shapefile
  64. in their original spatial reference system (WGS84) to the spatial reference
  65. system of the GeoDjango model (NAD83). If no spatial reference system is
  66. defined for the layer, use the ``source_srs`` keyword with a
  67. :class:`~django.contrib.gis.gdal.SpatialReference` object to specify one.
  68. ``LayerMapping`` API
  69. ====================
  70. .. class:: LayerMapping(model, data_source, mapping, layer=0, source_srs=None, encoding=None, transaction_mode='commit_on_success', transform=True, unique=True, using='default')
  71. The following are the arguments and keywords that may be used during
  72. instantiation of ``LayerMapping`` objects.
  73. ================= =========================================================
  74. Argument Description
  75. ================= =========================================================
  76. ``model`` The geographic model, *not* an instance.
  77. ``data_source`` The path to the OGR-supported data source file
  78. (e.g., a shapefile). Also accepts
  79. :class:`django.contrib.gis.gdal.DataSource` instances.
  80. ``mapping`` A dictionary: keys are strings corresponding to
  81. the model field, and values correspond to
  82. string field names for the OGR feature, or if the
  83. model field is a geographic then it should
  84. correspond to the OGR geometry type,
  85. e.g., ``'POINT'``, ``'LINESTRING'``, ``'POLYGON'``.
  86. ================= =========================================================
  87. ===================== =====================================================
  88. Keyword Arguments
  89. ===================== =====================================================
  90. ``layer`` The index of the layer to use from the Data Source
  91. (defaults to 0)
  92. ``source_srs`` Use this to specify the source SRS manually (for
  93. example, some shapefiles don't come with a ``'.prj'``
  94. file). An integer SRID, WKT or PROJ strings, and
  95. :class:`django.contrib.gis.gdal.SpatialReference`
  96. objects are accepted.
  97. ``encoding`` Specifies the character set encoding of the strings
  98. in the OGR data source. For example, ``'latin-1'``,
  99. ``'utf-8'``, and ``'cp437'`` are all valid encoding
  100. parameters.
  101. ``transaction_mode`` May be ``'commit_on_success'`` (default) or
  102. ``'autocommit'``.
  103. ``transform`` Setting this to False will disable coordinate
  104. transformations. In other words, geometries will
  105. be inserted into the database unmodified from their
  106. original state in the data source.
  107. ``unique`` Setting this to the name, or a tuple of names,
  108. from the given model will create models unique
  109. only to the given name(s). Geometries from
  110. each feature will be added into the collection
  111. associated with the unique model. Forces
  112. the transaction mode to be ``'autocommit'``.
  113. ``using`` Sets the database to use when importing spatial data.
  114. Default is ``'default'``.
  115. ===================== =====================================================
  116. ``save()`` Keyword Arguments
  117. ----------------------------
  118. .. method:: LayerMapping.save(verbose=False, fid_range=False, step=False, progress=False, silent=False, stream=sys.stdout, strict=False)
  119. The ``save()`` method also accepts keywords. These keywords are
  120. used for controlling output logging, error handling, and for importing
  121. specific feature ranges.
  122. =========================== =================================================
  123. Save Keyword Arguments Description
  124. =========================== =================================================
  125. ``fid_range`` May be set with a slice or tuple of
  126. (begin, end) feature ID's to map from
  127. the data source. In other words, this
  128. keyword enables the user to selectively
  129. import a subset range of features in the
  130. geographic data source.
  131. ``progress`` When this keyword is set, status information
  132. will be printed giving the number of features
  133. processed and successfully saved. By default,
  134. progress information will be printed every 1000
  135. features processed, however, this default may
  136. be overridden by setting this keyword with an
  137. integer for the desired interval.
  138. ``silent`` By default, non-fatal error notifications are
  139. printed to ``sys.stdout``, but this keyword may
  140. be set to disable these notifications.
  141. ``step`` If set with an integer, transactions will
  142. occur at every step interval. For example, if
  143. ``step=1000``, a commit would occur after the
  144. 1,000th feature, the 2,000th feature etc.
  145. ``stream`` Status information will be written to this file
  146. handle. Defaults to using ``sys.stdout``, but
  147. any object with a ``write`` method is supported.
  148. ``strict`` Execution of the model mapping will cease upon
  149. the first error encountered. The default value
  150. (``False``)
  151. behavior is to attempt to continue.
  152. ``verbose`` If set, information will be printed
  153. subsequent to each model save
  154. executed on the database.
  155. =========================== =================================================
  156. Troubleshooting
  157. ===============
  158. Running out of memory
  159. ---------------------
  160. As noted in the warning at the top of this section, Django stores all SQL
  161. queries when ``DEBUG=True``. Set ``DEBUG=False`` in your settings, and this
  162. should stop excessive memory use when running ``LayerMapping`` scripts.
  163. MySQL: ``max_allowed_packet`` error
  164. -----------------------------------
  165. If you encounter the following error when using ``LayerMapping`` and MySQL:
  166. .. code-block:: pytb
  167. OperationalError: (1153, "Got a packet bigger than 'max_allowed_packet' bytes")
  168. Then the solution is to increase the value of the ``max_allowed_packet``
  169. setting in your MySQL configuration. For example, the default value may
  170. be something low like one megabyte -- the setting may be modified in MySQL's
  171. configuration file (``my.cnf``) in the ``[mysqld]`` section:
  172. .. code-block:: ini
  173. max_allowed_packet = 10M