QGIS etichettare in base a relazioni spaziali

Etichettare usando caratteristiche geometriche non è difficile, anzi con QGIS è facilissimo: supponiamo di voler etichettare le Regioni italiane ISTAT con le superfici di ogni regione: basta utilizzare la funzione $area; ma la cosa diventa parecchio complicata se volessimo usare queste caratteristiche (spaziali) per ordinare le regioni stesse; mi spiego meglio con l’esempio che segue.

Supponiamo di voler etichettare le regioni italiane (da 1 a 20) in base alla superficie della regione, cioè dare 1 alla regione con area maggiore (Sicilia) fino a 20 la regione più piccola (Valle d’Aosta).

Regioni ISTAT con label in base alla superficie

per ottenere questa etichettatura ho usato questa espressione:

array_find( 
           array_reverse(
                      array_sort(
                               array_agg($Area))), $Area)+1

L’espressione significa:
Crea un array (un vettore) e mettici dentro tutti i valori delle aree delle regioni, ordinali in senso crescente (dal più piccolo al più grande) e poi fai l’inverso, cioè, ordinali dal più grande al più piccolo; infine assegna l’indice della posizione del valore dell’area.

Se volessi, invece, etichettare le regioni in funzione della minima coordinata x (cioè secondo la minor longitudine), cioè dare etichetta 1 alla regione Piemonte fino alla 20 regione Calabria:


Regioni ISTAT con label in base alla longitudine

espressione usata:

array_find( 
                   array_sort(
                                       array_agg(x_min( $geometry)))
                                                                                    ),x_min( $geometry))+1 

Ma passiamo a un caso concreto che mi è stato sottoposto recentemente: dato un vettore poligonale con feature regolari (rettangoli) inclinate come in figura:

esempio concreto

nello screenshot è visibile l’etichettatura usando la funzione $id che indica la numerazione relativa alla genesi delle feature,

come etichettare, in modo sequenziale, i rettangoli?

un possibile risultato atteso
altro risultato possibile

Un modo per poter ottenere questi risultati passa da una osservazione fatta, qualche tempo fa, da Andrea Borruso durante uno dei mille confronti e scambi di idee in un gruppo Telegram, un gruppo famoso ma chiuso a pochi utenti HfcQGIS in RTD by OSD; in questa discussione Andrea suggeriva, per ordinare delle feature in base a delle relazioni spaziali, di tracciare un punto o una linea e calcolare la distanza rispetto a questo nuovo strato:

creo un layer temporaneo lineare

espressione per il calcolo della distanza:

length(
        shortest_line($geometry, geometry (get_feature_by_id( 'linea', 1)))
            )

PS: per le varie funzioni consultare HfcQGIS

calcolo lunghezza della shortest_line

la linea è stata posizionata in modo tale che le distanze crescessero nel modo voluto (vedi screenshot di sopra) infatti dove leggiamo 1 la distanza è la minore possibile e cresce con il verso della linea.

Fin qui nulla di speciale, siamo riusciti solo ad ordinare secondo una distanza. Ora viene il bello delle funzioni implementate nel calcolatore di campi di QGIS: come trasmettere l’ordine dei record ottenuti dal calcolo delle distanze?? col senno di poi dico che è semplice, ma ho dovuto ragionarci qualche ora.

Partiamo dall’espressione usata:

array_find(  
          array_sort(
                    array_agg( "distanza" )) , "distanza" )+1

L’espressione significa:
Crea un array (un vettore) e mettici dentro tutti i valori delle distanze tra rettangoli e linea (array_agg), ordinali (array_sort) in senso crescente (dal più piccolo al più grande) infine assegna l’indice (array_find) della posizione del valore corrispondente. (+1 perché l’indice dell’array inizia da 0)

animazione

Infine, non è strettamente necessario creare un campo distanza e popolarlo con l’espressione di sopra, il field calc di QGIS permette di creare una unica espressione come quella che segue (che è una combinazione delle espressioni già usate):

array_find(  
     array_sort(
         array_agg(
               length(shortest_line( $geometry, geometry ( get_feature_by_id( 'linea', 1)))))) ,
               length(shortest_line( $geometry, geometry ( get_feature_by_id( 'linea', 1)))))+1

NOTE FINALI: ho impostato l’articolo parlando di etichette (calcolate al volo) ma è abbastanza semplice scrivere il risultato delle espressioni in un campo della tabella attributi: basta creare un nuovo campo e popolarlo con le espressioni usate.

Riferimenti

Ringraziamenti:

Buon lavoro con QGIS!!!

Se il blog post vi è stato utile partecipate a mantenerlo vivo!!! PayPal

Pubblicità

Un pensiero su “QGIS etichettare in base a relazioni spaziali

Rispondi

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

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. 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.