sql >> Base de Datos >  >> NoSQL >> MongoDB

Encuentre puntos cerca de LineString en mongodb ordenados por distancia

Como mencionaste, Mongo actualmente no admite nada más que Point . ¿Te has encontrado con el concepto de un boxeador de ruta? 1 Fue muy popular hace unos años en Google Maps. Dada la línea que ha dibujado, busque paradas que estén dentro de dist(x) . Se hizo creando una serie de cuadros delimitadores alrededor de cada punto de la línea y buscando los puntos que caen dentro del cubo.

Me topé con tu pregunta después de darme cuenta de que Mongo solo funciona con puntos, lo cual es razonable, supongo.

Ya tengo algunas opciones de cómo hacerlo (expanden lo que dice @mnemosyn en el comentario). Con el conjunto de datos en el que estoy trabajando, todo está en el lado del cliente, por lo que podría usar el enrutador, pero me gustaría implementarlo en el lado del servidor por razones de rendimiento. Estas son mis sugerencias:

  1. romper el LineString hacia abajo en sus conjuntos de coordenadas individuales, y consulta por $near usando cada uno de ellos, combine los resultados y extraiga un conjunto único. Existen algoritmos para simplificar una línea compleja, al reducir el número de puntos, pero uno simple es fácil de escribir.

  2. haga lo mismo que arriba, pero como un procedimiento/función almacenados. No he jugado con las funciones almacenadas de Mongo, y no sé qué tan bien funcionan con los controladores, pero esto podría ser más rápido que la primera opción anterior, ya que no tendrá que hacer viajes de ida y vuelta, y dependiendo de la máquina que su(s) instancia(s) de Mongo está(n) alojada(s), los cálculos podrían ser más rápidos en microsegundos.

  3. Implemente el enfoque de routeboxer en el lado del servidor (se ha hecho en PHP), y luego use cualquiera de los 2 anteriores para encontrar paradas que estén $within los cuadros delimitadores resultantes. Diablos, dado que el método routeboxer devuelve rectángulos, sería posible fusionar todos estos rectángulos en un polígono que cubra su ruta, y simplemente hacer un $within en ese. (Lo que sugirió @mnemosyn).

  4. EDITAR: Pensé en esto pero lo olvidé, pero podría ser posible lograr algo de lo anterior usando el marco de agregación.

Es algo en lo que voy a estar trabajando pronto (con suerte), abriré mis resultados en función de lo que termine eligiendo.

EDITAR: Sin embargo, debo mencionar que 1 y 2 tienen el defecto de que si tiene 2 puntos en una línea que están separados por 2 km y quiere puntos que están dentro de 1,8 km de su línea, obviamente perderá todos los puntos entre esa parte de tu línea. La solución es inyectar puntos en su línea al simplificarla (lo sé, supera el objetivo de reducir puntos al volver a agregar nuevos).

El problema con 3 es que no siempre será preciso, ya que es probable que algunos puntos dentro de su polígono tengan una distancia mayor que su límite, aunque la diferencia no sería un porcentaje significativo de su límite.

[1 ] google maps utils routeboxer