¿Cuáles son los mejores algoritmos para unir segmentos?
Estoy tratando de hacer coincidir los segmentos correspondientes de dos fuentes de mapas, uno menos preciso pero con nombres de segmento, y otro más preciso sin nombres de segmento. Quiero aplicar semiautomáticamente los nombres de segmento al mapa más preciso.
El algoritmo solicitado tiene una descripción bastante vaga porque una "coincidencia" no está bien definida y muchos factores (orientación, longitud relativa, distancia) pueden tener diferente peso en diferentes escenarios; Sin embargo, estoy buscando un conocimiento básico sobre los enfoques generales para manejar este problema.
Las implementaciones de trabajo para el entorno de código abierto (PostGIS, bien proporcionado, ...) son bienvenidas.
Segmentos de muestra : Ver descripción debajo de las imágenes.
fuente
Respuestas:
Se puede utilizar la distancia de Hausdorff : los segmentos coincidentes podrían ser segmentos "cercanos" de acuerdo con esta distancia. Es bastante simple calcular en segmentos.
Una implementación gratuita de Java está disponible en JTS ; consulte el Paquete de distancia JTS . También puede echar un vistazo a JCS Conflation Suite (ahora abandonada, copia de las fuentes, por ejemplo, en https://github.com/oschrenk/jcs ).
fuente
No sé cuál sería el "mejor", porque eso dependerá de los detalles de sus segmentos.
Un enfoque generalmente bueno es dividir los segmentos en información geométrica crucial . Esto incluiría, como mínimo, la ubicación del centro (x, y), orientación (0 a 180 grados) y longitud. Con los pesos apropiados aplicados y un poco de refinamiento de la orientación (debido a que 180 "se ajusta" a 0), podría aplicar casi cualquier algoritmo de agrupamiento estadístico a la colección de todos los segmentos. ( K-means sería una buena opción, pero la mayoría de los métodos jerárquicos deberían funcionar bien. Tales análisis de conglomerados tienden a ser rápidos y fáciles de aplicar). Idealmente, los segmentos se producirán en pares (o singletons para segmentos no coincidentes) y el resto es fácil.
Una forma de abordar el problema de orientación es hacer una copia de los segmentos etiquetados. Agregue 180 grados a la orientación de la primera copia, si es menor a 90, y reste 180 grados de la orientación. Esto amplía su conjunto de datos (obviamente), pero de lo contrario no cambia el algoritmo de ninguna manera.
Los pesos son necesarios porque las diferencias de coordenadas, longitudes y orientaciones pueden significar cosas muy diferentes con respecto a las similitudes de sus segmentos correspondientes. En muchas aplicaciones, las diferencias entre segmentos surgen de las diferencias en la ubicación de sus puntos finales. Como una aproximación aproximada, podemos esperar que la variación típica en las longitudes de los segmentos sea aproximadamente la misma que la variación típica entre sus puntos finales. Por lo tanto, los pesos asociados con x, y, y la longitud deberían ser aproximadamente los mismos. La parte difícil es la orientación de ponderación, porque la orientación no puede equipararse con la distancia y, lo que es peor, los segmentos cortos tendrían más probabilidades de estar mal orientados que los segmentos largos. Considere un método de prueba y error que iguale algunos grados de desorientación con el tamaño de una brecha típica entre segmentos y luego ajuste eso hasta que el procedimiento parezca funcionar bien. Para orientación, dejemosL sea una longitud de segmento típica. Un cambio de orientación en un ángulo pequeño t grados barrerá una distancia de aproximadamente L / 2 * t / 60 (el 60 se aproxima al número de grados en un radián), que es L / 120 veces t . Eso sugiere comenzar con pesos unitarios para x, y, longitud y un peso de L / 120 para la orientación.
En resumen , esta sugerencia es:
Haga copias de los segmentos etiquetados (como se describe en el párrafo sobre cómo afinar la orientación).
Convierta cada segmento en el cuádruple (x, y, longitud, orientación L / 120 *) donde L es una longitud de segmento típica.
Realizar un análisis de conglomerados de los cuádruples. Use un buen paquete estadístico ( R es gratis).
Utilice el resultado del análisis de conglomerados como una tabla de búsqueda para asociar segmentos etiquetados con segmentos no etiquetados cercanos.
fuente
Trabajé en un proyecto con un requisito similar hace unos 5 años. Implicaba combinar coordenadas de las líneas centrales de las calles (con una precisión de coordenadas relativamente alta) con enlaces de red de tráfico del Sistema de Monitoreo de Desempeño de Carreteras (HPMS).
En ese momento, la FHWA no proporcionó ninguna herramienta para hacer este tipo de cosas. Eso puede haber cambiado, es posible que desee verificar. Incluso si no está trabajando con datos de autopistas, las herramientas podrían ser relevantes.
Lo escribí con ArcGIS, pero el algoritmo debería funcionar en código abierto, siempre que proporcione capacidades de rastreo similares a ISegmentGraph :
fuente
Aqui viene una idea
Si separa una de las cadenas de líneas para comparar y prueba si los puntos de vértice están a cierta distancia de la otra cadena de líneas para comparar, puede controlar la prueba de muchas maneras.
esos ejemplos funcionan en PostGIS (quién podría adivinar :-))
Primero, si decimos que hay una coincidencia si todos los puntos de vértice en una cadena lineal en la tabla_1 son 0.5 metros (unidades de mapa) o más cerca de una cadena lineal en la tabla_2:
Entonces podemos decir que hay una coincidencia si más del 60% de los puntos de vértice en una cadena lineal en la tabla_1 está dentro de la distancia de una cadena lineal en la tabla_2
O podemos aceptar que un punto no está dentro del rango:
También deberá ejecutar la consulta con table_1 y table_2 en roles invertidos.
No sé qué tan rápido será. ST_Dumppoints es actualmente una función sql en PostGIS y no una función C, lo que lo hace más lento de lo que debería ser. Pero creo que será bastante rápido de todos modos.
Los índices espaciales ayudarán mucho a que ST_Dwithin sea efectivo.
HTH Nicklas
fuente
He escrito código para manejar la coincidencia de segmentos de línea descuidada (y superponerlos) en Boundary Generator. Escribí las matemáticas (bastante elementales) detrás de esto aquí: http://blog.shoutis.org/2008/10/inside-boundary-generator-computational.html . El código es de código abierto y está vinculado desde esa publicación de blog.
El código sigue un enfoque realmente simple:
La principal ventaja de este enfoque es que obtiene perillas muy precisas para ángulos válidos, distancias y longitud de superposición; En el lado negativo, no es una forma de medir generalmente la similitud de dos segmentos de línea, por lo que es mucho más difícil, por ejemplo, hacer un agrupamiento estadístico para determinar coincidencias probables: está atascado con las perillas precisas.
Nota: Supongo que con suficientes chops de SQL podría incluir la prueba segmento-segmento en una cláusula WHERE ... :)
¡Aclamaciones!
fuente
He implementado un prototipo aproximado para la correspondencia de mapas aquí , que es relativamente fácil de usar. Se basa en el motor de enrutamiento de código abierto y está escrito en Java. El algoritmo utilizado se describe aquí .
fuente