Prelevare attributi da layer più vicini↵
Livello di linea (MultiLineString) e 4 livelli di punti (MultiPoint).
Il mio livello di linea
ha 2 campi di attributi start_pt
e end_pt
, ho bisogno che vengano compilati con un attributo identificativo (dati stringa popolati con valori come A01, B01, B02, C01, ecc. quindi non è il $id
valore normale) da una qualsiasi delle potenziali caratteristiche dei 4 livelli punti che può essere agganciato alla feature di linea.
esempio sotto:
Espressioni utilizzate per QGIS >= 3.18:
campo start_pt
:
overlay_nearest(layer:=
with_variable('in_layer',array('cat_A','cat_B','cat_C','cat_D'),
with_variable('in_dist',
array_foreach(@in_layer,distance(overlay_nearest(@element,$geometry)[0], start_point($geometry))),
array_get(@in_layer, array_find(@in_dist, array_min(@in_dist)))))
,expression:= id )[0]
campo end_pt
:
overlay_nearest(layer:=
with_variable('in_layer',array('cat_A','cat_B','cat_C','cat_D'),
with_variable('in_dist',
array_foreach(@in_layer,distance(overlay_nearest(@element,$geometry)[0], end_point($geometry))),
array_get(@in_layer, array_find(@in_dist, array_min(@in_dist)))))
,expression:= id )[0]
l'unica differenza tra le due espressioni di sopra è nelle funzioni: start_point
e and_point
.
nel linguaggio umano:
l'espressione crea due varibili, la prima contiene i nomi dei 4 layer, la seconda crea un array di distanze tra i 4 layer e il layer lineare; infine, tra i vari valori distanza scelgo quello più piccolo, una volta rispetto a star_point
e una volta per l'end_point
.
EDIT:
Le espressioni di sopra risolvono il caso in esame, ma non risolvono il caso in cui una linea abbia, come punti estremi, punti dello stesso layer puntuale: in questo caso le espressioni non riescono a distinguere lo start_point dall'end_point e restituirebbe sempre lo stesso valore; per risolvere il problema si propone la seguente espressione:
-- select id
with_variable('feature',
-- search for the nearest points
overlay_nearest(layer:=
-- search for the closest layer
with_variable('in_layer',array('cat_A','cat_B','cat_C','cat_D'), -- point layer list
with_variable('in_dist',
array_foreach(@in_layer,
distance(overlay_nearest(@element,$geometry)[0],
end_point($geometry))), -- change start or end_point
array_get(@in_layer, array_find(@in_dist, array_sort(@in_dist)[0]))))
-- search for the closest layer
,expression:= id, limit:=2, max_distance:=0.1 )
-- search for the nearest points
, if(array_length(
@feature)>1,
@feature[1], -- 0: start_point; 1: end_point
@feature[0]) --
)
-- select id
quesito su stackexchange: https://gis.stackexchange.com/questions/417080/populate-lines-attribute-fields-with-attributes-from-point-features-snapped-to
osservazioni:
- i 4 livelli punti si chiamano 'cat_A','cat_B','cat_C','cat_D';
- il livello linea si chiama line.
Provaci tu↵
il GeoPackage è qui
Funzioni e variabili utilizzate: