You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.6 KiB
75 lines
2.6 KiB
from rest_framework import status
|
|
|
|
from django.contrib.gis.geos import Point
|
|
from rest_framework.exceptions import ValidationError
|
|
from rest_framework.response import Response
|
|
from rest_framework.viewsets import GenericViewSet
|
|
from typing import Optional, Tuple
|
|
|
|
from ..actions.get_object import get_object_from_cache
|
|
from ..models import ServiceArea
|
|
from ..serializers import ServiceAreaSerializer
|
|
|
|
|
|
class FindServiceAreaView(GenericViewSet):
|
|
|
|
serializer_class = ServiceAreaSerializer
|
|
|
|
def validate_querystring(self, latitude: Optional[str], longitude: Optional[str]) -> Optional[Tuple[float, float]]:
|
|
try:
|
|
lat = float(latitude)
|
|
except (TypeError, ValueError):
|
|
raise ValidationError({'latitude': f'Invalid value: {latitude}.'})
|
|
|
|
if lat < -90 or lat > 90:
|
|
raise ValidationError({'latitude': f'Invalid value: {lat}.'})
|
|
|
|
try:
|
|
lng = float(longitude)
|
|
except (TypeError, ValueError):
|
|
raise ValidationError({'longitude': f'Invalid value: {longitude}.'})
|
|
|
|
if lng < -180 or lng > 180:
|
|
raise ValidationError({'longitude': f'Invalid value: {lng}.'})
|
|
|
|
return lat, lng
|
|
|
|
def generate_cache_key(self, latitude, longitude):
|
|
latitude = int(latitude)
|
|
if latitude < 0:
|
|
latitude -= latitude
|
|
|
|
longitude = int(longitude)
|
|
if longitude < 0:
|
|
longitude -= 1
|
|
|
|
return f'{latitude}_{longitude}'
|
|
|
|
def find_service_areas(self, request, *args, **kwargs):
|
|
query_parameters = self.request.query_params
|
|
|
|
latitude = query_parameters.get('latitude')
|
|
longitude = query_parameters.get('longitude')
|
|
|
|
validated_coordinates = self.validate_querystring(latitude, longitude)
|
|
|
|
cache_key = self.generate_cache_key(*validated_coordinates)
|
|
service_area_ids = get_object_from_cache(cache_key)
|
|
point = Point(validated_coordinates)
|
|
|
|
cache_failure = False # TODO: Implement a check to activate fallback system
|
|
|
|
if cache_failure:
|
|
service_area_qs = ServiceArea.objects.filter(polygon__contains=point)
|
|
else:
|
|
service_area_qs = ServiceArea.objects.filter(id__in=service_area_ids).filter(polygon__contains=point)
|
|
|
|
page = self.paginate_queryset(service_area_qs)
|
|
if page is not None:
|
|
serializer = self.get_serializer(page, many=True)
|
|
return self.get_paginated_response(serializer.data)
|
|
|
|
serializer = self.get_serializer(service_area_qs, many=True)
|
|
|
|
return Response(serializer.data, status=status.HTTP_200_OK)
|