|
|
""" |
|
|
UI Components for Traffic Accident Reconstruction System |
|
|
======================================================== |
|
|
Reusable Streamlit components for the application. |
|
|
""" |
|
|
|
|
|
import streamlit as st |
|
|
from config import CASE_STUDY_LOCATION, ALTERNATIVE_LOCATIONS |
|
|
|
|
|
|
|
|
def render_sidebar(): |
|
|
"""Render the application sidebar.""" |
|
|
|
|
|
with st.sidebar: |
|
|
|
|
|
try: |
|
|
st.image("assets/mindspore_logo.png", width=120) |
|
|
except: |
|
|
st.markdown("### π€ MindSpore") |
|
|
|
|
|
st.markdown("---") |
|
|
|
|
|
st.header("π Accident Analyzer") |
|
|
|
|
|
st.markdown(""" |
|
|
This system helps traffic authorities |
|
|
understand accidents through: |
|
|
|
|
|
- **AI-powered** scenario generation |
|
|
- **Real map** visualization |
|
|
- **2D simulation** of accidents |
|
|
- **Probability analysis** of scenarios |
|
|
""") |
|
|
|
|
|
st.markdown("---") |
|
|
|
|
|
st.subheader("π Case Study Location") |
|
|
|
|
|
st.info(f""" |
|
|
**{CASE_STUDY_LOCATION['name']}** |
|
|
|
|
|
π {CASE_STUDY_LOCATION['city']}, {CASE_STUDY_LOCATION['country']} |
|
|
|
|
|
πΊοΈ Lat: {CASE_STUDY_LOCATION['latitude']:.4f} |
|
|
πΊοΈ Lng: {CASE_STUDY_LOCATION['longitude']:.4f} |
|
|
""") |
|
|
|
|
|
st.markdown("---") |
|
|
|
|
|
st.subheader("π Help") |
|
|
|
|
|
with st.expander("How to use"): |
|
|
st.markdown(""" |
|
|
1. **Select Location**: View the roundabout location |
|
|
2. **Vehicle 1**: Enter first vehicle details and draw its path |
|
|
3. **Vehicle 2**: Enter second vehicle details and draw its path |
|
|
4. **Analyze**: Let AI generate possible scenarios |
|
|
5. **Results**: View scenarios with probability scores |
|
|
""") |
|
|
|
|
|
with st.expander("About MindSpore"): |
|
|
st.markdown(""" |
|
|
This system uses **Huawei MindSpore** |
|
|
for AI-powered scenario generation. |
|
|
|
|
|
MindSpore is an open-source deep |
|
|
learning framework optimized for |
|
|
Ascend processors. |
|
|
""") |
|
|
|
|
|
st.markdown("---") |
|
|
|
|
|
st.caption("Huawei AI Innovation Challenge 2026") |
|
|
|
|
|
|
|
|
def render_header(): |
|
|
"""Render the application header.""" |
|
|
|
|
|
st.markdown(""" |
|
|
<div style=" |
|
|
background: linear-gradient(135deg, #1e3a5f 0%, #2d5a87 100%); |
|
|
padding: 2rem; |
|
|
border-radius: 10px; |
|
|
color: white; |
|
|
margin-bottom: 2rem; |
|
|
text-align: center; |
|
|
"> |
|
|
<h1 style="margin: 0; font-size: 2.5rem;">π Traffic Accident Reconstruction System</h1> |
|
|
<p style="margin: 0.5rem 0 0 0; opacity: 0.9;">AI-Powered Analysis using Huawei MindSpore</p> |
|
|
</div> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
def render_footer(): |
|
|
"""Render the application footer.""" |
|
|
|
|
|
st.markdown("---") |
|
|
|
|
|
col1, col2, col3 = st.columns([2, 1, 2]) |
|
|
|
|
|
with col1: |
|
|
st.markdown("π **Huawei AI Innovation Challenge 2026**") |
|
|
|
|
|
with col2: |
|
|
|
|
|
try: |
|
|
st.image("assets/mindspore_logo.png", width=80) |
|
|
except: |
|
|
st.markdown("**[M]**") |
|
|
|
|
|
with col3: |
|
|
st.markdown("π€ **Powered by MindSpore AI Framework**") |
|
|
|
|
|
|
|
|
def render_info_card(title: str, content: str, color: str = "#2d5a87"): |
|
|
"""Render an information card.""" |
|
|
|
|
|
st.markdown(f""" |
|
|
<div style=" |
|
|
background: #f8f9fa; |
|
|
padding: 1.5rem; |
|
|
border-radius: 10px; |
|
|
border-left: 4px solid {color}; |
|
|
margin: 1rem 0; |
|
|
"> |
|
|
<h4 style="margin: 0 0 0.5rem 0;">{title}</h4> |
|
|
<p style="margin: 0;">{content}</p> |
|
|
</div> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
def render_metric_card(label: str, value: str, delta: str = None, color: str = "#2d5a87"): |
|
|
"""Render a metric card.""" |
|
|
|
|
|
delta_html = "" |
|
|
if delta: |
|
|
delta_color = "#28a745" if "+" in delta or "High" in delta else "#dc3545" |
|
|
delta_html = f'<span style="color: {delta_color}; font-size: 0.9rem;">{delta}</span>' |
|
|
|
|
|
st.markdown(f""" |
|
|
<div style=" |
|
|
background: rgba(255, 255, 255, 0.08); |
|
|
backdrop-filter: blur(10px); |
|
|
padding: 1.5rem; |
|
|
border-radius: 12px; |
|
|
border-top: 3px solid {color}; |
|
|
text-align: center; |
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.2); |
|
|
border: 1px solid rgba(255, 255, 255, 0.12); |
|
|
"> |
|
|
<p style="margin: 0; color: rgba(255, 255, 255, 0.7); font-size: 0.9rem; font-weight: 500;">{label}</p> |
|
|
<h2 style="margin: 0.5rem 0; color: {color}; font-weight: 700;">{value}</h2> |
|
|
{delta_html} |
|
|
</div> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
def render_progress_bar(value: float, label: str = "", color: str = "#2d5a87"): |
|
|
"""Render a custom progress bar.""" |
|
|
|
|
|
percentage = min(max(value * 100, 0), 100) |
|
|
|
|
|
st.markdown(f""" |
|
|
<div style="margin: 0.5rem 0;"> |
|
|
<div style="display: flex; justify-content: space-between; margin-bottom: 0.25rem;"> |
|
|
<span>{label}</span> |
|
|
<span>{percentage:.1f}%</span> |
|
|
</div> |
|
|
<div style=" |
|
|
background: #e9ecef; |
|
|
border-radius: 5px; |
|
|
height: 20px; |
|
|
overflow: hidden; |
|
|
"> |
|
|
<div style=" |
|
|
background: {color}; |
|
|
width: {percentage}%; |
|
|
height: 100%; |
|
|
border-radius: 5px; |
|
|
transition: width 0.3s ease; |
|
|
"></div> |
|
|
</div> |
|
|
</div> |
|
|
""", unsafe_allow_html=True) |
|
|
|