2012-09-24 20 views
10

Me gustaría conocer su opinión. Creé una aplicación, donde los usuarios crean rutas y rastreamos esta ruta y guardamos puntos de la base de datos. Luego, la aplicación hace comparaciones de los puntos de paso de los usuarios.¿La manera más eficiente de guardar puntos de paso y hacer comparaciones?

Actualmente, utilizo un servidor MSSQL, usando dos tablas, una para Rutas y la otra para almacenar puntos de ruta (con tipo de datos espaciales). Las comparaciones se realizan en un procedimiento almacenado utilizando las funciones geográficas de SQL Server, como st_distance ...

He investigado otras opciones. Uno que implementé es con Oracle 11g usando objetos. Guardo todos los datos en una sola Tabla de objetos y los puntos de ruta se almacenan en una variedad de un tipo con atributos de latitud y longitud. De esta manera es muy eficiente guardar y recuperar datos, pero se complica un poco al comparar.

Estoy buscando una solución NoSQL, algún algoritmo o método para hacerlo de manera eficiente. ¿Qué piensas?

+0

¿Te ha respondido mi pregunta? –

+0

Sí, ayudó, ¡gracias! Creo que la solución no está en la forma en que almaceno la información, sino en el algoritmo para comparar puntos de referencia. Para hacer esto, primero tengo que reducir la cantidad de puntos de referencia a los más relevantes y uniformes que pueden coincidir con otras rutas y luego hacer una comparación (como dice tu respuesta). Realmente no lo he probado, si resulta con un mejor rendimiento, publicaré mi solución. –

Respuesta

15

El uso de funciones de base de datos como STDistance para todos los n registros es subóptimo. Su sobrecarga de la CPU aumentará exponencialmente.

Lo que debe hacer es verificar la cantidad de puntos dentro de un rectángulo alrededor del epicentro actual que está buscando. Aquí hay un ejemplo (en MySQL):

SELECT * FROM `points` 
    WHERE `latitude` >= X1 AND `latitude` <= X2 
    AND `longitude` >= Y1 AND `longitude` <= Y2 

Esto proporciona una reducida superset de puntos que entonces debe reducirse aún más mediante el cálculo de la distancia ortodrómica (con respecto a la curvatura de la Tierra), utilizando el Haversine formula.

No se olvide para establecer un composite index en latitude y longitude.

Orthodromic distance

Aquí está en PHP:

<?php 
function haversine($latitude1, $longitude1, 
        $latitude2, $longitude2, $unit = 'Mi') { 
    $theta = $longitude1 - $longitude2; 
    $distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) + 
    (cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta))); 
    $distance = acos($distance); 
    $distance = rad2deg($distance); 
    $distance = $distance * 60 * 1.1515; 
    switch ($unit) { 
    case 'Mi': 
     break; 
    case 'Km': 
     $distance = $distance * 1.609344; 
    } 
    return (round($distance, 2)); 
} 
?> 

Para recapitular:

Aquí es una imagen de ejemplo que ilustra lo que debe hacer:

Example with CN Tower

La primera búsqueda implicaría una búsqueda de colisión de cuadro delimitador (ejemplo de MySQL) para determinar el superset, excluyendo los puntos rojos. El segundo proceso de verificación implicaría calcular si los puntos están dentro de una distancia ortodrómica adecuada con la fórmula de Haversine (ejemplo de PHP) y tomando un subset (compuesto por los puntos negros).

+0

¡Gracias por su respuesta, voy a pensar en una solución para implementar esta idea!Tengo una preocupación con esta solución, creo que funciona bien para puntos que están muy cerca, cuando hablamos de distancias más grandes, los puntos se extienden en un área más grande, se complica porque no funciona para mí hacer un rectángulo muy grande, los criterios de coincidencia entre las rutas deben ser más precisos. ¡Gracias! –

+0

No hay problema, buena suerte con su algoritmo. –

Cuestiones relacionadas