Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve API v2 sensitive areas filters #3341

Merged
merged 1 commit into from
Dec 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ CHANGELOG
2.92.2+dev (XXXX-XX-XX)
-----------------------

**Improvements**

- API v2:
- revert ?trek filter by direct intersecting geometry on sensitive area endpoint.
- improve ?near_xxx filters by direct intersecting buffered geometry on sensitive area endpoint.


2.92.2 (2022-12-01)
-----------------------
Expand Down
34 changes: 25 additions & 9 deletions geotrek/api/v2/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

if 'geotrek.outdoor' in settings.INSTALLED_APPS:
from geotrek.outdoor.models import Course, Site
if 'geotrek.sensitivity' in settings.INSTALLED_APPS:
from geotrek.sensitivity.models import SensitiveArea


class GeotrekQueryParamsFilter(BaseFilterBackend):
Expand Down Expand Up @@ -177,7 +179,7 @@ def filter_queryset(self, request, queryset, view):
contents_intersecting = intersecting(qs,
trek,
distance=0,
field='geom_buffered')
field='geom')
qs = contents_intersecting.order_by('id')
return qs.distinct()

Expand All @@ -203,7 +205,7 @@ def get_schema_fields(self, view):
), Field(
name='trek', required=False, location='query', schema=coreschema.Integer(
title=_("Trek"),
description=_('Filter by a trek id. It will show only the sensitive areas related to this trek.')
description=_('Filter by a trek id. It will show only the sensitive areas intersecting this trek.')
)
),
)
Expand Down Expand Up @@ -268,32 +270,46 @@ def get_schema_fields(self, view):

class NearbyContentFilter(BaseFilterBackend):

def intersect_queryset_with_object(self, qs, model, obj_pk):
def intersect_queryset_with_object(self, qs, model, obj_pk, distance=None, field="geom"):
obj = model.objects.filter(pk=obj_pk).first()
if obj:
qs = intersecting(qs, obj)
qs = intersecting(qs, obj, distance=distance, field=field)
else:
# Intersecting with a non-existing object results in empty data
qs = model.objects.none()
return qs

def filter_queryset(self, request, qs, view):
distance = None
field = "geom"

# sensitive area particular cases. We should intersect with the buffered geometry
if 'geotrek.sensitivity' in settings.INSTALLED_APPS:
if qs.model == SensitiveArea:
distance = 0
field = "geom_buffered"

near_touristicevent = request.GET.get('near_touristicevent')
if near_touristicevent:
qs = self.intersect_queryset_with_object(qs, TouristicEvent, near_touristicevent)
qs = self.intersect_queryset_with_object(qs, TouristicEvent, near_touristicevent,
distance=distance, field=field)
near_touristiccontent = request.GET.get('near_touristiccontent')
if near_touristiccontent:
qs = self.intersect_queryset_with_object(qs, TouristicContent, near_touristiccontent)
qs = self.intersect_queryset_with_object(qs, TouristicContent, near_touristiccontent,
distance=distance, field=field)
near_trek = request.GET.get('near_trek')
if near_trek:
qs = self.intersect_queryset_with_object(qs, Trek, near_trek)
qs = self.intersect_queryset_with_object(qs, Trek, near_trek,
distance=distance, field=field)
near_outdoorsite = request.GET.get('near_outdoorsite')
if 'geotrek.outdoor' in settings.INSTALLED_APPS:
if near_outdoorsite:
qs = self.intersect_queryset_with_object(qs, Site, near_outdoorsite)
qs = self.intersect_queryset_with_object(qs, Site, near_outdoorsite,
distance=distance, field=field)
near_outdoorcourse = request.GET.get('near_outdoorcourse')
if near_outdoorcourse:
qs = self.intersect_queryset_with_object(qs, Course, near_outdoorcourse)
qs = self.intersect_queryset_with_object(qs, Course, near_outdoorcourse,
distance=distance, field=field)
return qs

def get_schema_fields(self, view):
Expand Down