¿Agregar campo con nombre de archivo al combinar shapefiles con ogr2ogr?

14

Estoy fusionando algunos archivos de forma y tuve algunos problemas para hacerlo dentro de QGIS, así que estoy usando ogr2ogr directamente. Estoy haciendo esto (en un lote):

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

Funciona bien, pero ahora necesito tener en el archivo de forma resultante, un campo con los nombres de los archivos de forma originales que fusioné. No suena muy difícil, pero no estoy logrando hacerlo.

¿Alguien puede ayudar? ¡Gracias!

vascobnunes
fuente

Respuestas:

14

Con una pequeña secuencia de comandos sería factible. Con algo como lo siguiente, debería poder agregar una columna a un archivo de forma en todos los archivos de forma de una carpeta y fusionarlos con el archivo 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 
)

editar: lo mismo que un script Bash, con algunos cambios para que funcione:

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
fuente
Esta solución solo funcionaría si todas sus capas / archivos de forma tuvieran el mismo nombre, por ejemplo, "CHEMIN" ¿correcto? Estoy buscando una solución para los archivos de secuencias de comandos con diferentes nombres de capa.
oeon
Correcto, si reemplaza CHEMIN con% f, entonces debería funcionar con cualquier nombre, ya que en el nombre de la tabla del archivo de forma es el nombre de la capa. Edité la respuesta. No tengo ventanas para probarlo realmente
JaakL
9

Usaría la opción -sql e importaría el archivo de forma de la siguiente manera:

ogr2ogr -update -append %destination% %n2% -sql 'SELECT "%n2%" as SHAPE_ORIG, field1, field2, ... FROM %n2%'
capooti
fuente
Paolo: estoy luchando para que esto funcione. ¿Se puede hacer solo con ogr2ogr y no con ogrinfo? También he publicado en gdal-dev, con mis ejemplos lists.osgeo.org/pipermail/gdal-dev/2012-November/034849.html No puedo hacerlo en Windows o Bash ..
oeon
Joe, ¿falla la única línea de ogrinfo o falla solo en el contexto del script (dentro del bucle)?
capooti
Paolo - Voy a agregar la respuesta que funcionó para mí, a continuación. ¡Gracias por seguirme, amable señor! :)
oeon
7

Hay algunas formas de fusionar archivos shape.

  • si desea fusionar capas como una sola capa, puede usar las herramientas MMqgis para fusionar ...

mmqgis

  • si desea fusionar todos los archivos de forma en una carpeta, puede usar el código simple de DARREN COPE aquí.

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 )
)
  • además de esto, puede usar la herramienta gratuita GeoMerge para fusionar muchos archivos, pero no olvide considerar el tamaño de su archivo para trabajar con él.

y agregar atributo a shapefile @dango directon es bueno. puede usar layer.CreateField (field_name) para crear una nueva columna que se rellena desde

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

Espero que te ayude...

Aragón
fuente
5

vascobnunes, así es como logré este problema usando un script de Python para encadenar varias instrucciones ogr2ogr juntas. Puede convertirlo fácilmente en un script por lotes, básicamente solo concateno las instrucciones de ogr2ogr ( cmd), luego las ejecuto llamando os.system(cmd), pasando el comando ogr2ogr que concatenamos juntos.

El arma secreta es ( como demostró Capooti ) aplicar OGR_SQL para imponer el nombre de archivo como un valor constante del conjunto de datos de origen que está agregando a su resultado de fusión.

En mi ejemplo, la -sqlbandera maneja esto, en el código es así:

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

Pero eso es confuso de leer porque necesito aplicar comillas simples y comillas dobles en la concatenación resultante. Para hacerlo, tengo que escapar de las comillas simples (es decir, \ ') para usarlas "de verdad". Entonces, para facilitar la lectura, es útil verlo sin variables y secuencias de escape. Si finge que el nombre de archivo era "roads1" para una iteración particular, la concatenación resultante se vería así en la oración ogr2ogr:

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

Este script .py es una amalgama de tres trucos que le robé a matt wilkie (un clon vacío de un shapefile), j03lar50n (agregando una columna a un shapefile usando ogrinfo y ogr_sql) y capooti (usando ogr_sql para imponer un valor de columna fijo en todos los registros en un shapefile). Así que aquí está el guión 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
elrobis
fuente
4

Agregue una columna con el nombre del archivo fuente de la carpeta de archivos de forma. Requiere GDAL 1.10dev, mi intento de eliminar la extensión .shp no funciona, pero en general funciona. - Me imagino que podría agregarse a las líneas que se fusionan 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;
oeon
fuente
+1 para la especificación del dialecto. Recibía errores en la respuesta principal debido a que OGR SQL no hacía actualizaciones.
user15741
3

Hola tal vez este enlace te ayude. Muestra cómo agregar un campo a un archivo de forma usando los enlaces de gdal de python.

dango
fuente
2

Dentro de QGIS puede agregar el complemento Merge Shapefile. Hay una opción para "Agregar columna con nombre de archivo"ingrese la descripción de la imagen aquí

Ryan Garnett
fuente
Me sale un TypeError: el objeto de tipo 'NoneType' no tiene len ()
Hannes Ledegen
0

Una versión ligeramente modificada de la respuesta de JaaKL. Tenga en cuenta que -append foo.shp y -nln foo deben coincidir. Además, tenga en cuenta el uso del dialecto SQLite (GDAL aparentemente no acepta la palabra clave 'Actualizar', por lo que el dialecto SQLite debe usarse instaed), y la ausencia de la palabra clave 'TABLE' después de la palabra 'ACTUALIZAR' (no es necesario o aceptado por 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 
  )
)

fuente
0

Un poco tarde para la discusión, pero ahora también hay ogrmerge

ogrmerge.py -single -o merged.shp *.shp -src_layer_field_content {DS_BASENAME}
t libro
fuente