2008-12-01 13 views
12

Estoy tratando de ver si alguien sabe cómo agrupar algunos resultados de Lat/Long, usando una base de datos, para reducir la cantidad de resultados enviados a la aplicación a través del cable.Clustering Lat/Longs en una base de datos

Hay una serie de recursos sobre la forma de agruparse, ya sea en el lado del cliente o en el lado del servidor (aplicación) .. pero no en el lado de la base de datos :(

This is a similar question, se le preguntó por un compañero miembro de SO Las soluciones están basadas en el servidor (es decir, código C# detrás).

¿Alguien ha tenido algo de suerte o experiencia al resolver esto, pero en una base de datos? ¿Hay algún gurú de base de datos que esté detrás de un hawt y sexy DB? desafío?

por favor ayuda :)

EDIT 1: Aclaración: al agrupar, espero agrupar x número de puntos en un solo punto, para un área. Entonces, si digo agrupar todo en un cuadrado de 1 milla/1 km, entonces todos los resultados en ese 'cuadrado' son GROUP'D en un solo resultado (digamos ... el centro del cuadrado).

EDIT 2: Estoy usando MS Sql 2008, pero estoy abierto a escuchar si hay otras soluciones en otros DB.

+0

¿Qué está buscando exactamente? ¿Un conjunto reducido de puntos lat/long que representan bien el conjunto de datos, un conjunto de puntos cerca de un punto de "prueba" determinado o algo completamente diferente? –

+0

Se agregó una aclaración al post de apertura. –

+0

Estoy teniendo el mismo problema. ¿Encontraste una solución? – shizik

Respuesta

12

Probablemente usaría una versión modificada * de k-means clustering utilizando las coordenadas cartesianas (por ejemplo, WGS-84 ECF) para sus puntos. Es fácil de implementar & converge rápidamente, y se adapta a sus datos sin importar cómo se vea. Además, puede elegir k para satisfacer sus requisitos de ancho de banda, y cada grupo tendrá el mismo número de puntos asociados (mod k).

Haría una tabla de centroides de clúster y agregaría un campo a la tabla de datos original para indicar a qué clúster pertenecía también. Obviamente, desea actualizar el clúster periódicamente si sus datos son dinámicos. No sé si podría hacer eso con un procedimiento almacenado & disparador, pero quizás.

* La "modificación" sería ajustar la longitud de los vectores centroides calculados para que estén en la superficie de la tierra. De lo contrario, terminarías con un montón de puntos con altitud negativa (cuando se vuelvan a convertir en LLH).

+0

kewlies! ... eh ... no tengo idea de cómo hacer esto ... pero tengo que decir lo que dices. hmm ... los datos no son demasiado dinámicos. pero aún tendré que pensar en cómo (y con qué frecuencia) voy a tener que calcificar esto. hmm. ¡tan duro! –

5

Si se está agrupando en una ubicación geográfica, y no puedo imaginar que sea otra cosa :-), podría almacenar la "ID de grupo" en la base de datos junto con las coordenadas lat/long.

Lo que quiero decir con eso es dividir el mapa mundial en (por ejemplo) una matriz de 100x100 (10,000 clústeres) y cada una de las coordenadas se asigna a uno de esos clústeres.

Luego, puede detectar coordenadas muy cercanas seleccionando aquellas en el mismo cuadrado y cerrándose moderadamente al seleccionarlas en casillas adyacentes.

El tamaño de sus cuadrados (y, por lo tanto, el número de ellos) se decidirá por la precisión con la que necesite el clúster. Obviamente, si solo tienes una matriz de 2x2, podrías obtener un conjunto de coordenadas que están muy lejos.

Yo siempre tendrá los casos extremos, tales como dos puntos cercanos juntos, pero en diferentes grupos (uno más al norte de su grupo, el otro meridional de su), pero se podía ajustar el tamaño del clúster O post-proceso de los resultados en el lado del cliente.

