ArcPyを使用してポリゴンの各辺の方向を計算していますか?


9

太陽の露出を計算できるように、ポリゴンの各線の向きを調べたいと思います。各ポリゴンは建物を表し、高さが関連付けられています。とりあえず、方向を検討したいと思います。後でシェーディングの問題を検討します。

多角形を線に分割し、各線の方向を計算するのが1つの方法でしたが、難しいのは、その線の外面を特定する必要があることです。ほとんどのポリゴンは直線の単純な4辺の図形ですが、そうでない場合もあります(検討したい問題ですが、まだ解決する必要はありません)。

私はpythonに精通しており、これをすべてスクリプトから実行する予定です。


1
この質問のヘルプに答えを行います。gis.stackexchange.com/questions/1886/...
ショーン・

@ショーン-ありがとう、はい、それは一般的に役立ちます。これを行うために使用できる特定のArcGISコマンドに精通していません。また、多角形の線の内側/外側の面が何であるかを知るという問題はまだ残っています。
djq 2010年

あなたが「向き」と言うとき、あなたはそれを私にとって十分に定義していません-たとえば、完全な六角形の向きは何ですか?
Dan S.

@Dan S.ポリゴンの各ラインの方向を含めるように回答を編集しました。
djq

申し訳ありませんが回答者-昨日、賞金を適切に割り当てることができませんでした。
djq

回答:


6

多数決オリエンテーションが必要な場合は、上記の@Mapperzの回答を確認してください。

それ以外の場合は、あなたが言うように、Polygon To Lineツール使用してポリゴンをラインに分割できます。これにより、左右のFIDフィールドが追加されます。外側のポリゴンがない場合、フィールドは-1です。建物が隣接しているか重なり合っている場合でも、これは少し不自然になります。

そこから、すべての頂点でラインを分割し([COGOラインに分割]を使用する場合があります)、各ラインの角度を計算します(COGO属性を更新することで可能性があります)。

Northから計算された角度フィールドがあると仮定すると、left_FIDが-1の場合はアスペクトが正しくなり、right_FIDが-1の場合にアスペクトを取得するには、180°を追加します。次に、元のFIDに基づいて、集計したり、長さに基づいて大部分を取得したりできます。

Polygon to Lineツールは(私が知る限り)スクリプト可能ですが、COGOツールはそうではないので、自分で何かを考え出す必要があります。

お役に立てれば!


2
恥知らずなプラグインとコメント:まず、Infoライセンスがない場合、code.google.com / p / boundary-generatorは、Polygon to Lineツールとほぼ同じように機能します。第二に、これにより、ポリゴン全体のある種の一般的な向きを見るだけではなく、より多くの情報が得られます。たとえば、結果のテーブルを使用して、個々の壁のアスペクトを考慮に入れて、より正確な日照計算を行うことができます。 。
Dan S.


5

オリエンテーションを見つける

スクリプト内では、ポリゴンはリングのセット(1つの外側のリングと0個以上の内側のリング)として使用でき、各リングはベクトル(v [0]、v 1、... 、v [m-1]、v [m] = v [0])。各ベクトルは、頂点の座標を示します(2つの連続する頂点が一致することはありません)。これから、他の人が指摘したように、法線ベクトル(つまり、エッジ方向に垂直なベクトル)を取得することは簡単です。

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

「t」操作は、ベクトルを反時計回りに 90度回転します。

t((x、y))=(y、-x)。

これらの法線ベクトルの方向のみが重要であるため、単位の長さを持つように再スケーリングします。ベクトル(x、y)は(x / s、y / s)に再スケーリングされます。ここで、s = Sqrt(x ^ 2 + y ^ 2)(これはは、対応するエッジの長さです)。これから、これが行われたと仮定しましょう。結果の単位法線ベクトルの成分を次のように記述します

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

内側と外側を区別する

お気づきのように、これには方向性のあいまいさが残ります。n[i]または-n [i]を使用する必要がありますか?どちらが外側を指していますか?この質問は、ガウスマップの次数を見つけることと同じです。それを計算するには、リングを行進するときに法線方向が変化する角度を合計する必要があります。法線ベクトルは単位長であるため、2つの連続するエッジ間の角度のコサインは

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

(n [m] = n [0]を定義します。)

2つの連続するエッジ間の角度のサインは、

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

(これらの計算に必要なのは、これまでのところ、合計、差、積のみです。)そのような(コサイン、サイン)のペアに主逆正接関数(ATan2)を適用すると、角度q_iが-180度から180度になります。これらの角度をi = 0、1、...、n-1で合計すると、(浮動小数点誤差まで)リングの全曲率が生成されます。これは360度の倍数でなければなりません。自己交差していない閉じたリングの場合は、+ 360または-360になります。最初のケースでは次数は1で、2番目のケースでは次数は-1です。 外側のリングの次数が+1で、内側のリングの次数が-1の場合、法線はすべて外向きになります。 このルールに従って、必要に応じてリングごとに方向を変えます。つまり、リングの次数が必要な次数と反対である場合、そのリングのすべての法線を無効にします。これで日射量の計算を進めることができます。


