Holen Sie sich Polygone in der Nähe einer LAT, lange in MySQL
Frage
Kennt jemand eine Möglichkeit, alle Polygone in einer MySQL -DB innerhalb eines bestimmten Abstands von einem Punkt zu holen? Die tatsächliche Entfernung ist nicht so wichtig, da sie später für jedes gefundene Polygon berechnet wird, aber es wäre eine enorme Optimierung, diese Berechnung für die "nah" -Polygone zu machen.
Ich habe mir das MBR angesehen und enthält Funktionen, aber das Problem ist, dass einige der Polygone nicht in einem Begrenzungsbox enthalten sind, da sie sehr groß sind, aber einige ihrer Eckpunkte sind immer noch nahe.
Irgendwelche Vorschläge?
Lösung
Eine langsame Version (ohne räumliche Indizes):
SELECT *
FROM mytable
WHERE MBRIntersects(mypolygon, LineString(Point(@X - @distance, @Y - @distance), Point(@X + @distance, @Y + @distance))
Um die räumlichen Indizes zu nutzen, müssen Sie Ihre Tabelle so denmormieren, dass jeder Polygonscheitelpunkt in seiner eigenen Aufzeichnung gespeichert wird.
Dann erstellen Sie die SPATIAL INDEX
Auf dem Feld, das die Koordinaten der Scheitelpunkte enthält, und diese Abfrage einfach ausgeben:
SELECT DISTINCT polygon_id
FROM vertices
WHERE MBRContains(vertex, LineString(Point(@X - @distance, @Y - @distance), Point(@X + @distance, @Y + @distance))
Die Dinge werden viel einfacher, wenn Sie aufbewahren UTM
Koordinaten eher in Ihrer Datenbank als in Breitengrad und Längengrad.
Andere Tipps
Ich glaube nicht, dass es eine einzige Antwort darauf gibt. Im Allgemeinen geht es darum, wie Sie Ihre Daten organisieren, damit die räumliche Lokalität Ihrem Problem inhärent ist.
Die erste Idee, die in meinem Kopf eintaucht, wäre die Verwendung eines Rasters, zuordnen jeden Punkt einem Quadrat und wähle das Quadrat aus. Wenn wir über unendliche Gitter sprechen, dann verwenden Sie einen Hash-Wert des Platzes, dies würde Ihnen mehr Punkte als nötig geben (wo Sie Kollisionen haben), verringert aber trotzdem die Menge um ein paar. Natürlich ist dies nicht sofort auf Polygone anwendbar, sondern nur ein Brainstorming. Ein möglicher Ansatz, der zu viele Kollisionen zu viel Hashed-Werten zusammen sein könnte und alle Einträge ausgewählt haben, bei denen die Hashes und mit diesem Wert ungleich Null sind (nicht sicher, ob dies in MySQL möglich ist), möchten Sie vielleicht einen großen verwenden Menge an Bits.
Das Problem bei diesem Ansatz ist, dass wir sphärische Koordinaten sprechen (Lat, lange im Allgemeinen), die Singularitäten sind, da das Gitter -Quadrate schmaler wird, wenn Sie sich den Polen nähern. Die einfache Herangehensweise daran ist ... keine Punkte nahe an den Polen zu setzen ... :) :)
Erstellen Sie ein Begrenzungsfeld für alle Polygone und speichert diese Ergebnisse in der Datenbank optional viel schneller für komplexe Polygone). Sie können dann den Begrenzungsbox für jedes Polygon mit dem einen Punkt mit der gewünschten Größe vergleichen. Wählen Sie alle Polygone mit sich überschneidenden Begrenzungsboxen.