Fix geocoding for "City,Country" format (e.g. Rab,Croatia)
Split location on comma, search for city name, then filter results by country name/code to find the correct match. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d3305a243c
commit
ac63370876
1 changed files with 32 additions and 7 deletions
|
|
@ -71,17 +71,28 @@ _geocode_cache: Dict[str, Dict[str, Any]] = {}
|
|||
async def _geocode(location: str) -> Optional[Dict[str, Any]]:
|
||||
"""Resolve a city name to lat/lon using Open-Meteo Geocoding API.
|
||||
|
||||
Supports "City,Country" format (e.g. "Rab,Croatia") — the country part
|
||||
is used to filter results when multiple matches exist.
|
||||
|
||||
Returns dict with keys: latitude, longitude, name, timezone
|
||||
"""
|
||||
cache_key = location.lower().strip()
|
||||
if cache_key in _geocode_cache:
|
||||
return _geocode_cache[cache_key]
|
||||
|
||||
# Split "City,Country" into search name + country filter
|
||||
city_name = location
|
||||
country_hint = ""
|
||||
if "," in location:
|
||||
parts = [p.strip() for p in location.split(",", 1)]
|
||||
city_name = parts[0]
|
||||
country_hint = parts[1].lower() if len(parts) > 1 else ""
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=10) as client:
|
||||
resp = await client.get(
|
||||
"https://geocoding-api.open-meteo.com/v1/search",
|
||||
params={"name": location, "count": 1, "language": "de"},
|
||||
params={"name": city_name, "count": 10, "language": "de"},
|
||||
)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
|
|
@ -94,15 +105,29 @@ async def _geocode(location: str) -> Optional[Dict[str, Any]]:
|
|||
logger.warning("[WEATHER] Geocoding: no results for '%s'", location)
|
||||
return None
|
||||
|
||||
# If country hint provided, try to find a matching result
|
||||
best = results[0]
|
||||
if country_hint:
|
||||
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:
|
||||
best = r
|
||||
break
|
||||
else:
|
||||
logger.warning("[WEATHER] Country '%s' not found in results for '%s', using first match",
|
||||
country_hint, city_name)
|
||||
|
||||
geo = {
|
||||
"latitude": results[0]["latitude"],
|
||||
"longitude": results[0]["longitude"],
|
||||
"name": results[0].get("name", location),
|
||||
"timezone": results[0].get("timezone", "Europe/Berlin"),
|
||||
"latitude": best["latitude"],
|
||||
"longitude": best["longitude"],
|
||||
"name": best.get("name", location),
|
||||
"timezone": best.get("timezone", "Europe/Berlin"),
|
||||
}
|
||||
_geocode_cache[cache_key] = geo
|
||||
logger.info("[WEATHER] Geocoded '%s' → %s (%.2f, %.2f)",
|
||||
location, geo["name"], geo["latitude"], geo["longitude"])
|
||||
logger.info("[WEATHER] Geocoded '%s' → %s (%s, %.2f, %.2f)",
|
||||
location, geo["name"], best.get("country", "?"),
|
||||
geo["latitude"], geo["longitude"])
|
||||
return geo
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue