Berechnen der Ausrichtung jeder Seite des Polygons mit ArcPy?

9

Ich möchte die Ausrichtung jeder Linie in einem Polygon untersuchen, damit ich ihre Sonneneinstrahlung berechnen kann. Jedes Polygon repräsentiert ein Gebäude und hat eine zugehörige Höhe. Im Moment möchte ich nur die Ausrichtung betrachten und später auf Schattierungsprobleme eingehen.

Ein Ansatz, den ich dachte, war, das Polygon in Linien aufzuteilen und die Ausrichtung jeder Linie zu berechnen, aber die Schwierigkeit besteht darin, dass ich dann die Außenseite dieser Linie identifizieren muss. Obwohl die meisten Polygone einfache vierseitige Figuren mit geraden Linien sind, gibt es eine kleine Zahl, bei der dies nicht der Fall ist (ein Problem, das ich nur betrachten möchte, aber noch nicht lösen muss).

Ich bin mit Python vertraut und habe vor, dies alles über ein Skript zu tun.

djq
quelle
1
Machen Sie die Antworten auf diese Frage Hilfe: gis.stackexchange.com/questions/1886/…
Sean
@ Sean - danke, ja das hilft im Allgemeinen. Ich bin nicht mit den spezifischen ArcGIS-Befehlen vertraut, die dazu verwendet werden können. Auch das Problem, zu wissen, wie die Innen- / Außenseite der Linie in einem Polygon aussieht, bleibt bestehen.
DJQ
Wenn Sie "Orientierung" sagen, haben Sie es für mich nicht gut genug definiert - wie ist zum Beispiel die Orientierung eines perfekten Sechsecks?
Dan S.
@ Dan S. Ich habe gerade meine Antwort bearbeitet, um die Ausrichtung jeder Linie im Polygon aufzunehmen.
DJQ
Entschuldigung, die Antwortenden - ich habe es gestern nicht geschafft, das Kopfgeld richtig zuzuweisen.
DJQ

Antworten:

6

Wenn Sie nur die Mehrheitsorientierung wünschen, lesen Sie die Antwort von @Mapperz oben.

Andernfalls können Sie, wie Sie sagen, die Polygone mit dem Werkzeug " Polygon in Linie" in Linien aufteilen . Dies fügt ein linkes und ein rechtes FID-Feld hinzu, wobei das Feld -1 ist, wenn kein äußeres Polygon vorhanden ist. Dies kann jedoch zu einigem Durcheinander führen, wenn Ihre Gebäude benachbart sind oder sich überlappen.

Von dort aus können Sie Ihre Linien an jedem Scheitelpunkt teilen (möglicherweise in COGO-Linien teilen ) und dann die Winkel für jede der Linien berechnen (möglicherweise durch Aktualisieren der COGO-Attribute ).

Angenommen, Sie haben Ihr Winkelfeld aus Nord berechnet, dann ist der Aspekt korrekt, wenn die left_FID -1 ist. Um den Aspekt zu erhalten, wenn die right_FID -1 ist, fügen Sie einfach 180 ° hinzu. Dann können Sie basierend auf der ursprünglichen FID aggregieren, den Mehrheitsaspekt basierend auf der Länge usw. erhalten.

Das Polygon-zu-Linie-Werkzeug ist skriptfähig (soweit ich weiß), COGO-Werkzeuge nicht, daher müssten Sie sich dort selbst etwas einfallen lassen.

Hoffe das hilft!

om_henners
quelle
2
Schamloser Plug und ein Kommentar: Wenn Sie keine Info-Lizenz haben, funktioniert code.google.com/p/boundary-generator mehr oder weniger wie das Tool Polygon to Line. Zweitens: Dies gibt Ihnen viel mehr Informationen als nur eine allgemeine Ausrichtung des gesamten Polygons. Sie können beispielsweise die resultierende Tabelle verwenden, um viel genauere Berechnungen der Sonneneinstrahlung durchzuführen, wobei der Aspekt jeder einzelnen Wand berücksichtigt wird .
Dan S.
5

