Ajout d'un champ avec un nom de fichier lors de la fusion de fichiers de formes avec ogr2ogr?

14

Je fusionne des fichiers de formes et j'ai eu des problèmes à le faire dans QGIS, donc j'utilise directement ogr2ogr. Je fais ça (en lot):

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

Cela fonctionne bien, mais maintenant je dois avoir dans le fichier de formes résultant, un champ avec les noms des fichiers de formes d'origine que j'ai fusionné. Cela ne semble pas très difficile, mais je n'arrive pas à le faire.

Quelqu'un peut-il aider? Je vous remercie!

vascobnunes
la source

Réponses:

14

Avec de petits scripts, ce serait faisable. Avec quelque chose comme ce qui suit, vous devriez pouvoir ajouter une colonne à un fichier de formes dans tous les fichiers de formes d'un dossier et les fusionner dans le fichier 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 
)

edit: Identique à un script Bash, avec quelques modifications pour le faire fonctionner:

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
la source
Cette solution ne fonctionnerait que si tous vos calques / fichiers de formes avaient le même nom, par exemple "CHEMIN" correct? Je recherche une solution pour l'écriture de fichiers avec différents noms de couches.
2012 à 15h13
Correct, si vous remplacez CHEMIN par% f, cela devrait fonctionner avec n'importe quel nom, car dans le nom de la table de fichiers de formes, c'est le nom du calque. J'ai édité la réponse. Je n'ai pas vraiment de fenêtres pour le tester
JaakL
9

J'utiliserais l'option -sql et j'importerais le fichier de formes de la manière suivante:

ogr2ogr -update -append %destination% %n2% -sql 'SELECT "%n2%" as SHAPE_ORIG, field1, field2, ... FROM %n2%'
capooti
la source
Paolo - J'ai du mal à faire fonctionner ça. Peut-on le faire uniquement avec ogr2ogr et non avec ogrinfo? J'ai également posté sur gdal-dev, avec mes exemples lists.osgeo.org/pipermail/gdal-dev/2012-November/034849.html Je ne peux pas le faire dans Windows ou Bash ..
oeon
Joe, la seule ligne ogrinfo échoue-t-elle ou échoue-t-elle uniquement dans le contexte du script (à l'intérieur de la boucle)?
capooti
Paolo - Je vais ajouter la réponse qui a fonctionné pour moi, ci-dessous. Merci d'avoir suivi avec moi, gentil monsieur! :)
oeon
7

il existe des moyens de fusionner les fichiers de formes.

  • si vous souhaitez fusionner des calques en un seul calque, vous pouvez utiliser les outils MMqgis pour la fusion ...

mmqgis

  • si vous souhaitez fusionner tous les fichiers de formes sous un dossier, vous pouvez utiliser le code simple DARREN COPE ici.

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 )
)
  • à côté de cela, vous pouvez utiliser l'outil gratuit GeoMerge pour fusionner de nombreux fichiers, mais n'oubliez pas de prendre en compte la taille de votre fichier pour travailler avec.

et l'ajout d'attribut au shapefile @dango directon est bon. vous pouvez utiliser layer.CreateField (field_name) pour créer une nouvelle colonne qui est remplie à partir de

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

J'espère que ça t'aide...

Aragon
la source
5

vascobnunes, voici comment j'ai résolu ce problème en utilisant un script Python pour chaîner plusieurs instructions ogr2ogr ensemble. Vous pouvez facilement le convertir en script batch, en gros je concatène ensemble les instructions ogr2ogr ( cmd), puis je les exécute en appelant os.system(cmd), en transmettant la commande ogr2ogr que j'ai concaténée ensemble.

L'arme secrète consiste ( comme Capooti l'a démontré ) à appliquer OGR_SQL pour imposer le nom de fichier en tant que valeur constante de l'ensemble de données source que vous ajoutez à votre résultat de fusion.

Dans mon exemple, le -sqldrapeau gère cela, dans le code, c'est comme ceci:

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

Mais c'est déroutant à lire car j'ai besoin d'appliquer des guillemets simples et des guillemets doubles dans la concaténation résultante. Pour ce faire, je dois échapper aux guillemets simples (c'est-à-dire \ ') pour les utiliser "pour de vrai". Donc, pour la lisibilité, cela aide à le voir sans variables et séquences d'échappement. Si vous prétendez que le nom de fichier était "routes1" pour une itération particulière, la concaténation résultante ressemblerait à ceci dans la phrase ogr2ogr:

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

Ce script .py est une fusion de trois astuces que j'ai volées à matt wilkie (un vide, clone d'un fichier de formes), j03lar50n (ajout d'une colonne à un fichier de formes à l'aide d'ogrinfo et ogr_sql) et capooti (à l'aide d'ogr_sql pour imposer une valeur de colonne fixe sur tous les enregistrements d'un fichier de formes). Voici donc le script complet:


# 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
la source
4

Ajoutez une colonne avec le nom de fichier source du dossier des fichiers de formes. Nécessite GDAL 1.10dev, ma tentative de suppression de l'extension .shp ne fonctionne pas - mais dans l'ensemble, fonctionne. - J'imagine que cela pourrait être ajouté aux lignes qui fusionnent avec 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
la source
+1 pour la spécification du dialecte. J'obtenais des erreurs sur la réponse du haut en raison de OGR SQL ne faisant pas de mises à jour.
user15741
3

Salut, peut-être que ce lien vous aidera. Il montre comment ajouter un feild à un fichier de formes à l'aide des liaisons gdal en python.

dango
la source
2

Dans QGIS, vous pouvez ajouter le plugin Merge Shapefile. Il y a une option pour "Ajouter une colonne avec un nom de fichier"entrez la description de l'image ici

Ryan Garnett
la source
J'obtiens une TypeError: l'objet de type 'NoneType' n'a pas de len ()
Hannes Ledegen
0

Une version légèrement modifiée de la réponse de JaaKL. Notez que -append foo.shp et -nln foo doivent correspondre. Notez également l'utilisation du dialecte SQLite (GDAL n'accepte apparemment pas le mot clé 'Update', donc le dialecte SQLite doit être utilisé instaed), et l'absence du mot clé 'TABLE' après le mot 'UPDATE' (pas nécessaire ou accepté par 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 
  )
)

la source
0

Un peu tard pour la discussion, mais maintenant il y a aussi ogrmerge

ogrmerge.py -single -o merged.shp *.shp -src_layer_field_content {DS_BASENAME}
t Réserver
la source