Aggiunta di campo con nome file quando si uniscono shapefile con ogr2ogr?


14

Sto unendo alcuni shapefile e ho avuto dei problemi a farlo all'interno di QGIS, quindi sto usando direttamente ogr2ogr. Lo sto facendo (in un 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

Funziona bene, ma ora devo avere nel file di forma risultante, un campo con i nomi dei file di forma originali che ho unito. Non sembra molto difficile, ma non riesco a farlo.

Qualcuno può aiutare? Grazie!

Risposte:


14

Con piccoli script sarebbe fattibile. Con qualcosa come il seguente dovresti essere in grado di aggiungere una colonna a un file di forma in tutti i file di forma in una cartella e unirli nel file 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 
)

modifica: lo stesso di uno script Bash, con alcune modifiche per farlo funzionare:

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

Questa soluzione funzionerebbe solo se tutti i tuoi layer / shapefile avessero lo stesso nome, ad es. "CHEMIN" corretto? Sto cercando una soluzione per i file di scripting con nomi di layer diversi.
oeon,

Corretto, se si sostituisce CHEMIN con% f, dovrebbe funzionare con qualsiasi nome, poiché nel nome della tabella shapefile è il nome del livello. Ho modificato la risposta. Non ho Windows per testarlo davvero
JaakL

9

Vorrei usare l'opzione -sql e importare lo shapefile nel modo seguente:

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

Paolo - Sto lottando per farlo funzionare. Può essere fatto solo con ogr2ogr e non con ogrinfo? Ho postato anche su gdal-dev, con i miei esempi lists.osgeo.org/pipermail/gdal-dev/2012-November/034849.html Non posso farlo in Windows o Bash ..
oeon

Joe, la singola riga di ogrinfo fallisce o fallisce solo nel contesto dello script (all'interno del loop)?
capooti,

Paolo - Aggiungerò la risposta che ha funzionato per me, di seguito. Grazie per avermi seguito, gentile signore! :)
oeon

7

ci sono alcuni modi per unire gli shapefile.

  • se vuoi unire i livelli come un unico livello, puoi usare gli strumenti MMqgis per unire ...

mmqgis

  • se vuoi unire tutti gli shapefile in una cartella, puoi usare il semplice codice DARREN COPE qui.

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 )
)
  • oltre a questo puoi usare lo strumento gratuito GeoMerge per unire molti file ma non dimenticare di considerare la dimensione del tuo file per lavorarci.

e l'aggiunta di attributi a shapefile @dango directon è buona. puoi usare layer.CreateField (field_name) per creare una nuova colonna da cui viene popolato

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

spero che ti aiuti ...


5

vascobnunes, ecco come ho realizzato questo problema usando uno script Python per collegare in sequenza diverse istruzioni di ogr2ogr. Potresti facilmente convertirlo in uno script batch, in pratica ho semplicemente concatenato insieme le istruzioni ogr2ogr ( cmd), quindi eseguirle chiamandoos.system(cmd) , passando il comando ogr2ogr che ho concatenato insieme.

L'arma segreta sta ( come ha dimostrato capooti ) applicando OGR_SQL per imporre il nome del file come valore costante del set di dati di origine che stai aggiungendo al risultato della fusione.

Nel mio esempio, la -sqlbandiera gestisce questo, nel codice è così:

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

Ma è confuso da leggere perché ho bisogno di applicare virgolette singole e doppie virgolette nella concatenazione risultante. Per fare ciò devo sfuggire alle virgolette singole (cioè \ ') per usarle "per davvero". Quindi, per leggibilità, aiuta a vederlo senza variabili e sequenze di escape. Se fingi che il nome file fosse "roads1" per una particolare iterazione, la concatenazione risultante sarebbe simile a questa nella frase ogr2ogr:

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

Questo script .py è una fusione di tre trucchi che ho rubato da matt wilkie (un vuoto, clone di un file di forma), j03lar50n (aggiungendo una colonna a un file di forma usando ogrinfo e ogr_sql) e capooti (usando ogr_sql per imporre un valore di colonna fisso su tutti i record in uno shapefile). Quindi, ecco lo script completo:


# 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

Aggiungi colonna con nome file sorgente dalla cartella di shapefile. Richiede GDAL 1.10dev, il mio tentativo di eliminare l'estensione .shp non funziona, ma nel complesso funziona. - Immagino che potrebbe essere aggiunto alle righe che si fondono con 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 per la specifica del dialetto. Stavo ricevendo errori nella risposta principale a causa del fatto che OGR SQL non eseguiva aggiornamenti.
user15741

3

Ciao forse questo link ti aiuterà. Illustra come aggiungere un feild a un file di forma usando i bind di Python Gdal.


2

All'interno di QGIS è possibile aggiungere il plug-in Merge Shapefile. C'è un'opzione per "Aggiungi colonna con nome file"inserisci qui la descrizione dell'immagine


Ottengo un TypeError: l'oggetto di tipo 'NoneType' non ha len ()
Hannes Ledegen,

0

Una versione leggermente modificata della risposta di JaaKL. Nota che -append foo.shp e -nln foo devono corrispondere. Inoltre, si noti l'uso del dialetto SQLite (apparentemente GDAL non accetta la parola chiave "Aggiorna", quindi il dialetto SQLite deve essere usato instabile) e l'assenza della parola chiave "TABELLA" dopo la parola "AGGIORNAMENTO" (non necessaria o accettato da 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

Un po 'in ritardo per la discussione, ma ora c'è anche ongmerge

ogrmerge.py -single -o merged.shp *.shp -src_layer_field_content {DS_BASENAME}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.