MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Trouver des points près de LineString dans mongodb triés par distance

Comme vous l'avez mentionné, Mongo ne supporte actuellement rien d'autre que Point . Avez-vous rencontré le concept d'un boxeur de route? 1 Il était très populaire il y a quelques années sur Google Maps. Étant donné la ligne que vous avez tracée, recherchez les arrêts situés dans dist(x) . Cela a été fait en créant une série de cadres de délimitation autour de chaque point de la ligne et en recherchant les points qui se trouvent dans le seau.

Je suis tombé sur votre question après avoir réalisé que Mongo ne fonctionnait qu'avec des points, ce qui est raisonnable, je suppose.

J'ai déjà quelques options sur la façon de le faire (elles développent ce que @mnemosyn dit dans le commentaire). Avec l'ensemble de données sur lequel je travaille, tout est côté client, donc je pourrais utiliser le routeboxer, mais j'aimerais l'implémenter côté serveur pour des raisons de performances. Voici mes suggestions :

  1. casser le LineString dans ses ensembles de coordonnées individuels et interrogez $near en utilisant chacun d'eux, combinez les résultats et extrayez un ensemble unique. Il existe des algorithmes pour simplifier une ligne complexe, en réduisant le nombre de points, mais un simple est facile à écrire.

  2. faire la même chose que ci-dessus, mais en tant que procédure/fonction stockée. Je n'ai pas joué avec les fonctions stockées de Mongo, et je ne sais pas dans quelle mesure elles fonctionnent avec les pilotes, mais cela pourrait être plus rapide que la première option ci-dessus car vous n'aurez pas à faire d'allers-retours, et selon la machine qui votre (vos) instance(s) de Mongo est (sont) hébergée(s), les calculs pourraient être plus rapides de quelques microsecondes.

  3. Implémentez l'approche routeboxer côté serveur (cela a été fait en PHP), puis utilisez l'un des 2 ci-dessus pour trouver des arrêts qui sont $within les boîtes englobantes résultantes. Heck étant donné que la méthode routeboxer renvoie des rectangles, il serait possible de fusionner tous ces rectangles en un seul polygone couvrant votre itinéraire, et de faire simplement un $within sur ça. (Ce que @mnemosyn a suggéré).

  4. MODIF : J'y ai pensé mais je l'ai oublié, mais il pourrait être possible d'atteindre certains des objectifs ci-dessus en utilisant le cadre d'agrégation.

C'est quelque chose sur lequel je vais travailler bientôt (j'espère), je vais ouvrir le(s) résultat(s) en fonction de ce que je vais finir par faire.

MODIF : Je dois mentionner cependant que 1 et 2 ont le défaut que si vous avez 2 points sur une ligne distants de 2 km, et que vous voulez des points situés à moins de 1,8 km de votre ligne, vous manquerez évidemment tous les points entre cette partie de votre ligne. La solution consiste à injecter des points sur votre ligne lors de la simplification (je sais, bat l'objectif de réduire les points lors de l'ajout de nouveaux).

Le défaut avec 3 est alors qu'il ne sera pas toujours précis car certains points de votre polygone sont susceptibles d'avoir une distance supérieure à votre limite, bien que la différence ne représente pas un pourcentage significatif de votre limite.

[1 ] google maps utils routeboxer