Spaces:
Running
Running
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 | |
# Carte centrée sur la ville | |
m = folium.Map(location=[lat, lon], zoom_start=10, tiles="OpenStreetMap") | |
# Définition du popup de risque | |
marker_color = "blue" | |
popup_html = f"<b>{city}, {country}</b><br>Lat: {lat:.4f}<br>Lon: {lon:.4f}" | |
# S'il y a des risques, complète le popup et change la couleur du marker | |
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>" | |
# Couleur du marker selon le risque max détecté | |
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" | |
# Création du marker principal | |
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 pour ouvrir automatiquement le popup à l’affichage | |
script = f""" | |
<script> | |
var marker = {marker.get_name()}; | |
marker.openPopup(); | |
</script> | |
""" | |
m.get_root().html.add_child(folium.Element(script)) | |
# Légende | |
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 "" | |