Hi All,
I've done some work this year with transmission routing and scoring for new projects. This work was done based on a request to determine the design deflection angle for a series of proposed structure locations along a new transmission route.
Based on this specific request and need, I created a python script that takes the input of any polyline (planned transmission project route), creates points at the vertices of that polyline, and calculates the relative deflection angle at each location. The output is a point feature class written out to the input workspace that contains attribute information that can be used to benefit scoring criteria for cost considerations when planning new projects.
1.)What use cases would this group find beneficial around this type of tool and output in any planning workflows you have which involve routing and scoring?
2.) What are you all doing to support workflows involving the ever increasing number of projects within your organization and how you are using GIS to help meet your organizational needs now and going forward?
3.) Feel free to copy and paste the python below into your ArcGIS Pro Project and try it out. Any questions or comments please reply to the group to get this conversation going.
import arcpy
import math
import os
# Define the input polyline feature class
line_fc = r""
# Define the output point feature class
filename = os.path.basename(line_fc)
output_fc = "deflection_angles_points_" + filename
# Create the output point feature class with the required fields
arcpy.CreateFeatureclass_management(
arcpy.env.workspace, output_fc, "POINT", line_fc, "SAME_AS_TEMPLATE"
)
arcpy.AddField_management(output_fc, "Vertex_Order", "LONG")
arcpy.AddField_management(output_fc, "Deflection_Angle", "DOUBLE")
# Iterate through each vertex of the polyline and calculate the deflection angle
with arcpy.da.SearchCursor(line_fc, ["OID@", "SHAPE@"]) as cursor:
with arcpy.da.InsertCursor(output_fc, ["OID@", "SHAPE@", "Vertex_Order", "Deflection_Angle"]) as insert_cursor:
for row in cursor:
object_id = row[0]
polyline = row[1]
# Iterate through each part of the polyline
for part_index in range(polyline.partCount):
part = polyline.getPart(part_index)
# Iterate through each vertex in the current part
for vertex_index in range(len(part)):
vertex = part[vertex_index]
# Calculate the deflection angle for the current vertex
if vertex_index > 0 and vertex_index < len(part) - 1:
previous_vertex = part[vertex_index - 1]
next_vertex = part[vertex_index + 1]
x1, y1 = previous_vertex.X, previous_vertex.Y
x2, y2 = vertex.X, vertex.Y
x3, y3 = next_vertex.X, next_vertex.Y
angle_rad = math.atan2(y3 - y2, x3 - x2) - math.atan2(y1 - y2, x1 - x2)
angle_deg = abs(math.degrees(angle_rad))
# Adjust the angle to be within the range of 0-90 degrees for each quadrant
if angle_deg < 0:
angle_deg += abs(360)
if angle_deg > 90:
angle_deg = abs(180 - angle_deg)
# Create a new point feature with the calculated deflection angle
point = arcpy.Point(vertex.X, vertex.Y)
point_geometry = arcpy.PointGeometry(point, polyline.spatialReference)
insert_cursor.insertRow([object_id, point_geometry, vertex_index, angle_deg])
# Print a message when the script is completed
print("Deflection angles calculated and stored in the output feature class.")