LayerMapping 数据导入实用程序

这个 LayerMapping 类提供了一种将矢量空间数据文件(例如shapefiles)的内容映射到geodjango模型中的方法。

该实用程序源于作者的个人需要,以消除将几何图形和字段从矢量层中拉出、转换为另一个坐标系(如wgs84)然后插入geodjango模型的代码重复。

备注

使用 LayerMapping 需要GDAL。

警告

GIS data sources, like shapefiles, may be very large. If you find that LayerMapping is using too much memory, set DEBUG to False in your settings. When DEBUG is set to True, Django automatically logs every SQL query -- and when SQL statements contain geometries, this may consume more memory than is typical.

例子

  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]]
  1. 现在我们定义了相应的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
    
  2. 使用 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 关键字与A 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

地理模型, not 一个实例。

data_source

OGR支持的数据源文件(例如,shapefile)的路径。也接受 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' .

save() 关键字参数

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 ,在第1000个特性、第2000个特性等之后将发生提交。

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配置中的设置。例如,缺省值可能较低,比如1MB--可以在MySQL的配置文件中修改该设置 (my.cnf ))中 [mysqld] 部分:

max_allowed_packet = 10M