非常に包括的な回答をありがとうございます。「スクリプト内で、ポリゴンはリングのセットとして利用できます」と言うと、ポリゴンはどのように利用できますか?一部のpythonスクリプトに精通していますが、このようにポリゴンを解釈する方法がわかりません。私はこれをゆっくり読んで理解しようとしていますが、説明の一部を、記述可能な疑似コードに変換するのが困難です。
djq 2010年

この回答に関するいくつかのメモ:典型的なGIS APIは、常にポリゴンの外側を反時計回りの順序で表示するIIRCです。つまり、外側と内側を区別するという派手な区別を行う必要はありません。外側のリングで時計回りの回転を使用し、穴を反時計回りに。celeniusの説明:「リングのセット」ビットは、ArcGISのPythonを含むほとんどのAPIで、ポリゴンを構成するラインセグメントに分解する方法です。リングはそれらの閉じた曲線です。ポリゴンは島と穴をサポートしている可能性があるため、複数のリングがある可能性があります...
Dan S.

@ダンGISがこのように一貫した表現を維持していたことを願っています。長年にわたって、ESRIソフトウェアは、ネガティブとポジティブの方向を向いたポリゴンの間で前後に変動し、方向性を失っています。現時点では、彼らの現在のアプローチに関する文書化された声明にさえ頼るのかどうか確信がありません。私は慎重になるでしょう。リングのすべてのエッジを処理した後、向きを確認するのにかかるコストはほとんどありません。
whuber

..ありがたいことに、私はその小さなIIRC免責事項を入力しました。;)私がESRIスタックでジオメトリレベルの処理を実行することはそれほど多くありません。
Dan S.

@Dan S.-これをpythonでどのようにプログラミングできるかについては、まだはっきりしていません。これに関するガイドラインはありますか?
djq

1

このヘルプは?


それはあなたが掘り下げた興味深い論文です。ただし、ここで説明されている方法はどれも、日射量の計算に関連していません(計算が大まかな概算であることが意図されている場合を除き、ここではそうではありません)。
whuber

1

/ *多分これは役に立ちます:

方位角-pi / 2は、RHRポリゴンの側面の外向きの向きです。

以下はPostGISの例です。最後のステートメントを使用してbldg117862テーブルを作成できます。SRIDはEPSG 2271(PA StatePlane North Feet)で、ジオメトリはマルチポリゴンです。ArcGIS 10で視覚化するには、テーブルbldg117862を作成した後、クエリ/サブクエリをクエリレイヤー接続に貼り付けてpostgisに貼り付けます。* /

-===クエリの開始===

/ *外側のクエリは、外向きの直交の向きを提供し、辺の中点から辺と同じ長さの外向きの直交線を作成します。

支配的な向き(複数可)は、長さの合計であり、方向でグループ化されます(降順)* /

SELECT line_id as side_id、length、degrees(orthoaz)as orientation、st_makeline(st_setsrid(st_line_interpolate_point(geom、.5)、2271)、st_setsrid(st_makepoint(st_x(st_line_interpolate_point(geom、.5))+(length *(sin( orthoaz))))、st_y(st_line_interpolate_point(geom、.5))+(length *(cos(orthoaz))))、2271))をgeomから

--next外部サブクエリは、辺のポイントペアからラインを作成し、各セグメントの外向き直交の方位角(オルソアズ)を計算します

(SELECT bldg2009gid、line_id、st_length(st_makeline(startpoint、endpoint)):: numeric(10,2)as length、azimuth(startpoint、endpoint)、azimuth(startpoint、endpoint)-pi()/ 2 as orthoaz、st_makeline(始点、終点)からのgeom

/ *最も内側のサブクエリ-generate_series()を使用して建物のポリゴンを側面の始点/終点のペアに分解します-注1-すべてのポリゴンの側面の共通の向きを保証するように右手の法則を強制します注2-例として、ポリゴンのジオメトリにマルチポリゴンを使用しますn()取り外し可能* /

(SELECT generate_series(1、npoints(exteriorring(geometryn(st_forceRHR(geom)、1)))-1)as line_id、gid as bldg2009gid、pointn(exteriorring(geometryn(st_forceRHR(geom)、1))、generate_series(1、 npoints(exteriorring(geometryn(st_forceRHR(geom)、1)))-1))を開始点として、pointn(exteriorring(geometryn(st_forceRHR(geom)、1))、generate_series(2、npoints(exteriorring(geometryn(st_forceRHR(geom) )、1)))))bldg117862からのエンドポイントとして)t1として)t2として

-===クエリの終了===

-bldg117862テーブル作成/挿入ステートメント

STANDARD_CONFORMING_STRINGSをONに設定します。SELECT DropGeometryColumn( ''、 'bldg117862'、 'geom'); DROP TABLE "bldg117862"; ベギン; CREATE TABLE "bldg117862"(gid serial PRIMARY KEY、 "motherpin" varchar(14)、 "taxpin" varchar(14)、 "status" varchar(15)、 "area" numeric、 "prev_area" numeric、 "pct_change" numeric、 「picture」varchar(133)、「mappage」varchar(6)、「sref_gid」int4、「e_address」varchar(19)、「a_address」varchar(19)、「perim」数値、「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); 終わり;


0

ポリゴンの線分の方向が一定であると仮定すると、各線分に垂直なベクトルの方位(方位)を計算できます。今はコードを打ち消す時間はありませんが、数学が必要な場合は簡単に提供できます:-)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.