Domanda

Qualcuno sa un modo per recuperare tutti i poligoni in un DB MySQL a una determinata distanza da un punto? La distanza effettiva non è così importante poiché viene calcolata per ciascun poligono trovato in seguito, ma sarebbe un'enorme ottimizzazione fare quel calcolo per i poligoni che sono "vicini".

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

Eventuali suggerimenti?

È stato utile?

Soluzione

Una versione lenta (senza indici spaziali):

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

Per utilizzare gli indici spaziali, è necessario denormalizzare la tabella in modo che ogni vertice poligono sia archiviato nel proprio record.

Quindi crea il SPATIAL INDEX sul campo che contiene le coordinate dei vertici e emette questa domanda:

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ù facili se memorizzi UTM coordina nel database piuttosto che latitudine e longitudine.

Altri suggerimenti

Non credo che ci sia una sola risposta a questo. È generalmente una questione di come organizzare i tuoi dati in modo che utilizzino la località spaziale inerente al tuo problema.

La prima idea che mi viene in testa sarebbe quella di usare una griglia, assegnare ogni punto in un quadrato e controllare selezionare il quadrato in cui si trova il punto e quelli che lo circondano. Se stiamo parlando di griglie infinite, allora usa un valore di hash della piazza, questo ti darebbe più punti del necessario (dove hai collisioni), ma ridurrà comunque l'importo di un mucchio. Naturalmente questo non è immediatamente applicabile ai poligoni, è solo un brainstorm. Un possibile approccio che potrebbe produrre troppe collisioni sarebbero o tutti i valori di hash e selezionare tutte le voci in cui gli hash e si sono messi con quel valore non zero (non sono sicuro che ciò sia possibile in MySQL), potresti voler usare un grande quantità di bit però.

Il problema con questo approccio è, supponendo che stiamo parlando di coordinate sferiche (lat, a lungo generalmente) sono le singolarità, mentre i "quadrati" della griglia si riducono mentre ti avvicini ai poli. L'approccio facile a questo è ... non mettere alcun punto vicino ai pali ... :)

Crea una scatola di delimitazione per tutti i poligoni e (opzionalmente memorizzazione di questi risultati nel database lo renderà molto più veloce per i poligoni complessi). È quindi possibile confrontare la scatola di delimitazione per ciascun poligono con quello round del punto alla dimensione desiderata. Seleziona tutti i poligoni con caselle di delimitazione intersecanti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top