srilanka / src /tabs /analytics_tab.py
jbbove's picture
Add landslide early warning report and current situation report for December 19, 2025
e9cdba5
Raw
History Blame Contribute Delete
6.99 kB
"""
Dynamic Analytical Brief tab for the Sri Lanka Disaster Dashboard.
Provides AI-powered trend analysis using LLM (DeepSeek/OpenAI).
"""
import streamlit as st
from datetime import datetime
from pathlib import Path
def render_analytics_tab(sitreps_dir: Path, floods_dir: Path, landslide_dir: Path, generate_trend_summary_func):
"""
Render the Dynamic Analytical Brief tab with AI-powered analysis.
Args:
sitreps_dir: Path to the sitreps data directory
floods_dir: Path to the floods data directory
landslide_dir: Path to the landslide data directory
generate_trend_summary_func: Function to call for generating trend summary
"""
st.header("πŸ€– Dynamic Analytical Brief")
st.markdown("""
AI-powered descriptive analysis of the current disaster situation in Sri Lanka.
The analysis covers:
- **Impact on People and Infrastructure** - Latest situation report data
- **Hazards Overview** - Current flood and landslide warnings
- **Trend Analysis** - Evolution of the situation over time
""")
st.divider()
# Initialize session state for trend summary
if "trend_summary" not in st.session_state:
st.session_state.trend_summary = None
if "trend_summary_error" not in st.session_state:
st.session_state.trend_summary_error = None
# Controls section
col_btn, col_warning = st.columns([1, 3])
with col_btn:
generate_clicked = st.button(
"πŸ€– Generate AI Analysis",
use_container_width=True,
type="primary",
help="Generates a comprehensive trend analysis using AI"
)
with col_warning:
st.info(
"⚠️ **Please use responsibly:** Only regenerate after several new situation reports "
"have been published to avoid unnecessary API usage."
)
if generate_clicked:
with st.spinner("πŸ”„ Analyzing situation reports, flood and landslide data..."):
result = generate_trend_summary_func(sitreps_dir, floods_dir, landslide_dir)
if result["success"]:
st.session_state.trend_summary = result["summary"]
st.session_state.trend_summary_meta = {
"provider": result.get("provider", "Unknown"),
"num_reports": result.get("num_reports", 0),
"date_range": result.get("date_range", {}),
"sitrep_date": result.get("sitrep_date", ""),
"flood_date": result.get("flood_date", ""),
"landslide_date": result.get("landslide_date", ""),
"generated_at": datetime.now().strftime("%Y-%m-%d %H:%M")
}
st.session_state.trend_summary_error = None
else:
st.session_state.trend_summary = None
st.session_state.trend_summary_error = result.get("error", "Unknown error occurred")
st.divider()
# Display the summary or placeholder
if st.session_state.trend_summary:
meta = st.session_state.get("trend_summary_meta", {})
# Metadata row - Data sources
st.subheader("πŸ“… Data Sources")
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Sitrep Date", meta.get('sitrep_date', 'N/A')[:20] if meta.get('sitrep_date') else 'N/A')
with col2:
st.metric("Flood Report", meta.get('flood_date', 'N/A')[:20] if meta.get('flood_date') else 'N/A')
with col3:
st.metric("Landslide Report", meta.get('landslide_date', 'N/A')[:20] if meta.get('landslide_date') else 'N/A')
with col4:
st.metric("Sitreps for Trends", meta.get('num_reports', '?'))
# AI Info row
col_ai, col_gen = st.columns(2)
with col_ai:
st.caption(f"πŸ€– AI Provider: {meta.get('provider', 'Unknown')}")
with col_gen:
st.caption(f"πŸ• Generated: {meta.get('generated_at', 'Unknown')}")
st.divider()
# Display the summary in a styled container
st.subheader("πŸ“‹ Analysis Report")
with st.container():
st.markdown(st.session_state.trend_summary)
elif st.session_state.trend_summary_error:
st.error(f"❌ {st.session_state.trend_summary_error}")
else:
# Placeholder when no analysis has been generated
st.markdown(
"""
<div style="padding: 40px; background-color: #f0f2f6; border-radius: 10px; text-align: center; margin-top: 20px;">
<h3 style="color: #333; margin-bottom: 10px;">πŸ“Š No Analysis Generated Yet</h3>
<p style="color: #666; margin: 0;">
Click <strong>"Generate AI Analysis"</strong> above to generate a comprehensive analytical brief.
</p>
<p style="color: #888; font-size: 14px; margin-top: 15px;">
The analysis includes:
</p>
<ul style="color: #888; font-size: 14px; text-align: left; display: inline-block;">
<li>🌍 Situation and Hazards overview (floods + landslides)</li>
<li>πŸ‘₯ Impact on Population (affected, deaths, displaced)</li>
<li>🏠 Impact on Infrastructure (house damage)</li>
<li>πŸ“ˆ Trend Analysis across all available reports</li>
</ul>
</div>
""",
unsafe_allow_html=True
)
# Data sources info
st.divider()
with st.expander("ℹ️ About This Analysis"):
st.markdown("""
### Analysis Structure
**🌍 SITUATION and HAZARDS**
- Overall context of the disaster situation
- Current flood alerts (Major/Minor/Alert/Normal levels)
- Active landslide warnings (Level 1/2/3 by district)
**πŸ‘₯ IMPACT ON POPULATION**
- People affected with changes from previous report
- Deaths and missing persons
- Displaced populations and top affected districts
**🏠 IMPACT ON INFRASTRUCTURE**
- Houses fully destroyed and partially damaged
- Most affected districts for infrastructure damage
**πŸ“ˆ TREND ANALYSIS**
- Evolution of the situation over time
- Whether conditions are improving, worsening, or stabilizing
- Key metric changes between reports
### Data Sources
- **Situation Reports**: Official DMC situation reports (PDF extracted)
- **Flood Data**: Water level and rainfall reports
- **Landslide Data**: Early warning bulletins from NBRO
### AI Providers
- **Primary**: DeepSeek AI (cost-effective, high quality)
- **Fallback**: OpenAI GPT-4o-mini (if DeepSeek is unavailable)
""")