@@ -22,13 +22,7 @@ def get_all_airports(_connection):
2222
2323@st .cache_data
2424def get_routes_for_airports (_connection , selected_airports_df ):
25- airports_faa = "["
26- for i in range (len (selected_airports_df )):
27- if i != len (selected_airports_df ) - 1 :
28- airports_faa += f'"{ (selected_airports_df .iloc [i ])["faa" ]} ", '
29- else :
30- airports_faa += f'"{ (selected_airports_df .iloc [i ])["faa" ]} "'
31- airports_faa += "]"
25+ airports_faa = str (selected_airports_df ["faa" ].to_list ()) # Initialize a string to store FAA codes in a list format
3226 query = f"""
3327 SELECT * FROM `travel-sample`.`inventory`.`route`
3428 WHERE (sourceairport IN { airports_faa } AND destinationairport IN { airports_faa } );
@@ -41,11 +35,8 @@ def get_routes_for_airports(_connection, selected_airports_df):
4135
4236def plot_airports_and_routes (airports_df , routes_df ):
4337 fig = go .Figure ()
44- airport_coords = {
45- row ["faa" ]: (row ["lat" ], row ["lon" ])
46- for _ , row in airports_df .iterrows ()
47- if row ["faa" ] is not None # Ensure faa is not null
48- }
38+ filtered_airports_df = airports_df .dropna (subset = ["faa" ]) # Remove rows where faa is NaN
39+ airport_coords = dict (zip (filtered_airports_df ["faa" ], zip (filtered_airports_df ["lat" ], filtered_airports_df ["lon" ])))
4940 lats = []
5041 lons = []
5142 for _ , row in routes_df .iterrows ():
@@ -75,7 +66,10 @@ def plot_airports_and_routes(airports_df, routes_df):
7566 color_discrete_sequence = ["red" ], # Color of airport markers
7667 )
7768 fig .add_traces (airports_markers .data )
69+ fig .update_geos (fitbounds = "locations" )
7870 fig .update_layout (
71+ map_zoom = 0.5 , # Zoom level
72+ showlegend = False , # Hide legend
7973 mapbox_style = "open-street-map" ,
8074 margin = dict (l = 0 , r = 0 , t = 50 , b = 0 ), # Remove extra margins
8175 title = "Airports and Flight Routes"
@@ -202,7 +196,11 @@ def get_hotels_near_landmark(_connection, landmark_lat, landmark_lon, max_distan
202196 return hotels
203197
204198def create_landmark_map (landmarks , hotels_near_landmark ):
205- fig = go .Figure ()
199+ fig = go .Figure ()
200+
201+ centre = {"lat" : 0 , "lon" : 0 }
202+ num_points = 0
203+
206204 for hotel in hotels_near_landmark :
207205 color = 'red' if hotel .get ('distance' ) <= 3 else 'orange' if hotel .get ('distance' ) <= 6 else 'gold'
208206 fig .add_trace (go .Scattermap (
@@ -216,6 +214,8 @@ def create_landmark_map(landmarks, hotels_near_landmark):
216214 hoverinfo = 'text' ,
217215 name = f'Hotel ({ color } )'
218216 ))
217+ centre = {"lat" : centre ["lat" ] + hotel .get ('lat' ), "lon" : centre ["lon" ] + hotel .get ('lon' )}
218+ num_points += 1
219219
220220 for landmark in landmarks :
221221 fig .add_trace (go .Scattermap (
@@ -229,8 +229,16 @@ def create_landmark_map(landmarks, hotels_near_landmark):
229229 hoverinfo = 'text' ,
230230 name = 'Landmark'
231231 ))
232+ centre = {"lat" : centre ["lat" ] + landmark .get ('lat' , 0 ), "lon" : centre ["lon" ] + landmark .get ('lon' , 0 )}
233+ num_points += 1
234+
235+ if num_points > 0 :
236+ centre = {"lat" : centre ["lat" ] / num_points , "lon" : centre ["lon" ] / num_points }
237+ fig .update_geos (fitbounds = "locations" )
232238
233239 fig .update_layout (
240+ map_zoom = 11 ,
241+ map_center = centre ,
234242 mapbox_style = 'open-street-map' ,
235243 margin = dict (l = 0 , r = 0 , t = 50 , b = 0 ),
236244 title = 'Landmarks and Hotels Nearby' ,
@@ -275,13 +283,7 @@ def get_all_cities(_connection):
275283
276284@st .cache_data
277285def get_all_hotels (_connection , cities ):
278- cities_str = "["
279- for i in range (len (cities )):
280- if i != len (cities ) - 1 :
281- cities_str += f'"{ cities [i ]} ", '
282- else :
283- cities_str += f'"{ cities [i ]} "'
284- cities_str += "]"
286+ cities_str = f"{ cities } "
285287 query = f"""
286288 SELECT h.*, geo.lat as lat, geo.lon as lon, ARRAY_AVG(ARRAY r.ratings.Overall FOR r IN h.reviews WHEN r.ratings.Overall IS NOT MISSING END) as avg_rating
287289 FROM `travel-sample`.inventory.hotel h
@@ -318,6 +320,10 @@ def create_hotel_map(hotels_df):
318320 if 'avg_rating' not in hotels_df .columns :
319321 hotels_df ['avg_rating' ] = np .nan # Add avg_rating column if it doesn't exist
320322 hotels_df ['avg_rating' ] = pd .to_numeric (hotels_df ['avg_rating' ], errors = 'coerce' )
323+ centre = {
324+ "lat" : hotels_df ['lat' ].mean (),
325+ "lon" : hotels_df ['lon' ].mean ()
326+ }
321327
322328 # Create a column for star ratings
323329 hotels_df ['star_rating' ] = hotels_df ['avg_rating' ].apply (lambda x : '⭐' * int (round (x )) if not np .isnan (x ) else 'No rating' )
@@ -363,6 +369,8 @@ def create_hotel_map(hotels_df):
363369 fig .add_traces (no_rating_markers .data )
364370
365371 fig .update_layout (
372+ map_zoom = 10 ,
373+ map_center = centre ,
366374 mapbox_style = "open-street-map" ,
367375 margin = dict (l = 0 , r = 0 , t = 50 , b = 0 ),
368376 title = "Hotels (colored by average rating)" ,
@@ -373,18 +381,11 @@ def create_hotel_map(hotels_df):
373381 )
374382 )
375383
376- fig .update_layout (
377- mapbox_style = "open-street-map" ,
378- margin = dict (l = 0 , r = 0 , t = 50 , b = 0 ),
379- title = "Hotels (colored by average rating)" ,
380- coloraxis_colorbar_title = "Avg Rating"
381- )
382-
383384 st .plotly_chart (fig , use_container_width = True )
384385
385386def tab3_visual ():
386387 all_cities = get_all_cities (connection )["city" ].tolist ()
387- cities = st .multiselect ("Select cities" , all_cities , default = ["Newport" , "Birmingham" , " London" ])
388+ cities = st .multiselect ("Select cities" , all_cities , default = ["London" ])
388389 hotels = get_all_hotels (connection , cities )
389390 create_hotel_map (hotels )
390391
0 commit comments