Hinzufügen von Feldern mit Dateinamen beim Zusammenführen von Shapefiles mit ogr2ogr?

14

Ich füge einige Shapefiles zusammen und ich hatte einige Probleme damit in QGIS, also verwende ich ogr2ogr direkt. Ich mache das (in einem Batch):

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

Es funktioniert einwandfrei, aber jetzt muss ich in dem resultierenden Shapefile ein Feld mit den Namen der ursprünglichen Shapefiles haben, die ich zusammengeführt habe. Klingt nicht sehr schwierig, aber ich schaffe es nicht.

Kann jemand helfen? Vielen Dank!

vascobnunes
quelle

Antworten:

14

Mit kleinen Skripten wäre es machbar. Mit etwas wie Folgendem sollten Sie in der Lage sein, einer Shapefile in allen Shapefiles in einem Ordner eine Spalte hinzuzufügen und diese in der Datei merged.shp zusammenzuführen

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 
)

edit: Das gleiche wie ein Bash-Skript, mit einigen Änderungen, damit es funktioniert:

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
JaakL
quelle
Diese Lösung würde nur funktionieren, wenn alle Ebenen / Shapefiles denselben Namen hätten, z. B. "CHEMIN". Richtig? Ich suche nach einer Lösung zum Erstellen von Skripten für Dateien mit unterschiedlichen Ebenennamen.
29.
Richtig, wenn Sie CHEMIN durch% f ersetzen, sollte dies mit jedem Namen funktionieren, da in der Formdatei der Tabellenname der Ebenenname ist. Ich habe die Antwort bearbeitet. Ich habe keine Fenster, um es wirklich zu testen
JaakL
9

Ich würde die Option -sql verwenden und das Shapefile folgendermaßen importieren:

ogr2ogr -update -append %destination% %n2% -sql 'SELECT "%n2%" as SHAPE_ORIG, field1, field2, ... FROM %n2%'
capooti
quelle
Paolo - Ich habe Mühe, das zum Laufen zu bringen. Kann es nur mit ogr2ogr und nicht mit ogrinfo gemacht werden? Ich habe auch zu gdal-dev geschrieben, mit meinen Beispielen lists.osgeo.org/pipermail/gdal-dev/2012-November/034849.html Can tut es nicht in Windows oder Bash ..
œOn
Joe, schlägt die einzelne Ogrinfo-Zeile fehl oder nur im Kontext des Skripts (innerhalb der Schleife)?
Capooti
Paolo - Ich werde die Antwort, die für mich funktioniert hat, unten hinzufügen. Vielen Dank für das Follow-up mit mir, gütiger Herr! :)
oeon
7

Es gibt verschiedene Möglichkeiten, Shapefiles zusammenzuführen.

  • Wenn Sie Ebenen als eine Ebene zusammenführen möchten, können Sie MMqgis- Tools zum Zusammenführen verwenden.

mmqgis

  • Wenn Sie alle Shapefiles in einem Ordner zusammenführen möchten, können Sie hier einfachen DARREN COPE- Code verwenden.

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 )
)
  • Außerdem können Sie mit dem kostenlosen GeoMerge- Tool viele Dateien zusammenführen. Vergessen Sie jedoch nicht, Ihre Dateigröße für die Bearbeitung zu berücksichtigen.

und das Hinzufügen eines Attributs zu shapefile @dango directon ist gut. Sie können layer.CreateField (field_name) verwenden, um eine neue Spalte zu erstellen, aus der gefüllt wird

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

ich hoffe es hilft dir ...

Aragon
quelle
5

vascobnunes, hier ist, wie ich dieses Problem gelöst habe, indem ich ein Python-Skript verwendet habe, um mehrere ogr2ogr-Anweisungen zu verketten. Sie können es problemlos in ein Stapelskript konvertieren. Im Grunde genommen verknüpfe ich ogr2ogr-Anweisungen ( cmd) und führe sie dann aus os.system(cmd), indem Sie den Befehl ogr2ogr übergeben, den ich verknüpft habe.

Die Geheimwaffe ist ( wie capooti demonstriert ), OGR_SQL anzuwenden , um den Dateinamen als konstanten Wert des Quelldatensatzes festzulegen , den Sie in Ihr Zusammenführungsergebnis einfügen .

In meinem Beispiel behandelt das -sqlFlag dies, im Code sieht es so aus:

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

Das ist jedoch verwirrend zu lesen, da ich in der resultierenden Verkettung einfache und doppelte Anführungszeichen verwenden muss. Um das zu tun, muss ich mich den einfachen Anführungszeichen entziehen , um sie "für echt" zu verwenden. Zur besseren Lesbarkeit ist es daher hilfreich, das Dokument ohne Variablen und Escape-Sequenzen anzuzeigen. Wenn Sie für eine bestimmte Iteration den Dateinamen "roads1" vorgeben, würde die resultierende Verkettung im Satz ogr2ogr folgendermaßen aussehen:

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

Dieses .py-Skript ist eine Zusammenführung von drei Tricks, die ich Matt Wilkie (einem leeren Klon eines Shapefiles), j03lar50n (Hinzufügen einer Spalte zu einem Shapefile mithilfe von ogrinfo und ogr_sql) und capooti (mithilfe von ogr_sql, um einen festen Spaltenwert festzulegen) gestohlen habe auf allen Datensätzen in einem Shapefile). Also hier ist das vollständige Skript:


# 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
Elrobis
quelle
4

Fügen Sie eine Spalte mit dem Quelldateinamen aus dem Shapefile-Ordner hinzu. Benötigt GDAL 1.10dev, mein Versuch, die Erweiterung .shp zu löschen, funktioniert nicht - aber insgesamt funktioniert es. - Ich stelle mir vor, es könnte zu den Linien hinzugefügt werden, die mit OGR verschmelzen.

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;
oeon
quelle
+1 für die Dialektspezifikation. Ich habe Fehler in der Top-Antwort erhalten, weil OGR-SQL keine Aktualisierungen durchführt.
user15741
3

Hallo, vielleicht hilft dieser Link . Es wird gezeigt, wie Sie einem Shapefile mithilfe der Python-GDAL-Bindungen ein Feld hinzufügen.

Dango
quelle
2

In QGIS können Sie das Merge Shapefile-Plugin hinzufügen. Es gibt eine Option zum "Hinzufügen einer Spalte mit einem Dateinamen"Bildbeschreibung hier eingeben

Ryan Garnett
quelle
Ich erhalte einen TypeError: Objekt vom Typ 'NoneType' hat kein len ()
Hannes Ledegen
0

Eine leicht abgewandelte Version von JaaKLs Antwort. Beachten Sie, dass -append foo.shp und -nln foo übereinstimmen müssen. Beachten Sie auch die Verwendung des SQLite-Dialekts (GDAL akzeptiert anscheinend nicht das Schlüsselwort 'Update', daher muss der SQLite-Dialekt instaiert verwendet werden) und das Fehlen des Schlüsselworts 'TABLE' nach dem Wort 'UPDATE' (nicht erforderlich) oder von SQLite akzeptiert).

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 
  )
)

quelle
0

Ein bisschen zu spät zur Diskussion, aber jetzt gibt es auch Ogerge

ogrmerge.py -single -o merged.shp *.shp -src_layer_field_content {DS_BASENAME}
t Buchen
quelle