-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
142 lines (111 loc) · 5.15 KB
/
app.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
import pathlib
import tkinter as tk
import pygubu
import generate_waypoints
PROJECT_PATH = pathlib.Path(__file__).parent
PROJECT_UI = PROJECT_PATH / "ui.ui"
max_z = 3700
class Messages:
"""Message colors"""
ERROR = "#eb0b1f"
WARN = "#eea500"
OK = "#000"
"""Message values"""
INVALID = (ERROR, "Inputs are not valid. Nothing was executed.")
NEGATIVE = (ERROR, "Inputs must be positive. Nothing was executed.")
OVERLAP = (ERROR, "Overlap value must be between 0 and 99%. Nothing was executed.")
Z_FILTER = (ERROR, f"Minimum Z height must be below {max_z} feet. Nothing was executed.")
LOW_MIN_HEIGHT = (WARN, "\nMinimum distance is too low. Results may be undesirable.")
LONG_RUN_TIME = (
WARN,
"Requested waypoints are very close together, and run time could be long.\nPress button again to confirm.")
OK_GRAPH = (OK, "Graph generated successfully.")
OK_EXPORT_FT = (OK, "Exporting to feet completed successfully: ")
OK_EXPORT_LL = (OK, "Exporting to latitude/longitude completed successfully: ")
class UiApp:
count = 0
labels = []
long_run = False
def __init__(self, master=None, translator=None):
self.builder = builder = pygubu.Builder(translator)
builder.add_resource_path(PROJECT_PATH)
builder.add_from_file(PROJECT_UI)
# Main widget
self.mainwindow = builder.get_object("frame1", master)
builder.connect_callbacks(self)
# Pull in labels from UI
for name, obj in self.builder.objects.items():
if type(obj) == pygubu.plugins.ttk.ttkstdwidgets.TTKEntry:
self.labels.append(name)
self.builder.get_object("message").configure(text="")
def run(self):
self.mainwindow.mainloop()
def handle(self, widget_id):
# Clear out previous error messages and set persistent message variable
self.builder.get_object("message").configure(foreground=Messages.OK)
color, message = Messages.OK, ""
labels = {}
# Check that inputs are numbers and in bounds
try:
check = 0
for label in self.labels:
val = float(self.builder.get_object(label).get())
if val < 0:
color, message = Messages.NEGATIVE
labels[label] = val
check += val
except ValueError:
color, message = Messages.INVALID
self.builder.get_object("message").configure(foreground=color, text=message)
return
# Catch special cases of numbers
if not (0 <= labels["f_overlap"] <= 99 and 0 <= labels["s_overlap"] <= 99):
color, message = Messages.OVERLAP
if labels["z_crop"] > max_z:
color, message = Messages.Z_FILTER
# If error, exit this function
if color == Messages.ERROR:
self.builder.get_object("message").configure(foreground=color, text=message)
return
# Transfer button info to variables and calculate frame spacing
frame_h, camera_h, camera_v = labels["frame_h"], labels["cam_h"], labels["cam_v"]
f_overlap, s_overlap, dist, z_crop = labels["f_overlap"], labels["s_overlap"], labels["dist"], labels["z_crop"]
frame_v = frame_h * camera_v / camera_h
# Since this is on a grid, frontal overlap = horizontal overlap, side overlap = vertical overlap
waypoint_h, waypoint_v = frame_h * (1 - f_overlap / 100), frame_v * (1 - s_overlap / 100)
# Check for excessive run time and ask for confirmation
if (waypoint_h * waypoint_v) < 20:
if not self.long_run:
color, message = Messages.LONG_RUN_TIME
self.builder.get_object("message").configure(foreground=color, text=message)
self.long_run = True
return
else:
self.long_run = False
# Set variables as configured
generate_waypoints.CAMERA_H = waypoint_h
generate_waypoints.CAMERA_V = waypoint_v
generate_waypoints.CLEARANCE = dist
generate_waypoints.Z_FILTER = z_crop
match widget_id:
case "graph":
generate_waypoints.WaypointPlotter(generate_waypoints.FILE)
color, message = Messages.OK_GRAPH
case "export_feet":
obj = generate_waypoints.WaypointGenerator(generate_waypoints.FILE)
message = Messages.OK_EXPORT_FT[1] + "\n" + obj.export()
color = Messages.OK_EXPORT_FT[0]
case "export_latlong":
obj = generate_waypoints.WaypointGenerator(generate_waypoints.FILE)
message = Messages.OK_EXPORT_LL[1] + "\n" + obj.export_latlong()
color = Messages.OK_EXPORT_LL[0]
if labels["dist"] < 10:
color, message = Messages.LOW_MIN_HEIGHT[0], message + Messages.LOW_MIN_HEIGHT[1]
self.builder.get_object("message").configure(foreground=color, text=message)
if __name__ == "__main__":
root = tk.Tk()
root.geometry("1000x600")
root.title("Waypoint Generator")
root.wm_iconphoto(False, tk.PhotoImage(file="data/site.png"))
app = UiApp(root)
app.run()