Orientierung finden

Innerhalb eines Skripts ist das Polygon als Satz von Ringen verfügbar - ein äußerer Ring und null oder mehr innere Ringe - wobei jeder Ring durch ein zyklisch geordnetes Tupel von Vektoren (v [0], v 1 , ...) dargestellt wird. , v [m-1], v [m] = v [0]). Jeder Vektor gibt die Koordinaten eines Scheitelpunkts an (wobei keine zwei aufeinanderfolgenden Scheitelpunkte zusammenfallen). Daraus ist es, wie andere betont haben, einfach, normale Vektoren (dh Vektoren senkrecht zu den Kantenrichtungen) zu erhalten:

n [i] = t (v [i + 1] - v [i]).

Die "t" -Operation dreht einen Vektor um 90 Grad gegen den Uhrzeigersinn :

t ((x, y)) = (y, -x).

Nur die Richtungen dieser Normalenvektoren sind von Bedeutung. Skalieren Sie sie daher neu, um eine Längeneinheit zu erhalten: Ein Vektor (x, y) skaliert auf (x / s, y / s), wobei s = Sqrt (x ^ 2 + y ^ 2) (welche) ist die Länge der entsprechenden Kante). Nehmen wir von nun an an, dass dies geschehen ist. Schreiben Sie die Komponenten der resultierenden Einheitsnormalenvektoren als

n [i] = (u [i], v [i]), i = 0, 1, ..., m-1.

Außen von innen unterscheiden

Wie Sie bemerken, hinterlässt dies eine Richtungsmehrdeutigkeit: Sollten wir n [i] oder -n [i] verwenden? Welches zeigt nach außen? Diese Frage entspricht dem Ermitteln des Grades der Gauß-Karte . Um dies zu berechnen, müssen Sie die Winkel summieren, um die sich die normalen Richtungen ändern, wenn Sie um einen Ring marschieren. Da die Normalenvektoren eine Einheitslänge haben, ist der Kosinus des Winkels zwischen zwei aufeinanderfolgenden Kanten

Cos (q_i) = n [i]. n [i + 1] = u [i] * u [i + 1] + v [i] * v [i + 1], i = 0, 1, ..., m-1.

(Definiere n [m] = n [0].)

Der Sinus des Winkels zwischen zwei aufeinanderfolgenden Kanten ist

Sin (q_i) = n [i]. t (n [i + 1]) = u [i] * v [i + 1] - v [i] * u [i + 1].

(Beachten Sie, dass diese Berechnungen bisher nur Summen, Differenzen und Produkte erfordern.) Die Anwendung der hauptsächlichen inversen Tangentenfunktion (ATan2) auf ein solches Paar (Cosinus, Sinus) ergibt den Winkel q_i zwischen -180 und 180 Grad. Das Summieren dieser Winkel für i = 0, 1, ..., n-1 ergibt (bis zum Gleitkommafehler) die Gesamtkrümmung des Rings, die ein Vielfaches von 360 Grad sein muss; Für einen geschlossenen, sich nicht selbst schneidenden Ring beträgt er entweder +360 oder -360. Im ersten Fall ist der Grad 1 und im zweiten Fall ist der Grad -1. Die Normalen sind alle nach außen ausgerichtet, wenn der Grad des Außenrings +1 und der Grad der Innenringe -1 beträgt. Richten Sie sie nach dieser Regel Ring für Ring nach Bedarf neu aus. Das heißt, wenn der Grad eines Rings das Gegenteil von dem ist, der benötigt wird, negieren Sie alle Normalen für diesen Ring. Jetzt können Sie mit Ihren Sonneneinstrahlungsberechnungen fortfahren.

