Da una richiesta via mail:
Ciao, è possibile aggiungere ad una tabella i colori
Alessandro
della categorizzazione del layer, come indicato nell’immagine ?

Che io sappia, non esiste nessun plugin o funzione del field calc o del processing che permetta di estrapolare questa dato dal layer (unico modo, restando all’interno di QGIS, è usare pyQGIS vedi fine blog post).
Estrarre dati dal file QML di QGIS
Usando la riga di comando
La tematizzazione (e non solo) di QGIS puo’ essere salvata in un file *.qml che è un file scritto in XML .
In questo caso specifico copiare solo la tematizzazione (metodo categorizzato) facendo tasto destro del mouse sul layer categorizzato:

In un Editor di testo (Notepad++ o Visual Studio Code) incollare gli appunti, in un nuovo file, e salvare in formato *.xml

A questo punto occorre estrarre i dati che ci interessano:
- il nome della regione (perché abbiamo tematizzato in funzione di questo campo) con relativo numero di symbol nella proprietà “renderer-v2”
- il numero del simbolo symbol nella proprietà “symbols” e relativo colore (codice rgba);
soluzione con utilityyq
#!/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_regioni_yq.csv
rm idColori.csv
rm idRegioni.csv

soluzione con utility xmlstarlet con linguaggio XPATH
#!/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
Gli script Bash (di sopra) estrapolano i dati in due file CSV/TSV ( le prime due righe) che verranno messi in JOIN nella terza riga creando un terzo file CSV7TSV finale (out_regioni_yq.csv ,out_regioni_xpath.tsv); le ultime due righe cancellano i primi file CSV/TSV che non servono più.
il file di output ha questa struttura:

ottenuto questo file CSV/TSV e importato in QGIS, con un semplice JOIN (tra il layer di partenza e il file CSV/TSV – NB: il file è senza intestazione) è possibile aggiungere la colonna ‘rgba‘ (cioè il secondo campo: field_2) alla tabella attributi del layer tematizzato:


Usando Google Sheet

Dopo aver creato il file tema.xml, occorre salvarlo nel web da qualche parte per esempio in un gist di GitHub
formule utilizzate:
NB: la sintassi delle formule è sensibile alle impostazioni dello sheet, qui la docs
poi esportare lo sheet con file CSV.
Lo sheet di esempio è raggiungibile da qui
La ricetta su T’ansigrari è qui – grazie a GBvitrano
Usando pyQGIS
- Aprile la console di Python menu Plugins | Console Python (CTRL+ALT +P);
- importare il file *.py;
- cliccare su esegui script
lo script aggiunge un campo COLOR alla tabella attributi del layer selezionato e lo popola con i codici colore rgba:
#Recupera il colore assegnato dalla categorizzazione al layer selezionato
#aggiunge un campo COLOR e salva i valori dei colori
#python 3 10.04.2019 Giulio Fattori
import datetime
current_time = datetime.datetime.now()
layer = iface.activeLayer()
renderer=layer.renderer()
if layer.renderer().type() == "categorizedSymbol":
matrix = {}
campo=renderer.legendClassificationAttribute()
for cat in renderer.categories():
matrix[cat.value()] = cat.symbol().symbolLayer(0).properties()['color']
layer.startEditing()
if layer.fields().indexFromName('COLOR') == -1:
layer.addAttribute(QgsField("COLOR", QVariant.String))
for feat in layer.getFeatures():
layer.changeAttributeValue(feat.id(),layer.fields().indexFromName('COLOR'),matrix[str(feat[campo])])
layer.commitChanges()
current_time = str(datetime.datetime.now() - current_time)
iface.messageBar().pushMessage("Elaborazione terminata in ", current_time, level=Qgis.Info, duration=5)
iface.messageBar().pushMessage("I COLORI SONO SALVATI IN UNA NUOVA COLONNA DENOMINATA ", "COLOR", level=Qgis.Warning, duration=5)
elif layer.renderer().type() != "categorizedSymbol":
current_time = str(datetime.datetime.now() - current_time)
iface.messageBar().pushMessage("NON E' UN LAYER CATEGORIZZATO - Elaborazione terminata in ", current_time, level=Qgis.Critical, duration=5)
lo script python è raggiungibile qui – grazie a Giulio Fattori
EDIT: lo script python non funziona bene su campi calcolati quindi se necessita categorizzare tramite una espressione è consigliato tematizzare utilizzando un campo virtuale popolato con l’espressione.

NOTE FINALI: questo blog post è valido solo per tematizzazioni con metodo categorizzato, il concetto di fondo è generale e implementabile per qualsiasi tipologia di stile ed etichettatura. Ho descritto vari metodi (riga di comando, gui e pyQGIS) sono tutti equivalenti nel senso che permettono di raggiungere lo stesso risultato: ognuno di noi è libero di utilizzare il metodo che ritiene più consono alle proprie attitudini. È ovvio che il metodo più diretto e adatto al caso è quello pyQGIS, metodo che ha grossi margini di miglioramento come per esempio: portarlo come script in processing, portarlo come funzione nel calcolatore di campi.
Riferimenti:
- QGIS.org;
- T’ansignari e T’appeddiri;
- Estrarre dati da un file XML;
- Estrarre dati da un file XML con Google sheet (XPATH);
- Script pyQGIS;
- Miller;
- yq;
- XmlStarlet;
- XPATH.
- Sotto sistema Bash su Win 10
Ringraziamenti:
- Andrea Borruso
- Giovan Battista Vitrano (@gbvitrano)
- Giulio Fattori
il tema utilizzato è raggiungibile qui
Un pensiero su “QGIS popolare un campo della tabella attributi con i colori dello stile categorizzato usato”