Fix country matching: English→ISO code lookup for geocoding

"Rab,Croatia" now correctly matches Croatia (HR) instead of
Rabat (Morocco). Added country code mapping for common English
and German country names.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sam 2026-03-02 17:51:56 +01:00
parent ac63370876
commit 4e7c1909ee

View file

@ -67,6 +67,49 @@ def _wmo_description(code: int) -> str:
_geocode_cache: Dict[str, Dict[str, Any]] = {}
# Common English country names → ISO 3166-1 alpha-2 codes
# (Open-Meteo returns German names, so we need this for English→code matching)
_COUNTRY_CODES: Dict[str, str] = {
"croatia": "hr", "kroatien": "hr",
"germany": "de", "deutschland": "de",
"austria": "at", "österreich": "at",
"switzerland": "ch", "schweiz": "ch",
"france": "fr", "frankreich": "fr",
"italy": "it", "italien": "it",
"spain": "es", "spanien": "es",
"portugal": "pt",
"greece": "gr", "griechenland": "gr",
"turkey": "tr", "türkei": "tr",
"netherlands": "nl", "niederlande": "nl",
"belgium": "be", "belgien": "be",
"poland": "pl", "polen": "pl",
"czech republic": "cz", "tschechien": "cz",
"hungary": "hu", "ungarn": "hu",
"romania": "ro", "rumänien": "ro",
"bulgaria": "bg", "bulgarien": "bg",
"sweden": "se", "schweden": "se",
"norway": "no", "norwegen": "no",
"denmark": "dk", "dänemark": "dk",
"finland": "fi", "finnland": "fi",
"uk": "gb", "united kingdom": "gb", "england": "gb",
"usa": "us", "united states": "us",
"canada": "ca", "kanada": "ca",
"australia": "au", "australien": "au",
"japan": "jp",
"china": "cn",
"india": "in", "indien": "in",
"brazil": "br", "brasilien": "br",
"mexico": "mx", "mexiko": "mx",
"morocco": "ma", "marokko": "ma",
"egypt": "eg", "ägypten": "eg",
"thailand": "th",
"indonesia": "id", "indonesien": "id",
"slovenia": "si", "slowenien": "si",
"serbia": "rs", "serbien": "rs",
"montenegro": "me",
"bosnia": "ba", "bosnien": "ba",
}
async def _geocode(location: str) -> Optional[Dict[str, Any]]:
"""Resolve a city name to lat/lon using Open-Meteo Geocoding API.
@ -108,13 +151,31 @@ async def _geocode(location: str) -> Optional[Dict[str, Any]]:
# If country hint provided, try to find a matching result
best = results[0]
if country_hint:
hint = country_hint.lower()
# Resolve English country names to ISO codes for matching
hint_code = _COUNTRY_CODES.get(hint, hint[:2])
matched = False
for r in results:
country = (r.get("country", "") or "").lower()
country_code = (r.get("country_code", "") or "").lower()
if country_hint in country or country_hint == country_code:
# Match: hint in DE name, DE name in hint, ISO code, or exact city name
if (hint in country or country in hint
or hint_code == country_code
or hint == country_code):
best = r
matched = True
break
else:
if not matched:
# Prefer an exact city name match over the first result
for r in results:
if r.get("name", "").lower() == city_name.lower():
best = r
matched = True
break
if not matched:
logger.warning("[WEATHER] Country '%s' not found in results for '%s', using first match",
country_hint, city_name)