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

[GIS] file XML come estrarre alcuni dati #50

Closed
pigreco opened this issue Apr 8, 2019 · 15 comments

Comments

Projects
None yet
2 participants
@pigreco
Copy link
Contributor

commented Apr 8, 2019

Ho un file XML che rappresenta la tematizzazione (metodo categorizzato) di un layer (esempio shapefile regioni ISTAT) e vorrei estrarre due dati importanti per il mio caso:

  1. la regione;
  2. il colore di riempimento espresso in rgba;

Ho provato usando, in LibreCalc, questa espressione

=FILTRO.XML(‪C:\Users\pigre\Desktop\tema.xml;"//categories/category/value/")

ma ottengo un errore

image

vorrei ottenere una tabella CSV cosi fatta:

regione colore
Sicilia 210,214,92,255
Sardegna 234,16,38,255

allego file XML

tema.zip

@pigreco pigreco added the help wanted label Apr 8, 2019

@pigreco pigreco changed the title file XML come estrarre alcuni dati [GIS] file XML come estrarre alcuni dati Apr 8, 2019

@aborruso

This comment has been minimized.

Copy link
Member

commented Apr 8, 2019

EDIT: corretto join con Miller (vedi errore qui)

Caro @pigreco una risposta di corsa. A riga di comando un tool è xmlstarlet, da accoppiare a XPATH. Questa prima è più facile, ma non ce l'ho pronta in canna.

Stasera una soluzione sporca che passa da xq (che è dentro yq), che consente di fare query a un XML, come se fosse un file JSON. Non riesco però stasera a dettagliare bene.

Con

<tema.xml xq -r '.qgis["renderer-v2"].symbols.symbol[]|[.["@name"],.layer.prop[1]["@v"]]|@csv' >./idColori.csv

estrai

"0","232,193,76,255"
"1","48,218,227,255"
"10","231,108,155,255"
"11","237,177,124,255"
"12","63,175,231,255"
"13","210,214,92,255"
"14","234,16,38,255"
"15","239,110,81,255"
"16","50,235,192,255"
"17","160,107,220,255"
"18","98,66,238,255"
"19","34,233,131,255"
"2","224,59,169,255"
"3","163,225,124,255"
"4","162,15,210,255"
"5","68,239,48,255"
"6","179,235,59,255"
"7","219,21,209,255"
"8","18,39,233,255"
"9","120,204,137,255"

Con

<tema.xml xq -r '.qgis["renderer-v2"].categories.category[]|[.["@symbol"],.["@value"]]|@csv' >./idRegioni.csv

estrai

"0","Abruzzo"
"1","Basilicata"
"2","Calabria"
"3","Campania"
"4","Emilia-Romagna"
"5","Friuli Venezia Giulia"
"6","Lazio"
"7","Liguria"
"8","Lombardia"
"9","Marche"
"10","Molise"
"11","Piemonte"
"12","Puglia"
"13","Sardegna"
"14","Sicilia"
"15","Toscana"
"16","Trentino-Alto Adige"
"17","Umbria"
"18","Valle d'Aosta"
"19","Veneto"

E poi basta fare un join. Con Miller è

mlr --csv --implicit-csv-header --headerless-csv-output  join  -j 1 --lp colori --rp regioni -f idColori.csv idRegioni.csv >./out.csv

Che ti da

0,"232,193,76,255",Abruzzo
1,"48,218,227,255",Basilicata
2,"224,59,169,255",Calabria
3,"163,225,124,255",Campania
4,"162,15,210,255",Emilia-Romagna
5,"68,239,48,255",Friuli Venezia Giulia
6,"179,235,59,255",Lazio
7,"219,21,209,255",Liguria
8,"18,39,233,255",Lombardia
9,"120,204,137,255",Marche
10,"231,108,155,255",Molise
11,"237,177,124,255",Piemonte
12,"63,175,231,255",Puglia
13,"210,214,92,255",Sardegna
14,"234,16,38,255",Sicilia
15,"239,110,81,255",Toscana
16,"50,235,192,255",Trentino-Alto Adige
17,"160,107,220,255",Umbria
18,"98,66,238,255",Valle d'Aosta
19,"34,233,131,255",Veneto
@pigreco

