QGIS popolare un campo della tabella attributi con i colori dello stile categorizzato usato

Da una richiesta via mail:

Ciao, è possibile aggiungere ad una tabella i colori
della categorizzazione del layer, come indicato nell’immagine ?

Alessandro
Screenshot QGIS

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:

copiare stile negli appunti

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

Visual Studio Code

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
Bash Ububtu 18.04 on Win 10

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:

out_regioni_yq.csv – senza intestazione

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:

creo JOIN in QGIS
risultato finale

Usando Google Sheet

Screenshot 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

Console Python QGIS 3.x
  1. Aprile la console di Python menu Plugins | Console Python (CTRL+ALT +P);
  2. importare il file *.py;
  3. 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.

tabella attributi

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:

Ringraziamenti:

il tema utilizzato è raggiungibile qui

Annunci

Un pensiero su “QGIS popolare un campo della tabella attributi con i colori dello stile categorizzato usato

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.