Vai al contenuto

Spatial join con condizione

L’unione spaziale di attributi è un problema frequente in ambito GIS - si tratta di trasferire attributi da un layer ad un altro basandosi solo sulle loro reciproche relazioni spaziali, in questo esempio aggiungiamo una difficoltà in più, ovvero, una condizione.

Il quesito nasce da questa challenge, proposta da Ujaval Gandhi e chiede:

Hai uno strato poligonale di aree urbane e uno strato puntuale di luoghi.Etichettare il poligono con il nome della città con popolazione maggiore usando una spatial join con condizione?

qui i dati: https://t.co/fqEKY68uGC

Soluzione proposta da Ujaval Gandhi

array_get(aggregate(
  layer:='ne_10m_populated_places_simple',
  aggregate:='array_agg',
  expression:="name",
  filter:=intersects($geometry, geometry(@parent)), order_by:="POP_MAX"), -1)

nel linguaggio umano:
Ordina in modo crescente (order_by) la popolazione relativa ai punti che ricadono dentro (aggregate) i poligoni ed estrai il nome della città. dove: - array_agg: crea un array che contiene i nomi delle città dentro i poligoni; - il filtro ordina i punti usando la popolazione

video youtube: https://youtu.be/qpiFT8UHhwM

Soluzione proporta da Totò Fiandaca

nel linguaggio umano:
Crea una variabile e la popola con il valore massimo della popolazione dei punti che ricadono dentro ogni poligono (ma non so ancora il nome della città), quindi ripeto la ricerca creando una mappa (map("name","pop_max")) e tra le varie mappe, prendo quella con popolazione maggiore (quest'ultima ricerca la fa array_find).

with_variable('max',
  overlay_contains(
    layer:='ne_10m_populated_places_simple',expression:= "pop_max"),
map_akeys( 
  overlay_contains(
    layer:='ne_10m_populated_places_simple',
    expression:= map("name","pop_max"))[array_find(@max,array_max(@max))])[0])
oppure:

with_variable('max',
  overlay_contains(
    layer:='ne_10m_populated_places_simple',expression:= "pop_max"),
attribute(overlay_contains(
  layer:='ne_10m_populated_places_simple',
  expression:= @feature)[array_find(@max,array_max(@max))],'name'))

in questo caso ho usato la variabile @faeture che contiene l'intero rigo (compreso di geometria) dell'elemento valutato; quindi, usando attribute posso richiamare qualsiasi attributo delle riga.

video youtube: https://youtu.be/NOgDku2S9ws

posizionare l'etichetta

Per posizionare l'etichetta nel corretto punto, corrispondente al punto della città con popolazione maggiore, occorre usare questa espressione nel tab posizione Generatore geometria:

with_variable('max',
  overlay_contains(
  layer:='ne_10m_populated_places_simple',expression:= "pop_max"),
overlay_contains(
  layer:='ne_10m_populated_places_simple',
  expression:= $geometry)[array_find(@max,array_max(@max))])

Funzioni e variabili utilizzate: