niobures's picture
Remote Sensing Collection (code, models, papers)
96d632b verified
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)