ArcGISを使用せずにPython経由で既存のシェープファイルに属性フィールドを追加する方法は?


24

存在しない場合、Shapefileに属性フィールドを追加するPythonスクリプトがあります。これはArcGISを使用して(グラフィックまたはPythonを介して)簡単に実行できますが、ArcGISに依存しないものを探しています。

私のShapefileには機能が含まれているため、これをOGRで試しましたが失敗しました。

私はpyshpを見てきましたが、同様に、作成されたスキーマを変更する方法はありません。シェイプファイル(Python用)を試したことはありませんが、この機能は宣伝されていません。また、dbfpyを介してDBFファイルをいじることで、これがどのように行われるのかもわかりません

誰にもアイデアはありますか?


既存のシェープファイル構造のクローンを作成し、新しい列を追加してから、元のシェープファイルに基づいてデータを入力することは受け入れられますか?
-DavidF


この質問はgis.stackexchange.com/q/3623/664の複製として終了する必要があります
whuber

はい、基本的に同じです。見ましたが、見ませんでした。
マイクT

回答:


8

あなたはすでに答えられているので、これらの質問を見なければなりません: Pythonを使用してShapefileにカスタムフィーチャー属性を追加する方法は?

/programming/4215658/adding-custom-feature-attributes-to-esri-shapefile-with-python

結果として1つのシェープファイルだけが必要な場合は、スクリプトの最後で入力ファイルを削除するだけです。


どちらもに似てgis.stackexchange.com/questions/3623/...のその掘り起こしてくれてありがとう
マイク・Tを


4

DBFと呼ばれるかなり頭の痛い形式のおかげで、既存の属性データを使用してシェープファイルにフィールドを追加することは、DBFに書き換えまたはパディングを追加しない限り不可能です。既成のソリューションはわかりませんが、既存のファイルに基づいて新しいシェープファイルを作成し、新しいシェープファイルに追加のフィールドを追加するスクリプトを作成します。次に、ジオメトリ/属性データを古いシェープファイルから新しいシェープファイルにコピーします。最後のステップとして、古いシェープファイルを削除し、新しいシェープファイルの名前を変更します。これはすべて、OGR pythonバインディングを使用してかなり簡単に実現できます。

または、dbfpyを使用して、DBFファイルのみで上記を実行できます。ステップの順序は同じままです。

  1. 元の構造と同じ構造を持つ新しいDBFを作成します
  2. 新しいDBFに新しい属性フィールドを作成します
  3. 元のDBFから新しいDBFにデータをコピーする
  4. 古いDBFを削除し、新しいDBFの名前を古いDBFに変更します

シェープファイル(.shp)自体または他のファイルは、DBFに含まれる属性情報を参照しないため、変更する必要はありません。ただし、古いDBFと新しいDBFでレコードの順序をまったく同じにする必要があります。


3

DBFpyはこれで動作するはずです。このページの例をご覧になりましたか?

http://dbfpy.sourceforge.net/

シェープファイルが、ArcGISを含む他のアプリケーションによって編集されていないことを確認してください。これにより、ロックによって問題が発生する可能性があります。


DBFファイルに既にデータがある場合、これが機能するとは思わない。以前見たことがありますが、「少なくとも1つのレコードが追加されました。構造は変更できません」というエラーが表示されます。特定の例を念頭に置いていますか?
マイクT

ああ、今は覚えています。新しいDBFの作成が必要だとササが言ったので。スキーマ(フィールドなど)をコピーしてから追加し、レコードをコピーします。「素晴らしい」DBF ... :(
ロブ・クラーク

@Mike フィールドを追加するだけの場合、レコードはどのように追加されましたか?レコードを追加すると、属性とシェイプ間の接続が損なわれるため、エラーになります。フィールドを追加してもまったく害はありません。 dbfファイルを編集できるライブラリはすべて、適切に機能します。
whuber

@whuber:それは彼らのエラーメッセージです。:データを持っていると見既存DBF開くfrom dbfpy import dbf; db = dbf.Dbf('my.dbf'); db.addField(("FOO", "C", 15))
マイク・T

@Mike状況を明確にしてくれてありがとう。それはdbfpyの不必要な制限の結果のように聞こえます:-(。理由は推測できます:空でないデータベースにフィールドを追加するには、すべてのレコードを物理的に読み取り、展開し、書き戻す必要があります。別のdBaseライブラリを見つけるか、他のソフトウェアを使用します;-)。
whuber

1

OGRを使用して解決策を見つけました。前の質問からの助けに感謝します。完全な例を次に示します。

from osgeo import ogr

# Open a Shapefile, and get field names
source = ogr.Open('my.shp', update=True)
layer = source.GetLayer()
layer_defn = layer.GetLayerDefn()
field_names = [layer_defn.GetFieldDefn(i).GetName() for i in range(layer_defn.GetFieldCount())]
print len(field_names), 'MYFLD' in field_names

# Add a new field
new_field = ogr.FieldDefn('MYFLD', ogr.OFTInteger)
layer.CreateField(new_field)

# Close the Shapefile
source = None

私の問題は、私が使ったのlayer_defn.AddFieldDefn(new_field)ではなくてlayer.CreateField(new_field)。ヘルプに感謝し、同様のその他の質問を徹底的にチェックしないで申し訳ありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.