Somiglianza tra due o più traiettorie


11

Ho i dati dei camion ( http://www.chorochronos.org/ ).

Questi dati sono coordinate GPS di più traiettorie di camion ad Atene.

Devo calcolare la somiglianza tra i trajetories, al fine di eliminare quelli che sono molto simili!

Problema:

Rosso e verde sono simili, ma blu, nero e (rosso o verde) sono traiettorie diverse. Voglio eliminare uno dei simili, rosso o verde.

I dati sono in punti (geometria, lat e long, xey) (coordinate gps), l'immagine sono esempi di traiettorie


1
Cosa succede se rosso e verde sono simili e verde e nero sono simili, ma rosso e nero non sono simili? Inoltre, come definisci "simile" - è una proporzione della linea che rientra in una distanza dell'altra linea o qualche altra metrica?
floema

Voglio solo stare con traiettorie diverse dalle altre. I trajetories sono coordinate GPS, non linee ...
user2883056

1
Hai tag per postgis e postgresql ma non menzionarli nel corpo delle domande. Mentre il tagging è importante, se stai usando quei prodotti, ti consiglio vivamente di registrarli nel corpo della tua domanda perché, dopo aver dato uno sguardo al titolo, questa sarà la sezione della tua domanda che attirerà tutta l'attenzione.
PolyGeo

2
Sono d'accordo con @phloem - la domanda chiave è "come si definisce simile"? Tutte le rotte vanno da AB, quindi sono "simili" in questo senso. È necessario fornire ulteriori informazioni su come valutare un risultato positivo
Stephen Lead,

Risposte:


10

Una misura davvero semplice, ma non fantastica, è quella di ottenere la distanza di Hausdorff tra ogni combinazione, che viene eseguita con la funzione ST_HausdorffDistance . Utilizzando approssimativamente LineString dalla tua figura, questi sono tutti mostrati in blu e la distanza di Hausdorff è mostrata per una delle coppie di linee in rosso:

Distanza di Hausdorff

E la query per ordinare le 6 combinazioni in ordine decrescente:

WITH data AS (
  SELECT 'blue' AS name, 'LINESTRING (60 200, 110 290, 200 320, 330 320, 430 240, 450 200)'::geometry AS geom
  UNION SELECT 'black', 'LINESTRING (60 200, 120 270, 235 297, 295 207, 450 200)'::geometry
  UNION SELECT 'green', 'LINESTRING (60 200, 280 190, 450 200)'::geometry
  UNION SELECT 'red', 'LINESTRING (60 200, 150 210, 257 195, 360 210, 430 190, 450 200)'::geometry)
SELECT a.name || ' <-> ' || b.name AS compare, ST_HausdorffDistance(a.geom, b.geom)
FROM data a, data b WHERE a.name < b.name
ORDER BY ST_HausdorffDistance(a.geom, b.geom) DESC;

     compare     | st_hausdorffdistance
-----------------+----------------------
 blue <-> green  |                  130
 blue <-> red    |                  125
 black <-> blue  |     110.102502131467
 black <-> green |     104.846289061163
 black <-> red   |     97.9580173908678
 green <-> red   |     15.2677257073823
(6 rows)

Quindi funziona bene per questo esempio, ma non è una tecnica eccezionale o robusta per il raggruppamento di linee, poiché l'unica metrica è il punto singolo con la distanza maggiore, anziché confrontare le differenze delle linee complete. Esistono metodi molto migliori, ma saranno più complicati.


Bella risposta. Avrei probabilmente usato qualcosa di simile al punto ST_Interpolate e quindi calcolato le distanze medie per ogni serie di punti correlati come approccio ingenuo. Cosa avevi in ​​mente con metodi molto migliori?
John Powell,

1
@ JohnBarça metodi migliori sarebbero di confrontare le statistiche spaziali della copertura di ciascuna linea. Un metodo rasterizza ogni linea, esegue una sfocatura gaussiana con il raster, quindi determina la correlazione dei valori raster coincidenti di ciascuna combinazione. Funzionerebbe anche un metodo basato sugli strumenti ST_Segmentize e ST_Interpolate.
Mike T,

4

Non ho accesso a PostGres / PostGIS, ma ecco come lo farei in ArcGIS (o altro).

  1. Calcola la lunghezza delle linee originali in una colonna statica
  2. Buffer le tue linee in base a come definisci "simile". Non dissolvere i buffer. I buffer risultanti avranno un FID uguale alla linea originale.
  3. Buffer di intersezione e linee originali. Il livello risultante identificherà i FID che partecipano a quel particolare incrocio (ad esempio, "FID_lines" e "FID_buff").
  4. Sciogli il livello dal n. 3 dalle due colonne FID originali e dalla colonna della lunghezza originale
  5. Ignora le linee risultanti che hanno lo stesso valore per le due colonne FID originali usando una query di definizione o altri mezzi (ovviamente una linea bufferizzata e intersecata con il proprio buffer si sovrapporrà completamente).
  6. Aggiungi una colonna numerica e popolala con la nuova lunghezza
  7. Dividi la nuova lunghezza con la lunghezza originale (in una nuova colonna) per ottenere un rapporto della linea originale che rientra nel buffer di ciascuna linea vicina.
  8. Ispezionare i valori per il rapporto. Mantieni quelli che hai definito "abbastanza simili". Ad esempio, forse una linea che rientra nel buffer di un'altra linea per il 75% della sua lunghezza è abbastanza simile, forse il limite è un accordo del 50%, ecc.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.