Spaces:
Running
Running
| 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})") | |