This comment has been minimized.

Copy link
Contributor Author

commented Apr 8, 2019

@aborruso ho installato yq

sudo add-apt-repository ppa:rmescandon/yq
sudo apt update
sudo apt install yq -y

preso da qui: https://mikefarah.github.io/yq/

ma lanciando

<tema.xml xq -r '.qgis["renderer-v2"].symbols.symbol[]|[.["@name"],.layer.prop[1]["@v"]]|@csv' >./idColori.csv

ho questo messaggio:

image

@pigreco

This comment has been minimized.

Copy link
Contributor Author

commented Apr 8, 2019

yq si installa cosi:

pip3 install yq


poi, noto che il join si mangia la prima cifra del codice colore:

image

@aborruso

This comment has been minimized.

Copy link
Member

commented Apr 8, 2019

@pigreco grazie ho modificato il join, errore mio

@pigreco

This comment has been minimized.

Copy link
Contributor Author

commented Apr 9, 2019

@aborruso grazie per il tempo dedicato e la rapidità della soluzione, ho messo tutto assieme per creare un piccolo script da lanciare, per esempio, in win 10 usando bash ubuntu:

#!/bin/bash
set -x

<tema.xml xq -r '.qgis["renderer-v2"].symbols.symbol[]|[.["@name"],.layer.prop[1]["@v"]]|@csv' >./idColori.csv
<tema.xml xq -r '.qgis["renderer-v2"].categories.category[]|[.["@symbol"],.["@value"]]|@csv' >./idRegioni.csv
mlr --csv --implicit-csv-header --headerless-csv-output  join  -j 1 --lp colori --rp regioni -f idColori.csv idRegioni.csv >./out.csv

rm idColori.csv
rm idRegioni.csv

image

funzione benissimo.

Grazie a breve aggiungo ricetta

@pigreco pigreco closed this Apr 9, 2019

@pigreco

This comment has been minimized.

Copy link
Contributor Author

commented Apr 9, 2019

Lo script di sopra è valido per il metodo categorizzato, per il metodo graduato lo script è il seguente:

#!/bin/bash
set -x

<tema_range.xml xq -r '.qgis["renderer-v2"].symbols.symbol[]|[.["@name"],.layer.prop[1]["@v"]]|@csv' >./idColori.csv
<tema_range.xml xq -r '.qgis["renderer-v2"].ranges.range[]|[.["@symbol"],.["@label"]]|@csv' >./idRange.csv
mlr --csv --implicit-csv-header --headerless-csv-output  join  -j 1 --lp colori --rp regioni -f idColori.csv idRange.csv >./out_range.csv

rm idColori.csv
rm idRange.csv

testato con ottimi risultati :-)

@aborruso

This comment has been minimized.

Copy link
Member

commented Apr 9, 2019

Edit: corretto XPATH colori

Con XPATH è più leggibile e diretto (nasce per lavorare su XML). Un utility a riga di comando è xmlstarlet (che si installa con sudo apt-get install xmlstarlet)

Con

<tema.xml xmlstarlet fo -D | xmlstarlet sel -T -t -m "//category" -v $'concat(@symbol,"\t",@value)' -n >./idRegioni.tsv

si ottiene

0       Abruzzo
1       Basilicata
2       Calabria
3       Campania
4       Emilia-Romagna
5       Friuli Venezia Giulia
6       Lazio
7       Liguria
8       Lombardia
9       Marche
10      Molise
11      Piemonte
12      Puglia
13      Sardegna
14      Sicilia
15      Toscana
16      Trentino-Alto Adige
17      Umbria
18      Valle d'Aosta
19      Veneto

Con

<tema.xml xmlstarlet fo -D | xmlstarlet sel -T -t -m "//symbols/symbol" -v $'concat(@name,"\t",layer/prop[@k="color"]/@v)' -n >./idColori.tsv

