ogr2ogrでシェープファイルをマージするときにファイル名でフィールドを追加しますか?


14

私はいくつかのシェープファイルをマージしていますが、QGIS内でそれを行うのにいくつかの問題があったので、ogr2ogrを直接使用しています。私はこれを(バッチで)やっています:

ogr2ogr -overwrite %destination% %n1%
ogr2ogr -update -append %destination% %n2% -nln all_new
ogr2ogr -update -append %destination% %n3% -nln all_new
ogr2ogr -update -append %destination% %n4% -nln all_new

正常に動作しますが、結果のシェープファイルには、マージした元のシェープファイルの名前を持つフィールドが必要です。難しいことではないように聞こえますが、どうにかすることはできません。

誰でも助けることができますか?ありがとうございました!

回答:


14

小さなスクリプトを使用すると、実行可能になります。次のようなものを使用すると、フォルダー内のすべてのシェープファイル内のシェープファイルに列を追加し、それらをmerged.shpファイルにマージできるはずです。

for %f in (*.shp) do (
  ogrinfo %f -sql "ALTER TABLE %f ADD COLUMN filename character(15)"
  ogrinfo %f -sql "UPDATE TABLE %f filename = '%f'"
  ogr2ogr -update -append merged.shp %f -f esri shapefile -nln merge 
)

編集:Bashスクリプトと同じですが、動作させるためにいくつかの変更があります。

for f in *.shp
do 
  base=${f%.shp}
  ogrinfo $f -sql "ALTER TABLE $base ADD COLUMN filename character(15)"
  ogrinfo $f -dialect SQLite -sql "UPDATE $base SET filename = '$base'"
  ogr2ogr -update -append merged.shp $f
done

このソリューションは、すべてのレイヤー/シェープファイルの名前が同じ場合(たとえば、「CHEMIN」が正しい場合)にのみ機能しますか?異なるレイヤー名のファイルをスクリプト化するためのソリューションを探しています。
-oeon

正しい、CHEMINを%fに置き換えると、シェープファイルテーブル名はレイヤー名のように、任意の名前で機能するはずです。回答を編集しました。私は実際にそれをテストするために窓を持っていない
JaakL

9

-sqlオプションを使用し、次の方法でシェープファイルをインポートします。

ogr2ogr -update -append %destination% %n2% -sql 'SELECT "%n2%" as SHAPE_ORIG, field1, field2, ... FROM %n2%'

パオロ-これを機能させるのに苦労しています。ogrinfoではなくogr2ogrでのみ実行できますか?私は私の例では、あまりにもGDAL-devのに投稿したlists.osgeo.org/pipermail/gdal-dev/2012-November/034849.html ..缶は、Windowsやbashでそれをしない
oeon

ジョー、単一のogrinfo行は失敗しますか、それともスクリプトのコンテキスト(ループ内)でのみ失敗しますか?
カポオーティ

パオロ-私に合った答えを以下に追加します。私にフォローアップしてくれてありがとう、親切な先生!:)
oeon

7

シェープファイルをマージするにはいくつかの方法があります。

  • レイヤーを1つのレイヤーとしてマージする場合は、MMqgisツールを使用してマージできます...

mmqgis

  • フォルダーの下のすべてのシェープファイルをマージする場合は、ここでDARREN COPEの簡単なコードを使用できます。

mkdir merged
for %f in (*.shp) do (
if not exist merged\merged.shp (
ogr2ogr -f esri shapefile merged\merged.shp %f) else (
ogr2ogr -f esri shapefile -update -append merged\merged.shp %f -nln Merged )
)
  • これに加えて、GeoMergeの無料ツールを使用して大量のファイルをマージできますが、作業に使用するファイルサイズを考慮することを忘れないでください。

シェープファイル@dangoダイレクトンに属性を追加するのは良いことです。layer.CreateField(field_name)を使用して新しい列を作成できます。

import os
shapeFileName = os.path.splitext("your_shape_file_path")[0]

私はそれがあなたを助けることを願っています...


5

vascobnunes、Pythonスクリプトを使用していくつかのogr2ogr命令をデイジーチェーン接続することにより、この問題をどのように達成したかを以下に示します。バッチスクリプトに簡単に変換できます。基本的には、単にogr2ogr命令を連結し(cmd)、を呼び出して実行し、os.system(cmd)連結したogr2ogrコマンドを渡します。

