diff --git a/pygeoapi/provider/base.py b/pygeoapi/provider/base.py index 8f85c71..5ba8372 100644 --- a/pygeoapi/provider/base.py +++ b/pygeoapi/provider/base.py @@ -48,6 +48,7 @@ class BaseProvider(object): self.data = provider_def['data'] self.id_field = provider_def['id_field'] self.time_field = provider_def.get('time_field') + self.properties = provider_def.get('properties', []) self.fields = {} def get_fields(self): diff --git a/pygeoapi/provider/csv_.py b/pygeoapi/provider/csv_.py index 4ebca60..c2c08ba 100644 --- a/pygeoapi/provider/csv_.py +++ b/pygeoapi/provider/csv_.py @@ -27,11 +27,12 @@ # # ================================================================= +from collections import OrderedDict import csv import itertools import logging -from pygeoapi.provider.base import BaseProvider +from pygeoapi.provider.base import BaseProvider, ProviderQueryError LOGGER = logging.getLogger(__name__) @@ -90,7 +91,17 @@ class CSVProvider(BaseProvider): float(row.pop(self.geometry_y)) ] } - feature['properties'] = row + if self.properties: + feature['properties'] = OrderedDict() + for p in self.properties: + try: + feature['properties'][p] = row[p] + except KeyError as err: + LOGGER.error(err) + raise ProviderQueryError() + else: + feature['properties'] = row + if identifier is not None and feature['ID'] == identifier: found = True result = feature diff --git a/pygeoapi/provider/elasticsearch_.py b/pygeoapi/provider/elasticsearch_.py index d61d687..1691802 100644 --- a/pygeoapi/provider/elasticsearch_.py +++ b/pygeoapi/provider/elasticsearch_.py @@ -27,6 +27,7 @@ # # ================================================================= +from collections import OrderedDict import logging from elasticsearch import Elasticsearch, exceptions, helpers @@ -211,6 +212,15 @@ class ElasticsearchProvider(BaseProvider): } query['sort'].append(sort_) + if self.properties: + LOGGER.debug('including specified fields: {}'.format( + self.properties)) + query['_source'] = { + 'includes': list(map('properties.{}'.format, self.properties)) + } + query['_source']['includes'].append('properties.{}'.format( + self.id_field)) + query['_source']['includes'].append('geometry') try: LOGGER.debug('querying Elasticsearch') if startindex + limit > 10000: @@ -253,7 +263,22 @@ class ElasticsearchProvider(BaseProvider): id_ = feature['_source']['properties'][self.id_field] LOGGER.debug('serializing id {}'.format(id_)) feature['_source']['ID'] = id_ - feature_collection['features'].append(feature['_source']) + if self.properties: + feature_thinned = { + 'geometry': feature['_source']['geometry'], + 'properties': OrderedDict() + } + for p in self.properties: + try: + feature_thinned['properties'][p] = \ + feature['_source']['properties'][p] + except KeyError as err: + LOGGER.error(err) + raise ProviderQueryError() + + feature_collection['features'].append(feature_thinned) + else: + feature_collection['features'].append(feature['_source']) return feature_collection diff --git a/tests/test_csv__provider.py b/tests/test_csv__provider.py index c34f8f6..a01a3a4 100644 --- a/tests/test_csv__provider.py +++ b/tests/test_csv__provider.py @@ -82,6 +82,13 @@ def test_query(fixture, config): assert len(results['features']) == 1 assert results['features'][0]['ID'] == '238' + assert len(results['features'][0]['properties']) == 3 + + config['properties'] = ['value', 'stn_id'] + p = CSVProvider(config) + results = p.query() + assert len(results['features'][0]['properties']) == 2 + def test_get(fixture, config): p = CSVProvider(config) diff --git a/tests/test_elasticsearch__provider.py b/tests/test_elasticsearch__provider.py index 0dedbfd..a9c2054 100644 --- a/tests/test_elasticsearch__provider.py +++ b/tests/test_elasticsearch__provider.py @@ -75,6 +75,13 @@ def test_query(config): results = p.query(sortby=[{'property': 'scalerank', 'order': 'D'}]) assert results['features'][0]['properties']['scalerank'] == 8 + assert len(results['features'][0]['properties']) == 37 + + config['properties'] = ['nameascii'] + p = ElasticsearchProvider(config) + results = p.query() + assert len(results['features'][0]['properties']) == 1 + def test_get(config): p = ElasticsearchProvider(config)