| import streamlit as st |
| import folium |
| from streamlit_folium import folium_static |
| from folium.plugins import MarkerCluster |
| import requests |
| import json |
| from datetime import datetime |
| import re |
| from geopy.distance import geodesic |
| from typing import Dict, List, Tuple, Optional |
| import time |
| import random |
|
|
| |
| st.set_page_config( |
| page_title="GeoVision Pro", |
| page_icon="๐", |
| layout="wide", |
| initial_sidebar_state="expanded" |
| ) |
|
|
| |
| st.markdown(""" |
| <style> |
| @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); |
| |
| body { |
| font-family: 'Roboto', sans-serif; |
| background-color: #e0f7fa; |
| color: #263b5e; |
| margin: 0; |
| padding: 0; |
| } |
| |
| .stApp { |
| max-width: 1200px; |
| margin: 0 auto; |
| padding: 2rem; |
| } |
| |
| .header { |
| position: fixed; |
| top: 0; |
| left: 0; |
| width: 100%; |
| background: #007bff; |
| padding: 1rem 2rem; |
| box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
| z-index: 1000; |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| } |
| |
| .header h1 { |
| font-size: 1.8rem; |
| color: #fff; |
| margin: 0; |
| } |
| |
| .header .subtitle { |
| font-size: 1rem; |
| color: #e0f7fa; |
| } |
| |
| .main { |
| margin-top: 6rem; /* Adjust for the fixed header */ |
| } |
| |
| .section { |
| margin-bottom: 3rem; |
| } |
| |
| .section-title { |
| font-size: 1.5rem; |
| color: #004085; |
| margin-bottom: 1rem; |
| border-bottom: 2px solid #b3e5fc; |
| padding-bottom: 0.5rem; |
| } |
| |
| .card { |
| background: #fff; |
| border: 1px solid #b3e5fc; |
| border-radius: 8px; |
| box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
| padding: 1.5rem; |
| margin-bottom: 1.5rem; |
| transition: transform 0.3s; |
| } |
| |
| .card:hover { |
| transform: translateY(-5px); |
| box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); |
| } |
| |
| .card h3 { |
| margin-top: 0; |
| font-size: 1.2rem; |
| color: #004085; |
| } |
| |
| .card p { |
| font-size: 1rem; |
| color: #263b5e; |
| } |
| |
| .map-container { |
| border: 1px solid #b3e5fc; |
| border-radius: 8px; |
| overflow: hidden; |
| box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
| } |
| |
| .button-container { |
| display: flex; |
| justify-content: center; |
| gap: 1rem; |
| margin-top: 2rem; |
| } |
| |
| .button { |
| background-color: #007bff; |
| color: #fff; |
| border: none; |
| border-radius: 5px; |
| padding: 0.7rem 1.5rem; |
| font-size: 1rem; |
| cursor: pointer; |
| transition: background-color 0.3s; |
| } |
| |
| .button:hover { |
| background-color: #0056b3; |
| } |
| |
| .footer { |
| text-align: center; |
| margin-top: 3rem; |
| font-size: 0.9rem; |
| color: #999; |
| } |
| |
| .earth-bg { |
| position: fixed; |
| top: 0; |
| left: 0; |
| width: 100vw; |
| height: 100vh; |
| z-index: -1; |
| overflow: hidden; |
| } |
| |
| .earth-orbit { |
| position: absolute; |
| left: 50%; |
| top: 50%; |
| transform: translate(-50%, -50%); |
| width: 100vw; |
| height: 100vw; |
| animation: earth-spin 120s linear infinite; |
| } |
| |
| @keyframes earth-spin { |
| 0% { transform: translate(-50%, -50%) rotate(0deg); } |
| 100% { transform: translate(-50%, -50%) rotate(360deg); } |
| } |
| |
| .earth-img { |
| width: 100%; |
| height: 100%; |
| object-fit: cover; |
| border-radius: 50%; |
| filter: brightness(1.2) saturate(1.5); |
| } |
| </style> |
| """, unsafe_allow_html=True) |
|
|
| |
| st.markdown(''' |
| <div class="earth-bg"> |
| <div class="earth-orbit"> |
| <img class="earth-img" src="https://upload.wikimedia.org/wikipedia/commons/9/97/The_Earth_seen_from_Apollo_17.jpg" alt="Earth"> |
| </div> |
| </div> |
| ''', unsafe_allow_html=True) |
|
|
| |
| st.markdown('<div class="header"><h1>GeoVision Pro</h1><p class="subtitle">Your Professional Geospatial Data Solution</p></div>', unsafe_allow_html=True) |
|
|
| |
| st.markdown('<div class="main">', unsafe_allow_html=True) |
|
|
| |
| st.markdown('<div class="section"><h2 class="section-title">Query Interface</h2></div>', unsafe_allow_html=True) |
|
|
| |
| def smart_location_search(): |
| st.session_state.query = "Show restaurants near the Eiffel Tower" |
| st.experimental_rerun |
|
|
| |
| query = st.text_input("Enter your query:", placeholder="Try: 'Show restaurants near the Eiffel Tower' or 'What's the weather in Tokyo?'", key="query_input") |
|
|
| if st.button("Smart Location Search"): |
| smart_location_search() |
|
|
| |
| def fetch_data_from_backend(endpoint, params=None): |
| try: |
| response = requests.get(f"https://geosapi.onrender.com/{endpoint}", params=params) |
| response.raise_for_status() |
| return response.json() |
| except requests.exceptions.RequestException as e: |
| st.error(f"Error fetching data: {e}") |
| return None |
|
|
| |
| st.markdown('<div class="section"><h2 class="section-title">Features</h2></div>', unsafe_allow_html=True) |
|
|
| features = [ |
| {"icon": "๐", "title": "Smart Location Search", "description": "Find places and get directions with natural language queries."}, |
| {"icon": "๐ฆ๏ธ", "title": "Real-time Weather", "description": "Get current weather conditions and forecasts for any location."}, |
| {"icon": "๐ฌ๏ธ", "title": "Air Quality", "description": "Check air quality levels and pollution data worldwide."}, |
| {"icon": "๐", "title": "Personal Places", "description": "Save and manage your favorite locations with notes and emotions."} |
| ] |
|
|
| for feature in features: |
| st.markdown(f""" |
| <div class="card"> |
| <h3>{feature['icon']} {feature['title']}</h3> |
| <p>{feature['description']}</p> |
| </div> |
| """, unsafe_allow_html=True) |
|
|
| |
| st.markdown('<div class="section"><h2 class="section-title">Map Visualization</h2></div>', unsafe_allow_html=True) |
|
|
| |
| if query: |
| |
| data = fetch_data_from_backend("your-endpoint", params={"query": query}) |
| if data: |
| st.write("Data from backend:", data) |
|
|
| |
| st.markdown('<div class="map-container" style="height: 500px;"></div>', unsafe_allow_html=True) |
|
|
| |
| st.markdown('<div class="button-container">', unsafe_allow_html=True) |
|
|
| if st.button("Random Place"): |
| random_queries = [ |
| "Show restaurants in Tokyo", |
| "Find museums in Berlin", |
| "Show hospitals in Paris", |
| "Find parks in New York", |
| "Show cafes in London", |
| "Find supermarkets in Rome" |
| ] |
| st.write(f"Random Query: {random.choice(random_queries)}") |
|
|
| if st.button("Clear Results"): |
| st.write("Results cleared.") |
|
|
| st.markdown('</div>', unsafe_allow_html=True) |
|
|
| |
| st.markdown('<div class="footer"><p>© 2025 GeoVision Pro. All rights reserved.</p></div>', unsafe_allow_html=True) |
|
|
| st.markdown('</div>', unsafe_allow_html=True) |
|
|