import streamlit as st import openrouteservice from openrouteservice import convert import requests from geopy.geocoders import Nominatim import folium from streamlit_folium import st_folium import os from urllib.parse import quote # Page setup st.set_page_config(page_title="Commute Planner", layout="centered") st.title("🚗 Commute Planner") st.markdown("Estimate travel time, view the route, check weather, air quality, and traffic alerts.") # API keys ORS_API_KEY = os.getenv("ORS_API_KEY", st.secrets.get("ORS_API_KEY", "")) OWM_API_KEY = os.getenv("OWM_API_KEY", st.secrets.get("OWM_API_KEY", "")) # Initialize services client = openrouteservice.Client(key=ORS_API_KEY) geolocator = Nominatim(user_agent="commute_planner") # Transport options transport_modes = { "Driving": "driving-car", "Walking": "foot-walking", "Cycling": "cycling-regular", "Transit (experimental)": "driving-hgv" } # Inputs start_location = st.text_input("Enter Start Location", key="start") end_location = st.text_input("Enter Destination", key="end") mode = st.selectbox("Select Transportation Mode", list(transport_modes.keys()), key="mode") submit = st.button("Get Route") # Route planning if submit or st.session_state.get("show_results"): if submit: try: start_coords = geolocator.geocode(start_location) end_coords = geolocator.geocode(end_location) if not start_coords or not end_coords: st.error("Could not geocode one of the locations.") else: start_point = [start_coords.longitude, start_coords.latitude] end_point = [end_coords.longitude, end_coords.latitude] route = client.directions( coordinates=[start_point, end_point], profile=transport_modes[mode], format="geojson" ) distance_km = route['features'][0]['properties']['segments'][0]['distance'] / 1000 duration_min = route['features'][0]['properties']['segments'][0]['duration'] / 60 st.session_state["show_results"] = True st.session_state["distance_km"] = distance_km st.session_state["duration_min"] = duration_min st.session_state["start_coords"] = [start_coords.latitude, start_coords.longitude] st.session_state["end_coords"] = [end_coords.latitude, end_coords.longitude] st.session_state["route"] = route st.session_state["start_location_name"] = start_coords.address st.session_state["end_location_name"] = end_coords.address except Exception as e: st.error(f"Error: {e}") # Results if st.session_state.get("show_results"): st.success(f"**Distance:** {st.session_state['distance_km']:.2f} km") st.success(f"**Estimated Duration:** {st.session_state['duration_min']:.1f} minutes") # Route map route = st.session_state["route"] m = folium.Map(location=st.session_state["start_coords"], zoom_start=13) folium.Marker(st.session_state["start_coords"], tooltip="Start", icon=folium.Icon(color='green')).add_to(m) folium.Marker(st.session_state["end_coords"], tooltip="End", icon=folium.Icon(color='red')).add_to(m) folium.GeoJson(route, name="Route").add_to(m) st_folium(m, width=700, height=500) # Weather and AQI lat, lon = st.session_state["start_coords"] weather_url = f"https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={OWM_API_KEY}&units=metric" air_url = f"http://api.openweathermap.org/data/2.5/air_pollution?lat={lat}&lon={lon}&appid={OWM_API_KEY}" try: weather = requests.get(weather_url).json() air = requests.get(air_url).json() temp = weather['main']['temp'] condition = weather['weather'][0]['description'].capitalize() aqi = air['list'][0]['main']['aqi'] st.info(f"**Current Temperature:** {temp}°C") st.info(f"**Weather Condition:** {condition}") st.info(f"**Air Quality Index (AQI):** {aqi} (1=Good, 5=Very Poor)") except: st.warning("Could not fetch weather or air quality data.") # 🔎 News Alerts (Protests, Traffic, Closures) st.subheader("🚨 Local Alerts: Traffic, Closures, Protests") start_loc = st.session_state.get("start_location_name", start_location) end_loc = st.session_state.get("end_location_name", end_location) keywords = ["traffic jam", "protest", "road blocked", "highway closed", "accident"] st.markdown("Here are some quick links to news related to your route:") for keyword in keywords: search_query = f"{keyword} near {start_loc} OR {end_loc}" search_url = f"https://www.google.com/search?q={quote(search_query)}" st.markdown(f"- [{keyword.title()} Alerts]({search_url})")