So erstellen Sie Linestrings mit einem bestimmten Winkel und einer bestimmten Länge, die an einem Punkt befestigt sind

8

Ich möchte Linestrings mit einem bestimmten Winkel (z. B. 160 °) und einer bestimmten Länge (z. B. 2 m) erstellen, die an einer Reihe von Punkten eines anderen Linestrings befestigt sind. Daher möchte ich die ST_DumpPoints-Funktion verwenden, um die Punkte zu finden und die erstellten Linestrings an sie zu binden. Gibt es eine Möglichkeit, einen Winkel (α) während der Linestring-Erstellung zu deklarieren? Hier ist ein Beispielbild:

Geben Sie hier die Bildbeschreibung ein

Ich möchte die blauen Linien erstellen.

BEARBEITEN

Der Winkel (α2) im Bild ist nicht wirklich vorbildlich. Sondern ein Azimut von 160 ° (wie α1).

AKTUALISIEREN

Die Antwort von Evil Genius half mir, die maximale Breite eines Polygons mit einem bestimmten Aspekt zu berechnen.

Stefan
quelle

Antworten:

11

Sie können dies auf verschiedene Arten erreichen, je nachdem, welche Art von Ausgabe Sie wünschen, aber das Konzept ist das gleiche. Es ist im Allgemeinen einfacher, eine einfache Drehung gefolgt von einer Übersetzung durchzuführen, als zu versuchen, die Koordinaten in einem einzigen Schritt zu berechnen.

In diesem Fall sind die grundlegenden Schritte:

  • Erstellen Sie am Ursprung eine Linie mit der gewünschten Länge (0,0). Diese Linie sollte entlang der Achse verlaufen, von der aus Sie Ihren Winkel messen möchten, und ihre Mitte am Ursprung haben.
  • Drehen Sie die Linie um den Ursprung.
  • Verschieben Sie die Linie um die Koordinaten des Punktes, auf den sie zentriert werden soll.

In der folgenden PostGIS-Ansicht werden die Zeilen aus Ihrem Beispielszenario erstellt. Einige Dinge werden angenommen:

  • Die Geometriespalte wird aufgerufen shape
  • Der Winkel wird von der x-Achse gemessen. Ihre Beispielzeichnung war etwas verwirrend, da Sie zum ersten Mal 40 Grad erwähnt haben, eine gepunktete vertikale Linie gezeichnet haben, dann aber gesagt haben, dass sie bei 160 Grad liegen sollte. Ich habe das so interpretiert, dass Sie tatsächlich von der x-Achse aus messen möchten.
  • Die Daten werden in denselben Einheiten projiziert, mit denen Sie messen möchten (dh Meter).

    CREATE OR REPLACE VIEW <viewname> AS
    WITH vertices AS
    (SELECT 
          objectid, 
          (ST_DumpPoints(shape)).path[1] AS v_id, 
          (ST_DumpPoints(shape)).geom AS vertex
    FROM <source_data>
    )
    SELECT
        objectid,
        v_id,
        ST_SetSRID(ST_Translate(ST_Rotate(ST_MakeLine(ST_MakePoint( 1.0,0.0), 
                                                      ST_MakePoint(-1.0,0.0)),
                                          radians(40)), ST_X(vertex), ST_Y(Vertex)),
                                          ST_SRID(vertex)) AS newline
    FROM vertices

Um herauszufinden, was mit dieser letzten Zeile tatsächlich los ist, beginnend mit dem Innersten: ST_SetSRID(ST_Translate(ST_Rotate(ST_MakeLine(ST_MakePoint( 0,1.0), ST_MakePoint(0,-1.0)), radians(40)), ST_X(vertex), ST_Y(Vertex)), ST_SRID(vertex)) AS newline

  • ST_MakePoint(1.0,0.0)und ST_MakePoint(-1.0,0.0): Erstellen Sie die Endpunkte für eine horizontale Linie, die unserer gewünschten Länge entspricht und auf dem Ursprung zentriert ist.
  • ST_MakeLine(...): Verwenden Sie unsere neu erstellten Endpunkte, um eine Linie zu erstellen.
  • ST_Rotate(..., radians(40)): Drehen Sie diese neue Linie um den Ursprung.
  • ST_Translate(..., ST_X(vertex), ST_Y(vertex)): Zentrieren Sie die gedrehte Linie auf unseren Referenzpunkt (Eingabepunkt).
  • ST_SetSRID(..., ST_SRID(vertex)): Geben Sie der neuen Linie dieselbe SRID wie die Eingabegeometrie.

Wenn Sie PostGIS 2.0 verwenden, können Sie dies vereinfachen, da Sie einen anderen Ursprung für angeben können ST_Rotate. Wenn Sie sich auf der Grundlage der Neigung der Linie in einen Winkel drehen möchten, müssen Sie diesen zuerst berechnen und zum Drehwinkel hinzufügen.

Wenn die Daten nicht in denselben Einheiten projiziert werden, in denen Sie messen möchten, können Sie dennoch etwas Ähnliches tun, benötigen jedoch einen zusätzlichen Schritt:

  • Erstellen Sie eine Linie (projiziert in etwas, das das verwendet, in dem Sie messen möchten)
  • Drehen
  • Projizieren Sie auf Ihre Zielprojektion
  • Zum Zielpunkt übersetzen

Bearbeiten

Ich verstehe jetzt, was du mit dem Winkel meinst. Im Wesentlichen möchten Sie eine Drehung von der Y-Achse im Uhrzeigersinn (0 ist oben, 90 ist rechts, 180 ist unten usw.).

Sie müssen die radiansFunktion weiterhin verwenden, da Sie ST_Rotateden Winkel im Bogenmaß erwarten. Sie sollten in der Lage sein, den richtigen Winkel mit zwei kleinen Änderungen zu erhalten:

  • Beginnen Sie mit einer vertikalen Linie (verwenden Sie ST_MakePoint(0.0,1.0)und ST_MakePoint(0.0,-1.0))
  • Multiplizieren Sie Ihren Winkel mit -1. Dadurch wird es negativ und ST_rotateim Uhrzeigersinn gedreht.radians(<angle> * -1)
Böses Genie
quelle
Du bist ein böses Genie! Vielen Dank. Es funktioniert perfekt, stellt aber den richtigen Winkel ein. Ich arbeite mit Winkeln (in einer Spalte gespeichert), die wie eine Exposition oder ein Aspekt (0 bis 360 Grad) sind. Ein Aspekt von 200 ° zum Beispiel (wie Georichtung SSW): Wenn ich die Linien zeichne, haben sie nicht den richtigen Winkel. Bei Verwendung von Grad () ist die Georichtung wie bei SSE und bei Verwendung von Bogenmaß () wie bei SW.
Stefan
@StefanB. Ich bin froh, dass es hilfreich war! Ich habe meine Antwort (ganz unten) bearbeitet, um zu zeigen, wie Sie den gewünschten Winkel erreichen können.
Evil Genius
Es klappt. Brilliante Idee!
Stefan