Samanfatima563474's picture
Create app.py
f053aff verified
import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime, timedelta
import folium
from streamlit_folium import st_folium
import requests
from geopy.distance import geodesic
import time
# Page configuration
st.set_page_config(
page_title="AI City Companion",
page_icon="🌍",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS for modern styling
st.markdown("""
<style>
.main-header {
font-size: 3rem;
font-weight: bold;
text-align: center;
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 2rem;
}
.feature-card {
background: white;
padding: 1.5rem;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
margin: 1rem 0;
border-left: 4px solid #667eea;
}
.emergency-alert {
background: #fee2e2;
border: 1px solid #fecaca;
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
color: #991b1b;
}
.success-alert {
background: #dcfce7;
border: 1px solid #bbf7d0;
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
color: #166534;
}
.metric-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 1rem;
border-radius: 10px;
text-align: center;
margin: 0.5rem;
}
</style>
""", unsafe_allow_html=True)
# Initialize session state
if 'user_location' not in st.session_state:
st.session_state.user_location = [24.8607, 67.0011] # Karachi, Pakistan
if 'user_preferences' not in st.session_state:
st.session_state.user_preferences = {}
if 'search_history' not in st.session_state:
st.session_state.search_history = []
if 'current_itinerary' not in st.session_state:
st.session_state.current_itinerary = []
# Mock data for demonstration
@st.cache_data
def load_mock_data():
# Healthcare & Emergency
healthcare_data = pd.DataFrame({
'name': ['City Hospital', 'Emergency Clinic 24/7', 'Al-Shifa Medical Center', 'Quick Care Pharmacy', 'Blood Bank Center'],
'category': ['Hospital', 'Clinic', 'Hospital', 'Pharmacy', 'Blood Bank'],
'lat': [24.8615, 24.8590, 24.8625, 24.8580, 24.8635],
'lon': [67.0020, 67.0000, 67.0040, 66.9990, 67.0050],
'rating': [4.5, 4.2, 4.7, 4.0, 4.3],
'distance': [0.5, 0.8, 0.3, 1.2, 0.7],
'phone': ['+92-21-111-222', '+92-21-333-444', '+92-21-555-666', '+92-21-777-888', '+92-21-999-000'],
'open_24h': [True, True, False, False, True]
})
# Food & Restaurants
food_data = pd.DataFrame({
'name': ['Halal Biryani House', 'Vegetarian Delight', 'Quick Bites Cafe', 'Traditional Karahi', 'Fresh Juice Corner'],
'category': ['Pakistani', 'Vegetarian', 'Fast Food', 'Pakistani', 'Beverages'],
'lat': [24.8600, 24.8620, 24.8585, 24.8640, 24.8575],
'lon': [67.0015, 67.0035, 66.9995, 67.0055, 66.9985],
'rating': [4.6, 4.3, 4.1, 4.8, 4.2],
'price_range': ['$$', '$', '$', '$$$', '$'],
'dietary': ['Halal', 'Vegetarian', 'Mixed', 'Halal', 'Vegan'],
'crowd_level': ['Medium', 'Low', 'High', 'Medium', 'Low'],
'noise_level': ['Medium', 'Low', 'High', 'Medium', 'Low']
})
# Electronics & Repairs
electronics_data = pd.DataFrame({
'name': ['TechMart Electronics', 'Mobile Repair Hub', 'Laptop Service Center', 'Gadget World', 'SIM Card Center'],
'category': ['Electronics Store', 'Repair Shop', 'Repair Shop', 'Electronics Store', 'Telecom'],
'lat': [24.8610, 24.8595, 24.8630, 24.8570, 24.8645],
'lon': [67.0025, 67.0005, 67.0045, 66.9980, 67.0060],
'rating': [4.4, 4.1, 4.5, 4.3, 4.0],
'services': ['Phones, Laptops, Accessories', 'Phone Repair', 'Laptop Repair', 'All Electronics', 'SIM Cards, Top-up'],
'price_fair': [True, True, False, True, True]
})
# Attractions & Places
attractions_data = pd.DataFrame({
'name': ['Clifton Beach', 'Quaid Mausoleum', 'Empress Market', 'Karachi Zoo', 'Port Grand'],
'category': ['Beach', 'Monument', 'Market', 'Zoo', 'Entertainment'],
'lat': [24.8138, 24.8738, 24.8615, 24.9056, 24.8406],
'lon': [67.0299, 67.0362, 67.0099, 67.0516, 67.0219],
'rating': [4.2, 4.7, 4.0, 3.8, 4.1],
'best_time': ['Evening', 'Morning', 'Morning', 'Morning', 'Evening'],
'crowd_level': ['High', 'Medium', 'High', 'Medium', 'Medium'],
'entry_fee': [0, 0, 0, 50, 0]
})
return healthcare_data, food_data, electronics_data, attractions_data
# Load data
healthcare_df, food_df, electronics_df, attractions_df = load_mock_data()
# Helper functions
def calculate_distance(lat1, lon1, lat2, lon2):
return geodesic((lat1, lon1), (lat2, lon2)).kilometers
def get_recommendations(category, user_prefs=None):
if category == "healthcare":
return healthcare_df.sort_values('rating', ascending=False)
elif category == "food":
df = food_df.copy()
if user_prefs and 'dietary' in user_prefs:
df = df[df['dietary'].str.contains(user_prefs['dietary'], case=False, na=False)]
if user_prefs and 'crowd_preference' in user_prefs:
if user_prefs['crowd_preference'] == 'Low':
df = df[df['crowd_level'] == 'Low']
return df.sort_values('rating', ascending=False)
elif category == "electronics":
return electronics_df.sort_values('rating', ascending=False)
elif category == "attractions":
return attractions_df.sort_values('rating', ascending=False)
def create_map(data_df, center_lat, center_lon):
m = folium.Map(location=[center_lat, center_lon], zoom_start=13)
# Add user location
folium.Marker(
[center_lat, center_lon],
popup="Your Location",
icon=folium.Icon(color='red', icon='user')
).add_to(m)
# Add points of interest
colors = {'Hospital': 'green', 'Clinic': 'blue', 'Pharmacy': 'orange',
'Pakistani': 'red', 'Vegetarian': 'green', 'Fast Food': 'orange',
'Electronics Store': 'purple', 'Repair Shop': 'darkblue',
'Beach': 'lightblue', 'Monument': 'gray', 'Market': 'orange'}
for idx, row in data_df.iterrows():
color = colors.get(row.get('category', 'Unknown'), 'gray')
folium.Marker(
[row['lat'], row['lon']],
popup=f"<b>{row['name']}</b><br>Rating: {row.get('rating', 'N/A')}<br>Category: {row.get('category', 'N/A')}",
icon=folium.Icon(color=color)
).add_to(m)
return m
# Main App
def main():
# Header
st.markdown('<h1 class="main-header">🌍 AI City Companion</h1>', unsafe_allow_html=True)
st.markdown('<p style="text-align: center; font-size: 1.2rem; color: #666;">Your Smart Travel Guide for Safe & Smart City Navigation</p>', unsafe_allow_html=True)
# Sidebar for user preferences
with st.sidebar:
st.header("🎯 Your Preferences")
# Location input
st.subheader("πŸ“ Current Location")
col1, col2 = st.columns(2)
with col1:
user_lat = st.number_input("Latitude", value=24.8607, format="%.4f")
with col2:
user_lon = st.number_input("Longitude", value=67.0011, format="%.4f")
st.session_state.user_location = [user_lat, user_lon]
# Personal preferences
st.subheader("πŸ‘€ Personal Preferences")
dietary_pref = st.selectbox("Dietary Preference", ["Any", "Halal", "Vegetarian", "Vegan"])
crowd_pref = st.selectbox("Crowd Preference", ["Any", "Low", "Medium", "High"])
budget_pref = st.selectbox("Budget Range", ["Any", "$", "$$", "$$$"])
st.session_state.user_preferences = {
'dietary': dietary_pref,
'crowd_preference': crowd_pref,
'budget': budget_pref
}
# Emergency contacts
st.subheader("🚨 Quick Emergency")
if st.button("πŸ₯ Nearest Hospital", use_container_width=True):
st.session_state.emergency_mode = True
if st.button("πŸš“ Police Station", use_container_width=True):
st.info("Emergency: 15 (Police)")
if st.button("πŸš‘ Ambulance", use_container_width=True):
st.info("Emergency: 1122 (Rescue)")
# Main content tabs
tab1, tab2, tab3, tab4, tab5 = st.tabs(["πŸ—ΊοΈ Smart Map", "πŸ” AI Search", "πŸ“‹ Itinerary Builder", "πŸ“Š City Insights", "βš™οΈ Settings"])
with tab1:
st.header("πŸ—ΊοΈ Smart Contextual City Map")
# Map controls
col1, col2, col3, col4 = st.columns(4)
with col1:
map_category = st.selectbox("Show Category", ["All", "Healthcare", "Food", "Electronics", "Attractions"])
with col2:
time_filter = st.selectbox("Time Filter", ["Current", "Morning", "Afternoon", "Evening", "Night"])
with col3:
radius_km = st.slider("Search Radius (km)", 0.5, 10.0, 2.0)
with col4:
show_traffic = st.checkbox("Show Traffic Info")
# Create and display map
if map_category == "All":
all_data = pd.concat([healthcare_df, food_df, electronics_df, attractions_df], ignore_index=True)
elif map_category == "Healthcare":
all_data = healthcare_df
elif map_category == "Food":
all_data = get_recommendations("food", st.session_state.user_preferences)
elif map_category == "Electronics":
all_data = electronics_df
elif map_category == "Attractions":
all_data = attractions_df
# Filter by radius
all_data['distance_calc'] = all_data.apply(
lambda row: calculate_distance(user_lat, user_lon, row['lat'], row['lon']), axis=1
)
filtered_data = all_data[all_data['distance_calc'] <= radius_km]
if not filtered_data.empty:
map_obj = create_map(filtered_data, user_lat, user_lon)
st_folium(map_obj, width=700, height=500)
# Show nearby places
st.subheader(f"πŸ“ Nearby Places ({len(filtered_data)} found)")
for idx, row in filtered_data.head(5).iterrows():
with st.expander(f"{row['name']} - {row.get('category', 'Unknown')} ({row['distance_calc']:.1f}km)"):
col1, col2 = st.columns(2)
with col1:
st.write(f"⭐ Rating: {row.get('rating', 'N/A')}")
st.write(f"πŸ“ž Phone: {row.get('phone', 'N/A')}")
with col2:
if 'services' in row:
st.write(f"πŸ”§ Services: {row['services']}")
if 'dietary' in row:
st.write(f"🍽️ Dietary: {row['dietary']}")
else:
st.warning("No places found in the selected radius. Try increasing the search area.")
with tab2:
st.header("πŸ” AI-Powered Smart Search")
# Multi-modal search
search_type = st.radio("Search Type", ["Text Query", "Voice Command (Simulated)", "Image Upload (Simulated)"])
if search_type == "Text Query":
query = st.text_input("Ask me anything about the city:",
placeholder="e.g., 'Find halal biryani that's not crowded' or 'Where can I fix my laptop?'")
if query:
st.session_state.search_history.append({"query": query, "timestamp": datetime.now()})
# Simple AI simulation
results = []
query_lower = query.lower()
if any(word in query_lower for word in ['hospital', 'doctor', 'medical', 'emergency']):
results = healthcare_df.head(3).to_dict('records')
st.success("πŸ₯ Found healthcare facilities for you!")
elif any(word in query_lower for word in ['food', 'eat', 'restaurant', 'biryani', 'halal']):
results = get_recommendations("food", st.session_state.user_preferences).head(3).to_dict('records')
st.success("🍽️ Found great food options!")
elif any(word in query_lower for word in ['laptop', 'phone', 'repair', 'electronics', 'charger']):
results = electronics_df.head(3).to_dict('records')
st.success("πŸ”§ Found electronics and repair services!")
elif any(word in query_lower for word in ['visit', 'see', 'attraction', 'tourist']):
results = attractions_df.head(3).to_dict('records')
st.success("🎯 Found amazing places to visit!")
else:
st.info("πŸ€” I'm learning! Try asking about healthcare, food, electronics, or attractions.")
# Display results
if results:
for result in results:
with st.container():
st.markdown(f"""
<div class="feature-card">
<h4>{result['name']}</h4>
<p><strong>Category:</strong> {result.get('category', 'N/A')}</p>
<p><strong>Rating:</strong> ⭐ {result.get('rating', 'N/A')}</p>
<p><strong>Distance:</strong> {result.get('distance', calculate_distance(user_lat, user_lon, result['lat'], result['lon'])):.1f} km</p>
</div>
""", unsafe_allow_html=True)
elif search_type == "Voice Command (Simulated)":
st.info("🎀 Voice search simulation - Click to 'speak'")
if st.button("πŸŽ™οΈ Start Voice Search"):
with st.spinner("Listening..."):
time.sleep(2)
st.success("Voice recognized: 'Find nearest pharmacy'")
results = healthcare_df[healthcare_df['category'] == 'Pharmacy']
for idx, row in results.iterrows():
st.write(f"πŸ“ {row['name']} - {row['distance']}km away")
else: # Image Upload
st.info("πŸ“Έ Image search simulation")
uploaded_file = st.file_uploader("Upload an image of what you're looking for", type=['jpg', 'jpeg', 'png'])
if uploaded_file:
st.image(uploaded_file, caption="Analyzing image...", width=300)
with st.spinner("AI analyzing image..."):
time.sleep(2)
st.success("πŸ” Detected: Broken phone charger")
st.write("Found electronics repair shops nearby:")
repair_shops = electronics_df[electronics_df['category'] == 'Repair Shop']
for idx, row in repair_shops.iterrows():
st.write(f"πŸ”§ {row['name']} - {row['services']}")
with tab3:
st.header("πŸ“‹ Smart Itinerary Builder")
# Itinerary preferences
st.subheader("🎯 Tell me about your day")
col1, col2 = st.columns(2)
with col1:
duration = st.selectbox("Trip Duration", ["Half Day (4 hours)", "Full Day (8 hours)", "Weekend (2 days)"])
walking_pref = st.selectbox("Walking Preference", ["Minimal walking", "Moderate walking", "Lots of walking"])
interests = st.multiselect("Interests", ["Food", "Shopping", "Culture", "Nature", "Technology", "Healthcare"])
with col2:
budget = st.selectbox("Budget Range", ["Budget ($)", "Mid-range ($$)", "Premium ($$$)"])
group_size = st.number_input("Group Size", min_value=1, max_value=10, value=1)
special_needs = st.multiselect("Special Requirements", ["Wheelchair accessible", "Halal food only", "Quiet places", "Female-friendly"])
if st.button("πŸš€ Generate Smart Itinerary", use_container_width=True):
with st.spinner("AI is crafting your perfect day..."):
time.sleep(3)
# Generate sample itinerary
itinerary = [
{"time": "09:00 AM", "activity": "Breakfast at Halal Biryani House", "duration": "1 hour", "type": "food"},
{"time": "10:30 AM", "activity": "Visit Quaid Mausoleum", "duration": "1.5 hours", "type": "culture"},
{"time": "12:30 PM", "activity": "Electronics shopping at TechMart", "duration": "1 hour", "type": "shopping"},
{"time": "02:00 PM", "activity": "Lunch at Traditional Karahi", "duration": "1 hour", "type": "food"},
{"time": "04:00 PM", "activity": "Relax at Clifton Beach", "duration": "2 hours", "type": "nature"},
{"time": "06:30 PM", "activity": "Dinner at Port Grand", "duration": "1.5 hours", "type": "food"}
]
st.session_state.current_itinerary = itinerary
st.success("βœ… Your personalized itinerary is ready!")
# Display itinerary
for i, item in enumerate(itinerary):
with st.expander(f"{item['time']} - {item['activity']} ({item['duration']})"):
col1, col2, col3 = st.columns(3)
with col1:
st.write(f"⏰ Duration: {item['duration']}")
with col2:
st.write(f"🏷️ Type: {item['type'].title()}")
with col3:
if st.button(f"Get Directions", key=f"dir_{i}"):
st.info("πŸ—ΊοΈ Opening navigation...")
# Itinerary summary
st.subheader("πŸ“Š Itinerary Summary")
col1, col2, col3, col4 = st.columns(4)
with col1:
st.markdown('<div class="metric-card"><h3>6</h3><p>Total Stops</p></div>', unsafe_allow_html=True)
with col2:
st.markdown('<div class="metric-card"><h3>8.5h</h3><p>Total Duration</p></div>', unsafe_allow_html=True)
with col3:
st.markdown('<div class="metric-card"><h3>5.2km</h3><p>Total Distance</p></div>', unsafe_allow_html=True)
with col4:
st.markdown('<div class="metric-card"><h3>$$</h3><p>Est. Budget</p></div>', unsafe_allow_html=True)
with tab4:
st.header("πŸ“Š City Insights & Analytics")
# Real-time city stats
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("🌑️ Temperature", "28°C", "2°C")
with col2:
st.metric("🚦 Traffic Level", "Medium", "↑ 15%")
with col3:
st.metric("πŸ‘₯ Crowd Density", "Low", "↓ 5%")
with col4:
st.metric("πŸ’° Price Index", "Moderate", "↑ 2%")
# Charts and analytics
col1, col2 = st.columns(2)
with col1:
st.subheader("πŸ“ˆ Popular Categories")
category_data = pd.DataFrame({
'Category': ['Food', 'Healthcare', 'Electronics', 'Attractions', 'Shopping'],
'Searches': [45, 23, 18, 32, 28]
})
fig = px.bar(category_data, x='Category', y='Searches',
title="Most Searched Categories Today")
st.plotly_chart(fig, use_container_width=True)
with col2:
st.subheader("⏰ Best Times to Visit")
time_data = pd.DataFrame({
'Hour': list(range(6, 23)),
'Crowd_Level': [20, 30, 45, 60, 70, 85, 90, 95, 80, 70, 60, 50, 45, 55, 70, 85, 90]
})
fig = px.line(time_data, x='Hour', y='Crowd_Level',
title="Crowd Levels Throughout the Day")
st.plotly_chart(fig, use_container_width=True)
# Safety alerts
st.subheader("πŸ›‘οΈ Safety & Alerts")
alerts = [
{"type": "warning", "message": "Heavy traffic on Shahrah-e-Faisal (avoid 5-7 PM)"},
{"type": "info", "message": "New electronics market opened in Saddar"},
{"type": "success", "message": "All hospitals report normal capacity"},
]
for alert in alerts:
if alert["type"] == "warning":
st.warning(f"⚠️ {alert['message']}")
elif alert["type"] == "info":
st.info(f"ℹ️ {alert['message']}")
else:
st.success(f"βœ… {alert['message']}")
with tab5:
st.header("βš™οΈ Settings & Preferences")
col1, col2 = st.columns(2)
with col1:
st.subheader("πŸ”” Notifications")
st.checkbox("Emergency alerts", value=True)
st.checkbox("Traffic updates", value=True)
st.checkbox("Price alerts", value=False)
st.checkbox("New place recommendations", value=True)
st.subheader("🌐 Language & Region")
language = st.selectbox("Language", ["English", "Urdu", "Arabic"])
currency = st.selectbox("Currency", ["PKR", "USD", "EUR"])
with col2:
st.subheader("πŸ”’ Privacy & Safety")
st.checkbox("Share location for better recommendations", value=True)
st.checkbox("Save search history", value=True)
st.checkbox("Anonymous usage analytics", value=False)
st.subheader("πŸ“± App Preferences")
theme = st.selectbox("Theme", ["Auto", "Light", "Dark"])
map_style = st.selectbox("Map Style", ["Standard", "Satellite", "Terrain"])
# Export data
st.subheader("πŸ“€ Export Your Data")
if st.button("Download Search History"):
if st.session_state.search_history:
df = pd.DataFrame(st.session_state.search_history)
st.download_button(
label="πŸ“₯ Download CSV",
data=df.to_csv(index=False),
file_name="search_history.csv",
mime="text/csv"
)
else:
st.info("No search history to export yet!")
if st.button("Download Current Itinerary"):
if st.session_state.current_itinerary:
df = pd.DataFrame(st.session_state.current_itinerary)
st.download_button(
label="πŸ“₯ Download Itinerary",
data=df.to_csv(index=False),
file_name="my_itinerary.csv",
mime="text/csv"
)
else:
st.info("No itinerary created yet!")
# Footer
st.markdown("---")
st.markdown("""
<div style="text-align: center; color: #666; padding: 2rem;">
<p>🌍 <strong>AI City Companion</strong> - Your Smart Travel Guide</p>
<p>Built with ❀️ for safe and smart city navigation | Hackathon MVP 2024</p>
<p>🚨 Emergency: Police (15) | Rescue (1122) | Fire (16)</p>
</div>
""", unsafe_allow_html=True)
if __name__ == "__main__":
main()