LayerMapping data import utility

LayerMapping类提供了一种将矢量空间数据文件(例如,shapefiles)到GeoDjango模型中。

这个实用程序源自作者个人的需要,以消除在向量层中拉几何形状和字段,转换到另一坐标系(例如,向量)的代码重复。WGS84),然后插入GeoDjango模型。

注意

使用LayerMapping需要GDAL。

警告

GIS数据源,如shapefile,可能非常大。如果您发现LayerMapping使用的内存过多,请在设置中将DEBUG设置为FalseDEBUG设置为True时,Django automatically logs 每个 SQL查询 - 它容易消耗比典型的更多的内存。

Example

  1. 您需要一个GDAL支持的数据源,例如shapefile(这里我们使用一个简单的多边形shapefile,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
        objects = models.GeoManager()
    
        def __str__(self):              # __unicode__ on Python 2
            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)中的shapefile转换为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的数据源文件的路径(例如,shapefile)。也接受django.contrib.gis.gdal.DataSource实例。
mapping字典:键是对应于模型字段的字符串,值对应于OGR特征的字符串字段名称,或者如果模型字段是地理的,则它应该对应于OGR几何类型,例如'POINT''LINESTRING''POLYGON'
关键字参数
layer要从数据源使用的图层的索引(默认为0)
source_srs使用此选项手动指定源SRS(例如,某些shape文件不带有'.prj'文件)。接受整数SRID,WKT或PROJ.4字符串和django.contrib.gis.gdal.SpatialReference对象。
encoding指定OGR数据源中的字符串的字符集编码。例如,'latin-1''utf-8''cp437'都是有效的编码参数。
transaction_mode可以是'commit_on_success'(默认)或'autocommit'
transform将此设置为False将禁用坐标变换。换句话说,几何将被插入到数据库中的未经修改的数据源中的原始状态。
unique将此设置为来自给定模型的名称或名称元组将创建仅对给定名称唯一的模型。几何将从每个要素添加到与唯一模型相关联的集合中。强制事务模式为'autocommit'
using设置导入空间数据时要使用的数据库。默认值为'default'

save() Keyword Arguments

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

save()方法也接受关键字。这些关键字用于控制输出日志记录,错误处理以及用于导入特定功能范围。

保存关键字参数描述
fid_range可以设置具有(开始,结束)特征ID的切片或元组以从数据源映射。换句话说,该关键字使得用户能够选择性地导入地理数据源中的子集范围的特征。
progress设置此关键字时,将打印状态信息,指明已处理的功能数量并已成功保存。默认情况下,将每处理1000个功能打印进度信息,但是,可以通过将此关键字设置为所需时间间隔的整数来覆盖此默认值。
silent默认情况下,非致命错误通知打印到sys.stdout,但此关键字可能设置为禁用这些通知。
step如果设置为整数,则事务将在每个步骤间隔发生。例如,如果step=1000,则在第1,000个特征,第2000个特征等之后发生提交。
stream状态信息将被写入此文件句柄。默认为使用sys.stdout,但支持使用write方法的任何对象。
strict执行模型映射将在遇到第一个错误时停止。默认值(False)行为是尝试继续。
verbose如果设置,将在数据库上执行的每个模型保存之后打印信息。

Troubleshooting

Running out of memory

如本节顶部的警告中所述,Django在DEBUG=True时存储所有SQL查询。在设置中设置DEBUG=False,并且在运行LayerMapping脚本时应停止过多的内存使用。

MySQL: max_allowed_packet error

如果在使用LayerMapping和MySQL时遇到以下错误:

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

然后解决方法是增加MySQL配置中的max_allowed_packet设置的值。例如,默认值可能低至1兆字节 - 可以在[mysqld]部分中的MySQL配置文件(my.cnf

max_allowed_packet = 10M