@@ -18,24 +18,25 @@ def main():
1818 """
1919 Main code which runs the app.
2020 """
21- st .set_page_config (
22- page_title = "Radar Plotting App" ,
23- page_icon = "🎯" ,
24- layout = "wide"
25- )
21+ st .set_page_config (page_title = "Radar Plotting App" , page_icon = "🎯" , layout = "wide" )
2622
2723 # Initialize session state for active tab
28- if ' active_tab' not in st .session_state :
24+ if " active_tab" not in st .session_state :
2925 st .session_state .active_tab = "Calculator"
3026
3127 st .title ("⚓️ Collision Avoidance Radar Plotting App" )
32- st .markdown ("Calculate collision avoidance maneuvers using radar plotting techniques" )
28+ st .markdown (
29+ "Calculate collision avoidance maneuvers using radar plotting techniques"
30+ )
3331
3432 # Disclaimer
35- st .warning ("⚠️ **Disclaimer**: This is an educational tool ONLY and should NOT be used for real collision avoidance situations. This is for training purposes ONLY." )
33+ st .warning (
34+ "⚠️ **Disclaimer**: This is an educational tool ONLY and should NOT be used for real collision avoidance situations. This is for training purposes ONLY."
35+ )
3636
3737 # Custom CSS for tab-like buttons (Coast Guard Auxiliary colors)
38- st .markdown ("""
38+ st .markdown (
39+ """
3940 <style>
4041 /* Style for our custom tab buttons */
4142 div.stButton > button {
@@ -46,22 +47,34 @@ def main():
4647 box-shadow: 0 2px 4px rgba(0,0,0,0.1);
4748 }
4849 </style>
49- """ , unsafe_allow_html = True )
50+ """ ,
51+ unsafe_allow_html = True ,
52+ )
5053
5154 # Create custom tab buttons using columns
5255 col1 , col2 = st .columns (2 )
5356
5457 with col1 :
55- if st .button ("📊 Calculator" , use_container_width = True ,
56- type = "primary" if st .session_state .active_tab == "Calculator" else "secondary" ,
57- key = "calc_tab_btn" ):
58+ if st .button (
59+ "📊 Calculator" ,
60+ use_container_width = True ,
61+ type = "primary"
62+ if st .session_state .active_tab == "Calculator"
63+ else "secondary" ,
64+ key = "calc_tab_btn" ,
65+ ):
5866 st .session_state .active_tab = "Calculator"
5967 st .rerun ()
6068
6169 with col2 :
62- if st .button ("ℹ️ Instructions" , use_container_width = True ,
63- type = "primary" if st .session_state .active_tab == "Instructions" else "secondary" ,
64- key = "instr_tab_btn" ):
70+ if st .button (
71+ "ℹ️ Instructions" ,
72+ use_container_width = True ,
73+ type = "primary"
74+ if st .session_state .active_tab == "Instructions"
75+ else "secondary" ,
76+ key = "instr_tab_btn" ,
77+ ):
6578 st .session_state .active_tab = "Instructions"
6679 st .rerun ()
6780
@@ -71,35 +84,19 @@ def main():
7184 # Own ship information
7285 st .sidebar .subheader ("Your Vessel" )
7386 our_course = st .sidebar .number_input (
74- "Course (°)" ,
75- min_value = 0.0 ,
76- max_value = 359.0 ,
77- value = 0.0 ,
78- step = 1.0
79- )
87+ "Course (°)" , min_value = 0.0 , max_value = 359.0 , value = 0.0 , step = 1.0
88+ )
8089 our_speed = st .sidebar .number_input (
81- "Speed (kts)" ,
82- min_value = 0.0 ,
83- max_value = 50.0 ,
84- value = 10.0 ,
85- step = 0.1
90+ "Speed (kts)" , min_value = 0.0 , max_value = 50.0 , value = 10.0 , step = 0.1
8691 )
8792
8893 # Maneuver parameters
8994 st .sidebar .subheader ("Maneuver Parameters" )
9095 maneuver_dist = st .sidebar .number_input (
91- "Maneuver Distance (NM)" ,
92- min_value = 0.1 ,
93- max_value = 20.0 ,
94- value = 5.0 ,
95- step = 0.1
96+ "Maneuver Distance (NM)" , min_value = 0.1 , max_value = 20.0 , value = 5.0 , step = 0.1
9697 )
9798 new_cpa_dist = st .sidebar .number_input (
98- "Keep Out Distance (NM)" ,
99- min_value = 0.1 ,
100- max_value = 20.0 ,
101- value = 2.5 ,
102- step = 0.1
99+ "Keep Out Distance (NM)" , min_value = 0.1 , max_value = 20.0 , value = 2.5 , step = 0.1
103100 )
104101
105102 # Target Vessel (First position [Point R])
@@ -110,21 +107,12 @@ def main():
110107 max_value = 359.0 ,
111108 value = 45.0 ,
112109 step = 1.0 ,
113- key = "r_bearing"
110+ key = "r_bearing" ,
114111 )
115112 r_ranage = st .sidebar .number_input (
116- "Range (NM)" ,
117- min_value = 0.1 ,
118- max_value = 50.0 ,
119- value = 11.5 ,
120- step = 0.1 ,
121- key = "r_range"
122- )
123- r_time = st .sidebar .text_input (
124- "Time (HH:MM) [24hr]" ,
125- value = "14:00" ,
126- key = "r_time"
113+ "Range (NM)" , min_value = 0.1 , max_value = 50.0 , value = 11.5 , step = 0.1 , key = "r_range"
127114 )
115+ r_time = st .sidebar .text_input ("Time (HH:MM) [24hr]" , value = "14:00" , key = "r_time" )
128116
129117 # Target Vessel (Second position [Point M])
130118 st .sidebar .subheader ("Target Vessel - Second Appearance" )
@@ -134,21 +122,12 @@ def main():
134122 max_value = 359.0 ,
135123 value = 43.0 ,
136124 step = 1.0 ,
137- key = "m_bearing"
125+ key = "m_bearing" ,
138126 )
139127 m_ranage = st .sidebar .number_input (
140- "Range (NM)" ,
141- min_value = 0.1 ,
142- max_value = 50.0 ,
143- value = 9.0 ,
144- step = 0.1 ,
145- key = "m_range"
146- )
147- m_time = st .sidebar .text_input (
148- "Time (HH:MM) [24hr]" ,
149- value = "14:06" ,
150- key = "m_time"
128+ "Range (NM)" , min_value = 0.1 , max_value = 50.0 , value = 9.0 , step = 0.1 , key = "m_range"
151129 )
130+ m_time = st .sidebar .text_input ("Time (HH:MM) [24hr]" , value = "14:06" , key = "m_time" )
152131
153132 # Calculate Button
154133 if st .sidebar .button ("🎯 Calculate Solution" , type = "primary" ):
@@ -157,12 +136,12 @@ def main():
157136 st .session_state .active_tab = "Calculator"
158137 # Create problem
159138 problem = RadarProblem (
160- our_course = our_course ,
161- our_speed = our_speed ,
162- maneuver_dist = maneuver_dist ,
163- new_cpa_dist = new_cpa_dist ,
164- r_point = RadarPoint (r_bearing , r_ranage , r_time ),
165- m_point = RadarPoint (m_bearing , m_ranage , m_time )
139+ our_course = our_course ,
140+ our_speed = our_speed ,
141+ maneuver_dist = maneuver_dist ,
142+ new_cpa_dist = new_cpa_dist ,
143+ r_point = RadarPoint (r_bearing , r_ranage , r_time ),
144+ m_point = RadarPoint (m_bearing , m_ranage , m_time ),
166145 )
167146
168147 # Solve
@@ -187,39 +166,65 @@ def main():
187166 # Display content based on active tab
188167 if st .session_state .active_tab == "Calculator" :
189168 # Calculator Tab Content
190- if ' has_solution' in st .session_state and st .session_state .has_solution :
169+ if " has_solution" in st .session_state and st .session_state .has_solution :
191170 st .header ("📊 Results" )
192171
193172 col1 , col2 , col3 = st .columns (3 )
194173
195174 with col1 :
196- st .metric ("CPA Distance" , f"{ st .session_state .solution .cpa_range :.1f} NM" )
197- st .metric ("CPA Bearing" , f"{ st .session_state .solution .cpa_bearing :06.2f} °" )
198- st .metric ("Time to CPA" , st .session_state .solution .cpa_time .strftime ("%H:%M" ))
175+ st .metric (
176+ "CPA Distance" , f"{ st .session_state .solution .cpa_range :.1f} NM"
177+ )
178+ st .metric (
179+ "CPA Bearing" , f"{ st .session_state .solution .cpa_bearing :06.2f} °"
180+ )
181+ st .metric (
182+ "Time to CPA" , st .session_state .solution .cpa_time .strftime ("%H:%M" )
183+ )
199184
200185 with col2 :
201- st .metric ("SRM (Speed Relative Movement)" , f"{ st .session_state .solution .srm :.1f} kts" )
202- st .metric ("DRM (Direction Relative Movement)" , f"{ st .session_state .solution .drm :06.2f} °" )
203- st .metric ("STM (Speed True Movement)" , f"{ st .session_state .solution .stm :.1f} kts" )
186+ st .metric (
187+ "SRM (Speed Relative Movement)" ,
188+ f"{ st .session_state .solution .srm :.1f} kts" ,
189+ )
190+ st .metric (
191+ "DRM (Direction Relative Movement)" ,
192+ f"{ st .session_state .solution .drm :06.2f} °" ,
193+ )
194+ st .metric (
195+ "STM (Speed True Movement)" ,
196+ f"{ st .session_state .solution .stm :.1f} kts" ,
197+ )
204198
205199 with col3 :
206- st .metric ("DTM (Direction True Movement)" , f"{ st .session_state .solution .dtm :06.2f} °" )
207- st .metric ("New Course (N/C)" , f"{ st .session_state .solution .new_course :06.2f} °" )
208- st .metric ("New Speed (N/S)" , f"{ st .session_state .solution .new_speed :.1f} kts" )
200+ st .metric (
201+ "DTM (Direction True Movement)" ,
202+ f"{ st .session_state .solution .dtm :06.2f} °" ,
203+ )
204+ st .metric (
205+ "New Course (N/C)" , f"{ st .session_state .solution .new_course :06.2f} °"
206+ )
207+ st .metric (
208+ "New Speed (N/S)" , f"{ st .session_state .solution .new_speed :.1f} kts"
209+ )
209210
210211 # Plot
211212 st .header ("📈 Radar Plot" )
212- fig = plot_radar_solution (st .session_state .problem , st .session_state .solution , show = False )
213+ fig = plot_radar_solution (
214+ st .session_state .problem , st .session_state .solution , show = False
215+ )
213216 st .pyplot (fig )
214217
215218 # Success message
216219 st .success ("✅ Solution calculated successfully!" )
217- elif ' error_message' in st .session_state :
220+ elif " error_message" in st .session_state :
218221 st .error (st .session_state .error_message )
219- if ' error_exception' in st .session_state :
222+ if " error_exception" in st .session_state :
220223 st .exception (st .session_state .error_exception )
221224 else :
222- st .info ("👈 Enter your vessel information and target observations in the sidebar, then click 'Calculate Solution' to see results." )
225+ st .info (
226+ "👈 Enter your vessel information and target observations in the sidebar, then click 'Calculate Solution' to see results."
227+ )
223228
224229 else : # Instructions tab
225230 st .header ("How to Use This App" )
0 commit comments