diff --git a/apps/cap_feed/formats/cap_xml.py b/apps/cap_feed/formats/cap_xml.py index a4cc3ca..1834ed5 100644 --- a/apps/cap_feed/formats/cap_xml.py +++ b/apps/cap_feed/formats/cap_xml.py @@ -27,6 +27,7 @@ Feed, ProcessedAlert, ) +from apps.cap_feed.utils import distance_to_decimal_degrees from main.managers import BulkCreateManager logger = logging.getLogger(__name__) @@ -251,7 +252,13 @@ def process_alert( for circle in alert_info_circles_collections: possible_admin1s = admin1_base_qs.filter( # TODO: Check for performance issues - geometry___dwithin=(circle[0], Distance(m=circle[1])), + geometry__dwithin=( + circle[0], + distance_to_decimal_degrees( + Distance(km=circle[1]), + circle[0], + ), + ), ).exclude(id__in=tagged_admin1s_id) for admin1_id in possible_admin1s.values_list('id', flat=True): tagged_admin1s_id.add(admin1_id) diff --git a/apps/cap_feed/utils.py b/apps/cap_feed/utils.py index fa47714..357c743 100644 --- a/apps/cap_feed/utils.py +++ b/apps/cap_feed/utils.py @@ -1,13 +1,15 @@ import json import logging +import math +from django.contrib.gis.geos import Point +from django.contrib.gis.measure import Distance from django.utils import timezone from django_celery_beat.models import IntervalSchedule, PeriodicTask from main.celery import INTERNAL_CELERY_TASK_NAME_PREFIX from .models import Feed -from .tasks import poll_feed logger = logging.getLogger(__name__) @@ -35,6 +37,9 @@ def force_delete_all_tasks(cls): @classmethod def add_task(cls, feed: Feed): + # XXX: Circular dependency fix + from .tasks import poll_feed + interval_schedule, _ = IntervalSchedule.objects.get_or_create( every=feed.polling_interval, period='seconds', @@ -64,3 +69,10 @@ def remove_task(cls, feed: Feed): def update_task(cls, feed: Feed): cls.remove_task(feed) cls.add_task(feed) + + +def distance_to_decimal_degrees(distance: Distance, point: Point): + # https://gis.stackexchange.com/a/384823 + lat_radians = point.y * (math.pi / 180) # Where point.y is latitude + # 1 longitudinal degree at the equator equal 111,319.5m equiv to 111.32km + return distance.m / (111_319.5 * math.cos(lat_radians))