si ottiene

0       232,193,76,255
1       48,218,227,255
10      231,108,155,255
11      237,177,124,255
12      63,175,231,255
13      210,214,92,255
14      234,16,38,255
15      239,110,81,255
16      50,235,192,255
17      160,107,220,255
18      98,66,238,255
19      34,233,131,255
2       224,59,169,255
3       163,225,124,255
4       162,15,210,255
5       68,239,48,255
6       179,235,59,255
7       219,21,209,255
8       18,39,233,255
9       120,204,137,255
0       183,72,75,255

E poi sui due TSV si fa il join.

La query //prop[@k="color"]/@v, corrisponde al valore della proprietà v del tag prop che ha color come valore della proprietà k. Ovvero cerca righe come questa <prop v="210,214,92,255" k="color"/>

@pigreco

This comment has been minimized.

Copy link
Contributor Author

commented Apr 9, 2019

@aborruso bella anche questa soluzione

domanda:

  1. aggiungo alla ricetta
  2. realizzo altra ricetta usando il metodo graduato al posto del categorizzato
@aborruso

This comment has been minimized.

Copy link
Member

commented Apr 9, 2019

Aggiungerei alla ricetta

@pigreco

This comment has been minimized.

Copy link
Contributor Author

commented Apr 9, 2019

@aborruso
ho provato a fare il JOIN con miller

mlr --tsv --implicit-tsv-header --headerless-tsv-output  join  -j 1 --lp colori --rp regioni -f idColori.tsv idRegioni.tsv >./out_regioni_xpath.tsv

il file di output è vuoto:
image

@aborruso

This comment has been minimized.

Copy link
Member

commented Apr 9, 2019

@pigreco prova con

mlr --tsv --implicit-csv-header --headerless-csv-output  join  -j 1 --lp colori --rp regioni -f idColori.tsv idRegioni.tsv

Nel file XML mi sembra che ci siano due symbol con name 0. È corretto?

@pigreco

This comment has been minimized.

Copy link
Contributor Author

commented Apr 10, 2019

Buongiorno @aborruso
funziona ma, come osservi, nel file di output, ci sono sue righe con valore 0

ho analizzato il file XML: il primo name="0" si trova sotto <symbols> il secondo sotto <source-symbol>

image

@aborruso

This comment has been minimized.

Copy link
Member

commented Apr 10, 2019

@pigreco grazie, mi hai fatto vedere l'errore. Nella query sui colori ho impostato correttamente la gerarchia e modificato //symbol in //symbols/symbol.

Ho modificato il messaggio di sopra

@pigreco

This comment has been minimized.

Copy link
Contributor Author

commented Apr 10, 2019

@aborruso grazie per il tempo dedicato e la duplice soluzione, ho messo tutto assieme per creare un piccolo script da lanciare, per esempio, in win 10 usando bash ubuntu:

#!/bin/bash
set -x

<tema.xml xmlstarlet fo -D | xmlstarlet sel -T -t -m "//symbols/symbol" -v $'concat(@name,"\t",layer/prop[@k="color"]/@v)' -n >./idColori.tsv
<tema.xml xmlstarlet fo -D | xmlstarlet sel -T -t -m "//category" -v $'concat(@symbol,"\t",@value)' -n >./idRegioni.tsv
mlr --tsv --implicit-csv-header --headerless-csv-output  join  -j 1 --lp colori --rp regioni -f idColori.tsv idRegioni.tsv >./out_regioni_xpath.tsv


rm idColori.tsv
rm idRegioni.tsv

funziona benissimo.

Aggiungo lo script alla ricetta

@aborruso

This comment has been minimized.

Copy link
Member

commented Apr 10, 2019

Aggiungo la stessa cosa, ma fatta con un foglio elettronico https://docs.google.com/spreadsheets/d/1tjXYrhP2nggPxML3Vay2Ycab7ikACQ95scRHLjo_GYc/edit#gid=0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.