From 768c533e8e22933f904bc8d0dab1e934d731a0ba Mon Sep 17 00:00:00 2001 From: mortezaei Date: Sun, 28 Dec 2025 14:08:01 +0330 Subject: [PATCH] Refactor city detection logic to include optional debug query for nearby cities, enhancing error handling and logging for optimized location retrieval. --- city_detection_ip.py | 73 +++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/city_detection_ip.py b/city_detection_ip.py index 69571f5..8165e29 100644 --- a/city_detection_ip.py +++ b/city_detection_ip.py @@ -72,40 +72,44 @@ def get_location_by_coordinates_optimized(lat, lon): lon_max = lon + lon_range # Query with population weighting to prefer larger cities + # Debug query (optional - if fails, we continue without debug info) + try: + with connection.cursor() as cursor: + cursor.execute(""" + WITH bounded_cities AS ( + SELECT name, country_code, latitude, longitude, population + FROM geonames_city + WHERE feature_class = 'P' + AND latitude BETWEEN %s AND %s + AND longitude BETWEEN %s AND %s + ), + distance_calc AS ( + SELECT name, country_code, population, + (6371 * acos(least(1, greatest(-1, + cos(radians(%s)) * cos(radians(latitude)) * + cos(radians(longitude) - radians(%s)) + + sin(radians(%s)) * sin(radians(latitude)) + )))) AS distance + FROM bounded_cities + ) + SELECT name, country_code, population, distance + FROM distance_calc + WHERE distance <= 100 + ORDER BY distance + LIMIT 10 + """, [lat_min, lat_max, lon_min, lon_max, lat, lon, lat]) + + debug_results = cursor.fetchall() + if debug_results: + logger.info(f"🔍 Top 10 nearby cities for coordinates ({lat}, {lon}):") + for name, cc, pop, dist in debug_results: + logger.info(f" 📍 {name} ({cc}): population={pop:,}, distance={dist:.2f}km") + except Exception as debug_error: + logger.warning(f"⚠️ Debug query failed for ({lat}, {lon}): {str(debug_error)}") + # Continue without debug info - this is not critical + + # Main query - use separate cursor to avoid transaction issues with connection.cursor() as cursor: - # First, let's get debug information about nearby cities - cursor.execute(""" - WITH bounded_cities AS ( - SELECT name, country_code, latitude, longitude, population - FROM geonames_city - WHERE feature_class = 'P' - AND latitude BETWEEN %s AND %s - AND longitude BETWEEN %s AND %s - ), - distance_calc AS ( - SELECT name, country_code, population, - (6371 * acos(least(1, greatest(-1, - cos(radians(%s)) * cos(radians(latitude)) * - cos(radians(longitude) - radians(%s)) + - sin(radians(%s)) * sin(radians(latitude)) - )))) AS distance - FROM bounded_cities - ) - SELECT name, country_code, population, distance - FROM distance_calc - WHERE distance <= 100 - ORDER BY distance - LIMIT 10 - """, [lat_min, lat_max, lon_min, lon_max, lat, lon, lat]) - - debug_results = cursor.fetchall() - if debug_results: - logger.info(f"🔍 Top 10 nearby cities for coordinates ({lat}, {lon}):") - for name, cc, pop, dist in debug_results: - logger.info(f" 📍 {name} ({cc}): population={pop:,}, distance={dist:.2f}km") - - # Now get the best city using a weighted approach - # Prefer cities with larger population within reasonable distance cursor.execute(""" WITH bounded_cities AS ( SELECT name, country_code, latitude, longitude, population @@ -163,7 +167,8 @@ def get_location_by_coordinates_optimized(lat, lon): cache.set(cache_key, None, 3600) return None - except Exception: + except Exception as e: + logger.warning(f"⚠️ Optimized method failed for ({lat}, {lon}): {str(e)} - trying fallback") # Fallback to original method on any error return get_location_by_coordinates_original(lat, lon)