Similitud entre dos o más trayectorias.

11

Tengo los datos de camiones ( http://www.chorochronos.org/ ).

Estos datos son coordenadas gps de múltiples trayectorias de camiones en Atenas.

¡Tengo que calcular la similitud entre las trayectorias para eliminar aquellas que son muy similares!

Problema:

Rojo y Verde son similares, pero azul, negro y (rojo o verde) son trayectorias diferentes. Quiero eliminar uno de los similares, rojo o verde.

Los datos están en puntos (geometría, lat y long, x e y) (coordenadas gps), la imagen son ejemplos de trayectorias

usuario2883056
fuente
1
¿Qué sucede si el rojo y el verde son similares, y el verde y el negro son similares, pero el rojo y el negro no son similares? Además, ¿cómo define "similar"? ¿Es una proporción de la línea que cae dentro de una distancia de la otra línea o alguna otra métrica?
floema
Solo quiero quedarme con trayectorias que son diferentes de las demás. Las trayectorias son coordenadas gps, no líneas ...
user2883056
1
Tiene etiquetas para postgis y postgresql, pero tampoco las mencione en el cuerpo de su pregunta. Si bien el etiquetado es importante, si está utilizando esos productos, le recomiendo que los registre en el cuerpo de su pregunta porque, después de mirar el título, esta será la sección de su pregunta que llamará toda la atención.
PolyGeo
2
Estoy de acuerdo con @phloem: la pregunta clave es "¿cómo se define similar"? Todas las rutas van desde AB, por lo que son 'similares' en ese sentido. Debe proporcionar más información sobre cómo evaluará un resultado exitoso
Stephen Lead,

Respuestas:

10

Una medida realmente fácil, pero no fantástica, es obtener la distancia de Hausdorff entre cada combinación, lo que se hace con la función ST_HausdorffDistance . Usando LineStrings aproximados de su figura, todos se muestran en azul, y la distancia de Hausdorff se muestra para uno de los pares de líneas en rojo:

Distancia de Hausdorff

Y la consulta para ordenar las 6 combinaciones en orden descendente:

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)

Por lo tanto, funciona bien para este ejemplo, pero no es una técnica excelente o robusta para agrupar líneas, ya que la única métrica es el único punto con la mayor distancia, en lugar de comparar las diferencias de las líneas completas. Hay métodos mucho mejores, pero serán más complicados.

Mike T
fuente
Buena respuesta. Probablemente hubiera usado algo como ST_Interpolate point y luego calculé las distancias promedio para cada conjunto de puntos relacionados como un enfoque ingenuo. ¿Qué tenía en mente por métodos mucho mejores?
John Powell
1
@ JohnBarça mejores métodos sería comparar estadísticas espaciales de la cobertura de cada línea. Un método rasterizaría cada línea, haría un desenfoque gaussiano con el ráster y luego determinaría la correlación de los valores de ráster coincidentes de cada combinación. Un método basado en las herramientas ST_Segmentize y ST_Interpolate también funcionaría.
Mike T
4

No tengo acceso a PostGres / PostGIS, pero así es como lo haría en ArcGIS (u otro).

  1. Calcule la longitud de las líneas originales en una columna estática.
  2. Guarda tus líneas de acuerdo a cómo definas "similar". No disuelva los tampones. Los búferes resultantes tendrán FID igual a la línea original.
  3. Entrecruzar tampones y líneas originales. La capa resultante identificará los FID que participan en esa intersección particular (por ejemplo, "FID_lines" y "FID_buff").
  4. Disuelva la capa del n. ° 3 por las dos columnas FID originales y la columna de longitud original
  5. Ignore las líneas resultantes que tienen el mismo valor para las dos columnas FID originales utilizando una consulta de definición u otros medios (por supuesto, una línea almacenada en búfer e intersectada con su propio búfer se superpondrá por completo).
  6. Agregue una columna numérica y llénela con la nueva longitud
  7. Divida la nueva longitud con la longitud original (en una nueva columna) para obtener una relación de la línea original que cae en el búfer de cada línea cercana.
  8. Inspeccione los valores para la relación. Conserve los que haya definido como "suficientemente similares". Por ejemplo, tal vez una línea que se encuentra dentro del búfer de otra línea para el 75% de su longitud es lo suficientemente similar, tal vez su límite sea del 50% de acuerdo, etc.
líber
fuente