Browse Source

Enhance city detection by restructuring debug query for nearby cities, improving error handling, and ensuring fallback to original method on failure.

master
mortezaei 5 months ago
parent
commit
67edc0a0b3
  1. 74
      city_detection_ip.py

74
city_detection_ip.py

@ -14,7 +14,6 @@ from django.core.wsgi import get_wsgi_application
application = get_wsgi_application() application = get_wsgi_application()
from apps.account.models import LoginHistory from apps.account.models import LoginHistory
# from apps.account.models.geoNames import GeoNamesCity
# Configure logging # Configure logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -72,44 +71,40 @@ 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
@ -167,8 +162,7 @@ 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 as e:
logger.warning(f"⚠️ Optimized method failed for ({lat}, {lon}): {str(e)} - trying fallback")
except Exception:
# 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