import streamlit as st import requests from geopy.distance import great_circle import folium from streamlit_folium import st_folium from datetime import datetime def format_datetime(iso_string): # Convert ISO 8601 string to datetime object dt_object = datetime.fromisoformat(iso_string) # Format as DD-MM-YYYY and 24-hour time return dt_object.strftime("%d-%m-%Y %H:%M") # Expanded list of Indian cities with their latitude and longitude cities = { "Visakhapatnam": (17.6868, 83.2185), "Delhi": (28.6139, 77.2090), "Mumbai": (19.0760, 72.8777), "Bangalore": (12.9716, 77.5946), "Chennai": (13.0827, 80.2707), "Kolkata": (22.5726, 88.3639), "Hyderabad": (17.3850, 78.4867), "Pune": (18.5204, 73.8567), "Jaipur": (26.9124, 75.7873), "Ahmedabad": (23.0225, 72.5714), "Surat": (21.1702, 72.8311), "Lucknow": (26.8467, 80.9462), "Kanpur": (26.4499, 80.3319), "Nagpur": (21.1458, 79.0882), "Indore": (22.7196, 75.8577), "Bhopal": (23.2599, 77.4126), "Patna": (25.5941, 85.1376), "Vadodara": (22.3072, 73.1812), "Ludhiana": (30.9010, 75.8573), "Agra": (27.1767, 78.0081), "Nashik": (19.9975, 73.7898), "Faridabad": (28.4089, 77.3178), "Meerut": (28.9845, 77.7064), "Rajkot": (22.3039, 70.8022), "Varanasi": (25.3176, 82.9739), "Srinagar": (34.0837, 74.7973), "Amritsar": (31.6340, 74.8723), "Navi Mumbai": (19.0330, 73.0297), "Allahabad": (25.4358, 81.8463), "Ranchi": (23.3441, 85.3096), "Coimbatore": (11.0168, 76.9558), "Jabalpur": (23.1815, 79.9864), "Gwalior": (26.2183, 78.1828), "Vijayawada": (16.5062, 80.6480), "Jodhpur": (26.2389, 73.0243), "Madurai": (9.9252, 78.1198), "Raipur": (21.2514, 81.6296), "Kota": (25.2138, 75.8648), "Guwahati": (26.1445, 91.7362), "Chandigarh": (30.7333, 76.7794), "Solapur": (17.6599, 75.9064) } def get_weather(lat, lon): # Using Open-Meteo API url = f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}¤t_weather=true" response = requests.get(url) if response.status_code == 200: data = response.json() current_weather = data['current_weather'] weather = { 'temperature': current_weather['temperature'], 'wind_speed': current_weather['windspeed'], 'wind_direction': current_weather['winddirection'], 'time': current_weather['time'] } return weather else: return None def find_nearest_city(lat, lon): min_distance = float('inf') nearest_city = None for city, (city_lat, city_lon) in cities.items(): distance = great_circle((lat, lon), (city_lat, city_lon)).kilometers if distance < min_distance: min_distance = distance nearest_city = city return nearest_city # Streamlit Layout st.set_page_config(page_title="Indian Cities Weather", layout="wide") st.title("🌤️ Indian Cities Weather App") # Dropdown Menu st.sidebar.subheader("Select a City") selected_city = st.sidebar.selectbox("Choose a city:", list(cities.keys())) # Show weather for selected city if selected_city: lat, lon = cities[selected_city] weather = get_weather(lat, lon) if weather: st.markdown(f"### Weather in {selected_city}") st.markdown(f"- 🌡️ Temperature: **{weather['temperature']}°C**") st.markdown(f"- 💨 Wind Speed: **{weather['wind_speed']} km/h**") st.markdown(f"- 🧭 Wind Direction: **{weather['wind_direction']}°**") formatted_time = format_datetime(weather['time']) st.markdown(f"- 🕒 Reported at: **{formatted_time}**") # Interactive Map with Clickable Markers st.subheader("📍 Click on the Map or Select a City to Get Weather Information") # Create a map with OpenStreetMap tiles for better compatibility m = folium.Map(location=[22.9734, 78.6569], zoom_start=5, tiles='OpenStreetMap', attr='Map data © OpenStreetMap contributors') # Add markers with popups for each city for city, (lat, lon) in cities.items(): weather = get_weather(lat, lon) if weather: popup_text = (f"{city}
" f"🌡️ Temp: {weather['temperature']}°C
" f"💨 Wind: {weather['wind_speed']} km/h
" f"🧭 Dir: {weather['wind_direction']}°
" f"🕒 Time: {weather['time']}") folium.Marker( [lat, lon], popup=folium.Popup(popup_text, max_width=250), tooltip=city, icon=folium.Icon(color='blue', icon='info-sign') ).add_to(m) # Display map in Streamlit clicked_location = st_folium(m, width=800, height=600) # Get weather of nearest city when clicking on map if clicked_location and clicked_location['last_clicked']: lat = clicked_location['last_clicked']['lat'] lon = clicked_location['last_clicked']['lng'] nearest_city = find_nearest_city(lat, lon) if nearest_city: st.markdown(f"### Nearest City: **{nearest_city}**") nearest_lat, nearest_lon = cities[nearest_city] weather = get_weather(nearest_lat, nearest_lon) if weather: st.markdown(f"- 🌡️ Temperature: **{weather['temperature']}°C**") st.markdown(f"- 💨 Wind Speed: **{weather['wind_speed']} km/h**") st.markdown(f"- 🧭 Wind Direction: **{weather['wind_direction']}°**") st.markdown(f"- 🕒 Reported at: **{weather['time']}**") st.markdown("", unsafe_allow_html=True) # Footer st.markdown( """ """, unsafe_allow_html=True, )