-
Notifications
You must be signed in to change notification settings - Fork 2
/
NG911_flip_RCLs.py
148 lines (113 loc) · 4.33 KB
/
NG911_flip_RCLs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# -*- coding: utf-8 -*-
"""
Created on Mon Aug 30 13:01:42 2021
@author: eneemann
Script to fix NG911 errors where RCLs are pointed in the wrong direction
"""
import arcpy
import os
import time
from datetime import datetime
import pandas as pd
import math
# Start timer and print start time in UTC
start_time = time.time()
readable_start = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
print("The script start time is {}".format(readable_start))
######################
# Set up variables #
######################
# Set up databases (SGID must be changed based on user's path)
ng911_db = r"C:\Users\eneemann\Desktop\Neemann\NG911\911 DataMaster\NG911_Errors_20210812.gdb"
arcpy.env.workspace = ng911_db
arcpy.env.overwriteOutput = True
arcpy.env.qualifiedFieldNames = False
today = time.strftime("%Y%m%d")
#RCLs = os.path.join(ng911_db, 'Davis_Road_errors_20210815_v3')
RCLs = os.path.join(ng911_db, 'RoadCenterlines')
RCLs_working = os.path.join(ng911_db, f'RCL_flip_fixes_{today}')
# Make a copy of the data to work on
arcpy.management.CopyFeatures(RCLs, RCLs_working)
# Get the spatial reference for later use
sr = arcpy.Describe(RCLs_working).spatialReference
def angle_calc(line):
angle = math.degrees(math.atan2((line.lastPoint.X - line.firstPoint.X),(line.lastPoint.Y - line.firstPoint.Y)))
if angle < 0:
angle += 360.0
return angle
def reversed_check(line, predir):
status = False
# Calculate angle
angle = angle_calc(line)
# Compare angle to expected range based on predir
# If angle doesn't align with predir, change status to True
if predir == 'NORTH' and (angle > 90 and angle < 270):
status = True
elif predir == 'SOUTH' and (angle > 270 or angle < 90):
status = True
elif predir == 'EAST' and (angle > 180 and angle < 360):
status = True
elif predir == 'WEST' and (angle > 0 and angle < 180):
status = True
if not status:
print(f'predir is {predir}, but angle is {angle}')
return status, angle
def reverse_line(line):
pts_orig = []
if shape_obj.partCount > 1:
print("Warning: multiple parts! extra parts are automatically trimmed!")
print(f"Line has {shape_obj.partCount} parts")
# Step through and use first part of the feature
part = line.getPart(0)
# put the points into a list, then reverse the list
for pnt in part:
pts_orig.append((pnt.X, pnt.Y))
pts_rev = pts_orig[::-1]
# print(pts_orig)
# print(pts_rev)
# rebuild geometry of reversed line
arc_pts = [arcpy.Point(item[0], item[1]) for item in pts_rev]
array= arcpy.Array(arc_pts)
geom_rev = arcpy.Polyline(array, sr)
return geom_rev
# Loop through data and flip roads that have bad directions
flip_count = 0
query = "Error_ID = 512"
# 0 1 2 3 4 5 6
fields = ['RCL_NGUID', 'Feature_Description', 'Error_Detail', 'Error_Status', 'SHAPE@', 'OBJECTID', 'St_PreDir']
with arcpy.da.UpdateCursor(RCLs_working, fields, query) as update_cursor:
print("Looping through rows in FC to check for flipped segments ...")
for row in update_cursor:
# if row[5] == 4:
shape_obj = row[4]
predir = row[6]
# print(shape_obj)
# print(f'part count: {shape_obj.partCount}')
is_reversed, ang = reversed_check(shape_obj, predir)
if is_reversed:
print(f"flipping NGUID {row[0]}: {row[1]}")
shape_rev = reverse_line(shape_obj)
row[4] = shape_rev
row[2] = f'python flipped {predir} {round(ang, 1)}'
row[3] = 'Closed'
flip_count += 1
else:
row[2] = f'ok {predir} {round(ang, 1)}'
update_cursor.updateRow(row)
print(f"Total count of flipped segments is: {flip_count}")
##########################
# Call Functions Below #
##########################
print("Script shutting down ...")
# Stop timer and print end time in UTC
readable_end = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
print("The script end time is {}".format(readable_end))
print("Time elapsed: {:.2f}s".format(time.time() - start_time))
#
#blanks = [None, '', ' ']
#
#test = ' '
#if test in blanks:
# print("it is")
#else:
# print("it's not")