File size: 12,070 Bytes
96d632b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
import streamlit as st
import pandas as pd
import numpy as np
import joblib
import json
import folium
from streamlit_folium import st_folium
import plotly.graph_objects as go
import plotly.express as px
from datetime import datetime, timedelta
import requests

# Page configuration
st.set_page_config(
    page_title="Charsadda Flood Prediction System",
    page_icon="๐ŸŒŠ",
    layout="wide",
    initial_sidebar_state="expanded"
)

# Custom CSS
st.markdown("""<style>
.main-header {
    font-size: 2.5rem;
    font-weight: bold;
    color: #1f77b4;
    text-align: center;
    margin-bottom: 2rem;
}
.warning-box {
    background-color: #fff3cd;
    border-left: 5px solid #ffc107;
    padding: 1rem;
    margin: 1rem 0;
}
.danger-box {
    background-color: #f8d7da;
    border-left: 5px solid #dc3545;
    padding: 1rem;
    margin: 1rem 0;
}
.safe-box {
    background-color: #d4edda;
    border-left: 5px solid #28a745;
    padding: 1rem;
    margin: 1rem 0;
}
</style>""", unsafe_allow_html=True)

# Load model and scaler
@st.cache_resource
def load_models():
    try:
        rf_model = joblib.load('random_forest_model.pkl')
        scaler = joblib.load('scaler.pkl')
        with open('model_metadata.json', 'r') as f:
            metadata = json.load(f)
        return rf_model, scaler, metadata
    except Exception as e:
        st.error(f"Error loading models: {e}")
        return None, None, None

rf_model, scaler, metadata = load_models()

# Header
st.markdown('<div class="main-header">๐ŸŒŠ AI-Powered Flood Prediction System</div>', unsafe_allow_html=True)
st.markdown("### Charsadda, Khyber Pakhtunkhwa, Pakistan")

# Sidebar
with st.sidebar:
    st.image("https://upload.wikimedia.org/wikipedia/commons/thumb/3/32/Flag_of_Pakistan.svg/320px-Flag_of_Pakistan.svg.png", width=150)
    st.title("Navigation")
    page = st.radio("Select Page", ["๐Ÿ  Home", "๐Ÿ”ฎ Flood Prediction", "๐Ÿ—บ๏ธ Interactive Map", "๐Ÿ“Š Model Info", "โ„น๏ธ About"])
    st.markdown("---")
    st.markdown("### Study Area")
    st.markdown("**Location:** Charsadda District")
    st.markdown("**Province:** Khyber Pakhtunkhwa")
    st.markdown("**Coordinates:** 34.15ยฐN, 71.72ยฐE")

# HOME PAGE
if page == "๐Ÿ  Home":
    col1, col2 = st.columns(2)
    with col1:
        st.markdown("### ๐Ÿ“‹ Project Overview")
        st.write("""This AI-powered system predicts flood risks in Charsadda district using:
        - **Satellite imagery** (Sentinel-1 SAR & Sentinel-2 optical)
        - **Weather data** (temperature, humidity, rainfall)
        - **Topographic data** (elevation, slope)
        - **Machine Learning** (Random Forest, CNN, LSTM models)""")
        st.markdown("### ๐ŸŽฏ Key Features")
        st.markdown("""- โœ… Real-time flood risk assessment
        - โœ… Multi-source data integration
        - โœ… Interactive flood mapping
        - โœ… 1-3 day advance predictions
        - โœ… High-accuracy ML models""")
    with col2:
        st.markdown("### ๐Ÿ“ˆ Historical Floods")
        st.info("""**2022 Flood (August 25-31)**\n- Affected thousands of people\n- Major infrastructure damage\n- Rivers Swat and Kabul overflowed\n\n**2025 Floods (June & August)**\n- Multiple flood events\n- ~35 kmยฒ area affected\n- ~41,000 people impacted""")
        st.markdown("### ๐Ÿšจ Current Status")
        st.success("System operational and monitoring ongoing")

