From 89f1de552ce855f093daa763f82ca93cd6e8fc89 Mon Sep 17 00:00:00 2001 From: sbsimo Date: Tue, 10 Oct 2017 18:17:33 +0200 Subject: [PATCH] enable layer filtering by region bbox --- filter/__init__.py | 0 filter/admin.py | 3 ++ filter/migrations/0001_initial.py | 25 +++++++++ filter/migrations/__init__.py | 0 filter/models.py | 11 ++++ filter/resourcebase_api.py | 86 +++++++++++++++++++++++++++++++ filter/tests.py | 3 ++ filter/urls.py | 9 ++++ filter/views.py | 3 ++ haitidata/settings.py | 3 +- haitidata/urls.py | 5 +- 11 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 filter/__init__.py create mode 100644 filter/admin.py create mode 100644 filter/migrations/0001_initial.py create mode 100644 filter/migrations/__init__.py create mode 100644 filter/models.py create mode 100644 filter/resourcebase_api.py create mode 100644 filter/tests.py create mode 100644 filter/urls.py create mode 100644 filter/views.py diff --git a/filter/__init__.py b/filter/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/filter/admin.py b/filter/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/filter/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/filter/migrations/0001_initial.py b/filter/migrations/0001_initial.py new file mode 100644 index 0000000..6655bef --- /dev/null +++ b/filter/migrations/0001_initial.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('base', '24_to_26'), + ] + + operations = [ + migrations.CreateModel( + name='RegionBBox', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('bbox_x0', models.DecimalField(null=True, max_digits=19, decimal_places=10, blank=True)), + ('bbox_x1', models.DecimalField(null=True, max_digits=19, decimal_places=10, blank=True)), + ('bbox_y0', models.DecimalField(null=True, max_digits=19, decimal_places=10, blank=True)), + ('bbox_y1', models.DecimalField(null=True, max_digits=19, decimal_places=10, blank=True)), + ('region', models.OneToOneField(to='base.Region')), + ], + ), + ] diff --git a/filter/migrations/__init__.py b/filter/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/filter/models.py b/filter/models.py new file mode 100644 index 0000000..6dc7840 --- /dev/null +++ b/filter/models.py @@ -0,0 +1,11 @@ +from django.db import models + +from geonode.base.models import Region + + +class RegionBBox(models.Model): + region = models.OneToOneField(Region, on_delete=models.CASCADE) + bbox_x0 = models.DecimalField(max_digits=19, decimal_places=10, blank=True, null=True) + bbox_x1 = models.DecimalField(max_digits=19, decimal_places=10, blank=True, null=True) + bbox_y0 = models.DecimalField(max_digits=19, decimal_places=10, blank=True, null=True) + bbox_y1 = models.DecimalField(max_digits=19, decimal_places=10, blank=True, null=True) diff --git a/filter/resourcebase_api.py b/filter/resourcebase_api.py new file mode 100644 index 0000000..f4fd7ad --- /dev/null +++ b/filter/resourcebase_api.py @@ -0,0 +1,86 @@ +from django.conf import settings +from django.core.exceptions import ObjectDoesNotExist + +from geonode.api.resourcebase_api import CommonModelApi, CommonMetaApi +from geonode.layers.models import Layer +from geonode.base.models import Region + + +class CommonModelApiExt(CommonModelApi): + def apply_filters(self, request, applicable_filters): + types = applicable_filters.pop('type', None) + extent = applicable_filters.pop('extent', None) + keywords = applicable_filters.pop('keywords__slug__in', None) + region = applicable_filters.get('regions__name__in', None) + region_bbox = None + if region: + print('region is ', region) + try: + region_obj = Region.objects.get(name=region[0]) + except Region.DoesNotExist: + print 'it does not exists' + else: + print('db record', region_obj.name_en) + try: + regionbbox_obj = region_obj.regionbbox + except ObjectDoesNotExist: + print 'regionbbox does not exist' + else: + print(str(regionbbox_obj.bbox_x0)) + bbox = [regionbbox_obj.bbox_x0, regionbbox_obj.bbox_y0, regionbbox_obj.bbox_x1, regionbbox_obj.bbox_y1] + bbox_valid = not any(coo is None for coo in bbox) + if bbox_valid: + region_bbox = ','.join([str(coo) for coo in bbox]) + del applicable_filters['regions__name__in'] + extent = None + print region_bbox + else: + print 'bbox not valid' + + semi_filtered = super( + CommonModelApi, + self).apply_filters( + request, + applicable_filters) + filtered = None + if types: + for the_type in types: + if the_type in LAYER_SUBTYPES.keys(): + if filtered: + filtered = filtered | semi_filtered.filter( + Layer___storeType=LAYER_SUBTYPES[the_type]) + else: + filtered = semi_filtered.filter( + Layer___storeType=LAYER_SUBTYPES[the_type]) + else: + if filtered: + filtered = filtered | semi_filtered.instance_of( + FILTER_TYPES[the_type]) + else: + filtered = semi_filtered.instance_of( + FILTER_TYPES[the_type]) + else: + filtered = semi_filtered + + if extent: + filtered = self.filter_bbox(filtered, extent) + + if keywords: + filtered = self.filter_h_keywords(filtered, keywords) + + if region_bbox: + filtered = self.filter_bbox(filtered, region_bbox) + print 'filtering by bbox: ', region_bbox + + return filtered + + +class LayerExtResource(CommonModelApiExt): + """Layer Ext API""" + + class Meta(CommonMetaApi): + queryset = Layer.objects.distinct().order_by('-date') + if settings.RESOURCE_PUBLISHING: + queryset = queryset.filter(is_published=True) + resource_name = 'layers' + excludes = ['csw_anytext', 'metadata_xml'] diff --git a/filter/tests.py b/filter/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/filter/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/filter/urls.py b/filter/urls.py new file mode 100644 index 0000000..1539670 --- /dev/null +++ b/filter/urls.py @@ -0,0 +1,9 @@ +from tastypie.api import Api + +#from geonode.api.resourcebase_api import LayerResource +from filter.resourcebase_api import LayerExtResource + + +api_ext = Api(api_name='api') + +api_ext.register(LayerExtResource()) diff --git a/filter/views.py b/filter/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/filter/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/haitidata/settings.py b/haitidata/settings.py index f9e4955..04ab195 100644 --- a/haitidata/settings.py +++ b/haitidata/settings.py @@ -62,7 +62,8 @@ INSTALLED_APPS = INSTALLED_APPS + ( 'geonode-client', 'charts_app', 'wfs_harvest', - "clip-and-ship" + "clip-and-ship", + 'filter' ) LAYER_PREVIEW_LIBRARY = 'react' diff --git a/haitidata/urls.py b/haitidata/urls.py index 9ae5fb3..db07836 100644 --- a/haitidata/urls.py +++ b/haitidata/urls.py @@ -4,14 +4,17 @@ from osgeo_importer.urls import urlpatterns as importer_urlpatterns from geonode.urls import * +from filter.urls import api_ext + urlpatterns = patterns('', url(r'^/?$', TemplateView.as_view(template_name='site_index.html'), name='home'), + url(r'', include(api_ext.urls)) ) + urlpatterns + [ url(r'^chart/', include('charts_app.urls')), url(r'^table/', include('wfs_harvest.urls')), - url(r'^clip/', include('clip-and-ship.urls')) + url(r'^clip/', include('clip-and-ship.urls')), ] urlpatterns += patterns(