LayerMapping 資料匯入工具

LayerMapping 類別提供一種方法,將向量空間資料檔案(例如 shapefile)的內容對應到 GeoDjango 模型。

此工具的開發源於作者個人的需求,目的是消除從向量圖層提取幾何圖形和欄位、轉換到另一個坐標系統(例如 WGS84),然後插入到 GeoDjango 模型中的重複程式碼。

注意

使用 LayerMapping 需要 GDAL。

警告

GIS 資料來源(如 shapefile)可能非常大。如果您發現 LayerMapping 使用過多的記憶體,請將設定中的 DEBUG 設定為 False。當 DEBUG 設定為 True 時,Django 會自動記錄每個 SQL 查詢 – 而當 SQL 語句包含幾何圖形時,這可能會消耗比平常更多的記憶體。

範例

  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 將 shapefile 中的三個幾何圖形從其原始空間參考系統(WGS84)轉換為 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(例如,某些 shapefile 沒有 '.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

如果設定,則在資料庫上執行每次模型儲存之後,將列印資訊。

疑難排解

記憶體不足

如同本節開頭的警告所述,當 DEBUG=True 時,Django 會儲存所有的 SQL 查詢。請在設定中將 DEBUG=False 設為關閉,這應該可以停止在執行 LayerMapping 腳本時過度使用記憶體的問題。

MySQL:max_allowed_packet 錯誤

如果您在使用 LayerMapping 和 MySQL 時遇到以下錯誤

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

那麼解決方案是增加 MySQL 設定中 max_allowed_packet 設定的值。例如,預設值可能很低,像是 1 MB,這個設定可以在 MySQL 的設定檔 (my.cnf) 的 [mysqld] 區段中修改

max_allowed_packet = 10M
返回頂部