add skip_geometry to remaining feature providers (#887)
* skip geometry for SQLite/GPKG backends (#886) * simplify GKPG * add for remaining providers, add to doc
This commit is contained in:
@@ -15,17 +15,17 @@ pygeoapi core feature providers are listed below, along with a matrix of support
|
||||
parameters.
|
||||
|
||||
.. csv-table::
|
||||
:header: Provider, property filters/display, resulttype, bbox, datetime, sortby, CQL
|
||||
:header: Provider, property filters/display, resulttype, bbox, datetime, sortby, skipGeometry, CQL
|
||||
:align: left
|
||||
|
||||
CSV,✅/✅,results/hits,❌,❌,❌,❌
|
||||
Elasticsearch,✅/✅,results/hits,✅,✅,✅,✅
|
||||
GeoJSON,✅/✅,results/hits,❌,❌,❌,❌
|
||||
MongoDB,✅/❌,results,✅,✅,✅,❌
|
||||
OGR,✅/❌,results/hits,✅,❌,❌,❌
|
||||
PostgreSQL,✅/✅,results/hits,✅,❌,✅,❌
|
||||
SQLiteGPKG,✅/❌,results/hits,✅,❌,❌,❌
|
||||
SensorThingsAPI,✅/✅,results/hits,✅,✅,✅,❌
|
||||
CSV,✅/✅,results/hits,❌,❌,❌,✅,❌
|
||||
Elasticsearch,✅/✅,results/hits,✅,✅,✅,✅,✅
|
||||
GeoJSON,✅/✅,results/hits,❌,❌,❌,✅,❌
|
||||
MongoDB,✅/❌,results,✅,✅,✅,✅,❌
|
||||
OGR,✅/❌,results/hits,✅,❌,❌,✅,❌
|
||||
PostgreSQL,✅/✅,results/hits,✅,❌,✅,✅,❌
|
||||
SQLiteGPKG,✅/❌,results/hits,✅,❌,❌,✅,❌
|
||||
SensorThingsAPI,✅/✅,results/hits,✅,✅,✅,✅,❌
|
||||
|
||||
|
||||
Below are specific connection examples based on supported providers.
|
||||
|
||||
@@ -81,7 +81,8 @@ class MongoProvider(BaseProvider):
|
||||
map, reduce, "myresults")
|
||||
return result.distinct('_id')
|
||||
|
||||
def _get_feature_list(self, filterObj, sortList=[], skip=0, maxitems=1):
|
||||
def _get_feature_list(self, filterObj, sortList=[], skip=0, maxitems=1,
|
||||
skip_geometry=False):
|
||||
featurecursor = self.featuredb[self.collection].find(filterObj)
|
||||
|
||||
if sortList:
|
||||
@@ -93,6 +94,8 @@ class MongoProvider(BaseProvider):
|
||||
featurelist = list(featurecursor)
|
||||
for item in featurelist:
|
||||
item['id'] = str(item.pop('_id'))
|
||||
if skip_geometry:
|
||||
item['geometry'] = None
|
||||
|
||||
return featurelist, matchCount
|
||||
|
||||
@@ -126,10 +129,9 @@ class MongoProvider(BaseProvider):
|
||||
ASCENDING if (sort['order'] == '+') else DESCENDING)
|
||||
for sort in sortby]
|
||||
|
||||
featurelist, matchcount = self._get_feature_list(filterobj,
|
||||
sortList=sort_list,
|
||||
skip=offset,
|
||||
maxitems=limit)
|
||||
featurelist, matchcount = self._get_feature_list(
|
||||
filterobj, sortList=sort_list, skip=offset, maxitems=limit,
|
||||
skip_geometry=skip_geometry)
|
||||
|
||||
if resulttype == 'hits':
|
||||
featurelist = []
|
||||
|
||||
@@ -353,7 +353,8 @@ class OGRProvider(BaseProvider):
|
||||
result = self._response_feature_hits(layer)
|
||||
elif resulttype == 'results':
|
||||
LOGGER.debug('results specified')
|
||||
result = self._response_feature_collection(layer, limit)
|
||||
result = self._response_feature_collection(
|
||||
layer, limit, skip_geometry=skip_geometry)
|
||||
else:
|
||||
LOGGER.error('Invalid resulttype: %s' % resulttype)
|
||||
|
||||
@@ -455,13 +456,15 @@ class OGRProvider(BaseProvider):
|
||||
LOGGER.error(self.gdal.GetLastErrorMsg())
|
||||
raise gdalerr
|
||||
|
||||
def _ogr_feature_to_json(self, ogr_feature):
|
||||
def _ogr_feature_to_json(self, ogr_feature, skip_geometry=False):
|
||||
geom = ogr_feature.GetGeometryRef()
|
||||
if self.transform_out:
|
||||
# Optionally reproject the geometry
|
||||
geom.Transform(self.transform_out)
|
||||
|
||||
json_feature = ogr_feature.ExportToJson(as_object=True)
|
||||
if skip_geometry:
|
||||
json_feature['geometry'] = None
|
||||
try:
|
||||
json_feature['id'] = json_feature['properties'].pop(self.id_field)
|
||||
except Exception as err:
|
||||
@@ -470,7 +473,7 @@ class OGRProvider(BaseProvider):
|
||||
|
||||
return json_feature
|
||||
|
||||
def _response_feature_collection(self, layer, limit):
|
||||
def _response_feature_collection(self, layer, limit, skip_geometry=False):
|
||||
"""
|
||||
Assembles output from Layer query as
|
||||
GeoJSON FeatureCollection structure.
|
||||
@@ -492,7 +495,8 @@ class OGRProvider(BaseProvider):
|
||||
ogr_feature = _ignore_gdal_error(layer, 'GetNextFeature')
|
||||
count = 0
|
||||
while ogr_feature is not None:
|
||||
json_feature = self._ogr_feature_to_json(ogr_feature)
|
||||
json_feature = self._ogr_feature_to_json(
|
||||
ogr_feature, skip_geometry=skip_geometry)
|
||||
|
||||
feature_collection['features'].append(json_feature)
|
||||
|
||||
|
||||
@@ -128,11 +128,12 @@ class SQLiteGPKGProvider(BaseProvider):
|
||||
# WHERE continent=? <class 'tuple'>: ('Europe',)
|
||||
return where_clause, where_values
|
||||
|
||||
def __response_feature(self, row_data):
|
||||
def __response_feature(self, row_data, skip_geometry=False):
|
||||
"""
|
||||
Assembles GeoJSON output from DB query
|
||||
|
||||
:param row_data: DB row result
|
||||
:param skip_geometry: whether to skip geometry (default False)
|
||||
|
||||
:returns: `dict` of GeoJSON Feature
|
||||
"""
|
||||
@@ -145,6 +146,9 @@ class SQLiteGPKGProvider(BaseProvider):
|
||||
feature["geometry"] = json.loads(
|
||||
rd.pop('AsGeoJSON({})'.format(self.geom_col))
|
||||
)
|
||||
if skip_geometry:
|
||||
feature["geometry"] = None
|
||||
|
||||
feature['properties'] = rd
|
||||
feature['id'] = feature['properties'].pop(self.id_field)
|
||||
|
||||
@@ -306,7 +310,7 @@ class SQLiteGPKGProvider(BaseProvider):
|
||||
|
||||
for rd in row_data:
|
||||
feature_collection['features'].append(
|
||||
self.__response_feature(rd))
|
||||
self.__response_feature(rd, skip_geometry=skip_geometry))
|
||||
|
||||
return feature_collection
|
||||
|
||||
|
||||
@@ -96,6 +96,10 @@ def test_query(config):
|
||||
|
||||
assert len(results['features'][0]['properties']) == 37
|
||||
|
||||
results = p.query(skip_geometry=True)
|
||||
for feature in results['features']:
|
||||
assert feature['geometry'] is None
|
||||
|
||||
|
||||
def test_get(config):
|
||||
p = MongoProvider(config)
|
||||
|
||||
@@ -174,3 +174,12 @@ def test_query_with_property_vsicurl(config_vsicurl_csv):
|
||||
assert len(features) == 10
|
||||
for feature in features:
|
||||
assert 'Lazio' in feature['properties']['denominazione_regione']
|
||||
|
||||
|
||||
def test_query_with_skip_geometry_vsicurl(config_vsicurl_csv):
|
||||
"""Testing query for a valid JSON object with property filter"""
|
||||
|
||||
p = OGRProvider(config_vsicurl_csv)
|
||||
feature_collection = p.query(skip_geometry=True)
|
||||
for feature in feature_collection['features']:
|
||||
assert feature['geometry'] is None
|
||||
|
||||
@@ -167,3 +167,12 @@ def test_get_geopackage_not_existing_item_raise_exception(config_geopackage):
|
||||
p = SQLiteGPKGProvider(config_geopackage)
|
||||
with pytest.raises(ProviderItemNotFoundError):
|
||||
p.get(-1)
|
||||
|
||||
|
||||
def test_get_geopackage_skip_geometry(config_geopackage):
|
||||
"""Testing query for skipped geometry"""
|
||||
p = SQLiteGPKGProvider(config_geopackage)
|
||||
|
||||
feature_collection = p.query(skip_geometry=True)
|
||||
for feature in feature_collection['features']:
|
||||
assert feature['geomtry'] is None
|
||||
|
||||
Reference in New Issue
Block a user