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(""" """, 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"{row['name']}
Rating: {row.get('rating', 'N/A')}
Category: {row.get('category', 'N/A')}", icon=folium.Icon(color=color) ).add_to(m) return m # Main App def main(): # Header st.markdown('

🌍 AI City Companion

', unsafe_allow_html=True) st.markdown('

Your Smart Travel Guide for Safe & Smart City Navigation

', 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"""

{result['name']}

Category: {result.get('category', 'N/A')}

Rating: ⭐ {result.get('rating', 'N/A')}

Distance: {result.get('distance', calculate_distance(user_lat, user_lon, result['lat'], result['lon'])):.1f} km

""", 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('

6

Total Stops

', unsafe_allow_html=True) with col2: st.markdown('

8.5h

Total Duration

', unsafe_allow_html=True) with col3: st.markdown('

5.2km

Total Distance

', unsafe_allow_html=True) with col4: st.markdown('

$$

Est. Budget

', 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("""

🌍 AI City Companion - Your Smart Travel Guide

Built with ❀️ for safe and smart city navigation | Hackathon MVP 2024

🚨 Emergency: Police (15) | Rescue (1122) | Fire (16)

""", unsafe_allow_html=True) if __name__ == "__main__": main()