2013-09-25 15 views
11

Ho una serie di punti che rappresentano una strada (linea nera) e punti, che rappresentano i luoghi sulla mappa (punti rossi). Voglio trovare tutti i punti vicino alla strada specificata, ordinati per distanza. Devo anche avere la possibilità di specificare la distanza massima (aree blu e verde). Ecco un semplice esempio:Trova punti vicino LineString in mongodb ordinati per distanza

enter image description here

ho pensato di usare l'operatore $near ma accetta solo Point come input, non LineString.

Come mongodb può gestire questo tipo di query?

+0

Non credo che sia possibile. Tuttavia, potresti "allargare" la strada e usare '$ polygon' o usare' $ near' e fare il resto lato client o usare una serie di '$ near' con sfere sovrapposte. – mnemosyn

+0

"Ingrandisci" la strada e usa $ poligono? – icaro56

+0

Ciao, hai trovato la soluzione? –

risposta

7

Come già accennato, Mongo attualmente non supporta altro che lo Point. Ti sei imbattuto nel concetto di un pugile in rotta? 1 Era molto popolare qualche anno fa su Google Maps. Data la linea che hai disegnato, trova le fermate che si trovano entro dist(x). È stato creato creando una serie di riquadri di delimitazione attorno a ciascun punto della linea e cercando i punti che rientrano nel secchio.

Mi sono imbattuto nella tua domanda dopo aver appena realizzato che Mongo funziona solo con i punti, il che è ragionevole presumo.

Ho già alcune opzioni su come farlo (si espandono su ciò che @mnemosyn dice nel commento). Con il set di dati su cui sto lavorando, è tutto sul lato client, quindi potrei usare il routeboxer, ma vorrei implementarlo sul lato server per motivi di prestazioni. Qui sono i miei suggerimenti:

  1. pausa il LineString giù nella sua individuale coordinare gruppi e query per $near con ciascuno di quelli, combinare i risultati ed estrarre un insieme unico. Esistono algoritmi per semplificare una linea complessa, riducendo il numero di punti, ma uno semplice è facile da scrivere.

  2. fare lo stesso come sopra, ma come procedura/funzione memorizzata. Non ho giocato con le funzioni memorizzate di Mongo, e non so quanto bene funzionino con i driver, ma potrebbe essere più veloce della prima opzione di cui sopra dato che non dovrai fare roundtrip e, a seconda della macchina, che la tua istanza (o) di Mongo è (sono) ospitata, i calcoli potrebbero essere più rapidi di microsecondi.

  3. Implementare l'approccio routeboxer sul lato server (è stato eseguito in PHP), quindi utilizzare uno dei due precedenti per trovare gli arresti corrispondenti a $within. A parte il fatto che il metodo routeboxer restituisce i rettangoli, sarebbe possibile unire tutti questi rettangoli in un poligono che copre il percorso, e basta fare uno $within su quello. (Cosa suggerito da @mnemosyn).

  4. EDIT: ho pensato a questo, ma se ne dimenticò, ma potrebbe essere possibile ottenere alcuni di quanto sopra utilizzando il framework di aggregazione.

E 'qualcosa che ho intenzione di essere al lavoro su presto (si spera), aprirò-source mio risultato (s) in base al quale io alla fine per andare con.

MODIFICA: Devo dire però che 1 e 2 hanno il difetto che se si hanno 2 punti in una linea che dicono 2 km di distanza e si desidera che i punti siano entro 1.A 8 km dalla tua linea, ovviamente perderai tutti i punti tra quella parte della tua linea. La soluzione è iniettare punti sulla linea quando la si semplifica (lo so, batte l'obiettivo di ridurre i punti quando si aggiungono di nuovi).

Il difetto con 3 è che non sarà sempre preciso poiché alcuni punti all'interno del poligono avranno una distanza maggiore del limite, sebbene la differenza non sia una percentuale significativa del limite.

[1]google maps utils routeboxer

0

Come hai detto di Mongo $ vicino funziona solo su punti non linee come il punto centrale se si ribalta il vostro premessa da punti di trovare vicino alla linea per trovare la linea in prossimità del punto allora è possibile utilizzare i punti come il centro e la linea come l'obiettivo

questa è la differenza tra

foreach line find points near it 

e

foreach point find line near it 

se si dispone di un gran numero di punti per controllare È possibile combinare questo con la risposta di nevi_me per ridurre l'elenco dei punti che hanno bisogno di controllo a un sottoinsieme molto più piccolo

Problemi correlati