| | import requests |
| | import folium |
| |
|
| | COUNTRIES_AND_CITIES = { |
| | "Afghanistan": ["Kabul", "Kandahar", "Herat", "Mazar-i-Sharif", "Jalalabad"], |
| | "Albania": ["Tirana", "Durrës", "Vlorë", "Shkodër", "Fier"], |
| | "Algeria": ["Algiers", "Oran", "Constantine", "Annaba", "Blida"], |
| | "Argentina": ["Buenos Aires", "Córdoba", "Rosario", "Mendoza", "La Plata"], |
| | "Armenia": ["Yerevan", "Gyumri", "Vanadzor", "Vagharshapat", "Hrazdan"], |
| | "Australia": [ |
| | "Sydney", |
| | "Melbourne", |
| | "Brisbane", |
| | "Perth", |
| | "Adelaide", |
| | "Gold Coast", |
| | "Newcastle", |
| | "Canberra", |
| | "Sunshine Coast", |
| | "Wollongong", |
| | ], |
| | "Austria": ["Vienna", "Graz", "Linz", "Salzburg", "Innsbruck"], |
| | "Azerbaijan": ["Baku", "Ganja", "Sumqayit", "Mingachevir", "Lankaran"], |
| | "Bahrain": ["Manama", "Riffa", "Muharraq", "Hamad Town", "A'ali"], |
| | "Bangladesh": ["Dhaka", "Chittagong", "Sylhet", "Rajshahi", "Khulna"], |
| | "Belarus": ["Minsk", "Gomel", "Mogilev", "Vitebsk", "Grodno"], |
| | "Belgium": ["Brussels", "Antwerp", "Ghent", "Charleroi", "Liège"], |
| | "Bolivia": ["La Paz", "Santa Cruz", "Cochabamba", "Sucre", "Oruro"], |
| | "Bosnia and Herzegovina": ["Sarajevo", "Banja Luka", "Tuzla", "Zenica", "Mostar"], |
| | "Brazil": [ |
| | "São Paulo", |
| | "Rio de Janeiro", |
| | "Brasília", |
| | "Salvador", |
| | "Fortaleza", |
| | "Belo Horizonte", |
| | "Manaus", |
| | "Curitiba", |
| | "Recife", |
| | "Goiânia", |
| | ], |
| | "Bulgaria": ["Sofia", "Plovdiv", "Varna", "Burgas", "Ruse"], |
| | "Cambodia": ["Phnom Penh", "Siem Reap", "Battambang", "Sihanoukville", "Poipet"], |
| | "Canada": [ |
| | "Toronto", |
| | "Montreal", |
| | "Vancouver", |
| | "Calgary", |
| | "Edmonton", |
| | "Ottawa", |
| | "Winnipeg", |
| | "Quebec City", |
| | "Hamilton", |
| | "Kitchener", |
| | ], |
| | "Chile": ["Santiago", "Valparaíso", "Concepción", "La Serena", "Antofagasta"], |
| | "China": [ |
| | "Shanghai", |
| | "Beijing", |
| | "Chongqing", |
| | "Tianjin", |
| | "Guangzhou", |
| | "Shenzhen", |
| | "Wuhan", |
| | "Dongguan", |
| | "Chengdu", |
| | "Nanjing", |
| | ], |
| | "Colombia": ["Bogotá", "Medellín", "Cali", "Barranquilla", "Cartagena"], |
| | "Croatia": ["Zagreb", "Split", "Rijeka", "Osijek", "Zadar"], |
| | "Czech Republic": ["Prague", "Brno", "Ostrava", "Plzen", "Liberec"], |
| | "Denmark": ["Copenhagen", "Aarhus", "Odense", "Aalborg", "Esbjerg"], |
| | "Ecuador": ["Quito", "Guayaquil", "Cuenca", "Santo Domingo", "Machala"], |
| | "Egypt": ["Cairo", "Alexandria", "Giza", "Shubra El Kheima", "Port Said"], |
| | "Estonia": ["Tallinn", "Tartu", "Narva", "Pärnu", "Kohtla-Järve"], |
| | "Ethiopia": ["Addis Ababa", "Dire Dawa", "Mekelle", "Adama", "Awassa"], |
| | "Finland": ["Helsinki", "Espoo", "Tampere", "Vantaa", "Oulu"], |
| | "France": [ |
| | "Paris", |
| | "Lyon", |
| | "Marseille", |
| | "Toulouse", |
| | "Nice", |
| | "Nantes", |
| | "Strasbourg", |
| | "Montpellier", |
| | "Bordeaux", |
| | "Lille", |
| | ], |
| | "Georgia": ["Tbilisi", "Batumi", "Kutaisi", "Rustavi", "Gori"], |
| | "Germany": [ |
| | "Berlin", |
| | "Hamburg", |
| | "Munich", |
| | "Cologne", |
| | "Frankfurt", |
| | "Stuttgart", |
| | "Düsseldorf", |
| | "Dortmund", |
| | "Essen", |
| | "Leipzig", |
| | ], |
| | "Ghana": ["Accra", "Kumasi", "Tamale", "Takoradi", "Cape Coast"], |
| | "Greece": ["Athens", "Thessaloniki", "Patras", "Heraklion", "Larissa"], |
| | "Hungary": ["Budapest", "Debrecen", "Szeged", "Miskolc", "Pécs"], |
| | "Iceland": ["Reykjavik", "Kópavogur", "Hafnarfjörður", "Akureyri", "Reykjanesbær"], |
| | "India": [ |
| | "Mumbai", |
| | "Delhi", |
| | "Bangalore", |
| | "Hyderabad", |
| | "Chennai", |
| | "Kolkata", |
| | "Ahmedabad", |
| | "Pune", |
| | "Surat", |
| | "Jaipur", |
| | ], |
| | "Indonesia": [ |
| | "Jakarta", |
| | "Surabaya", |
| | "Bandung", |
| | "Bekasi", |
| | "Medan", |
| | "Tangerang", |
| | "Depok", |
| | "Semarang", |
| | "Palembang", |
| | "Makassar", |
| | ], |
| | "Iran": ["Tehran", "Mashhad", "Isfahan", "Karaj", "Shiraz"], |
| | "Iraq": ["Baghdad", "Basra", "Mosul", "Erbil", "Najaf"], |
| | "Ireland": ["Dublin", "Cork", "Limerick", "Galway", "Waterford"], |
| | "Israel": ["Jerusalem", "Tel Aviv", "Haifa", "Rishon LeZion", "Petah Tikva"], |
| | "Italy": [ |
| | "Rome", |
| | "Milan", |
| | "Naples", |
| | "Turin", |
| | "Palermo", |
| | "Genoa", |
| | "Bologna", |
| | "Florence", |
| | "Bari", |
| | "Catania", |
| | ], |
| | "Japan": [ |
| | "Tokyo", |
| | "Osaka", |
| | "Yokohama", |
| | "Nagoya", |
| | "Sapporo", |
| | "Fukuoka", |
| | "Kobe", |
| | "Kawasaki", |
| | "Kyoto", |
| | "Saitama", |
| | ], |
| | "Jordan": ["Amman", "Zarqa", "Irbid", "Russeifa", "Wadi as-Ser"], |
| | "Kazakhstan": ["Almaty", "Nur-Sultan", "Shymkent", "Aktobe", "Taraz"], |
| | "Kenya": ["Nairobi", "Mombasa", "Kisumu", "Nakuru", "Eldoret"], |
| | "Kuwait": ["Kuwait City", "Al Ahmadi", "Hawalli", "As Salimiyah", "Sabah as Salim"], |
| | "Latvia": ["Riga", "Daugavpils", "Liepāja", "Jelgava", "Jūrmala"], |
| | "Lebanon": ["Beirut", "Tripoli", "Sidon", "Tyre", "Nabatieh"], |
| | "Lithuania": ["Vilnius", "Kaunas", "Klaipėda", "Šiauliai", "Panevėžys"], |
| | "Luxembourg": [ |
| | "Luxembourg City", |
| | "Esch-sur-Alzette", |
| | "Differdange", |
| | "Dudelange", |
| | "Ettelbruck", |
| | ], |
| | "Malaysia": ["Kuala Lumpur", "George Town", "Ipoh", "Shah Alam", "Petaling Jaya"], |
| | "Mexico": [ |
| | "Mexico City", |
| | "Guadalajara", |
| | "Monterrey", |
| | "Puebla", |
| | "Tijuana", |
| | "León", |
| | "Juárez", |
| | "Torreón", |
| | "Querétaro", |
| | "Mérida", |
| | ], |
| | "Morocco": ["Casablanca", "Rabat", "Fez", "Marrakech", "Agadir"], |
| | "Nepal": ["Kathmandu", "Pokhara", "Lalitpur", "Bharatpur", "Biratnagar"], |
| | "Netherlands": [ |
| | "Amsterdam", |
| | "Rotterdam", |
| | "The Hague", |
| | "Utrecht", |
| | "Eindhoven", |
| | "Tilburg", |
| | "Groningen", |
| | "Almere", |
| | "Breda", |
| | "Nijmegen", |
| | ], |
| | "New Zealand": ["Auckland", "Wellington", "Christchurch", "Hamilton", "Tauranga"], |
| | "Nigeria": ["Lagos", "Abuja", "Kano", "Ibadan", "Port Harcourt"], |
| | "Norway": [ |
| | "Oslo", |
| | "Bergen", |
| | "Trondheim", |
| | "Stavanger", |
| | "Drammen", |
| | "Fredrikstad", |
| | "Kristiansand", |
| | "Sandnes", |
| | "Tromsø", |
| | "Sarpsborg", |
| | ], |
| | "Pakistan": ["Karachi", "Lahore", "Faisalabad", "Rawalpindi", "Multan"], |
| | "Peru": ["Lima", "Arequipa", "Trujillo", "Chiclayo", "Huancayo"], |
| | "Philippines": ["Manila", "Quezon City", "Davao", "Cebu City", "Zamboanga"], |
| | "Poland": ["Warsaw", "Kraków", "Łódź", "Wrocław", "Poznań"], |
| | "Portugal": ["Lisbon", "Porto", "Vila Nova de Gaia", "Amadora", "Braga"], |
| | "Qatar": ["Doha", "Al Rayyan", "Umm Salal", "Al Wakrah", "Al Khor"], |
| | "Romania": ["Bucharest", "Cluj-Napoca", "Timișoara", "Iași", "Constanța"], |
| | "Russia": [ |
| | "Moscow", |
| | "Saint Petersburg", |
| | "Novosibirsk", |
| | "Yekaterinburg", |
| | "Kazan", |
| | "Nizhny Novgorod", |
| | "Chelyabinsk", |
| | "Samara", |
| | "Omsk", |
| | "Rostov-on-Don", |
| | ], |
| | "Saudi Arabia": ["Riyadh", "Jeddah", "Mecca", "Medina", "Dammam"], |
| | "Serbia": ["Belgrade", "Novi Sad", "Niš", "Kragujevac", "Subotica"], |
| | "Singapore": ["Singapore"], |
| | "Slovakia": ["Bratislava", "Košice", "Prešov", "Žilina", "Banská Bystrica"], |
| | "Slovenia": ["Ljubljana", "Maribor", "Celje", "Kranj", "Velenje"], |
| | "South Africa": [ |
| | "Cape Town", |
| | "Johannesburg", |
| | "Durban", |
| | "Pretoria", |
| | "Port Elizabeth", |
| | ], |
| | "South Korea": [ |
| | "Seoul", |
| | "Busan", |
| | "Incheon", |
| | "Daegu", |
| | "Daejeon", |
| | "Gwangju", |
| | "Suwon", |
| | "Ulsan", |
| | "Changwon", |
| | "Goyang", |
| | ], |
| | "Spain": [ |
| | "Madrid", |
| | "Barcelona", |
| | "Valencia", |
| | "Seville", |
| | "Zaragoza", |
| | "Málaga", |
| | "Murcia", |
| | "Palma", |
| | "Las Palmas", |
| | "Bilbao", |
| | ], |
| | "Sri Lanka": [ |
| | "Colombo", |
| | "Dehiwala-Mount Lavinia", |
| | "Moratuwa", |
| | "Sri Jayawardenepura Kotte", |
| | "Negombo", |
| | ], |
| | "Sweden": [ |
| | "Stockholm", |
| | "Gothenburg", |
| | "Malmö", |
| | "Uppsala", |
| | "Västerås", |
| | "Örebro", |
| | "Linköping", |
| | "Helsingborg", |
| | "Jönköping", |
| | "Norrköping", |
| | ], |
| | "Switzerland": [ |
| | "Zurich", |
| | "Geneva", |
| | "Basel", |
| | "Bern", |
| | "Lausanne", |
| | "Winterthur", |
| | "Lucerne", |
| | "St. Gallen", |
| | "Lugano", |
| | "Biel/Bienne", |
| | ], |
| | "Thailand": ["Bangkok", "Chiang Mai", "Pattaya", "Phuket", "Hat Yai"], |
| | "Turkey": [ |
| | "Istanbul", |
| | "Ankara", |
| | "Izmir", |
| | "Bursa", |
| | "Adana", |
| | "Gaziantep", |
| | "Konya", |
| | "Antalya", |
| | "Kayseri", |
| | "Mersin", |
| | ], |
| | "Ukraine": ["Kyiv", "Kharkiv", "Odesa", "Dnipro", "Donetsk"], |
| | "United Arab Emirates": ["Dubai", "Abu Dhabi", "Sharjah", "Al Ain", "Ajman"], |
| | "United Kingdom": [ |
| | "London", |
| | "Birmingham", |
| | "Manchester", |
| | "Leeds", |
| | "Liverpool", |
| | "Sheffield", |
| | "Bristol", |
| | "Glasgow", |
| | "Leicester", |
| | "Edinburgh", |
| | ], |
| | "United States": [ |
| | "New York", |
| | "Los Angeles", |
| | "Chicago", |
| | "Houston", |
| | "Phoenix", |
| | "Philadelphia", |
| | "San Antonio", |
| | "San Diego", |
| | "Dallas", |
| | "San Jose", |
| | ], |
| | "Uruguay": ["Montevideo", "Salto", "Paysandú", "Las Piedras", "Rivera"], |
| | "Venezuela": ["Caracas", "Maracaibo", "Valencia", "Barquisimeto", "Maracay"], |
| | "Vietnam": ["Ho Chi Minh City", "Hanoi", "Da Nang", "Bien Hoa", "Hue"], |
| | } |
| |
|
| | US_STATES = [ |
| | "Alabama", |
| | "Alaska", |
| | "Arizona", |
| | "Arkansas", |
| | "California", |
| | "Colorado", |
| | "Connecticut", |
| | "Delaware", |
| | "Florida", |
| | "Georgia", |
| | "Hawaii", |
| | "Idaho", |
| | "Illinois", |
| | "Indiana", |
| | "Iowa", |
| | "Kansas", |
| | "Kentucky", |
| | "Louisiana", |
| | "Maine", |
| | "Maryland", |
| | "Massachusetts", |
| | "Michigan", |
| | "Minnesota", |
| | "Mississippi", |
| | "Missouri", |
| | "Montana", |
| | "Nebraska", |
| | "Nevada", |
| | "New Hampshire", |
| | "New Jersey", |
| | "New Mexico", |
| | "New York", |
| | "North Carolina", |
| | "North Dakota", |
| | "Ohio", |
| | "Oklahoma", |
| | "Oregon", |
| | "Pennsylvania", |
| | "Rhode Island", |
| | "South Carolina", |
| | "South Dakota", |
| | "Tennessee", |
| | "Texas", |
| | "Utah", |
| | "Vermont", |
| | "Virginia", |
| | "Washington", |
| | "West Virginia", |
| | "Wisconsin", |
| | "Wyoming", |
| | "District of Columbia", |
| | ] |
| |
|
| |
|
| | def get_coordinates_from_dropdown(country: str, city: str, state: str = None) -> tuple: |
| | """Get coordinates using dropdown selections""" |
| | if not country or not city: |
| | return None, "Please select both country and city." |
| |
|
| | if country == "United States" and state: |
| | query = f"{city}, {state}, United States" |
| | else: |
| | query = f"{city}, {country}" |
| |
|
| | try: |
| | url = "https://nominatim.openstreetmap.org/search" |
| | params = {"q": query, "format": "json", "limit": 1} |
| | headers = {"User-Agent": "ClimateRiskTool/1.0"} |
| |
|
| | response = requests.get(url, params=params, headers=headers, timeout=10) |
| | data = response.json() |
| |
|
| | if data: |
| | lat = float(data[0]["lat"]) |
| | lon = float(data[0]["lon"]) |
| | return ( |
| | lat, |
| | lon, |
| | ), f"✅ Location found: {data[0].get('display_name', query)}" |
| | else: |
| | return None, f"❌ Location '{city}' not found in {country}." |
| |
|
| | except Exception as e: |
| | return None, f"❌ Error looking up location: {str(e)}" |
| |
|
| |
|
| | def create_risk_map( |
| | lat: float, lon: float, city: str, country: str, risk_analysis: dict = None |
| | ) -> str: |
| | import folium |
| |
|
| | |
| | m = folium.Map(location=[lat, lon], zoom_start=10, tiles="OpenStreetMap") |
| |
|
| | |
| | marker_color = "blue" |
| | popup_html = f"<b>{city}, {country}</b><br>Lat: {lat:.4f}<br>Lon: {lon:.4f}" |
| |
|
| | |
| | if risk_analysis and isinstance(risk_analysis, dict): |
| | risks = risk_analysis.get("risk_analysis", {}) |
| | popup_html += "<br><b>Risks for this location:</b><br>" |
| | max_level = 0 |
| | for risk_name, risk_data in risks.items(): |
| | if isinstance(risk_data, dict): |
| | risk_level = risk_data.get("risk_level", 0) |
| | max_level = max(max_level, risk_level) |
| | if risk_level > 80: |
| | emoji = "🔴" |
| | elif risk_level > 60: |
| | emoji = "🟠" |
| | elif risk_level > 40: |
| | emoji = "🟡" |
| | elif risk_level > 20: |
| | emoji = "🟢" |
| | else: |
| | emoji = "⚪" |
| | popup_html += f"{emoji} <b>{risk_name.title()}:</b> {risk_level}/100<br>" |
| |
|
| | |
| | if max_level > 80: |
| | marker_color = "red" |
| | elif max_level > 60: |
| | marker_color = "orange" |
| | elif max_level > 40: |
| | marker_color = "lightgreen" |
| | elif max_level > 20: |
| | marker_color = "green" |
| | else: |
| | marker_color = "blue" |
| |
|
| | |
| | marker = folium.Marker( |
| | [lat, lon], |
| | popup=popup_html, |
| | tooltip=f"Risks for {city}", |
| | icon=folium.Icon(color=marker_color, icon="info-sign"), |
| | ) |
| | marker.add_to(m) |
| |
|
| | |
| | script = f""" |
| | <script> |
| | var marker = {marker.get_name()}; |
| | marker.openPopup(); |
| | </script> |
| | """ |
| | m.get_root().html.add_child(folium.Element(script)) |
| |
|
| | |
| | legend_html = """ |
| | <div style="position: fixed; |
| | top: 10px; right: 10px; width: 280px; height: auto; |
| | background-color: white; border: 2px solid grey; z-index: 9999; |
| | font-size: 13px; padding: 12px; border-radius: 10px; |
| | box-shadow: 0 4px 8px rgba(0,0,0,0.1);"> |
| | <h4 style="margin: 0 0 10px 0;">🗺️ Legend</h4> |
| | <div><span style="color:red;">🔴</span> High risk<br> |
| | <span style="color:orange;">🟠</span> Moderate risk<br> |
| | <span style="color:yellow;">🟡</span> Mild risk<br> |
| | <span style="color:green;">🟢</span> Low risk</div> |
| | </div> |
| | """ |
| | m.get_root().html.add_child(folium.Element(legend_html)) |
| |
|
| | return m._repr_html_() |
| |
|
| | def get_city_suggestions(country: str) -> str: |
| | """Return city suggestions for selected country""" |
| | if country in COUNTRIES_AND_CITIES: |
| | cities = COUNTRIES_AND_CITIES[country] |
| | return f"💡 Popular cities in {country}: {', '.join(cities[:8])}..." |
| | return "" |
| |
|