LayerMapping
データインポートユーティリティ¶
LayerMapping
クラスは、ベクトル空間データファイル (例: shapefile) の内容を GeoDjango モデルにマッピングする方法を提供します。
このユーティリティは、ベクターレイヤーからジオメトリとフィールドを取り出し、別の座標系 (WGS84など) に変換し、GeoDjango モデルに挿入するまでのコードの繰り返しをなくしたいという作者の個人的なニーズから生まれました。
注釈
LayerMapping
の使用には GDAL が必要です。
警告
GISデータソース、例えば shapefile は非常に大きい場合があります。もし LayerMapping
がメモリを多く消費していると感じた場合は、設定で DEBUG
を False
に設定してください。 DEBUG
を True
に設定していると、Djangoは 自動的にログを出力 します。 すべての SQLクエリが記録されるため、SQLステートメントにジオメトリが含まれると通常よりも多くのメモリを消費する可能性があります。
カスタマイズ例¶
シェープファイルのような、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]]
ここで、対応する 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
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
オブジェクトのインスタンス生成時に使用できる引数とキーワードです。
引数 |
説明 |
---|---|
|
地理情報モデルで、インスタンスではありません。 |
|
OGR がサポートするデータソースファイル (シェープファイルなど) へのパス。 |
|
辞書: キーはモデルフィールドに対応する文字列で、値はOGRフィーチャ用の文字列フィールド名に対応します。もしくは、モデルフィールドがジオグラフィックの場合は、OGRジオメトリの種類に対応する必要があります。例: |
キーワード引数 |
|
---|---|
|
データソースから使用するレイヤーのインデックス (デフォルトは 0) |
|
ソース SRS を手動で指定する場合に使用します (例えば、シェープファイルの中には |
|
OGR データソースの文字列の文字セットエンコーディングを指定します。例えば、 |
|
|
|
これを False に設定すると、座標変換が無効になります。つまり、ジオメトリはデータソース内の元の状態から変更されずにデータベースに挿入されます。 |
|
指定されたモデルの名前、または名前のタプルを設定すると、指定された名前 (複数可) のみに固有なモデルが作成されます。各フィーチャーのジオメトリは、一意のモデルに関連付けられたコレクションに追加されます。トランザクションモードを |
|
空間データをインポートする際に使用するデータベースを設定します。デフォルトは |
save()
のキーワード引数¶
- LayerMapping.save(verbose=False, fid_range=False, step=False, progress=False, silent=False, stream=sys.stdout, strict=False)[ソース]¶
save()
メソッドはキーワードも受け付けます。これらのキーワードは、出力のロギングやエラー処理を制御したり、特定の機能範囲をインポートしたりするために使用します。
Save のキーワード引数 |
説明 |
---|---|
|
データソースからマップするフィーチャ ID のスライスまたはタプル (開始、終了) を設定できます。言い換えると、このキーワードを使用すると、地理データソース内のフィーチャのサブセット範囲を選択的にインポートできます。 |
|
このキーワードを設定すると、処理され、正常に保存されたフィーチャの数を示すステータス情報が出力されます。デフォルトでは、処理された 1000 フィーチャごとに進捗情報が表示されますが、このキーワードに希望の間隔の整数を設定することで、このデフォルトを上書きできます。 |
|
デフォルトでは、致命的でないエラー通知は |
|
整数で設定すると、トランザクションは各ステップの間隔で発生します。たとえば、 |
|
ステータス情報はこのファイルハンドルに書き込まれます。デフォルトでは |
|
モデルマッピングの実行は、最初にエラーが発生した時点で停止します。デフォルト値 ( |
|
設定された場合、データベース上で実行される各モデル保存の後に情報が出力されます。 |
トラブルシューティング¶
メモリ不足¶
このセクションの一番上の警告にあるように、 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