Spaces:
Sleeping
Sleeping
| """ | |
| Free geolocation module using OpenStreetMap Nominatim API. | |
| Converts place names to coordinates. No API key required. | |
| Works offline with a fallback dictionary of Indian cities. | |
| """ | |
| import requests | |
| import json | |
| import os | |
| # Offline fallback: major Indian cities + water bodies | |
| OFFLINE_LOCATIONS = { | |
| 'silchar': (24.81, 92.80), | |
| 'guwahati': (26.14, 91.74), | |
| 'delhi': (28.61, 77.23), | |
| 'mumbai': (19.08, 72.88), | |
| 'chennai': (13.08, 80.27), | |
| 'kolkata': (22.57, 88.36), | |
| 'bengaluru': (12.97, 77.59), | |
| 'varanasi': (25.32, 83.01), | |
| 'haridwar': (29.95, 78.16), | |
| 'rishikesh': (30.09, 78.27), | |
| 'srinagar': (34.08, 74.80), | |
| 'dal lake': (34.11, 74.86), | |
| 'barak river': (24.80, 92.82), | |
| 'ganga river varanasi': (25.30, 83.01), | |
| 'yamuna river delhi': (28.66, 77.23), | |
| 'brahmaputra guwahati': (26.18, 91.75), | |
| 'chilika lake': (19.72, 85.31), | |
| 'loktak lake': (24.55, 93.83), | |
| 'vembanad lake': (9.58, 76.42), | |
| } | |
| def search_location(query: str) -> dict: | |
| """ | |
| Search for a location by name. | |
| Returns {'name': str, 'lat': float, 'lon': float, 'source': str} or {'error': str} | |
| """ | |
| query = query.strip().lower() | |
| # Check offline cache first | |
| if query in OFFLINE_LOCATIONS: | |
| lat, lon = OFFLINE_LOCATIONS[query] | |
| return {'name': query.title(), 'lat': lat, 'lon': lon, 'source': 'offline_cache'} | |
| # Partial match in offline cache | |
| for key, (lat, lon) in OFFLINE_LOCATIONS.items(): | |
| if query in key or key in query: | |
| return {'name': key.title(), 'lat': lat, 'lon': lon, 'source': 'offline_partial_match'} | |
| # Try OpenStreetMap Nominatim (free, no key needed) | |
| try: | |
| url = 'https://nominatim.openstreetmap.org/search' | |
| params = { | |
| 'q': query, | |
| 'format': 'json', | |
| 'limit': 3, | |
| 'countrycodes': 'in' # Bias toward India | |
| } | |
| headers = {'User-Agent': 'Divine-Earthly-Water-Guardian/1.0'} | |
| resp = requests.get(url, params=params, headers=headers, timeout=10) | |
| if resp.status_code == 200 and resp.json(): | |
| results = resp.json() | |
| best = results[0] | |
| return { | |
| 'name': best.get('display_name', query), | |
| 'lat': float(best['lat']), | |
| 'lon': float(best['lon']), | |
| 'source': 'openstreetmap', | |
| 'all_results': [ | |
| {'name': r['display_name'], 'lat': float(r['lat']), 'lon': float(r['lon'])} | |
| for r in results[:3] | |
| ] | |
| } | |
| except Exception as e: | |
| pass | |
| return {'error': f'Location "{query}" not found. Try a nearby city or lat/lon manually.'} | |
| if __name__ == '__main__': | |
| # Test | |
| for q in ['Silchar', 'Dal Lake', 'Varanasi Ganga', 'NonexistentPlace']: | |
| print(f'{q}:', search_location(q)) | |