import arcpy
import math
# Input layers
trail_lines = "TrailSegments" # Line feature class
fork_points = "ForkPoints" # Point feature class
# Add fields to store trail classification
arcpy.AddField_management(trail_lines, "TrailType", "TEXT")
# Function to calculate angle between two line segments
def calculate_angle(line1, line2):
# Get angle in radians between two lines
angle1 = math.atan2(line1.lastPoint.Y - line1.firstPoint.Y,
line1.lastPoint.X - line1.firstPoint.X)
angle2 = math.atan2(line2.lastPoint.Y - line2.firstPoint.Y,
line2.lastPoint.X - line2.firstPoint.X)
angle = math.degrees(angle2 - angle1)
return angle if angle >= 0 else angle + 360
# Loop through each fork
with arcpy.da.UpdateCursor(trail_lines, ["SHAPE@", "TrailType"]) as line_cursor:
for line in line_cursor:
line_geometry = line[0]
closest_fork = None
min_distance = float('inf')
# Find closest fork to determine which direction the line takes at the fork
with arcpy.da.SearchCursor(fork_points, ["SHAPE@"]) as fork_cursor:
for fork in fork_cursor:
distance = line_geometry.distanceTo(fork[0])
if distance < min_distance:
min_distance = distance
closest_fork = fork[0]
# For each line segment connected to the fork, calculate angle
if closest_fork:
main_angle = calculate_angle(line_geometry, closest_fork)
# Classify based on angle thresholds (you may adjust these as needed)
if 0 <= main_angle < 30 or main_angle > 330:
line[1] = "Main"
elif 30 <= main_angle <= 180:
line[1] = "Left"
else:
line[1] = "Right"
line_cursor.updateRow(line)
print("Trail classification completed.")
The above script is pretty good, although there are a few issues you'll need to adjust to suit your data. Consider this crudely drawn example:
If you found all the locations where trails intersected, buffered those points out slightly, and calculated the angle of each line intersection that would solve most of these issues. You would just need to flip the angle of the line that represents the angle of travel.