LayerMapping データインポートユーティリティ

LayerMapping クラスは、ベクトル空間データファイル (例: shapefile) の内容を GeoDjango モデルにマッピングする方法を提供します。

このユーティリティは、ベクターレイヤーからジオメトリとフィールドを取り出し、別の座標系 (WGS84など) に変換し、GeoDjango モデルに挿入するまでのコードの繰り返しをなくしたいという作者の個人的なニーズから生まれました。

注釈

LayerMapping の使用には GDAL が必要です。

警告

GISデータソース、例えば shapefile は非常に大きい場合があります。もし LayerMapping がメモリを多く消費していると感じた場合は、設定で DEBUGFalse に設定してください。 DEBUGTrue に設定していると、Djangoは 自動的にログを出力 します。 すべての SQLクエリが記録されるため、SQLステートメントにジオメトリが含まれると通常よりも多くのメモリを消費する可能性があります。

カスタマイズ例

  1. シェープファイルのような、GDALがサポートするデータソースが必要です (ここでは、3つのフィーチャを持つ単純なポリゴンシェープファイル、 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 から取得した3つのジオメトリを、元の空間参照系 (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 がサポートするデータソースファイル (シェープファイルなど) へのパス。 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() メソッドはキーワードも受け付けます。これらのキーワードは、出力のロギングやエラー処理を制御したり、特定の機能範囲をインポートしたりするために使用します。

Save のキーワード引数 説明
fid_range データソースからマップするフィーチャ ID のスライスまたはタプル (開始、終了) を設定できます。言い換えると、このキーワードを使用すると、地理データソース内のフィーチャのサブセット範囲を選択的にインポートできます。
progress このキーワードを設定すると、処理され、正常に保存されたフィーチャの数を示すステータス情報が出力されます。デフォルトでは、処理された 1000 フィーチャごとに進捗情報が表示されますが、このキーワードに希望の間隔の整数を設定することで、このデフォルトを上書きできます。
silent デフォルトでは、致命的でないエラー通知は sys.stdout に出力されますが、このキーワードを設定すると、これらの通知を無効できます。
step 整数で設定すると、トランザクションは各ステップの間隔で発生します。たとえば、step=1000 の場合、1,000個目のフィーチャー、2,000個目のフィーチャーなどでコミットが行われます。
stream ステータス情報はこのファイルハンドルに書き込まれます。デフォルトでは sys.stdout が使用されますが、write メソッドを持つ任意のオブジェクトがサポートされています。
strict モデルマッピングの実行は、最初にエラーが発生した時点で停止します。デフォルト値 (False) の動作は、続行を試みます。
verbose 設定された場合、データベース上で実行される各モデル保存の後に情報が出力されます。

トラブルシューティング

メモリ不足

このセクションの一番上の警告にあるように、 Django は DEBUG=True の場合、全ての 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 の値を増やすことです。たとえば、デフォルト値は1MBのように低い場合があります。この設定は MySQL の設定ファイル (my.cnf) の [mysqld] セクションで変更できます。

max_allowed_packet = 10M
Back to Top