# FLOOD PREDICTION PAGE
elif page == "๐Ÿ”ฎ Flood Prediction":
    st.markdown("## Flood Risk Prediction")
    tab1, tab2 = st.tabs(["๐Ÿ“ค Upload Data", "โŒจ๏ธ Manual Input"])
    
    with tab1:
        st.markdown("### Upload Weather Forecast CSV")
        st.info("Upload a CSV file with columns: temperature, humidity, rainfall, pressure, wind_speed")
        uploaded_file = st.file_uploader("Choose a CSV file", type=['csv'])
        
        if uploaded_file is not None:
            df = pd.read_csv(uploaded_file)
            st.write("**Preview of uploaded data:**")
            st.dataframe(df.head())
            
            if st.button("Predict Flood Risk", key="predict_upload"):
                df['VV'] = -10
                df['B2'] = 800
                df['B3'] = 900
                df['B4'] = 600
                df['B8'] = 2000
                df['B11'] = 1500
                df['NDWI'] = 0.0
                df['MNDWI'] = 0.0
                df['NDVI'] = 0.4
                df['elevation'] = 300
                df['slope'] = 2
                
                feature_order = metadata['features']
                df = df[feature_order]
                X_scaled = scaler.transform(df)
                predictions = rf_model.predict(X_scaled)
                probabilities = rf_model.predict_proba(X_scaled)[:, 1]
                
                df['Flood_Risk'] = predictions
                df['Confidence'] = probabilities * 100
                
                st.markdown("### Prediction Results")
                flood_count = predictions.sum()
                col1, col2, col3 = st.columns(3)
                col1.metric("Total Predictions", len(predictions))
                col2.metric("Flood Risk Days", int(flood_count))
                col3.metric("Risk Percentage", f"{flood_count/len(predictions)*100:.1f}%")
                st.dataframe(df[['temperature', 'humidity', 'rainfall', 'Flood_Risk', 'Confidence']])
    
    with tab2:
        st.markdown("### Manual Weather Input")
        col1, col2 = st.columns(2)
        
        with col1:
            temperature = st.slider("Temperature (ยฐC)", 15.0, 45.0, 30.0, 0.5)
            humidity = st.slider("Humidity (%)", 30.0, 100.0, 70.0, 1.0)
            rainfall = st.slider("Rainfall (mm)", 0.0, 300.0, 50.0, 5.0)
        with col2:
            pressure = st.slider("Pressure (hPa)", 950.0, 1050.0, 1010.0, 1.0)
            wind_speed = st.slider("Wind Speed (m/s)", 0.0, 30.0, 5.0, 0.5)
        
        if st.button("Predict Flood Risk", key="predict_manual"):
            input_data = pd.DataFrame([{
                'VV': -10, 'B2': 800, 'B3': 900, 'B4': 600, 'B8': 2000, 'B11': 1500,
                'NDWI': 0.0, 'MNDWI': 0.0, 'NDVI': 0.4, 'elevation': 300, 'slope': 2,
                'temperature': temperature, 'humidity': humidity, 'rainfall': rainfall,
                'pressure': pressure, 'wind_speed': wind_speed
            }])
            
            input_data = input_data[metadata['features']]
            X_scaled = scaler.transform(input_data)
            prediction = rf_model.predict(X_scaled)[0]
            probability = rf_model.predict_proba(X_scaled)[0, 1] * 100
            
            st.markdown("---")
            st.markdown("### Prediction Result")
            
            if prediction == 1:
                if probability > 75:
                    st.markdown(f'<div class="danger-box"><h3>๐Ÿšจ HIGH FLOOD RISK</h3><p>Confidence: {probability:.1f}%</p><p><strong>Action Required:</strong> Immediate evacuation recommended.</p></div>', unsafe_allow_html=True)
                else:
                    st.markdown(f'<div class="warning-box"><h3>โš ๏ธ MODERATE FLOOD RISK</h3><p>Confidence: {probability:.1f}%</p><p><strong>Action Required:</strong> Stay alert.</p></div>', unsafe_allow_html=True)
            else:
                st.markdown(f'<div class="safe-box"><h3>โœ… LOW FLOOD RISK</h3><p>Confidence: {100-probability:.1f}%</p><p>Conditions are favorable.</p></div>', unsafe_allow_html=True)
            
            fig = go.Figure(go.Indicator(
                mode="gauge+number", value=probability, title={'text': "Flood Risk Level"},
                gauge={'axis': {'range': [0, 100]}, 'bar': {'color': "darkblue"},
                       'steps': [{'range': [0, 33], 'color': "lightgreen"},
                                 {'range': [33, 66], 'color': "yellow"},
                                 {'range': [66, 100], 'color': "red"}],
                       'threshold': {'line': {'color': "red", 'width': 4}, 'thickness': 0.75, 'value': 50}}
            ))
            fig.update_layout(height=300)
            st.plotly_chart(fig, use_container_width=True)

