Spaces:
Sleeping
Sleeping
| 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"<b>{city}</b><br>" | |
| f"🌡️ Temp: {weather['temperature']}°C<br>" | |
| f"💨 Wind: {weather['wind_speed']} km/h<br>" | |
| f"🧭 Dir: {weather['wind_direction']}°<br>" | |
| 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("<style>body {background-color: #F0F8FF;}</style>", unsafe_allow_html=True) | |
| # Footer | |
| st.markdown( | |
| """ | |
| <div class="footer"> | |
| Developed by <b>SKB</b> | © 2025. All Rights Reserved | |
| </div> | |
| """, | |
| unsafe_allow_html=True, | |
| ) | |