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?

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top