File size: 6,004 Bytes
90d1814
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
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}&current_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,
)