秘密兵器は(capootiが示したようにOGR_SQLを適用して、マージ結果に追加するソースデータセットの定数値としてファイル名を課すことです。

私の例では、-sqlフラグがこれを処理し、コードでは次のようになります。

-sql "SELECT \'' + filename + '\' AS filename, * FROM ' + filenameNoExt + '"'

しかし、結果の連結に一重引用符と二重引用符を適用する必要があるため、これは読みにくいです。そのためには、単一引用符(つまり、\ ')をエスケープして「実際に」使用する必要があります。そのため、読みやすくするために、変数やエスケープシーケンスなしで表示すると役立ちます。特定の反復でファイル名が「roads1」であると想定した場合、結果の連結はogr2ogr文で次のようになります。

-sql "SELECT 'roads1.shp' AS filename, * FROM roads1"

これの.pyスクリプトは私から盗んだ3つのトリックの融合であるマットウィルキー(シェープファイルの空の、クローン)、j03lar50n(ogrinfoとogr_sqlを使用してシェープファイルに列を追加する)、及びcapooti固定列値を課すことogr_sql使用します(シェープファイル内のすべてのレコードで)。完全なスクリプトは次のとおりです。


# merge_shps.py
import os    

path = "D:/GIS/01_tutorials/ND_Roads/extracted"  # path to your folder of .shp files
merge = "merge_filename"                         # this will be the name of your merged result

directory = os.listdir(path)

count = 0
for filename in directory:
    if ".SHP" in filename.upper() and not ".XML" in filename.upper():

        # On the first pass, create a clone and add the filename column.
        if count == 0:
            # Make a clone (matt wilkie)..
            cmd = 'ogr2ogr ' + path + '/' + merge + '.shp ' + path + '/' + filename + ' -where "FID < 0"'
            os.system(cmd)

            # Add the field (j03lar50n)..
            cmd = 'ogrinfo ' + path + '/' + merge + '.shp -sql "ALTER TABLE ' + merge + ' ADD COLUMN filename character(50)"'
            os.system(cmd)

        # Now populate the data (capooti)..
        print "Merging: " + str(filename)

        # You'll need the filename without the .shp extension for the OGR_SQL..
        filenameNoExt = filename.replace(".shp","")

        cmd = 'ogr2ogr -f "esri shapefile" -update -append ' + \
                path + '/' + merge + '.shp ' + \
                path + '/' + filename + \
                ' -sql "SELECT \'' + filename + '\' AS filename, * FROM ' + filenameNoExt + '"'

        # Uncomment this line to spit the ogr2ogr sentence to the terminal..
        #print "\n" + cmd + "\n"

        os.system(cmd)

        count += 1

4

シェープファイルのフォルダーからソースファイル名の列を追加します。GDAL 1.10devが必要です。.shp拡張子をドロップする試みは機能しませんが、全体としては機能します。-OGRとマージする行に追加できると思います。

for f in *.shp;

do

name=${f%.shp}

/Users/you/gdal_src/bin/ogrinfo $f -sql "ALTER TABLE $name ADD COLUMN filename character(21)"
/Users/you/gdal_src/bin/ogrinfo $f -dialect SQLite -sql "UPDATE $name SET filename = '$f'"
done;

方言仕様の場合は+1。OGR SQLが更新を行っていないため、トップアンサーでエラーが発生していました。
user15741

3

こんにちは、このリンクが役立つかもしれません。Python gdalバインディングを使用して、フィールドをシェープファイルに追加する方法を示します。


2

QGIS内に、Merge Shapefileプラグインを追加できます。「ファイル名で列を追加する」オプションがありますここに画像の説明を入力してください


私はTypeError例外を取得:「NoneTypeは」ノーでlenた型のオブジェクトを()
ハネスLedegen

0

JaaKLの答えを少し修正したバージョン。-append foo.shpと-nln fooは一致する必要があることに注意してください。また、SQLite方言の使用(GDALはキーワード 'Update'を受け入れないため、SQLite方言を使用する必要があります)、および単語 'UPDATE'の後にキーワード 'TABLE'が存在しないことに注意してください(不要)またはSQLiteで受け入れられます)。

for %%f in (*.shp) do (
  if not "%%f" == "merge.shp" (
    ogrinfo %%f -sql "ALTER TABLE %%~nf ADD COLUMN fname character(15)"
    ogrinfo %%f -dialect SQLite -sql "UPDATE %%~nf SET fname = '%%~nf'"
    ogr2ogr -update -append merge.shp %%f -f "ESRI SHAPEFILE" -nln merge 
  )
)

0

議論に少し遅れましたが、現在はogrmergeもあります

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