2009-12-14 14 views
6

Qualcuno sa di un modo per recuperare tutti i poligoni in un db MySQL entro una determinata distanza da un punto? La distanza effettiva non è così importante dato che è calcolata per ogni poligono trovato più tardi, ma sarebbe un'enorme ottimizzazione fare semplicemente quel calcolo per i poligoni che sono "vicini".Ottieni poligoni vicino a lat, long in MySQL

Ho esaminato l'MBR e contiene funzioni, ma il problema è che alcuni poligoni non sono contenuti all'interno di un riquadro di delimitazione disegnato attorno al punto poiché sono molto grandi, ma alcuni dei loro vertici sono ancora vicini.

Qualche suggerimento?

risposta

3

una versione lenta (senza indici spaziali):

SELECT * 
FROM mytable 
WHERE MBRIntersects(mypolygon, LineString(Point(@X - @distance, @Y - @distance), Point(@X + @distance, @Y + @distance)) 

Per fare uso di indici spaziali, è necessario denormalizzare vostro tavolo in modo tale che ogni vertice del poligono viene memorizzato nel proprio record.

quindi creare la SPATIAL INDEX sul campo che contiene le coordinate dei vertici e solo emettere questo query:

SELECT DISTINCT polygon_id 
FROM vertices 
WHERE MBRContains(vertex, LineString(Point(@X - @distance, @Y - @distance), Point(@X + @distance, @Y + @distance)) 

Le cose saranno molto più facile se si memorizzano UTM coordinate nel database, piuttosto che la latitudine e la longitudine.

+0

Grazie mille! Per quelli con problemi simili: ho finito per utilizzare l'MBR di un cerchio disegnato intorno al punto di interesse e recuperare tutti i poligoni i cui MBR intersecavano i cerchi MBR. – Gren

+0

Puoi dirmi cosa significa "distanza"? È in miglia, chilometri o metri? –

+1

@ShaishavJogani: '@ distance' è una variabile che contiene la distanza che stai cercando all'interno. Può essere in miglia o km o metri o qualsiasi altra unità di distanza, purché si memorizzino le coordinate nelle stesse unità. – Quassnoi

1

Non credo che ci sia una sola risposta a questo. In genere si tratta di come organizzare i dati in modo che utilizzi la località spaziale inerente al problema.

La prima idea che mi viene in mente sarebbe quella di utilizzare una griglia, assegnare ogni punto a un quadrato e controllare selezionare il quadrato in cui si trova il punto e quelli che lo circondano. Se stiamo parlando di griglie infinite, usa un valore hash del quadrato, questo ti darebbe più punti del necessario (dove hai collisioni), ma ridurrai comunque l'ammontare di un mazzo. Ovviamente questo non è immediatamente applicabile ai poligoni, è solo un brainstorming. Un possibile approccio che potrebbe dare troppe collisioni sarebbe quello di OR tutti i valori di hash insieme e selezionare tutte le voci in cui l'hash di hash con quel valore è diverso da zero (non è sicuro se questo è possibile in MySQL), potresti voler usare un grande quantità di bit però.

Il problema di questo approccio è, assumendo stiamo parlando coordinate sferiche (lat, fa lungo in genere) sono le singolarità, come la griglia 'piazze' crescere più stretta come ci si avvicina ai poli. L'approccio semplice a questo è ... non mettere nessun punto vicino ai poli ... :)

0

Creare un rettangolo di selezione per tutti i poligoni e (se si memorizzano questi risultati nel database, questo diventerà un molto più veloce per i poligoni complessi). È quindi possibile confrontare il riquadro di delimitazione per ciascun poligono con quello attorno al punto della dimensione desiderata. Seleziona tutti i poligoni che hanno caselle di delimitazione intersecanti.

Problemi correlati