Skip to content

Commit

Permalink
get map filter working with buffer, allow filters to return arbitrary…
Browse files Browse the repository at this point in the history
… data, re #4771
  • Loading branch information
apeters committed May 3, 2019
1 parent ff6cb7d commit cd80176
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 20 deletions.
67 changes: 65 additions & 2 deletions arches/app/search/components/map_filter.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
from django.contrib.gis.geos import GEOSGeometry
from arches.app.models.system_settings import settings
from arches.app.utils.betterJSONSerializer import JSONSerializer, JSONDeserializer
from arches.app.search.elasticsearch_dsl_builder import Bool, Nested, Terms, GeoShape

details = {
"searchcomponentid": "",
"name": "Map Filter",
Expand All @@ -15,5 +20,63 @@

class MapFilter():

def append_dsl(self, dsl):
pass
def append_dsl(self, querysting_params, query_dsl, permitted_nodegroups, include_provisional):
search_query = Bool()
spatial_filter = JSONDeserializer().deserialize(querysting_params)
if 'features' in spatial_filter:
if len(spatial_filter['features']) > 0:
feature_geom = spatial_filter['features'][0]['geometry']
feature_properties = {}
if 'properties' in spatial_filter['features'][0]:
feature_properties = spatial_filter['features'][0]['properties']
buffer = {'width': 0, 'unit': 'ft'}
if 'buffer' in feature_properties:
buffer = feature_properties['buffer']
search_buffer = _buffer(feature_geom, buffer['width'], buffer['unit'])
feature_geom = JSONDeserializer().deserialize(search_buffer.json)
geoshape = GeoShape(field='geometries.geom.features.geometry', type=feature_geom['type'], coordinates=feature_geom['coordinates'])

invert_spatial_search = False
if 'inverted' in feature_properties:
invert_spatial_search = feature_properties['inverted']

spatial_query = Bool()
if invert_spatial_search is True:
spatial_query.must_not(geoshape)
else:
spatial_query.filter(geoshape)

# get the nodegroup_ids that the user has permission to search
spatial_query.filter(Terms(field='geometries.nodegroup_id', terms=permitted_nodegroups))

if include_provisional is False:
spatial_query.filter(Terms(field='geometries.provisional', terms=['false']))

elif include_provisional == 'only provisional':
spatial_query.filter(Terms(field='geometries.provisional', terms=['true']))

search_query.filter(Nested(path='geometries', query=spatial_query))

query_dsl.add_query(search_query)

return {'search_buffer': search_buffer.geojson}


def _buffer(geojson, width=0, unit='ft'):
geojson = JSONSerializer().serialize(geojson)
geom = GEOSGeometry(geojson, srid=4326)

try:
width = float(width)
except:
width = 0

if width > 0:
if unit == 'ft':
width = width/3.28084

geom.transform(settings.ANALYSIS_COORDINATE_SYSTEM_SRID)
geom = geom.buffer(width)
geom.transform(4326)

return geom
31 changes: 13 additions & 18 deletions arches/app/views/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,7 @@ def search_results(request):
except Exception as err:
return JSONResponse(err.message, status=500)

dsl = search_results_dsl['query']
search_buffer = search_results_dsl['search_buffer']
dsl = search_results_dsl.pop('query', None)
dsl.include('graph_id')
dsl.include('root_ontology_class')
dsl.include('resourceinstanceid')
Expand Down Expand Up @@ -258,7 +257,8 @@ def search_results(request):

ret = {}
ret['results'] = results
ret['search_buffer'] = JSONSerializer().serialize(search_buffer) if search_buffer != None else None
for key, value in search_results_dsl.items():
ret[key] = value
ret['paginator'] = {}
ret['paginator']['current_page'] = page.number
ret['paginator']['has_next'] = page.has_next()
Expand Down Expand Up @@ -305,7 +305,6 @@ def get_provisional_type(request):
return result

def build_search_results_dsl(request):
spatial_filter = JSONDeserializer().deserialize(request.GET.get('mapFilter', '{}'))
include_provisional = get_provisional_type(request)
type_filter = request.GET.get('typeFilter', '')

Expand All @@ -314,8 +313,6 @@ def build_search_results_dsl(request):
page = 1 if request.GET.get('page') == '' else int(request.GET.get('page', 1))
temporal_filter = JSONDeserializer().deserialize(request.GET.get('temporalFilter', '{}'))
advanced_filters = JSONDeserializer().deserialize(request.GET.get('advanced', '[]'))
search_buffer = None
se = SearchEngineFactory().create()

if export != None:
limit = settings.SEARCH_EXPORT_ITEMS_PER_PAGE
Expand All @@ -325,7 +322,10 @@ def build_search_results_dsl(request):
limit = settings.SEARCH_ITEMS_PER_PAGE
limit = int(request.GET.get('limit', limit))

query = Query(se, start=limit*int(page-1), limit=limit)
se = SearchEngineFactory().create()
resultsObj = {
'query': Query(se, start=limit*int(page-1), limit=limit)
}
search_query = Bool()

nested_agg = NestedAgg(path='points', name='geo_aggs')
Expand Down Expand Up @@ -355,7 +355,7 @@ def build_search_results_dsl(request):
nested_agg_filter.add_aggregation(GeoHashGridAgg(field='points.point', name='grid', precision=settings.HEX_BIN_PRECISION))
nested_agg_filter.add_aggregation(GeoBoundsAgg(field='points.point', name='bounds'))
nested_agg.add_aggregation(nested_agg_filter)
query.add_aggregation(nested_agg)
resultsObj['query'].add_aggregation(nested_agg)

search_components = models.SearchComponent.objects.all()

Expand All @@ -364,15 +364,12 @@ def get_filter(filtertype):
if component.componentname == filtertype:
return get_class_from_modulename(component.modulename, component.classname, settings.SEARCH_COMPONENT_LOCATIONS)

# import ipdb
# ipdb.set_trace()
for filter_type, querystring in request.GET.items():
print filter_type
search_filter = get_filter(filter_type)
print search_filter
if search_filter:
search_filter().append_dsl(querystring, query, permitted_nodegroups, include_provisional)
print query.dsl
ret = search_filter().append_dsl(querystring, resultsObj['query'], permitted_nodegroups, include_provisional)
if ret is not None:
resultsObj[filter_type] = ret


# if term_filter != '':
Expand Down Expand Up @@ -557,10 +554,8 @@ def get_filter(filtertype):
advanced_query.should(grouped_query)
search_query.must(advanced_query)

query.add_query(search_query)
if search_buffer != None:
search_buffer = search_buffer.geojson
return {'query': query, 'search_buffer':search_buffer}
resultsObj['query'].add_query(search_query)
return resultsObj

def get_permitted_nodegroups(user):
return [str(nodegroup.pk) for nodegroup in get_nodegroups_by_perm(user, 'models.read_nodegroup')]
Expand Down

0 comments on commit cd80176

Please sign in to comment.