Add api endpoints for collecting location details
- includes soil order name and code, ecological district, ecological region and address from linz
This commit is contained in:
parent
2302ed6fc6
commit
49bcc85116
4 changed files with 107 additions and 13 deletions
|
@ -1,20 +1,16 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from django.contrib.gis.geos import Point
|
from django.http import Http404
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
from .models import EcologicalRegion, EcologicalDistrictLayer, SoilOrder, SoilVariant
|
from .models import EcologicalRegion, EcologicalDistrictLayer, SoilOrder, SoilVariant
|
||||||
|
from .utils import get_point_from_coordinates
|
||||||
|
|
||||||
def coordinate_filter(request, queryset):
|
def coordinate_filter(request, queryset):
|
||||||
coordinates = request.query_params.get('coordinates')
|
coordinates = request.query_params.get('coordinates')
|
||||||
|
|
||||||
if coordinates is not None:
|
if coordinates is not None:
|
||||||
coordinates_json = json.loads(coordinates)
|
pnt = get_point_from_coordinates(coordinates)
|
||||||
pnt = Point(coordinates_json["lng"],
|
|
||||||
coordinates_json["lat"], srid=4326)
|
|
||||||
pnt.transform(2193)
|
|
||||||
|
|
||||||
filtered_regions = EcologicalRegion.objects.filter(
|
filtered_regions = EcologicalRegion.objects.filter(
|
||||||
ecologicaldistrictlayer__geom__intersects=pnt).values_list('id', flat=True)
|
ecologicaldistrictlayer__geom__intersects=pnt).values_list('id', flat=True)
|
||||||
filtered_soil_orders = SoilOrder.objects.filter(
|
filtered_soil_orders = SoilOrder.objects.filter(
|
||||||
|
@ -37,3 +33,19 @@ def soil_variant_filter(request, queryset):
|
||||||
return queryset.filter(soil_variants__in=soil_variant_ids).distinct()
|
return queryset.filter(soil_variants__in=soil_variant_ids).distinct()
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
def soil_order_coordinate_filter(coordinates):
|
||||||
|
pnt = get_point_from_coordinates(coordinates)
|
||||||
|
try:
|
||||||
|
return SoilOrder.objects.filter(soillayer__geom__intersects=pnt)
|
||||||
|
except SoilOrder.DoesNotExist:
|
||||||
|
raise Http404(f"Soil Order cannot be found for point {pnt}")
|
||||||
|
|
||||||
|
|
||||||
|
def ecological_district_coordinate_filter(coordinates):
|
||||||
|
pnt = get_point_from_coordinates(coordinates)
|
||||||
|
try:
|
||||||
|
return EcologicalDistrictLayer.objects.filter(geom__intersects=pnt)
|
||||||
|
except EcologicalDistrictLayer.DoesNotExist:
|
||||||
|
raise Http404(f"Ecological district layer cannot be found for point {pnt}")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from right_tree.api.models import Plant, ToleranceLevel, SoilOrder, SoilVariant, EcologicalRegion
|
from right_tree.api.models import Plant, ToleranceLevel, SoilOrder, SoilVariant, EcologicalRegion, EcologicalDistrictLayer
|
||||||
|
|
||||||
|
|
||||||
class ToleranceLevelSerializer(serializers.HyperlinkedModelSerializer):
|
class ToleranceLevelSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
|
@ -14,10 +14,23 @@ class EcologicalRegionSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
fields = ['name']
|
fields = ['name']
|
||||||
|
|
||||||
|
|
||||||
|
class EcologicalDistrictLayerSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
|
ecological_district = serializers.CharField(max_length=50, source='ecologic_1')
|
||||||
|
ecological_region = serializers.CharField(
|
||||||
|
max_length=50, source='ecologic_2')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = EcologicalDistrictLayer
|
||||||
|
fields = ['ecological_district', 'ecological_region']
|
||||||
|
|
||||||
|
|
||||||
class SoilOrderSerializer(serializers.HyperlinkedModelSerializer):
|
class SoilOrderSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
|
soil_name = serializers.CharField(max_length=50, source='name')
|
||||||
|
soil_code = serializers.CharField(max_length=1, source='code')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SoilOrder
|
model = SoilOrder
|
||||||
fields = ['name']
|
fields = ['soil_name', 'soil_code']
|
||||||
|
|
||||||
|
|
||||||
class SoilVariantSerializer(serializers.HyperlinkedModelSerializer):
|
class SoilVariantSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
|
@ -26,6 +39,13 @@ class SoilVariantSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
fields = ['name']
|
fields = ['name']
|
||||||
|
|
||||||
|
|
||||||
|
class LocationDetailsSerializer(serializers.Serializer):
|
||||||
|
ecologic_1 = serializers.CharField(max_length=50)
|
||||||
|
ecologic_2 = serializers.CharField(max_length=50)
|
||||||
|
code = serializers.CharField(max_length=1)
|
||||||
|
name = serializers.CharField(max_length=50)
|
||||||
|
|
||||||
|
|
||||||
class PlantSerializer(serializers.HyperlinkedModelSerializer):
|
class PlantSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
id = serializers.ReadOnlyField()
|
id = serializers.ReadOnlyField()
|
||||||
water_tolerance = ToleranceLevelSerializer()
|
water_tolerance = ToleranceLevelSerializer()
|
||||||
|
@ -39,3 +59,7 @@ class PlantSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Plant
|
model = Plant
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class AddressSerializer(serializers.Serializer):
|
||||||
|
full_address = serializers.CharField(max_length=500)
|
||||||
|
|
|
@ -1,7 +1,17 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
from django.contrib.gis.geos import Point
|
||||||
|
from django.contrib.gis.db import models
|
||||||
|
from django.http import HttpResponseBadRequest
|
||||||
|
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
from right_tree.api.models import Plant
|
from rest_framework.response import Response
|
||||||
from right_tree.api.serializers import PlantSerializer
|
|
||||||
from .filters import coordinate_filter, soil_variant_filter
|
from right_tree.api.models import Plant, EcologicalDistrictLayer, SoilOrder
|
||||||
|
from right_tree.api.serializers import PlantSerializer, SoilOrderSerializer, EcologicalDistrictLayerSerializer, AddressSerializer
|
||||||
|
|
||||||
|
from .filters import *
|
||||||
|
from .utils import get_address_from_coordinates
|
||||||
|
|
||||||
class PlantViewSet(viewsets.ModelViewSet):
|
class PlantViewSet(viewsets.ModelViewSet):
|
||||||
"""
|
"""
|
||||||
|
@ -19,4 +29,49 @@ class PlantViewSet(viewsets.ModelViewSet):
|
||||||
queryset = soil_variant_filter(self.request, queryset)
|
queryset = soil_variant_filter(self.request, queryset)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
class SoilOrderViewSet(viewsets.ModelViewSet):
|
||||||
|
"""
|
||||||
|
Filtered viewset for soil details.
|
||||||
|
"""
|
||||||
|
serializer_class = SoilOrderSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
""" Filtering soil order query set by coordinate parameters in the URL.
|
||||||
|
"""
|
||||||
|
coordinates = self.request.query_params.get('coordinates')
|
||||||
|
if coordinates is not None:
|
||||||
|
return soil_order_coordinate_filter(coordinates)
|
||||||
|
|
||||||
|
return SoilOrder.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class EcologicalDistrictViewSet(viewsets.ModelViewSet):
|
||||||
|
"""
|
||||||
|
Filtered viewset for ecological district/region details.
|
||||||
|
"""
|
||||||
|
serializer_class = EcologicalDistrictLayerSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
""" Filtering ecological district/region query set by coordinate parameters in the URL.
|
||||||
|
"""
|
||||||
|
coordinates = self.request.query_params.get('coordinates')
|
||||||
|
if coordinates is not None:
|
||||||
|
return ecological_district_coordinate_filter(coordinates)
|
||||||
|
|
||||||
|
return EcologicalDistrictLayer.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class LINZPropertyViewSet(viewsets.ViewSet):
|
||||||
|
"""
|
||||||
|
Filtered viewset for ecological district/region details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def list(self, request):
|
||||||
|
coordinates = self.request.query_params.get('coordinates')
|
||||||
|
if coordinates is not None:
|
||||||
|
address_data = get_address_from_coordinates(coordinates)
|
||||||
|
serializer = AddressSerializer(address_data)
|
||||||
|
return Response(serializer.data)
|
||||||
|
else:
|
||||||
|
return HttpResponseBadRequest("No coordinate given.")
|
||||||
|
|
|
@ -21,6 +21,9 @@ from right_tree.api import views
|
||||||
|
|
||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.register(r'plants', views.PlantViewSet)
|
router.register(r'plants', views.PlantViewSet)
|
||||||
|
router.register(r'soil', views.SoilOrderViewSet, basename='soil')
|
||||||
|
router.register(r'ecologicaldistrict', views.EcologicalDistrictViewSet, basename='ecologicaldistrict')
|
||||||
|
router.register(r'address', views.LINZPropertyViewSet, basename='address')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
|
Loading…
Reference in a new issue