+0

Con MS SQL Server 2008, tienen índices espaciales. ¿Tal vez uno de estos índices podría aprovecharse como el clusterID y luego agrupar los resultados en este índice clusterID? –

3

Hice algo similar para una aplicación geográfica en la que quería asegurarme de poder guardar en caché los conjuntos de puntos fácilmente. Mi código de geoanálisis se ve así:

def compute_chunk(latitude, longitude) 
    (floor_lon(longitude) * 0x1000) | floor_lat(latitude) 
end 

def floor_lon(longitude) 
    ((longitude + 180) * 10).to_i 
end 

def floor_lat(latitude) 
    ((latitude + 90) * 10).to_i 
end 

Todo se volvió realmente fácil a partir de ahí. Tenía un código para capturar todos los fragmentos desde un punto dado hasta un radio dado que se traduciría en un solo Memcache multiget (y algún código para rellenarlo cuando faltaba).

+0

Hola Dustin, no lo entiendo. ¿Es este algún tipo de código DB sql? o algún php o algo? No puedo ver cómo está relacionado con un db? –

+0

Mi aplicación está escrita en ruby ​​y este es el código de la biblioteca. Lo uso para calcular un hash para una latitud y longitud determinada y almacenarlo en una columna junto con el punto. Cada edición de punto recalcula el hash e invalida el caché de todos los puntos para un hash dado. – Dustin

2

Para movielandmarks.com Utilicé el código de clúster de Mike Purvis, uno de los autores de Beginning Google Maps Applications with PHP and AJAX. Construye árboles de clústeres/puntos para diferentes niveles de zoom usando PHP y MySQL, almacenándolos en la base de datos para que la recuperación sea muy rápida. Parte de esto puede serle útil incluso si está usando una base de datos diferente.

+0

Brian - no pude encontrar el código ??? :( –

+0

Publicando esto en caso de que alguien llegue aquí desde google como yo lo hice ... puedes encontrar el [thread mencionado arriba usando archive.org] (http://web.archive.org/web/20071011143643/http://forum) .sydphp.org /? a = topic & t = 1074) - incluye enlaces a archivos fuente. Parece que el trabajo pesado se realiza a través de php tho - quizás no es el mejor enfoque, pero vale la pena leerlo. – Chris

0

Creo que puede usar MSSQL's spatial data types. Si son similares a otros tipos de datos espaciales que conozco, almacenarán sus puntos en un árbol de rectángulos, y luego podrán ir a los rectángulos de resolución más baja para obtener clústeres implícitos.

+0

Actualmente estoy usando el tipo GEOGRAPHY con un índice espacial. Pero no estoy seguro de cómo usar eso para obtener un resultado agrupado/agrupado. ¿Tiene algún ejemplo de código SQL? –

+0

Me equivoqué al asumir que GEOGRAFÍA explícitamente le da un árbol. puede usar la sugerencia de Drew Hall, usando GEOGRAPHY.STDistance como la función de distancia necesaria para k-means. –

1

¿Por qué no probar varios enfoques?

  1. traducen en la biblioteca weka .NET CLI con IKVM.NET
  2. añadir una asamblea el resultado de su código y weka.dll (uso ILMerge) en su base de datos

hacer algunas pruebas, es decir. Ningún clúster específico funciona mejor que nadie.

+0

whoa dude. no tengo idea de lo que quiere decir :( –

+0

Hay muchos algoritmos para agrupar.Cada algoritmo tiene sus propios parámetros. Es completamente imposible dar la mejor respuesta. Pruebe algunos algoritmos de agrupamiento (k-means, fuzzy-c means etc.) de la biblioteca weka. Para no traducir todo el código, puede incrustar un ensamblado que incluya weka en su servidor de base de datos (sql 2008 acepta ensamblajes .NET). Por lo tanto, puedes probar múltiples variantes. – lmsasu

Cuestiones relacionadas