Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[script] aggiornare attributo di uno shapefile che dipende dal nome dello strato #212

Closed
pigreco opened this issue May 6, 2022 · 7 comments

Comments

@pigreco
Copy link
Contributor

pigreco commented May 6, 2022

Per aggiornare un attributo di uno shapefile è possibile utilizzare la riga di comando e l'utility ogrinfo (in OSGeo4W Shell):

ogrinfo -dialect SQLite -sql "UPDATE nomeSHP SET nomeAttributo='TOTO' WHERE nomeAttributo='Andrea'" nomeSHP.shp

nel caso avessi molti shapefile in una cartella, utilizzerei questo ciclo:

for %f in (*.shp) do (ogrinfo -dialect SQLite -sql "UPDATE %~nf SET nomeAttributo='TOTO' WHERE nomeAttributo='Andrea'" %f)

ma il problema che dovrei risolvere è più complesso, ovvero, il nome del campo da aggiornare non è sempre lo stesso, ma cambia al cambiare del nome dello shapefile: il legame tra nome shapefile e attributo è il seguente:

Nome strato/shapefile: (senza spazi):

ST XX TE YY CL ZZ ABC

  • ABC può essere PLG, ARC o PNT
  • esempio: ST01TE01CL01PLG
  • XX varia in 01, 02, 03.... 10,11...
  • YY varia in 01,02,03....
  • ZZ varia in 01,02,03...

nome attributo da aggiornare: (senza spazi):

A XX YY ZZ 95

  • esempio: A01010195
  • XX varia in 01, 02, 03.... 10,11...
  • YY varia in 01,02,03....
  • ZZ varia in 01,02,03...

image

nome strato nome attributo vecchio valore nuovo valore
ST01TE01CL01PLG A01010195 2011 2021
ST12TE03CL05PLG A12030595 2011 2021

image

Valore da aggiornare

il valore del campo da aggiornare è sempre 2011 e va aggiornato a 2021

esempio applicativo

  • se il nome dello shapefile si chiamasse ST01TE01CL01PLG il campo da aggiornare sarebbe questo A01010195
  • se il nome dello shapefile si chiamasse ST01TE01CL01ARC il campo da aggiornare sarebbe questo A01010195
  • se il nome dello shapefile si chiamasse ST01TE01CL01PNT il campo da aggiornare sarebbe questo A01010195

dove:
XX = 01
YY = 01
ZZ = 01

  • se il nome dello shapefile si chiamasse ST11TE04CL14PNT il campo da aggiornare sarebbe questo A11041495

dove:
XX = 11
YY = 04
ZZ = 14

dati per test

shp.zip

@pigreco
Copy link
Contributor Author

pigreco commented May 6, 2022

Un modo per risolvere il problema potrebbe essere:

  1. creare la lista dei nomi degli shapefile;
  2. generare lista dei nomi degli attributi utilizzando il nome dello strato;
  3. creare dei cicli FOR annidati utilizzado ogrinfo?

@pigreco
Copy link
Contributor Author

pigreco commented May 6, 2022

FACCIO SOLO DEI TEST e CERCO DI ESERCITARMI CON BASH

Come scritto sopra:

  1. creo la lista dei nomi degli shapefile;
  2. genero lista dei nomi degli attributi utilizzando il nome dello strato;
  3. creo unica stringa con tutti i layer e nomi attributi, cosi fatta: "./aree_verdi ST06TE01CL02PLG A06010295"

Questo script ricostruisce il comando ogrinfo

#!/bin/bash

for file in "./aree_verdi ST06TE01CL02PLG A06010295" "./aree_verdi ST06TE01CL04PLG A06010495" "./aree_verdi ST06TE01CL05PLG A06010595" "./aree_verdi ST06TE04CL01PLG A06040195" "./aree_verdi ST06TE04CL02PLG A06040295" "./edificati ST02TE02CL01PLG A02020195" "./edificati ST02TE02CL02PLG A02020295" "./edificati ST02TE02CL03PLG A02020395" "./edificati ST02TE02CL03PTS A02020395" "./edificati ST02TE02CL04PLG A02020495" "./strade ST01TE01CL01PLG A01010195" "./strade ST01TE01CL02PLG A01010295" "./strade ST01TE01CL03PLG A01010395" "./strade ST01TE01CL04PLG A01010495" "./strade ST01TE01CL05ARC A01010595" "./strade ST01TE01CL05PLG A01010595" 
do
set -- $file
echo "ogrinfo -dialect SQLite -sql "UPDATE $2 SET $3='2021'  WHERE $3='2011'" $1/$2.shp"
done

