[QGIS-it-user] la funzione with_variable per ottimizzare espressioni complesse

L'espressione di sotto permette di selezionare la/le regione/i con più
regioni confinanti:

maximum(
array_length(overlay_touches(@layer_name,$id))
)

array_length(overlay_touches(@layer_name,$id))

'array_length(overlay_touches(@layer_name,$id))' è richiamata due volte e
quindi ho pensato di utilizzare la funzione 'with_variable' per ottimizzare
l'espressione:

with_variable (
'cucu',
array_length(overlay_touches(@layer_name,$id)),
maximum (@cucu) = @cucu)

ma quest ultima restituisce sempre 1, in quanto non viene calcolato il
valore maximun(@cucu), ma solo il valore @cucu e quindi risulterebbe @cucu =
@cucu, cioè uguglianza sempre verificata.

Non capisco se è un limite della funzione with_variable oppure cosa?

grazie

PS: per chi volesse testare, importare lo shapefile ISTAT regioni e eseguire
una selezione per espressione utilizzando la prima espressione.

saluti

-----
https://pigrecoinfinito.com/
--
Sent from: http://osgeo-org.1560.x6.nabble.com/QGIS-Italian-User-f5250612.html

Totò wrote

ma quest ultima restituisce sempre 1, in quanto non viene calcolato il
valore maximun(@cucu), ma solo il valore @cucu e quindi risulterebbe @cucu

@cucu, cioè uguglianza sempre verificata.

Non capisco se è un limite della funzione with_variable oppure cosa?

Ciao Salvatore,
per quanto ne so, with_variable assegna ad una variabile definita
dell'utente un "valore" calcolato a partire da una espressione; non assegna
alla variabile l'espressione stessa.

Quindi, quando per un determinato record viene valutata la tua espressione:

with_variable('cucu',array_length(overlay_touches(@layer_name,$id)),maximum
(@cucu) = @cucu)

la variabile @cucu conterrà un solo valore che è il risultato
dell'espressione array_length(overlay_touches(@layer_name,$id)) per quel
determinato record, per esempio il valore numerico 10, per cui
maximum(@cucu), o minimum(@cucu), sarà comunque uguale a 10 per quel
determinato record e l'uguaglianza nella tua espressione sarà quindi
soddisfatta per ogni record.

Non so se questo comportamento sia voluto oppure non sia stato considerato,
ma penso che si tratti di un altro tipo di funzionalità più simile alla
possibilità di definire una funzione utente (e non una variabile) tramite il
Function editor.

Comunque,
si può ovviare al problema usando la funzione eval che dovrebbe essere utile
proprio in queste situazioni.

Per esempio la tua espressione dovrebbe poter essere riscritta e funzionare
in seguente modo:

with_variable('cucu','array_length(overlay_touches(@layer_name,$id))',maximum(eval(@cucu))
= eval(@cucu))

In questo modo alla variabile @cucu viene assegnata una stringa che contiene
l'espressione che poi verrà valutata da eval come se fosse una funzione
utente.

Sembra funzionare anche:

with_variable('cucu',array_length(overlay_touches(@layer_name,$id)),maximum(eval(@cucu))=@cucu)

quindi senza che sia necessario rendere l'espressione una stringa (ma questo
non è indicato nel manuale).

A presto.

Andrea

--
Sent from: http://osgeo-org.1560.x6.nabble.com/QGIS-Italian-User-f5250612.html

Andrea Giudiceandrea wrote

Sembra funzionare anche:
with_variable('cucu',array_length(overlay_touches(@layer_name,$id)),maximum(eval(@cucu))=@cucu)
quindi senza che sia necessario rendere l'espressione una stringa (ma
questo non è indicato nel manuale).

In realtà mi sa che così non funziona (effettivamente non dovrebbe
funzionare in questo modo). Non so perché mi sembrato funzionasse...

--
Sent from: http://osgeo-org.1560.x6.nabble.com/QGIS-Italian-User-f5250612.html

Andrea Giudiceandrea wrote

Per esempio la tua espressione dovrebbe poter essere riscritta e
funzionare
in seguente modo:

with_variable('cucu','array_length(overlay_touches(@layer_name,$id))',maximum(eval(@cucu))
= eval(@cucu))

In questo modo alla variabile @cucu viene assegnata una stringa che
contiene
l'espressione che poi verrà valutata da eval come se fosse una funzione
utente.

Sembra funzionare anche:

with_variable('cucu',array_length(overlay_touches(@layer_name,$id)),maximum(eval(@cucu))=@cucu)

quindi senza che sia necessario rendere l'espressione una stringa (ma
questo
non è indicato nel manuale).

Buongiorno,
ho provato la prima espressione che suggerisci e funziona, ma impiega un
tempo enorme e quindi non più utile l'uso della with_variable (impiega 126
sec a partire dallo shapefile regioni istat, che ha solo 20 feature; la mia
iniziale espressione impiega 10 sec).

la seconda espressione che proponi:
with_variable('cucu',array_length(overlay_touches(@layer_name,$id)),maximum(eval(@cucu))=@cucu)
non funziona da me (avevo già fatto questa prova).

grazie

-----
https://pigrecoinfinito.com/
--
Sent from: http://osgeo-org.1560.x6.nabble.com/QGIS-Italian-User-f5250612.html

Totò wrote

funziona, ma impiega un tempo enorme

E sì, questo dovrebbe dipendere dal fatto che le funzioni di aggregazione,
usate normalmente, hanno un meccanismo di cache del risultato che le rende
più efficienti in caso di calcolo ripetuto sulle stesse feature.
Usate con eval, il mecccanismo di cache non funziona.

--
Sent from: http://osgeo-org.1560.x6.nabble.com/QGIS-Italian-User-f5250612.html