GIS (als Feld) hat es nicht allzu heiß gemacht, wenn es darum geht, sich wirklich mit der Oberfläche des Globus auseinanderzusetzen.
Zum Beispiel ist Ihr Problem nicht vollständig definiert. Anders als in 2D, wo wir wissen, dass die Kanten eines Polygons aus geraden Linien bestehen, was sind sie auf dem Globus? Bögen mit großen Kreisen, die den Abstand zwischen Scheitelpunkten minimieren, sind eine gute Wahl, aber nicht die einzige. Eine andere Wahl sind beispielsweise gerade Linien (die sich somit unter der Erdoberfläche bewegen). (Rhumb-Linien sind ebenfalls eine Wahl, aber möglicherweise eine dumme, insbesondere in der Nähe der Pole ...) Hier ist ein großartiger Link zu Problemen bei der Interpretation von WRT-Kanten: http://blog.opengeo.org/2010/08/10/shape-of -a-Polygon /
Ein weiteres großes Problem beim Projekt-zu-2d-dann-schneiden-Ansatz ist neben den anderen erwähnten Singularitäten, dass alle neu erstellten Schnittpunkte (an denen sich Polygonkanten kreuzen) fehl am Platz sind und von der verwendeten Projektion abhängen. (Ich glaube, hier kommt die Empfehlung für die Verdichtung her: Durch Hinzufügen einer Tonne Zwischenscheitelpunkte erhalten Sie einen reduzierten Fehler durch die Projektion der Mitte der Polygonkanten.)
Angenommen, Sie möchten nicht alle Kompromisse und Problemumgehungen bei der Projektion auf 2D eingehen und möchten selbst etwas durchdenken und codieren, dann habe ich ein wenig Prototyp-Code (und nur Prototyp-Code!) Für einen Kunden erstellt mit diesem.
Hier ist eine Skizze des Ansatzes. Sie müssen wissen, was ein Vektor ist und welche Bedeutung die Punkt- und Kreuzprodukte haben . (Vorsichtsmaßnahme: Wikipedia ist praktisch für schnelle Links, aber ausreichend, wenn es Ihre erste Einführung in die Themen ist. Ein gutes Tutorial für 3D-Grafiken hilft.)
- Stellen Sie einen Punkt auf der Kugel durch einen kartesischen 3D-Vektor dar. Der Punkt auf der Erdoberfläche ist der Punkt, an dem der Vektor, wenn Sie ihn zu einem unendlich langen Strahl ausdehnen, die Erdoberfläche schneiden würde.
- Stellen Sie große Kreise durch eine Ebene durch den Ursprung dar. (In 3D reicht ein einzelner Einheitsvektor aus, um eine Ebene durch den Ursprung zu definieren. Er ist die Normale zur Ebene.) Der Großkreis ist der Schnittpunkt der gesamten Ebene mit der Erdoberfläche.
- Sie können die Schnittpunkte zweier Großkreise finden, indem Sie ihre beiden Ebenen schneiden.
- Definieren Sie einen Bogen eines Großkreises durch zwei Punkte. Der Vektor, der die Großkreisnormalen definiert, ist das Kreuzprodukt der Vektoren der Start- und Endpunkte.
- Um festzustellen, ob ein Punkt, von dem wir wissen, dass er auf dem Großkreis liegt, innerhalb des Bogens liegt, erstellen Sie zwei Ebenen, sodass: Sie senkrecht zur Ebene des Großkreises stehen, eine den Startpunkt und die andere den Endpunkt enthält und sie sind einander zugewandt. Dann liegt der Punkt auf dem Bogen, wenn er im Inneren beider Ebenen liegt. (Zur Veranschaulichung: Sie haben das Lächeln eines Pac-Mannes erzeugt, als er auf den Bogen kaut. Wenn sich der Testpunkt zwischen seinen Kiefern befindet, liegt er auf dem Bogen, wie wir bereits wissen, dass er sich auf dem großen Kreis befindet.)
- Um festzustellen, ob sich zwei Bögen kreuzen: Suchen Sie die beiden Schnittpunkte der entsprechenden Großkreise und testen Sie jeden Punkt, um festzustellen, ob er in beiden Bögen liegt.
- Eine weniger mehrdeutige Definition: Ein Polygon ist eine Sammlung von Punkten, die jeweils durch Kanten verbunden sind, die aus Bögen großer Kreise bestehen. Die Punkte sind so angeordnet, dass, wenn Sie entlang der Erdoberfläche entlang der Kanten des Polygons gehen, das „Innere“ des Polygons zu Ihrer Linken liegt. Lassen wir zunächst komplexe Polygone (Inseln, Löcher und Selbstüberschneidungen) heraus.
- Anhand des Vorzeichens des Punktprodukts der entsprechenden Vektoren können Sie erkennen, ob sich ein Punkt auf der rechten oder linken Seite einer Ebene befindet. (Dies entspricht, wenn Sie sich um den Großkreis bewegen, ob der Punkt auf der Oberfläche der Kugel zu Ihrer Linken oder zu Ihrer Rechten liegt.)
- Ein genauer Test, um festzustellen, ob sich ein Punkt innerhalb eines Polygons befindet: Liegt er auf der linken Seite aller Kanten?
- Jetzt können wir testen, ob sich ein Punkt innerhalb eines Polygons befindet, und Kantenübergänge bestimmen: die Zutaten für Polygon-Polygon-Schnittpunkte! Der Rand dieses Kommentars ist zu klein, um einen vollständigen Algorithmus zu schreiben. Die grundlegenden Schritte bestehen jedoch darin, (a) alle Schnittpunkte zu finden und dann (b) Kanten zu gehen und abwechselnd das Polygon zu wechseln, auf dem Sie laufen, wenn Sie auf Schnittpunkte stoßen.
- Wenn alles oben Genannte funktioniert, sollten Sie über Indizierungsstrategien nachdenken, um es schneller zu machen, da die Umrisse des Punkt-in-Polygons I O (n) in der Anzahl der Kanten und der Polygonschnitt O (m * n) in der Anzahl von Kanten sind Kanten.
Pheew.
Dieser Ansatz bietet einige große Vorteile: Alle oben genannten Operationen beschränken sich nur auf Multiplikationen und Additionen. (Nach dem Konvertieren von Daten in diese Darstellung: z. B. Lat / Long-Koordinate erfordern einige Trigger, um einen kartesischen XYZ-Vektor zu erhalten.) Es gibt keine Singularitäten an den Polen oder im Koordinatensystem und nicht zu viele Sonderfälle, um die man sich Sorgen machen muss (Beispiel Sonderfall) : parallele überlappende Kanten).
Wenn man sich den Code ansieht, sieht es so aus, als ob das Spheres- Paket, das jemand anderes verlinkt hat, einem Teil dieses Ansatzes folgt, obwohl es auch ein bisschen halbherzig aussieht.
PostGIS verwendet möglicherweise auch einen ähnlichen Ansatz für den geografischen Datentyp , aber ich habe nicht unter die Haube geschaut. Ich weiß, dass sie zumindest für die räumliche Indizierung einen R-Baum über 3D-Kartesisch verwenden.
(Hinweis: Diese Antwort wurde lang genug, dass ich sie wahrscheinlich in einen Blog-Beitrag umwandeln werde ... Feedback / Kommentare sehr willkommen!)