whuber
quelle
Vielen Dank für eine sehr umfassende Antwort. Wenn Sie sagen: "Innerhalb eines Skripts ist das Polygon als Satz von Ringen verfügbar", wie ist das Polygon verfügbar? Obwohl ich mit einigen Python-Skripten vertraut bin, weiß ich nicht, wie ich das Polygon auf diese Weise interpretieren soll. Ich lese das langsam durch und versuche es zu verstehen, aber ich habe Schwierigkeiten, einige der Erklärungen in Pseudocodes zu übersetzen, die ich schreiben kann.
DJQ
Ein paar Anmerkungen zu dieser Antwort: Typische GIS-APIs zeigen die Außenseite eines Polygons immer in der Reihenfolge gegen den Uhrzeigersinn (IIRC) an gegen den Uhrzeigersinn auf den Löchern. Eine Klarstellung für Celenius: Mit dem Bit "Satz von Ringen" können Sie mit den meisten APIs, einschließlich ArcGISs Python, ein Polygon in seine konstituierenden Liniensegmente zerlegen - ein Ring ist eine geschlossene Kurve davon. Da Polygone Inseln und Löcher unterstützen können, können Sie mehrere Ringe haben ...
Dan S.
@Dan Ich wünschte, es wäre der Fall, dass GIS solche konsistenten Darstellungen beibehalten. Im Laufe der Jahre schwankte die ESRI-Software zwischen negativ und positiv ausgerichteten Polygonen hin und her und ließ sie einfach unorientiert. An dieser Stelle bin ich mir nicht sicher, ob ich mich auch nur auf dokumentierte Aussagen zu ihrem aktuellen Ansatz verlassen würde: Ich wäre vorsichtig. Das Überprüfen der Ausrichtung kostet wenig, nachdem Sie bereits alle Kanten in einem Ring bearbeitet haben.
whuber
.. Nun, ich habe zum Glück diesen kleinen IIRC-Haftungsausschluss eingefügt. ;) Es kommt nicht mehr so ​​oft vor, dass ich Sachen auf Geometrieebene auf dem ESRI-Stack mache.
Dan S.
@ Dan S. - Ich bin immer noch ein wenig unklar, wie dies in Python programmiert werden kann. Gibt es dafür Richtlinien?
DJQ
1

Kann das helfen?

julien
quelle
Das ist ein interessantes Papier, das du ausgegraben hast. Keine der dort beschriebenen Methoden ist jedoch für eine Berechnung der Sonnenexposition relevant (es sei denn, die Berechnung soll eine grobe Annäherung sein, was hier nicht der Fall zu sein scheint).
whuber
1

/* Vielleicht hilft das:

Azimut - pi / 2 ist die nach außen gerichtete Ausrichtung der Seiten eines RHR-Polygons:

In diesem PostGIS-Beispiel können Sie die Tabelle bldg117862 mithilfe der Anweisung am Ende erstellen. Die SRID ist EPSG 2271 (PA StatePlane North Feet) und die Geometrie ist ein Multipolygon. Fügen Sie zur Visualisierung in ArcGIS 10 Abfragen / Unterabfragen nach dem Erstellen der Tabelle bldg117862 in eine Query Layer-Verbindung zu postgis ein. * /

- === START DER ABFRAGE ===

/ * Die äußere Abfrage ermöglicht die Ausrichtung von nach außen gerichteten Orthogonalen und erstellt nach außen gerichtete orthogonale Linien mit der gleichen Länge wie die der Seiten vom Mittelpunkt der Seiten.

Dominante Blickrichtung (en) ist die Summe der Länge, gruppiert nach Ausrichtung, in absteigender Reihenfolge * /

SELECT line_id als side_id, Länge, Grad (orthoaz) als Orientierung, st_makeline (st_setsrid (st_line_interpolate_point (geom, .5), 2271), st_setsrid (st_makepoint (st_x (st_line_interpolate_point (geom, .5)) + (Länge * (sin ()) orthoaz))), st_y (st_line_interpolate_point (geom, .5)) + (Länge * (cos (orthoaz)))), 2271)) als Geom von

- Die nächste äußere Unterabfrage erstellt Linien aus den Punktpaaren der Seiten. Berechnen Sie für jedes Segment den Azimut (Orthoaz) der nach außen gerichteten Orthogonalität

(SELECT bldg2009gid, line_id, st_length (st_makeline (Startpunkt, Endpunkt)) :: numerisch (10,2) als Länge, Azimut (Startpunkt, Endpunkt), Azimut (Startpunkt, Endpunkt) - pi () / 2 als orthoaz, st_makeline ( Startpunkt, Endpunkt) als Geom von

/ * innerste Unterabfrage - Verwenden Sie generate_series (), um Gebäudepolygone in Startpunkt- / Endpunktpunktpaare der Seiten zu zerlegen. - note1 - Erzwingen Sie die Rechtsregel, um die gemeinsame Ausrichtung aller Polygonseiten zu gewährleisten. note2 - Beispiel verwendet Multipolygon, für Polygon die Geometrie n () kann entfernt werden */