# INTERACTIVE MAP PAGE
elif page == "๐Ÿ—บ๏ธ Interactive Map":
    st.markdown("## Interactive Flood Risk Map")
    st.info("This map shows the Charsadda study area with historical flood zones.")
    
    m = folium.Map(location=[34.15, 71.72], zoom_start=11)
    boundary_coords = [[34.05, 71.55], [34.05, 71.90], [34.25, 71.90], [34.25, 71.55], [34.05, 71.55]]
    folium.Polygon(locations=boundary_coords, color='red', weight=3, fill=False, popup='Charsadda Study Area').add_to(m)
    folium.Marker([34.15, 71.72], popup='Charsadda Center', tooltip='Charsadda District', icon=folium.Icon(color='blue', icon='info-sign')).add_to(m)
    
    flood_zones = [([34.10, 71.65], '2022 Flood Zone', 'red'),
                   ([34.18, 71.75], '2025 June Flood', 'orange'),
                   ([34.12, 71.80], '2025 August Flood', 'darkred')]
    for coords, name, color in flood_zones:
        folium.Circle(location=coords, radius=2000, popup=name, color=color, fill=True, fillColor=color, fillOpacity=0.4).add_to(m)
    
    st_folium(m, width=1000, height=600)
    st.markdown("### Map Legend")
    col1, col2, col3 = st.columns(3)
    col1.markdown("๐Ÿ”ด **2022 Flood Zone**")
    col2.markdown("๐ŸŸ  **2025 June Flood**")
    col3.markdown("๐Ÿ”ด **2025 August Flood**")

# MODEL INFO PAGE
elif page == "๐Ÿ“Š Model Info":
    st.markdown("## Model Information")
    if metadata:
        col1, col2 = st.columns(2)
        with col1:
            st.markdown("### Model Details")
            st.info(f"""**Best Model:** {metadata['best_model']}\n**Training Date:** {metadata['training_date'][:10]}\n**Features:** {metadata['n_features']}\n**Training Samples:** {metadata['training_samples']:,}\n**Test Samples:** {metadata['test_samples']:,}""")
        with col2:
            st.markdown("### Performance Metrics")
            metrics_df = pd.DataFrame(metadata['performance_metrics'])
            st.dataframe(metrics_df, use_container_width=True)
        st.markdown("### Features Used")
        st.write(metadata['features'])
        fig = px.bar(metrics_df, x='Model', y=['Accuracy', 'Precision', 'Recall', 'F1-Score', 'ROC-AUC'], barmode='group', title='Model Performance Comparison')
        st.plotly_chart(fig, use_container_width=True)

# ABOUT PAGE
elif page == "โ„น๏ธ About":
    st.markdown("## About This Project")
    st.markdown("""### AI-Powered Flood Prediction and Emergency Response System
    
#### Objective
To develop an AI-based flood prediction system that provides early warnings and supports efficient coordination of emergency services for Charsadda district, KPK, Pakistan.

#### Methodology
- **Multi-Source Data Fusion:** Combines Sentinel-1 SAR, Sentinel-2 optical imagery, SRTM elevation data, and weather forecasts
- **Machine Learning Models:** Random Forest, CNN, and LSTM models trained on historical flood events (2022 and 2025)
- **Real-time Monitoring:** Integration with OpenWeatherMap API for current conditions
- **Prediction Timeframe:** 1-3 days advance flood risk assessment

#### Data Sources
- **Satellite:** Sentinel-1, Sentinel-2 via Google Earth Engine
- **Elevation:** SRTM Digital Elevation Model
- **Weather:** OpenWeatherMap API
- **Historical Events:** 2022 and 2025 flood data

#### Technical Stack
- **Backend:** Python, scikit-learn, TensorFlow, Google Earth Engine
- **Frontend:** Streamlit
- **Deployment:** Hugging Face Spaces
- **Geospatial:** Folium, Geopandas, GDAL

#### Impact
- Early warning system for flood-prone communities
- Optimized emergency resource allocation
- Reduced flood-related casualties and economic losses
- Enhanced disaster preparedness and response""")
    st.markdown("---")
    st.markdown("### ๐Ÿ“ง Contact & Support")
    st.info("For questions or support, please contact the development team.")

# Footer
st.markdown("---")
st.markdown('<div style="text-align: center; color: gray;"><p>ยฉ 2025 Charsadda Flood Prediction System | Powered by AI & Satellite Data</p></div>', unsafe_allow_html=True)