Browse Source

Refactor city detection logic to include optional debug query for nearby cities, enhancing error handling and logging for optimized location retrieval.

shokhmgar
mortezaei 10 months ago
parent
commit
768c533e8e
  1. 73
      city_detection_ip.py

73
city_detection_ip.py

@ -72,40 +72,44 @@ def get_location_by_coordinates_optimized(lat, lon):
lon_max = lon + lon_range lon_max = lon + lon_range
# Query with population weighting to prefer larger cities # 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: 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(""" cursor.execute("""
WITH bounded_cities AS ( WITH bounded_cities AS (
SELECT name, country_code, latitude, longitude, population 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) cache.set(cache_key, None, 3600)
return None 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 # Fallback to original method on any error
return get_location_by_coordinates_original(lat, lon) return get_location_by_coordinates_original(lat, lon)

Loading…
Cancel
Save