Elenco ordinato di Comuni attraversati da un itinerario Domodossola-Aosta.

Ieri nel gruppo Telegram di QGIS Italia, il vice-presidente di GFOSS.it (Stefano Campus) pone questa domanda molto interessante:

qualcuno risponde:

Altri membri del gruppo rispondono con varie idee, in alcuni casi buone idee ma nulla di concreto. Dopo qualche ora presento la mia soluzione usando solo le espressioni e il calcolatore di campi.

Come nasce una espressione complessa

Per risolvere qualsiasi tipo di problema occorre una idea di base da tradurre, poi, in espressione utilizzando le varie funzioni messe a disposizione dal field calc.

Nel gruppo ci sono due suggerimenti:

L’idea è quella di fare una intersezione tra la linea che rappresenta l’itinerario e i poligoni comunali.

Step 1 : ottenere le linee di intersezione tra itinerario e poligoni

intersection($geometry, geometry(get_feature('percorso','fid',1)))

utilizzo l’espressione di sopra e genero una nuova geometria:

Step 2: per ogni linea ricadente nel poligono comunale, calcolo il baricentro creando una nuova geometria puntuale a partire dall’espressione di sopra (che rappresenta la geometria dell’ itinerari spezzato per ogni comune):

centroid(intersection($geometry, geometry(get_feature('percorso','fid',1))))

ma i centroid NON cadono lungo le linee e questo potrebbe creare problemi, per ovviare uso altra funzione :

line_interpolate_point(intersection($geometry, geometry(get_feature('percorso','fid',1))),
length(intersection($geometry, geometry(get_feature('percorso','fid',1)))))

Step 3: per ottenere la lunghezza del percorso, rispetto l’origine dell’itinerario e per ogni punto baricentro dell’area poligonale, occorre utilizzare altra funzione per popolare il campo lunghezza (sempre sul layer poligonale):

line_locate_point(geometry(get_feature('percorso','fid',1)),
line_interpolate_point(intersection($geometry, geometry(get_feature('percorso','fid',1))),
length(intersection($geometry, geometry(get_feature('percorso','fid',1))))/2))

e qui trovo un primo problema (segnalato da Stefano), cioè se l’itinerario parte da un Comune, passa in altro Comune e rientra nel Comune di partenza (vedi screenshot di sotto), si manifesta un problema: il secondo Comune viene conteggiato come se fosse il primo:

questo perché il centroide della linea del secondo Comune ha una lunghezza inferiore, dall’origine dell’itinerario, rispetto al primo Comune.

Per risolvere il problema, non posso utilizzare il centroide ma un altro punto lungo la linea. La funzione line_locate_point permette di esprimere una lunghezza in termini percentuali e quindi utilizzo il 10% o il 90% a seconda dell’origine dell’itinerario.

L’espressione finale è:

with_variable('toto',  reverse( geometry(get_feature('percorso','fid',1))),
    array_find( 
        array_filter(
            array_sort(
                array_agg(
                    line_locate_point(@toto, line_interpolate_point( intersection($geometry,@toto ), 
                    length(intersection($geometry,@toto))*0.1 ))
                         )
                      ), @element >0),
                    line_locate_point(@toto, line_interpolate_point( intersection($geometry,@toto ), 
                    length(intersection($geometry,@toto)) *0.1 ))
                )
) 

dove ho creato una variabile @toto che equivale a un pezzo di espressione: geometry(get_feature('percorso','fid',1)).

Un piccolo cenno agli Array utilizzati nell’espressione:

  • array_agg permette di aggregare tutti i valori in un unico array;
  • array_sort permette di ordinare i valori;
  • array_filter filtra i valori in modo da lavorare solo con lunghezze > 0;
  • array_find permette di usare i numeri da 0 a n al posto delle lunghezze che possono essere numero grossi.

I Comuni sono stati ordinati a partire da Domodossola, ma se volessi farlo al contrario, basterebbe sostituire due solo valori nell’espressione:

  1. usare la funzione reverse che inverte il senso di marcia dell’itinerario;
  2. utilizzare il 90% della lunghezza al posto del 10%.(length(intersection($geometry,@toto)) *0.9)

NOTE FINALI: questa è l’ennesima prova che dimostra la potenza delle espressioni e del calcolatore di campi di QGIS.


Download dati e progetto in formato gpkg (per gentile concessione di Stefano)


Riferiementi

Ringraziamenti

Per chi volesse approfondire l’uso del Field Calc:
http://hfcqgis.opendatasicilia.it/it/latest/corso_formazione/corso_di_formazione.html


Se il blog post vi è piaciuto cliccate su ‘Mi piace’, grazie!!!
if you liked the blog post click on ‘Like’, thank you !!!

SE IL POST VI È STATO UTILE CONTRIBUITE A MANTENERLO AGGIORNATO PAYPAL


2 pensieri su “Elenco ordinato di Comuni attraversati da un itinerario Domodossola-Aosta.

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 )

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.