さて、本日はラインの端点の角度を取得しようと思います。ラインの端点にはシンボルを置くことが多いので、端点の角度を取得して、そこにのっかるポイントに角度を与える場合などに使えるかと思います。
環境
Windows7 64bit
ArcGIS10.2
Python2.7.3
プログラムで取得できる値
対象のフィーチャクラスにおいて、端点の角度を含む以下情報をListで返します。端点以外の頂点の情報は格納しません。
[0]:OBJECTID
[1]:X
[2]:Y
[3]:頂点区分 1:始点 2:終点
[4]:角度
対象データ
以下のようなサンプルデータを作成しました。
左から順に作図しました。
サンプル
■calcangle.py
# -*- coding: utf-8 -*- import arcpy import math class CalcAngle(object): def __init__(self,workspace,in_feature): arcpy.env.workspace = workspace self.in_feature = in_feature self.generalize_list = list() def calc_angle(self): """各頂点の角度を計算する関数 self.generalize_list --ラインの始点終点などの情報 [0]:OBJECTID [1]:X [2]:Y [3]:頂点区分 1:始点,2:終点 [4]:角度 """ for i,pt in enumerate(self.generalize_list): #始点の場合 if pt[3] == 1: #角度を計算 result = math.atan2(pt[2]-self.generalize_list[i+1][2],pt[1]-self.generalize_list[i+1][1]) #角度をセット if math.degrees(result) < 0: self.generalize_list[i].append(abs(math.degrees(result))) else: self.generalize_list[i].append(abs(math.degrees(result) - 360)) #終点の場合 elif pt[3] == 2: #角度を計算 result = math.atan2(pt[2]-self.generalize_list[i-1][2],pt[1]-self.generalize_list[i-1][1]) #角度をセット if math.degrees(result) < 0: self.generalize_list[i].append(abs(math.degrees(result))) else: self.generalize_list[i].append(abs(math.degrees(result) -360)) else: self.generalize_list[i].append(0) def get_point_coord(self): """ラインの頂点ごとの情報をリストに格納する""" lines = [row for row in arcpy.da.SearchCursor(self.in_feature, ["OID@","SHAPE@"])] #頂点ごとにOID、X、Y、始点、終点の情報を格納する for line in lines: for parts in line[1]: for part in parts: #始点の場合 if part.X == line[1].firstPoint.X and part.Y == line[1].firstPoint.Y: self.generalize_list.append([line[0],part.X,part.Y,1]) #終点の場合 elif part.X == line[1].lastPoint.X and part.Y == line[1].lastPoint.Y: self.generalize_list.append([line[0],part.X,part.Y,2]) def calc_point_distance(self): """各種関数を呼び出し、self.generalize_listに要素を追加していく""" #始点終点の情報を取得 self.get_point_coord() #頂点の角度の計算 self.calc_angle() return self.generalize_list if __name__ == '__main__': #対象のgdb workspace = r"C:\ArcPySample\Generalize.gdb" #対象のフィーチャクラス名 in_feature = "Line" #インスタンス化 generalize = CalcAngle(workspace,in_feature) #角度計算 angle_list = generalize.calc_point_distance() print angle_list
実行結果はこのようになりました。
OBJECTIDが1のデータで確認すると始点(以下画像の緑丸)の角度=156.1363677663898、終点(以下画像の赤丸)の角度=336.1363677663898 で問題なさそうですね。
これを使用すれば端点の角度を利用してそこに接するポイントに角度を付与することができるかと思います。また、これを応用して、各頂点ごとの角度などを取得してもおもしろそうですね。
簡単ではありますが、本日は以上です。