(SELECT generate_series (1, nPunkte (Außenring (Geometrien (st_forceRHR (geom), 1))) - 1) als line_id, gid als bldg2009gid, pointn (Außenring (Geometrien (st_forceRHR (geom), 1)), generate_series (1, nPunkte (Außenring (Geometrien (st_forceRHR (geom), 1)) - 1)) als Startpunkt, Punktn (Außenring (Geometrien (st_forceRHR (geom), 1)), generate_series (2, nPunkte (Außenring (Geometrien (st_forceRHR (geom)) ), 1))))) als Endpunkt von bldg117862) als t1) als t2

- === ENDE DER ABFRAGE ===

- die Anweisungen zum Erstellen / Einfügen der Tabelle bldg117862

SET STANDARD_CONFORMING_STRINGS auf ON; SELECT DropGeometryColumn ('', 'bldg117862', 'geom'); DROP TABLE "bldg117862"; START; CREATE TABLE "bldg117862" (gid serial PRIMARY KEY, "Motherpin" varchar (14), "taxin" varchar (14), "status" varchar (15), "area" numeric, "prev_area" numeric, "pct_change" numeric, "Bild" varchar (133), "Zuordnung" varchar (6), "sref_gid" int4, "e_address" varchar (19), "a_address" varchar (19), "perim" numerisch, "card" int4, "a_addnum" int4, "e_street" varchar (50), "a_street" varchar (50), "e_hsnum" varchar (10)); SELECT AddGeometryColumn ('', 'bldg117862', 'geom', '2271', 'MULTIPOLYGON', 2); 0106000020DF080000010000000103000020DF080000010000000B0000008C721D6C98AC34415E2C5BB9D3E32541AE56DE17BEAC34410613E5A0A0E325411AB6C794AEAC3441BA392FE372E32541C89C38429DAC3441643857628AE325418C299A9095AC3441F66C29B573E32541983F02087EAC34413080AA9F93E325419BAC3C0A86AC3441AC1F3B3DABE32541803A40B974AC3441E8CF3DB9C2E325413E3758C186AC3441D0AAB0E7F7E325410AAAA5429BAC3441BA971217DCE325418C721D6C98AC34415E2C5BB9D3E32541' ); CREATE INDEX "bldg117862_geom_gist" ON "bldg117862" using gist ("geom" gist_geometry_ops); ENDE;


quelle
0

Unter der Annahme, dass die Ausrichtung der Liniensegmente in einem Polygon konstant ist, können Sie die Peilung (Überschrift) eines Vektors senkrecht zu jedem Liniensegment berechnen. Ich habe momentan keine Zeit, mich mit Code zu beschäftigen, aber wenn Sie die Mathematik brauchen, kann sie leicht geliefert werden :-)

WolfOdrade
quelle