|
|
@ -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) |
|
|
|
|
|
|
|
|
|