appena installo GDAL/OGR nella mia macchina win lo provo.

image

@pigreco
Copy link
Contributor Author

pigreco commented May 6, 2022

wow, lo script funziona!!!

#!/bin/bash

for file in "./aree_verdi ST06TE01CL02PLG A06010295" "./aree_verdi ST06TE01CL04PLG A06010495" "./aree_verdi ST06TE01CL05PLG A06010595" "./aree_verdi ST06TE04CL01PLG A06040195" "./aree_verdi ST06TE04CL02PLG A06040295" "./edificati ST02TE02CL01PLG A02020195" "./edificati ST02TE02CL02PLG A02020295" "./edificati ST02TE02CL03PLG A02020395" "./edificati ST02TE02CL03PTS A02020395" "./edificati ST02TE02CL04PLG A02020495" "./strade ST01TE01CL01PLG A01010195" "./strade ST01TE01CL02PLG A01010295" "./strade ST01TE01CL03PLG A01010395" "./strade ST01TE01CL04PLG A01010495" "./strade ST01TE01CL05ARC A01010595" "./strade ST01TE01CL05PLG A01010595" 
do
set -- $file # Verifica la variabile "file" e imposta i parametri
ogrinfo -dialect SQLite -sql "UPDATE $2 SET $3='2021'  WHERE $3='2011'" $1/$2.shp
done

image

sto studiando da qui: (paragrafo 10.2)
https://diraimondo.dmi.unict.it/wp-content/uploads/classes/so/mirror-stuff/abs-guide.pdf

@pigreco
Copy link
Contributor Author

pigreco commented May 6, 2022

script bash necessario per utilizzare lo script precedente: (crea unica stringa da dare in pasto al FOR)

#!/bin/bash

find -name *.shp | sed 's/.shp//' | sed 's/\// /g' | sed 's/ /\//' >nomeSHP.csv
find -name *.shp | sed 's/ST/A/' | sed 's/TE//' | sed 's/CL//' | sed 's/...\.shp/95/' | sed -E 's/^.+\/(.+)$/\1/' >campoSHP.csv
paste -d, nomeSHP.csv campoSHP.csv | sed 's/,/ /g' | sed 's/^/"/' | sed 's/$/"/' | tr '\n' ' '>fileunito.csv
rm *SHP.csv

@pigreco
Copy link
Contributor Author

pigreco commented May 6, 2022

Cambiando approccio, questo script sembra funzionare bene:

#!/bin/bash

set -x

# crea un file con i percorsi relativi dello shapefile
find . -name *.shp >pathSHP.csv

for file in $(cat pathSHP.csv)
do
    # crea variabile ed estrae solo il nome dello shapefile
    nomeSHP=`echo $file | sed -E 's/^.\/.+\/(.+).shp$/\1/'`
    # crea variabile ed estrae il nome dell attributo da aggiornare
    campo=`echo $file | sed 's/ST/A/' | sed 's/TE//' | sed 's/CL//' | sed 's/...\.shp/95/' | sed -E 's/^.+\/(.+)$/\1/'`
    # aggiorna gli shapefile
    ogrinfo -dialect SQLite -sql "UPDATE ${nomeSHP} SET $campo='2021'  WHERE $campo='2011'" $file
done

@pigreco
Copy link
Contributor Author

pigreco commented May 7, 2022

Appunti sull'uso di sed

utilizzando sed per fare sostituzioni consecutive, l'opzione -e ci aiuta, quindi invece di:

echo $file | sed 's/ST/A/' | sed 's/TE//' | sed 's/CL//' | sed 's/...\.shp/95/' | sed -E 's/^.+\/(.+)$/\1/'

è possibile scrivere questo:

echo $file | sed -e 's/ST/A/' -e 's/TE//' -e 's/CL//' -e 's/...\.shp/95/' -Ee 's/^.+\/(.+)$/\1/'

link: https://it.smartworldclub.net/11703426-how-to-use-sed-command-in-linux-examples

@pigreco
Copy link
Contributor Author

pigreco commented May 15, 2022

@pigreco pigreco closed this as completed May 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant