From 9e6ebb18b78b1d5f4bd3a79606736701c65ef668 Mon Sep 17 00:00:00 2001 From: Steven Gerrits Date: Tue, 4 Feb 2025 21:22:50 +0100 Subject: [PATCH] geojson fix --- vespadb/observations/views.py | 91 +++++++++++++++++++---------------- vespadb/settings.py | 4 +- 2 files changed, 52 insertions(+), 43 deletions(-) diff --git a/vespadb/observations/views.py b/vespadb/observations/views.py index 7216506..545c6c7 100644 --- a/vespadb/observations/views.py +++ b/vespadb/observations/views.py @@ -368,7 +368,7 @@ def retrieve_list(self, request: Request, *args: Any, **kwargs: Any) -> Response }, ) @method_decorator(ratelimit(key="ip", rate="60/m", method="GET", block=True)) - @action(detail=False, methods=["get"], url_path="dynamic-geojson") + @action(detail=False, methods=["get"], url_path="dynamic-geojson", permission_classes=[AllowAny]) def geojson(self, request: Request) -> HttpResponse: """Generate GeoJSON data for the observations.""" try: @@ -382,50 +382,59 @@ def geojson(self, request: Request) -> HttpResponse: cached_data = cache.get(cache_key) if cached_data: logger.info("Cache hit - Returning cached response") - return JsonResponse(cached_data, safe=False) - - bbox_str = request.GET.get("bbox") - if bbox_str: - try: - bbox_coords = list(map(float, bbox_str.split(","))) - if len(bbox_coords) == BBOX_LENGTH: - xmin, ymin, xmax, ymax = bbox_coords - bbox_wkt = ( - f"POLYGON(({xmin} {ymin}, {xmin} {ymax}, {xmax} {ymax}, {xmax} {ymin}, {xmin} {ymin}))" - ) - bbox = GEOSGeometry(bbox_wkt, srid=4326) - else: - return HttpResponse("Invalid bbox format", status=status.HTTP_400_BAD_REQUEST) - except ValueError: - return HttpResponse("Invalid bbox values", status=status.HTTP_400_BAD_REQUEST) + response = JsonResponse(cached_data, safe=False) else: - bbox = None - - queryset = self.filter_queryset(self.get_queryset()) + bbox_str = request.GET.get("bbox") + if bbox_str: + try: + bbox_coords = list(map(float, bbox_str.split(","))) + if len(bbox_coords) == BBOX_LENGTH: + xmin, ymin, xmax, ymax = bbox_coords + bbox_wkt = ( + f"POLYGON(({xmin} {ymin}, {xmin} {ymax}, {xmax} {ymax}, {xmax} {ymin}, {xmin} {ymin}))" + ) + bbox = GEOSGeometry(bbox_wkt, srid=4326) + else: + return HttpResponse("Invalid bbox format", status=status.HTTP_400_BAD_REQUEST) + except ValueError: + return HttpResponse("Invalid bbox values", status=status.HTTP_400_BAD_REQUEST) + else: + bbox = None + + queryset = self.filter_queryset(self.get_queryset()) + + if bbox: + queryset = queryset.filter(location__within=bbox) + + queryset = queryset.order_by("id").annotate(point=Transform("location", 4326)) + + features = [ + { + "type": "Feature", + "properties": { + "id": obs.id, + "status": "eradicated" + if obs.eradication_result is not None + else "reserved" + if obs.reserved_by + else "default", + }, + "geometry": json.loads(obs.location.geojson) if obs.location else None, + } + for obs in queryset + ] + geojson_response = {"type": "FeatureCollection", "features": features} + cache.set(cache_key, geojson_response, GEOJSON_REDIS_CACHE_EXPIRATION) + response = JsonResponse(geojson_response) - if bbox: - queryset = queryset.filter(location__within=bbox) + # Add CORS headers manually + response["Access-Control-Allow-Origin"] = request.META.get('HTTP_ORIGIN', '*') + response["Access-Control-Allow-Credentials"] = "true" + response["Access-Control-Allow-Methods"] = "GET, OPTIONS" + response["Access-Control-Allow-Headers"] = "Content-Type, Authorization" - queryset = queryset.order_by("id").annotate(point=Transform("location", 4326)) + return response - features = [ - { - "type": "Feature", - "properties": { - "id": obs.id, - "status": "eradicated" - if obs.eradication_result is not None - else "reserved" - if obs.reserved_by - else "default", - }, - "geometry": json.loads(obs.location.geojson) if obs.location else None, - } - for obs in queryset - ] - geojson_response = {"type": "FeatureCollection", "features": features} - cache.set(cache_key, geojson_response, GEOJSON_REDIS_CACHE_EXPIRATION) - return JsonResponse(geojson_response) except Exception: logger.exception("An error occurred while generating GeoJSON data") return HttpResponse( diff --git a/vespadb/settings.py b/vespadb/settings.py index 7682211..67ef279 100644 --- a/vespadb/settings.py +++ b/vespadb/settings.py @@ -20,8 +20,8 @@ secrets = { "DJANGO_SECRET_KEY": os.getenv("SECRET_KEY"), - "CORS_ALLOWED_ORIGINS": os.getenv("CORS_ALLOWED_ORIGINS", "http://localhost:3000").split(","), - "CSRF_TRUSTED_ORIGINS": os.getenv("CSRF_TRUSTED_ORIGINS", "http://localhost:3000").split(","), + "CORS_ALLOWED_ORIGINS": os.getenv("CORS_ALLOWED_ORIGINS", "http://localhost:3000").split(",") + ["https://nesten.vespawatch.be", "https://uat-nesten.vespawatch.be"], + "CSRF_TRUSTED_ORIGINS": os.getenv("CSRF_TRUSTED_ORIGINS", "http://localhost:3000").split(",") + ["https://nesten.vespawatch.be", "https://uat-nesten.vespawatch.be"], "CSRF_COOKIE_DOMAIN": os.getenv("CSRF_COOKIE_DOMAIN", ".vespawatch.be"), "SESSION_COOKIE_DOMAIN": os.getenv("SESSION_COOKIE_DOMAIN", ".vespawatch.be"), "POSTGRES_DB": os.getenv("POSTGRES_DB"),