[Gfoss] VirtualKNN e max_distance

a.furieri a lqt.it a.furieri a lqt.it
Sab 29 Maggio 2021 18:00:09 CEST


On Sat, 29 May 2021 07:11:42 -0700 (MST), pigreco wrote:
> Forse le query non sono scritte in modo ottimale, ma secondo me un 
> parametro
> max_distance nelle virtualKNN aiuterebbe molto
>

Toto' scusami tanto per la sincerita' forse brutale,
ma introdurre un parametro MaxDistance nel KNN e'
un completo nonsense logico.

mi spiego meglio: se l'approccio KNN ha qualcosa di
meritevole e' proprio nel fatto che ti consente di
lavorare su datasets di cui ignori completamente
la distribuzione spaziale delle features.
non importa se in alcuni casi troverai distanze
minime di pochi metri ed in altri di migliaia di
chilometri, il KNN ti trovera' sempre e comunque
quali sono le features piu' vicine le une alle
altre.

se invece hai gia' un'idea di massima di una
"ragionevole" distanza massima entro cui speri
di trovare delle possibili corrispondenze,
allora l'approccio KNN e' del tutto ridondante,
perche' una banalissima query basata sull'uso
convenzionale dello SpatialIndex imponendo
il raggio di distanza atteso nel codice della
tua query SQL sara' sempre sicuramente piu'
performante.

le due cose (KNN e MaxDistance) non stanno
assieme, sono mutuamente esclusive; o l'uno
o l'altra.

riassumendo: se conosci a priori un raggio di
distanza "ragionevole" allora la tua query puo'
essere riscritta come segue facendo del tutto
a meno ti tirare in ballo il KNN:

CREATE TABLE civici10m AS
SELECT p.id AS id_punto, s.id AS id_strada, Min(ST_Distance(s.geom, 
p.geom)) AS distance,
      ST_shortestline(p.geom, s.geom) as geom
FROM civici AS p
LEFT JOIN strade AS s ON (ST_Distance(s.geom, p.geom) < 10.0 AND s.id 
IN (
       SELECT rowid
       FROM SpatialIndex
       WHERE f_table_name = 'strade'
       AND f_geometry_column = 'geom'
       AND search_frame = ST_Buffer(p.geom, 10.0)))
GROUP BY p.id;

giusto per avere un'idea dei tempi di esecuzione
con datasets "pesantucci" ho testato la query
nelle condizioni seguenti:

a) grafo stradale ITER.NET di regione toscana
    (oltre 400mila archi)
    i punti di fermata degli autobus toscani
    sparsi su tutta le regione (circa 38mila)
    la query gira in meno di 10 sec

b) solito grafo stradale
    i numeri civici della toscana (poco piu'
    di 1 milione e mezzo)
    qua evidentemente i dimensionamenti si
    fanno sentire, ma comunque se la cava
    in circa 4 minuti, che definirei un
    tempo decisamente confortevole.

ciao Sandro

piccolo approfondimento tecnico: il KNN e'
un modulo molto sofisticato che va ad
intrufolarsi direttamente dentro alla
struttura interna degli R*Tree che sono
alla base dello SpatialIndex.
non e' necessariamente un fulmine di
velocita' perche' per esplorare tutti
i nodi dell'albero (almeno della parte
piu' interessante) occorre tempo, pero'
e' completo e sicuramente trova tutti
i possibili candidati.

in tutti gli altri casi l'approccio classico
di tipo dicotomico e' sicuramente preferibile.




Maggiori informazioni sulla lista Gfoss