Ich habe mir kürzlich Webseiten von Fluggesellschaften angesehen, auf denen deren Routen von einer bestimmten Stadt zu allen anderen Städten, die sie bedienen, angezeigt werden. Ich möchte in der Lage sein, ähnlich gekrümmte Routen zwischen Punkten zu erstellen. Hat jemand Skripte oder Funktionen erstellt, die die in diesem Beispiel gezeigten gekrümmten Bögen erzeugen ?
Gibt es in PostGIS eine Implementierung von ST_MakeLine, mit der Sie die Menge der Kurve angeben können, die beim Verbinden von 2 Punkten verwendet werden soll?
Während ich derzeit PostGIS und QGIS verwende, würde ich mich über weitere Softwareoptionen freuen, die möglicherweise das gleiche Erscheinungsbild erzielen.
Antworten:
Wenn Sie große Kreise erstellen, können Sie den gewünschten Effekt erzielen.
Vielleicht wird so etwas auf http://lists.osgeo.org/pipermail/postgis-users/2008-February/018620.html diskutiert
Aktualisieren:
Ich habe diese Idee in "Visualisierung globaler Verbindungen" weiterverfolgt . Es handelt sich um eine rein PostGIS-basierte Lösung, bei der zur Erstellung von Bögen eine Neuprojektion verwendet wird.
(Die CRS-Definition für 953027 finden Sie hier: http://spatialreference.org/ref/esri/53027/ )
quelle
Das Problem besteht darin, herauszufinden, wie stark die Bögen gebogen werden müssen, um ihre visuelle Auflösung zu verbessern.
Hier ist eine Lösung (unter den vielen möglichen). Betrachten wir alle Bögen, die von einem gemeinsamen Ursprung ausgehen. Die Bögen werden hier am meisten überfüllt. Um sie am besten zu trennen, ordnen wir sie so an, dass sie sich in gleichmäßigen Winkeln ausbreiten . Es ist ein Problem, wenn wir gerade Liniensegmente vom Ursprung zu den Zielen zeichnen, da es normalerweise Zielgruppen in verschiedenen Richtungen gibt. Lassen Sie uns unsere Freiheit nutzen, um die Bögen zu biegen, um die Abweichungswinkel so gleichmäßig wie möglich zu verteilen.
Zur Vereinfachung verwenden wir Kreisbögen auf der Karte. Ein natürliches Maß für die "Biegung" in einem Bogen von Punkt y zu Punkt x ist die Differenz zwischen seiner Peilung bei y und der Peilung direkt von y zu x . Ein solcher Bogen ist ein Kreisabschnitt, auf dem y und x liegen; Die Elementargeometrie zeigt, dass der Biegewinkel die Hälfte des im Bogen enthaltenen Winkels beträgt.
Um einen Algorithmus zu beschreiben, brauchen wir etwas mehr Notation. Sei y der Ursprungspunkt (wie auf der Karte projiziert) und sei x_1 , x_2 , ..., x_n der Zielpunkt. Definieren Sie a_i als Peilung von y nach x_i , i = 1, 2, ..., n .
Als ersten Schritt nehmen wir an, dass die Lager (alle zwischen 0 und 360 Grad) in aufsteigender Reihenfolge sind: Dies erfordert, dass wir die Lager berechnen und sie dann sortieren; beides sind unkomplizierte aufgaben.
Idealerweise möchten wir, dass die Peilung der Bögen 360 / n , 2 * 360 / n usw. entspricht, bezogen auf ein Startlager. Die Differenzen zwischen den gewünschten Lagern und den tatsächlichen Lagern betragen daher i * 360 / n - a_i zuzüglich des Startlagers a0 . Die größte Differenz ist das Maximum dieser n Differenzen und die kleinste Differenz ist ihr Minimum. Stellen wir a0 so ein , dass es auf halbem Weg zwischen dem Maximum und dem Minimum liegt. Dies ist ein guter Kandidat für das Startlager, da es das maximale Ausmaß der auftretenden Biegung minimiert . Folglich definieren
b_i = i * 360 / n - a0 - a_i:
Dies ist das Biegen zu verwenden .
Es ist eine Frage der Elementargeometrie, einen Kreisbogen von y nach x zu zeichnen, der einen Winkel von 2 b_i einschließt. Daher überspringe ich die Details und gehe direkt zu einem Beispiel. Hier finden Sie Abbildungen der Lösungen für 64, 16 und 4 zufällige Punkte in einer rechteckigen Karte
Wie Sie sehen können, scheinen die Lösungen zu erhalten schöner als die Anzahl der Zielpunkte erhöht. Die Lösung für n = 4 zeigt deutlich, wie die Lager gleichmäßig verteilt sind, denn in diesem Fall beträgt der Abstand 360/4 = 90 Grad und offensichtlich wird dieser Abstand genau erreicht.
Diese Lösung ist nicht perfekt: Sie können wahrscheinlich mehrere Bögen identifizieren, die manuell optimiert werden könnten, um die Grafik zu verbessern. Aber es wird keine schreckliche Arbeit leisten und scheint ein wirklich guter Anfang zu sein.
Der Algorithmus hat auch den Vorteil, dass er einfach ist: Der komplizierteste Teil besteht darin, die Ziele nach ihrer Peilung zu sortieren.
Codierung
Ich kenne PostGIS nicht, aber vielleicht kann der Code, mit dem ich die Beispiele gezeichnet habe, als Leitfaden für die Implementierung dieses Algorithmus in PostGIS (oder einem anderen GIS) dienen.
Betrachten Sie Folgendes als Pseudocode (aber Mathematica führt es aus :-). (Wenn diese Site TeX unterstützt, wie es Mathe, Statistik und TCS tun, könnte ich dies viel besser lesbar machen.) Die Notation beinhaltet:
Der ausführbare Teil des Codes ist erfreulicherweise kurz - weniger als 20 Zeilen -, da über die Hälfte davon entweder deklarativer Overhead oder Kommentare sind.
Zeichnen Sie eine Karte
z
ist eine Liste von Zielen undy
ist der Ursprung.Erstellen Sie einen Kreisbogen von Punkt
x
zu Punkt,y
beginnend in einem Winkel\[Beta]
relativ zur x -> y-Peilung.Berechnen Sie die Peilungen von einem Ursprung zu einer Liste von Punkten.
Berechnen Sie den Mittenbereich der Reste eines Lagersatzes.
x
ist eine Liste der Lager in sortierter Reihenfolge. Idealerweise x [[i]] ~ 2 [Pi] i / n.quelle
Versuchen Sie es mit ST_CurveToLine
So etwas wie zum Beispiel:
Sie können dies visualisieren, indem Sie die Abfrage in das Textfeld kopieren und auf Map1 unter http://www.postgisonline.org/map.php klicken
quelle
Ich würde denken, Sie möchten nur Ihre eigene Polylinie mit etwas Vektormathematik rollen, http://en.wikipedia.org/wiki/B%C3%A9zier_curve , oder wenn Ihr GIS eine ICurve- Oberfläche hat.
quelle
Am Ende habe ich dies ausprobiert, um mithilfe der ST_CurveToLine-Funktion eine Reihe von "Zweipunkt" -Linestrings zu kurven, wie von @Nicklas Avén vorgeschlagen.
Ich habe die folgenden 3 Koordinatensätze an die Funktion ST_OffsetCurve übergeben:
Ich habe die Funktion ST_OffsetCurve verwendet, um den Versatz - 1/10 der Länge der ursprünglichen Linie in meinem Beispiel zu berechnen.
Hier ist die SQL, mit der ich die gekrümmten Linien aus den ursprünglichen geraden Linien generiert habe:
quelle