diff --git a/README.md b/README.md index 993d961..0a4d7ae 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ pip install -e . cp pygeoapi-config.yml local.yml vi local.yml # update server.url -# add ES dataset(s) to datasets section +# add dataset(s) to datasets section export PYGEOAPI_CONFIG=`pwd`/local.yml python pygeoapi/app.py ``` @@ -28,7 +28,7 @@ curl http://localhost:5000/ # conformance curl http://localhost:5000/api/conformance # feature collection -curl http://localhost:5000/my-dataset +curl http://localhost:5000/obs # feature -curl http://localhost:5000/my-dataset/featureid +curl http://localhost:5000/obs/371 ``` diff --git a/pygeoapi/app.py b/pygeoapi/app.py index c4816ab..f5ef218 100644 --- a/pygeoapi/app.py +++ b/pygeoapi/app.py @@ -31,7 +31,7 @@ import os from urllib.parse import urlparse from flask import (abort, Flask, jsonify, make_response, - render_template) + render_template, request) from flask_cors import CORS import yaml @@ -115,8 +115,20 @@ def index_html(): def dataset(feature_collection, feature=None): """get feature from a feature collection""" + startindex = 0 + count = 10 + resulttype = 'results' + + if 'startIndex' in request.args: + startindex = int(request.args.get('startIndex')) + if 'count' in request.args: + count = int(request.args.get('count')) + if 'resultType' in request.args: + resulttype = request.args.get('resultType') + if feature is None: - response = views.get_feature_collection(config, feature_collection) + response = views.get_feature_collection(config, feature_collection, + startindex, count, resulttype) else: response = views.get_feature(config, feature_collection, feature) diff --git a/pygeoapi/provider/csv.py b/pygeoapi/provider/csv.py index 4a67797..66712c4 100644 --- a/pygeoapi/provider/csv.py +++ b/pygeoapi/provider/csv.py @@ -28,6 +28,8 @@ # ================================================================= import csv +import itertools + from shapely import wkt from shapely.geometry import mapping @@ -45,14 +47,18 @@ class CSVProvider(BaseProvider): with open(self.url) as ff: self.data = csv.DictReader(ff) - def _load(self, identifier=None): + def _load(self, startindex=0, count=10, resulttype='results', + identifier=None): feature_collection = { 'type': 'FeatureCollection', 'features': [] } with open(self.url) as ff: data = csv.DictReader(ff) - for row in data: + if resulttype == 'hits': + feature_collection['numberMatched'] = len(list(data)) + return feature_collection + for row in itertools.islice(data, startindex, startindex+count): feature = {'type': 'Feature'} feature['ID'] = row.pop('id') feature['geometry'] = mapping(wkt.loads(row.pop('geom'))) @@ -63,14 +69,14 @@ class CSVProvider(BaseProvider): return feature_collection - def query(self): + def query(self, startindex=0, count=10, resulttype='results'): """ CSV query :returns: dict of 0..n GeoJSON features """ - return self._load() + return self._load(startindex, count, resulttype) def get(self, identifier): """ diff --git a/pygeoapi/provider/elasticsearch.py b/pygeoapi/provider/elasticsearch.py index 2a5b086..17b560a 100644 --- a/pygeoapi/provider/elasticsearch.py +++ b/pygeoapi/provider/elasticsearch.py @@ -48,7 +48,7 @@ class ElasticsearchProvider(BaseProvider): self.es = Elasticsearch(self.es_host) - def query(self): + def query(self, startindex=0, count=10, resulttype='results'): """ query ES @@ -60,7 +60,11 @@ class ElasticsearchProvider(BaseProvider): 'features': [] } - results = self.es.search(index=self.index_name) + results = self.es.search(index=self.index_name, from_=startindex, + size=count) + if resulttype == 'hits': + feature_collection['numberMatched'] = results['hits']['total'] + return feature_collection for feature in results['hits']['hits']: id_ = feature['_source']['properties']['identifier'] diff --git a/pygeoapi/provider/geojson.py b/pygeoapi/provider/geojson.py index abff1bc..b928c6b 100644 --- a/pygeoapi/provider/geojson.py +++ b/pygeoapi/provider/geojson.py @@ -67,12 +67,18 @@ class GeoJSONProvider(BaseProvider): 'features': []} dst.write(json.dumps(empty)) - def _load(self): + def _load(self, startindex=0, count=10, resulttype='results'): with open(self.url) as src: data = json.loads(src.read()) + + if resulttype == 'hits': + data['numberMatched'] = len(data['features']) + data['features'] = [] + else: + data['features'] = data['features'][startindex:startindex + count] return data - def query(self): + def query(self, startindex=0, count=10, resulttype='results'): """ query the provider @@ -80,7 +86,7 @@ class GeoJSONProvider(BaseProvider): TODO yield GeoJSON features? """ - return self._load() + return self._load(startindex, count, resulttype) def get(self, identifier): """ diff --git a/pygeoapi/views.py b/pygeoapi/views.py index a53adbc..8f9276c 100644 --- a/pygeoapi/views.py +++ b/pygeoapi/views.py @@ -38,30 +38,28 @@ def get_feature_collection_metadata(config): 'collections': [] } + url = config['server']['url'].rstrip('/') + fcm['links'] = [{ 'rel': 'self', 'type': 'application/json', 'title': 'this document', - 'href': '{}{}'.format(config['server']['url'], - url_for('index_json')), + 'href': '{}{}'.format(url, url_for('index_json')), }, { 'rel': 'self', 'type': 'text/html', 'title': 'this document as HTML', - 'href': '{}{}'.format(config['server']['url'], - url_for('index_html')), + 'href': '{}{}'.format(url, url_for('index_html')), }, { 'rel': 'self', 'type': 'application/openapi+json;version=3.0', 'title': 'the OpenAPI definition as JSON', - 'href': '{}{}'.format(config['server']['url'], - url_for('api_json')), + 'href': '{}{}'.format(url, url_for('api_json')), }, { 'rel': 'self', 'type': 'text/html', 'title': 'the OpenAPI definition as HTML', - 'href': '{}{}'.format(config['server']['url'], - url_for('api_html')), + 'href': '{}{}'.format(url, url_for('api_html')), } ] @@ -84,13 +82,15 @@ def get_feature_collection_metadata(config): return fcm -def get_feature_collection(config, dataset): +def get_feature_collection(config, dataset, startindex=0, count=10, + resulttype='results'): if dataset not in config['datasets'].keys(): return None p = load_provider(config['datasets'][dataset]['data']) - results = p.query() + results = p.query(startindex=startindex, count=count, + resulttype=resulttype) return results