From 28157426f5b2467c1f5f3d8d3a02cbbb254e83dc Mon Sep 17 00:00:00 2001
From: Tom Kralidis
Date: Mon, 13 Jul 2020 06:28:11 -0400
Subject: [PATCH] update providers to allow 1..n representations (#489)
---
aws-lambda/pygeoapi-serverless-config.yml | 125 +++----
docker/default.config.yml | 334 +++++++++---------
.../elastic/pygeoapi/docker.config.yml | 46 +--
docker/examples/simple/my.config.yml | 35 +-
docs/source/configuration.rst | 28 +-
.../data-publishing/ogcapi-features.rst | 89 ++---
docs/source/data-publishing/stac.rst | 11 +-
docs/source/plugins.rst | 18 +-
pygeoapi-config.yml | 41 ++-
pygeoapi/api.py | 103 +++---
pygeoapi/openapi.py | 6 +-
pygeoapi/templates/collection.html | 2 +
pygeoapi/util.py | 43 ++-
tests/cite/ogcapi-features/cite.config.yml | 11 +-
tests/pygeoapi-test-config-envvars.yml | 15 +-
tests/pygeoapi-test-config.yml | 15 +-
tests/pygeoapi-test-ogr-config.yml | 307 ++++++++--------
tests/test_api.py | 2 +-
tests/test_util.py | 42 +++
19 files changed, 714 insertions(+), 559 deletions(-)
diff --git a/aws-lambda/pygeoapi-serverless-config.yml b/aws-lambda/pygeoapi-serverless-config.yml
index 88e6abf..57e3ece 100644
--- a/aws-lambda/pygeoapi-serverless-config.yml
+++ b/aws-lambda/pygeoapi-serverless-config.yml
@@ -108,13 +108,14 @@ resources:
begin: 2000-10-30T18:24:39Z
end: 2007-10-30T08:57:29Z
trs: http://www.opengis.net/def/uom/ISO-8601/0/Gregorian
- provider:
- name: CSV
- data: tests/data/obs.csv
- id_field: id
- geometry:
- x_field: long
- y_field: lat
+ providers:
+ - type: feature
+ name: CSV
+ data: tests/data/obs.csv
+ id_field: id
+ geometry:
+ x_field: long
+ y_field: lat
ne_110m_populated_places_simple:
type: collection
@@ -139,10 +140,11 @@ resources:
spatial:
bbox: [-180,-90,180,90]
crs: http://www.opengis.net/def/crs/OGC/1.3/CRS84
- provider:
- name: Elasticsearch
- data: http://localhost:9200/ne_110m_populated_places_simple
- id_field: geonameid
+ providers:
+ - type: feature
+ name: Elasticsearch
+ data: http://localhost:9200/ne_110m_populated_places_simple
+ id_field: geonameid
lakes:
type: collection
@@ -164,10 +166,11 @@ resources:
begin: 2011-11-11
end: null # or empty
trs: http://www.opengis.net/def/uom/ISO-8601/0/Gregorian
- provider:
- name: GeoJSON
- data: tests/data/ne_110m_lakes.geojson
- id_field: id
+ providers:
+ - type: feature
+ name: GeoJSON
+ data: tests/data/ne_110m_lakes.geojson
+ id_field: id
countries:
type: collection
@@ -189,11 +192,12 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: SQLiteGPKG
- data: tests/data/ne_110m_admin_0_countries.sqlite
- id_field: ogc_fid
- table: ne_110m_admin_0_countries
+ providers:
+ - type: feature
+ name: SQLiteGPKG
+ data: tests/data/ne_110m_admin_0_countries.sqlite
+ id_field: ogc_fid
+ table: ne_110m_admin_0_countries
poi:
type: collection
title: Portuguese point of interrest
@@ -220,11 +224,12 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: GeoPackage
- data: tests/data/poi_portugal.gpkg
- id_field: osm_id
- table: poi_portugal
+ providers:
+ - type: feature
+ name: GeoPackage
+ data: tests/data/poi_portugal.gpkg
+ id_field: osm_id
+ table: poi_portugal
hotosm_bdi_waterways:
type: collection
@@ -249,17 +254,18 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: PostgreSQL
- data:
- host: 127.0.0.1
- dbname: test
- user: postgres
- password: postgres
- port: 5432
- schema: public
- id_field: osm_id
- table: hotosm_bdi_waterways
+ providers:
+ - type: feature
+ name: PostgreSQL
+ data:
+ host: 127.0.0.1
+ dbname: test
+ user: postgres
+ password: postgres
+ port: 5432
+ schema: public
+ id_field: osm_id
+ table: hotosm_bdi_waterways
dutch_georef_stations:
type: collection
@@ -284,29 +290,30 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: WFS
- source: WFS:http://geodata.nationaalgeoregister.nl/rdinfo/wfs?
- source_srs: EPSG:28992
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- source_options:
-# OGR_WFS_VERSION: 1.1.0
- OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: gml_id
- layer: rdinfo:stations
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: WFS
+ source: WFS:http://geodata.nationaalgeoregister.nl/rdinfo/wfs?
+ source_srs: EPSG:28992
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ source_options:
+ # OGR_WFS_VERSION: 1.1.0
+ OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: gml_id
+ layer: rdinfo:stations
hello-world:
type: process
diff --git a/docker/default.config.yml b/docker/default.config.yml
index 27ec088..4c8d2cb 100644
--- a/docker/default.config.yml
+++ b/docker/default.config.yml
@@ -119,13 +119,14 @@ resources:
temporal:
begin: 2000-10-30T18:24:39Z
end: 2007-10-30T08:57:29Z
- provider:
- name: CSV
- data: tests/data/obs.csv
- id_field: id
- geometry:
- x_field: long
- y_field: lat
+ providers:
+ - type: feature
+ name: CSV
+ data: tests/data/obs.csv
+ id_field: id
+ geometry:
+ x_field: long
+ y_field: lat
lakes:
type: collection
@@ -146,10 +147,11 @@ resources:
temporal:
begin: 2011-11-11
end: null # or empty (either means open ended)
- provider:
- name: GeoJSON
- data: tests/data/ne_110m_lakes.geojson
- id_field: id
+ providers:
+ - type: feature
+ name: GeoJSON
+ data: tests/data/ne_110m_lakes.geojson
+ id_field: id
countries:
type: collection
@@ -171,11 +173,12 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: SQLiteGPKG
- data: tests/data/ne_110m_admin_0_countries.sqlite
- id_field: ogc_fid
- table: ne_110m_admin_0_countries
+ providers:
+ - type: feature
+ name: SQLiteGPKG
+ data: tests/data/ne_110m_admin_0_countries.sqlite
+ id_field: ogc_fid
+ table: ne_110m_admin_0_countries
dutch_georef_stations:
type: collection
@@ -200,29 +203,30 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: WFS
- source: WFS:http://geodata.nationaalgeoregister.nl/rdinfo/wfs?
- source_srs: EPSG:28992
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- source_options:
-# OGR_WFS_VERSION: 1.1.0
- OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: gml_id
- layer: rdinfo:stations
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: WFS
+ source: WFS:http://geodata.nationaalgeoregister.nl/rdinfo/wfs?
+ source_srs: EPSG:28992
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ source_options:
+ # OGR_WFS_VERSION: 1.1.0
+ OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: gml_id
+ layer: rdinfo:stations
utah_city_locations:
type: collection
@@ -246,29 +250,30 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: WFS
- source: WFS:http://demo.deegree.org/utah-workspace/services/wfs?TYPENAME=app:SGID93_LOCATION_UDOTMap_CityLocations
- source_srs: EPSG:26912
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- source_options:
-# OGR_WFS_VERSION: 2.0.0
- OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: NAME
- layer: app:SGID93_LOCATION_UDOTMap_CityLocations
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: WFS
+ source: WFS:http://demo.deegree.org/utah-workspace/services/wfs?TYPENAME=app:SGID93_LOCATION_UDOTMap_CityLocations
+ source_srs: EPSG:26912
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ source_options:
+ # OGR_WFS_VERSION: 2.0.0
+ OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: NAME
+ layer: app:SGID93_LOCATION_UDOTMap_CityLocations
unesco_pois_italy:
type: collection
@@ -291,29 +296,30 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: WFS
- source: WFS:https://demo.geo-solutions.it/geoserver/wfs
- source_srs: EPSG:32632
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- source_options:
-# OGR_WFS_VERSION: 1.1.0
- OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: gml_id
- layer: unesco:Unesco_point
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: WFS
+ source: WFS:https://demo.geo-solutions.it/geoserver/wfs
+ source_srs: EPSG:32632
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ source_options:
+ # OGR_WFS_VERSION: 1.1.0
+ OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: gml_id
+ layer: unesco:Unesco_point
ogr_gpkg_poi:
type: collection
@@ -341,25 +347,26 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: GPKG
- source: tests/data/poi_portugal.gpkg
- source_srs: EPSG:4326
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: osm_id
- layer: poi_portugal
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: GPKG
+ source: tests/data/poi_portugal.gpkg
+ source_srs: EPSG:4326
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: osm_id
+ layer: poi_portugal
ogr_geojson_lakes:
type: collection
@@ -380,25 +387,26 @@ resources:
temporal:
begin: 2011-11-11
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: GeoJSON
- source: tests/data/ne_110m_lakes.geojson
- source_srs: EPSG:4326
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: id
- layer: ne_110m_lakes
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: GeoJSON
+ source: tests/data/ne_110m_lakes.geojson
+ source_srs: EPSG:4326
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: id
+ layer: ne_110m_lakes
ogr_addresses_sqlite:
type: collection
@@ -421,26 +429,27 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: SQLite
- # source: tests/data/ne_110m_admin_0_countries.sqlite
- source: tests/data/dutch_addresses_4326.sqlite
- source_srs: EPSG:4326
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: id
- layer: ogrgeojson
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: SQLite
+ # source: tests/data/ne_110m_admin_0_countries.sqlite
+ source: tests/data/dutch_addresses_4326.sqlite
+ source_srs: EPSG:4326
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: id
+ layer: ogrgeojson
ogr_addresses_gpkg:
type: collection
@@ -463,25 +472,26 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: GPKG
- source: tests/data/dutch_addresses_4326.gpkg
- source_srs: EPSG:4326
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: id
- layer: OGRGeoJSON
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: GPKG
+ source: tests/data/dutch_addresses_4326.gpkg
+ source_srs: EPSG:4326
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: id
+ layer: OGRGeoJSON
hello-world:
type: process
diff --git a/docker/examples/elastic/pygeoapi/docker.config.yml b/docker/examples/elastic/pygeoapi/docker.config.yml
index c68138f..d55623e 100644
--- a/docker/examples/elastic/pygeoapi/docker.config.yml
+++ b/docker/examples/elastic/pygeoapi/docker.config.yml
@@ -111,13 +111,14 @@ resources:
begin: 2000-10-30T18:24:39Z
end: 2007-10-30T08:57:29Z
trs: http://www.opengis.net/def/uom/ISO-8601/0/Gregorian
- provider:
- name: CSV
- data: tests/data/obs.csv
- id_field: id
- geometry:
- x_field: long
- y_field: long
+ providers:
+ - type: feature
+ name: CSV
+ data: tests/data/obs.csv
+ id_field: id
+ geometry:
+ x_field: long
+ y_field: long
ne_110m_populated_places_simple:
type: collection
@@ -142,11 +143,12 @@ resources:
spatial:
bbox: [-180,-90,180,90]
crs: http://www.opengis.net/def/crs/OGC/1.3/CRS84
- provider:
- name: Elasticsearch
- #Note elastic_search is the docker container of ES the name is defined in the docker-compose.yml
- data: http://elastic_search:9200/ne_110m_populated_places_simple
- id_field: geonameid
+ providers:
+ - type: feature
+ name: Elasticsearch
+ #Note elastic_search is the docker container of ES the name is defined in the docker-compose.yml
+ data: http://elastic_search:9200/ne_110m_populated_places_simple
+ id_field: geonameid
lakes:
type: collection
@@ -168,10 +170,11 @@ resources:
begin: 2011-11-11
end: null # or empty
trs: http://www.opengis.net/def/uom/ISO-8601/0/Gregorian
- provider:
- name: GeoJSON
- data: tests/data/ne_110m_lakes.geojson
- id_field: id
+ providers:
+ - type: feature
+ name: GeoJSON
+ data: tests/data/ne_110m_lakes.geojson
+ id_field: id
countries:
type: collection
@@ -193,11 +196,12 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: SQLiteGPKG
- data: tests/data/ne_110m_admin_0_countries.sqlite
- id_field: ogc_fid
- table: ne_110m_admin_0_countries
+ providers:
+ - type: feature
+ name: SQLiteGPKG
+ data: tests/data/ne_110m_admin_0_countries.sqlite
+ id_field: ogc_fid
+ table: ne_110m_admin_0_countries
hello-world:
type: process
diff --git a/docker/examples/simple/my.config.yml b/docker/examples/simple/my.config.yml
index a75deb8..0379c14 100644
--- a/docker/examples/simple/my.config.yml
+++ b/docker/examples/simple/my.config.yml
@@ -109,13 +109,14 @@ resources:
begin: 2000-10-30T18:24:39Z
end: 2007-10-30T08:57:29Z
trs: http://www.opengis.net/def/uom/ISO-8601/0/Gregorian
- provider:
- name: CSV
- data: tests/data/obs.csv
- id_field: id
- geometry:
- x_field: long
- y_field: long
+ providers:
+ - type: feature
+ name: CSV
+ data: tests/data/obs.csv
+ id_field: id
+ geometry:
+ x_field: long
+ y_field: long
lakes:
type: collection
@@ -137,10 +138,11 @@ resources:
begin: 2011-11-11
end: null # or empty
trs: http://www.opengis.net/def/uom/ISO-8601/0/Gregorian
- provider:
- name: GeoJSON
- data: tests/data/ne_110m_lakes.geojson
- id_field: id
+ providers:
+ - type: feature
+ name: GeoJSON
+ data: tests/data/ne_110m_lakes.geojson
+ id_field: id
countries:
type: collection
@@ -162,11 +164,12 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: SQLiteGPKG
- data: tests/data/ne_110m_admin_0_countries.sqlite
- id_field: ogc_fid
- table: ne_110m_admin_0_countries
+ providers:
+ - type: feature
+ name: SQLiteGPKG
+ data: tests/data/ne_110m_admin_0_countries.sqlite
+ id_field: ogc_fid
+ table: ne_110m_admin_0_countries
hello-world:
type: process
diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst
index 502cbbd..83290b8 100644
--- a/docs/source/configuration.rst
+++ b/docs/source/configuration.rst
@@ -111,10 +111,20 @@ The ``metadata`` section provides settings for overall service metadata and desc
The ``resources`` section lists 1 or more dataset collections to be published by the server.
The ``resource.type`` property is required. Allowed types are:
+
- ``collection``
- ``process``
- ``stac-collection``
+The ``providers`` block is a list of 1..n providers with which to operate the data on. Each
+provider requires a ``type`` property. Allowed types are:
+
+- ``feature``
+
+A collection's default provider can be qualified with ``default: true`` in the provider
+configuration. If ``default`` is not included, the first provider is assumed to be the
+default.
+
.. code-block:: yaml
resources:
@@ -143,18 +153,20 @@ The ``resource.type`` property is required. Allowed types are:
temporal: # optional
begin: 2000-10-30T18:24:39Z # start datetime in RFC3339
end: 2007-10-30T08:57:29Z # end datetime in RFC3339
- provider: # required connection information
+ providers: # list of 1..n required connections information
# provider name
# see pygeoapi.plugin for supported providers
# for custom built plugins, use the import path (e.g. mypackage.provider.MyProvider)
# see Plugins section for more information
- name: CSV
- data: tests/data/obs.csv # required: the data filesystem path or URL, depending on plugin setup
- id_field: id # required for vector data, the field corresponding to the ID
- time_field: datetimestamp # optional field corresponding to the temporal propert of the dataset
- properties: # optional: only return the following properties, in order
- - stn_id
- - value
+ - type: feature # underlying data geospatial type: (allowed values are: feature)
+ default: true # optional: if not specified, the first provider definition is considered the default
+ name: CSV
+ data: tests/data/obs.csv # required: the data filesystem path or URL, depending on plugin setup
+ id_field: id # required for vector data, the field corresponding to the ID
+ time_field: datetimestamp # optional field corresponding to the temporal propert of the dataset
+ properties: # optional: only return the following properties, in order
+ - stn_id
+ - value
hello-world: # name of process
type: collection # REQUIRED (collection, process, or stac-collection)
diff --git a/docs/source/data-publishing/ogcapi-features.rst b/docs/source/data-publishing/ogcapi-features.rst
index 027af45..b0d2b0e 100644
--- a/docs/source/data-publishing/ogcapi-features.rst
+++ b/docs/source/data-publishing/ogcapi-features.rst
@@ -35,13 +35,14 @@ definition.
.. code-block:: yaml
- provider:
- name: CSV
- data: tests/data/obs.csv
- id_field: id
- geometry:
- x_field: long
- y_field: lat
+ providers:
+ - type: feature
+ name: CSV
+ data: tests/data/obs.csv
+ id_field: id
+ geometry:
+ x_field: long
+ y_field: lat
GeoJSON
@@ -51,10 +52,11 @@ To publish a GeoJSON file, the file must be a valid GeoJSON FeatureCollection.
.. code-block:: yaml
- provider:
- name: GeoJSON
- data: tests/data/file.json
- id_field: id
+ providers:
+ - type: feature
+ name: GeoJSON
+ data: tests/data/file.json
+ id_field: id
Elasticsearch
@@ -71,11 +73,12 @@ To publish an Elasticsearch index, the following are required in your index:
.. code-block:: yaml
- provider:
- name: Elasticsearch
- data: http://localhost:9200/ne_110m_populated_places_simple
- id_field: geonameid
- time_field: datetimefield
+ providers:
+ - type: feature
+ name: Elasticsearch
+ data: http://localhost:9200/ne_110m_populated_places_simple
+ id_field: geonameid
+ time_field: datetimefield
OGR
^^^
@@ -89,10 +92,11 @@ MongoDB
.. code-block:: yaml
- provider:
- name: MongoDB
- data: mongodb://localhost:27017/testdb
- collection: testplaces
+ providers:
+ - type: feature
+ name: MongoDB
+ data: mongodb://localhost:27017/testdb
+ collection: testplaces
PostgreSQL
@@ -102,17 +106,18 @@ PostgreSQL
.. code-block:: yaml
- provider:
- name: PostgreSQL
- data:
- host: 127.0.0.1
- dbname: test
- user: postgres
- password: postgres
- search_path: [osm, public]
- id_field: osm_id
- table: hotosm_bdi_waterways
- geom_field: foo_geom
+ providers:
+ - type: feature
+ name: PostgreSQL
+ data:
+ host: 127.0.0.1
+ dbname: test
+ user: postgres
+ password: postgres
+ search_path: [osm, public]
+ id_field: osm_id
+ table: hotosm_bdi_waterways
+ geom_field: foo_geom
SQLiteGPKG
@@ -124,22 +129,24 @@ SQLite file:
.. code-block:: yaml
- provider:
- name: SQLiteGPKG
- data: ./tests/data/ne_110m_admin_0_countries.sqlite
- id_field: ogc_fid
- table: ne_110m_admin_0_countries
+ providers:
+ - type: feature
+ name: SQLiteGPKG
+ data: ./tests/data/ne_110m_admin_0_countries.sqlite
+ id_field: ogc_fid
+ table: ne_110m_admin_0_countries
GeoPackage file:
.. code-block:: yaml
- provider:
- name: SQLiteGPKG
- data: ./tests/data/poi_portugal.gpkg
- id_field: osm_id
- table: poi_portugal
+ providers:
+ - type: feature
+ name: SQLiteGPKG
+ data: ./tests/data/poi_portugal.gpkg
+ id_field: osm_id
+ table: poi_portugal
Data access examples
diff --git a/docs/source/data-publishing/stac.rst b/docs/source/data-publishing/stac.rst
index 031ee99..c1860fe 100644
--- a/docs/source/data-publishing/stac.rst
+++ b/docs/source/data-publishing/stac.rst
@@ -18,11 +18,12 @@ to the given directory and specifying allowed file types:
my-stac-resource:
type: stac-collection
...
- provider:
- name: FileSystem
- data: /Users/tomkralidis/Dev/data/gdps
- file_types:
- - .grib2
+ providers:
+ - type: stac
+ name: FileSystem
+ data: /Users/tomkralidis/Dev/data/gdps
+ file_types:
+ - .grib2
.. note::
diff --git a/docs/source/plugins.rst b/docs/source/plugins.rst
index d7c3b9a..c09cb2e 100644
--- a/docs/source/plugins.rst
+++ b/docs/source/plugins.rst
@@ -111,10 +111,11 @@ The following methods are options to connect the plugin to pygeoapi:
.. code-block:: yaml
- provider:
- name: MyCoolData
- data: /path/to/file
- id_field: stn_id
+ providers:
+ - type: feature
+ name: MyCoolData
+ data: /path/to/file
+ id_field: stn_id
**Option 2**: implement outside of pygeoapi and add to configuration (recommended)
@@ -126,10 +127,11 @@ The following methods are options to connect the plugin to pygeoapi:
.. code-block:: yaml
- provider:
- name: mycooldatapackage.mycooldata.MyCoolDataProvider
- data: /path/to/file
- id_field: stn_id
+ providers:
+ - type: feature
+ name: mycooldatapackage.mycooldata.MyCoolDataProvider
+ data: /path/to/file
+ id_field: stn_id
Example: custom pygeoapi formatter
----------------------------------
diff --git a/pygeoapi-config.yml b/pygeoapi-config.yml
index 74895a8..a6e5fa3 100644
--- a/pygeoapi-config.yml
+++ b/pygeoapi-config.yml
@@ -111,13 +111,14 @@ resources:
temporal:
begin: 2000-10-30T18:24:39Z
end: 2007-10-30T08:57:29Z
- provider:
- name: CSV
- data: tests/data/obs.csv
- id_field: id
- geometry:
- x_field: long
- y_field: lat
+ providers:
+ - type: feature
+ name: CSV
+ data: tests/data/obs.csv
+ id_field: id
+ geometry:
+ x_field: long
+ y_field: lat
lakes:
type: collection
@@ -138,10 +139,11 @@ resources:
temporal:
begin: 2011-11-11
end: null # or empty (either means open ended)
- provider:
- name: GeoJSON
- data: tests/data/ne_110m_lakes.geojson
- id_field: id
+ providers:
+ - type: feature
+ name: GeoJSON
+ data: tests/data/ne_110m_lakes.geojson
+ id_field: id
test-data:
type: stac-collection
@@ -159,14 +161,15 @@ resources:
spatial:
bbox: [-180,-90,180,90]
crs: http://www.opengis.net/def/crs/OGC/1.3/CRS84
- provider:
- name: FileSystem
- data: tests/data
- file_types:
- - .gpkg
- - .sqlite
- - .csv
- - .grib2
+ providers:
+ - type: stac
+ name: FileSystem
+ data: tests/data
+ file_types:
+ - .gpkg
+ - .sqlite
+ - .csv
+ - .grib2
hello-world:
type: process
diff --git a/pygeoapi/api.py b/pygeoapi/api.py
index 7d02077..3cc9986 100644
--- a/pygeoapi/api.py
+++ b/pygeoapi/api.py
@@ -47,8 +47,9 @@ from pygeoapi.plugin import load_plugin, PLUGINS
from pygeoapi.provider.base import (
ProviderGenericError, ProviderConnectionError, ProviderNotFoundError,
ProviderQueryError, ProviderItemNotFoundError)
-from pygeoapi.util import (dategetter, filter_dict_by_key_value, json_serial,
- render_j2_template, TEMPLATES, to_json)
+from pygeoapi.util import (dategetter, filter_dict_by_key_value,
+ get_provider_by_type, get_provider_default,
+ json_serial, render_j2_template, TEMPLATES, to_json)
LOGGER = logging.getLogger(__name__)
@@ -302,9 +303,12 @@ class API:
LOGGER.debug('Creating collections')
for k, v in collections.items():
+ collection_data_type = get_provider_default(
+ v['providers'])['type']
+
collection = {'links': []}
collection['id'] = k
- collection['itemType'] = 'Feature'
+ collection['itemType'] = collection_data_type.capitalize()
collection['title'] = v['title']
collection['description'] = v['description']
collection['keywords'] = v['keywords']
@@ -346,42 +350,6 @@ class API:
collection['links'].append(lnk)
LOGGER.debug('Adding JSON and HTML link relations')
- collection['links'].append({
- 'type': 'application/json',
- 'rel': 'queryables',
- 'title': 'Queryables for this collection as JSON',
- 'href': '{}/collections/{}/queryables?f=json'.format(
- self.config['server']['url'], k)
- })
- collection['links'].append({
- 'type': 'text/html',
- 'rel': 'queryables',
- 'title': 'Queryables for this collection as HTML',
- 'href': '{}/collections/{}/queryables?f=html'.format(
- self.config['server']['url'], k)
- })
-
- collection['links'].append({
- 'type': 'application/geo+json',
- 'rel': 'items',
- 'title': 'items as GeoJSON',
- 'href': '{}/collections/{}/items?f=json'.format(
- self.config['server']['url'], k)
- })
- collection['links'].append({
- 'type': 'application/ld+json',
- 'rel': 'items',
- 'title': 'items as RDF (GeoJSON-LD)',
- 'href': '{}/collections/{}/items?f=jsonld'.format(
- self.config['server']['url'], k)
- })
- collection['links'].append({
- 'type': 'text/html',
- 'rel': 'items',
- 'title': 'Items as HTML',
- 'href': '{}/collections/{}/items?f=html'.format(
- self.config['server']['url'], k)
- })
collection['links'].append({
'type': 'application/json',
'rel': 'self' if not format_
@@ -405,6 +373,44 @@ class API:
self.config['server']['url'], k)
})
+ if collection_data_type == 'feature':
+ LOGGER.debug('Adding feature based links')
+ collection['links'].append({
+ 'type': 'application/json',
+ 'rel': 'queryables',
+ 'title': 'Queryables for this collection as JSON',
+ 'href': '{}/collections/{}/queryables?f=json'.format(
+ self.config['server']['url'], k)
+ })
+ collection['links'].append({
+ 'type': 'text/html',
+ 'rel': 'queryables',
+ 'title': 'Queryables for this collection as HTML',
+ 'href': '{}/collections/{}/queryables?f=html'.format(
+ self.config['server']['url'], k)
+ })
+ collection['links'].append({
+ 'type': 'application/geo+json',
+ 'rel': 'items',
+ 'title': 'items as GeoJSON',
+ 'href': '{}/collections/{}/items?f=json'.format(
+ self.config['server']['url'], k)
+ })
+ collection['links'].append({
+ 'type': 'application/ld+json',
+ 'rel': 'items',
+ 'title': 'items as RDF (GeoJSON-LD)',
+ 'href': '{}/collections/{}/items?f=jsonld'.format(
+ self.config['server']['url'], k)
+ })
+ collection['links'].append({
+ 'type': 'text/html',
+ 'rel': 'items',
+ 'title': 'Items as HTML',
+ 'href': '{}/collections/{}/items?f=html'.format(
+ self.config['server']['url'], k)
+ })
+
if dataset is not None and k == dataset:
fcm = collection
break
@@ -499,8 +505,8 @@ class API:
LOGGER.debug('Creating collection queryables')
LOGGER.debug('Loading provider')
try:
- p = load_plugin('provider',
- self.config['resources'][dataset]['provider'])
+ p = load_plugin('provider', get_provider_by_type(
+ self.config['resources'][dataset]['providers'], 'feature'))
except ProviderConnectionError:
exception = {
'code': 'NoApplicableCode',
@@ -723,8 +729,8 @@ class API:
LOGGER.debug('Loading provider')
try:
- p = load_plugin('provider',
- collections[dataset]['provider'])
+ p = load_plugin('provider', get_provider_by_type(
+ collections[dataset]['providers'], 'feature'))
except ProviderConnectionError:
exception = {
'code': 'NoApplicableCode',
@@ -909,8 +915,9 @@ class API:
content = formatter.write(
data=content,
options={
- 'provider_def':
- collections[dataset]['provider']
+ 'provider_def': get_provider_by_type(
+ collections[dataset]['providers'],
+ 'feature')
}
)
@@ -964,7 +971,8 @@ class API:
return headers_, 400, json.dumps(exception)
LOGGER.debug('Loading provider')
- p = load_plugin('provider', collections[dataset]['provider'])
+ p = load_plugin('provider', get_provider_by_type(
+ collections[dataset]['providers'], 'feature'))
try:
LOGGER.debug('Fetching id {}'.format(identifier))
@@ -1141,7 +1149,8 @@ class API:
LOGGER.debug('Loading provider')
try:
- p = load_plugin('provider', stac_collections[dataset]['provider'])
+ p = load_plugin('provider', get_provider_by_type(
+ stac_collections[dataset]['providers'], 'stac'))
except ProviderConnectionError as err:
LOGGER.error(err)
exception = {
diff --git a/pygeoapi/openapi.py b/pygeoapi/openapi.py
index 4034a91..8a724f1 100644
--- a/pygeoapi/openapi.py
+++ b/pygeoapi/openapi.py
@@ -35,7 +35,8 @@ import click
import yaml
from pygeoapi.plugin import load_plugin
-from pygeoapi.util import filter_dict_by_key_value, yaml_load
+from pygeoapi.util import (filter_dict_by_key_value, get_provider_by_type,
+ yaml_load)
LOGGER = logging.getLogger(__name__)
@@ -407,7 +408,8 @@ def get_oas_30(cfg):
}
}
- p = load_plugin('provider', collections[k]['provider'])
+ p = load_plugin('provider', get_provider_by_type(
+ collections[k]['providers'], 'feature'))
if p.fields:
queryables_path = '{}/queryables'.format(collection_name_path)
diff --git a/pygeoapi/templates/collection.html b/pygeoapi/templates/collection.html
index 3cafa71..d744d7f 100644
--- a/pygeoapi/templates/collection.html
+++ b/pygeoapi/templates/collection.html
@@ -19,6 +19,7 @@
{{ kw }}
{% endfor %}
+ {% if data['itemType'] == 'Feature' %}
Queryables
-
@@ -37,6 +38,7 @@
Browse through the items of "{{ data['title'] }}"
+ {% endif %}
Links
{% for link in data['links'] %}
diff --git a/pygeoapi/util.py b/pygeoapi/util.py
index fc2c3de..8bbcf28 100644
--- a/pygeoapi/util.py
+++ b/pygeoapi/util.py
@@ -276,7 +276,7 @@ def get_breadcrumbs(urlpath):
def filter_dict_by_key_value(dict_, key, value):
"""
- helper generator function to filter a dict by a dict key
+ helper function to filter a dict by a dict key
:param dict_: ``dict``
:param key: dict key
@@ -286,3 +286,44 @@ def filter_dict_by_key_value(dict_, key, value):
"""
return {k: v for (k, v) in dict_.items() if v[key] == value}
+
+
+def get_provider_by_type(providers, provider_type):
+ """
+ helper function to load a provider by a provider type
+
+ :param providers: ``list`` of providers
+ :param provider_type: type of provider (feature)
+
+ :returns: provider based on type
+ """
+
+ LOGGER.debug('Searching for provider type {}'.format(provider_type))
+ try:
+ p = (next(d for i, d in enumerate(providers)
+ if d['type'] == provider_type))
+ except StopIteration:
+ raise RuntimeError('Cannot find provider type')
+
+ return p
+
+
+def get_provider_default(providers):
+ """
+ helper function to get a resource's default provider
+
+ :param providers: ``list`` of providers
+
+ :returns: filtered ``dict``
+ """
+
+ try:
+ default = (next(d for i, d in enumerate(providers) if 'default' in d
+ and d['default'] is True))
+ LOGGER.debug('found default provider type')
+ except StopIteration:
+ LOGGER.debug('no default provider type. Returning first provider')
+ default = providers[0]
+
+ LOGGER.debug('Default provider: {}'.format(default['type']))
+ return default
diff --git a/tests/cite/ogcapi-features/cite.config.yml b/tests/cite/ogcapi-features/cite.config.yml
index b13f74d..b7dc9ca 100644
--- a/tests/cite/ogcapi-features/cite.config.yml
+++ b/tests/cite/ogcapi-features/cite.config.yml
@@ -93,8 +93,9 @@ resources:
begin: 1850-01-01
end: null # or empty
- provider:
- name: Elasticsearch
- data: http://localhost:9200/canada-hydat-daily-mean-02hc003
- id_field: IDENTIFIER
- time_field: DATE
+ providers:
+ - type: feature
+ name: Elasticsearch
+ data: http://localhost:9200/canada-hydat-daily-mean-02hc003
+ id_field: IDENTIFIER
+ time_field: DATE
diff --git a/tests/pygeoapi-test-config-envvars.yml b/tests/pygeoapi-test-config-envvars.yml
index 91d9cd2..86b309c 100644
--- a/tests/pygeoapi-test-config-envvars.yml
+++ b/tests/pygeoapi-test-config-envvars.yml
@@ -107,13 +107,14 @@ resources:
begin: 2000-10-30T18:24:39Z
end: 2007-10-30T08:57:29Z
trs: http://www.opengis.net/def/uom/ISO-8601/0/Gregorian
- provider:
- name: CSV
- data: tests/data/obs.csv
- id_field: id
- geometry:
- x_field: long
- y_field: lat
+ providers:
+ - type: feature
+ name: CSV
+ data: tests/data/obs.csv
+ id_field: id
+ geometry:
+ x_field: long
+ y_field: lat
hello-world:
type: process
diff --git a/tests/pygeoapi-test-config.yml b/tests/pygeoapi-test-config.yml
index 764ef34..83bd407 100644
--- a/tests/pygeoapi-test-config.yml
+++ b/tests/pygeoapi-test-config.yml
@@ -118,13 +118,14 @@ resources:
begin: 2000-10-30T18:24:39Z
end: 2007-10-30T08:57:29Z
trs: http://www.opengis.net/def/uom/ISO-8601/0/Gregorian
- provider:
- name: CSV
- data: tests/data/obs.csv
- id_field: id
- geometry:
- x_field: long
- y_field: lat
+ providers:
+ - type: feature
+ name: CSV
+ data: tests/data/obs.csv
+ id_field: id
+ geometry:
+ x_field: long
+ y_field: lat
hello-world:
type: process
diff --git a/tests/pygeoapi-test-ogr-config.yml b/tests/pygeoapi-test-ogr-config.yml
index 5e63164..768be7f 100644
--- a/tests/pygeoapi-test-ogr-config.yml
+++ b/tests/pygeoapi-test-ogr-config.yml
@@ -104,29 +104,30 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: WFS
- source: WFS:http://geodata.nationaalgeoregister.nl/rdinfo/wfs?
- source_srs: EPSG:28992
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- source_options:
-# OGR_WFS_VERSION: 1.1.0
- OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: gml_id
- layer: rdinfo:stations
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: WFS
+ source: WFS:http://geodata.nationaalgeoregister.nl/rdinfo/wfs?
+ source_srs: EPSG:28992
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ source_options:
+ # OGR_WFS_VERSION: 1.1.0
+ OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: gml_id
+ layer: rdinfo:stations
# Warning: this layer contains about 10 million addresses, the backend WFS seems not optimized
dutch_addresses:
@@ -152,29 +153,30 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: WFS
- source: WFS:http://geodata.nationaalgeoregister.nl/inspireadressen/wfs?
- source_srs: EPSG:28992
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- source_options:
-# OGR_WFS_VERSION: 2.0.0
- OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: gml_id
- layer: inspireadressen:inspireadressen
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: WFS
+ source: WFS:http://geodata.nationaalgeoregister.nl/inspireadressen/wfs?
+ source_srs: EPSG:28992
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ source_options:
+ # OGR_WFS_VERSION: 2.0.0
+ OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: gml_id
+ layer: inspireadressen:inspireadressen
utah_city_locations:
type: collection
@@ -198,29 +200,30 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: WFS
- source: WFS:http://demo.deegree.org/utah-workspace/services/wfs?TYPENAME=app:SGID93_LOCATION_UDOTMap_CityLocations
- source_srs: EPSG:26912
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- source_options:
-# OGR_WFS_VERSION: 2.0.0
- OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: NAME
- layer: app:SGID93_LOCATION_UDOTMap_CityLocations
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: WFS
+ source: WFS:http://demo.deegree.org/utah-workspace/services/wfs?TYPENAME=app:SGID93_LOCATION_UDOTMap_CityLocations
+ source_srs: EPSG:26912
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ source_options:
+ # OGR_WFS_VERSION: 2.0.0
+ OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: NAME
+ layer: app:SGID93_LOCATION_UDOTMap_CityLocations
unesco_pois_italy:
type: collection
@@ -243,29 +246,30 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: WFS
- source: WFS:https://demo.geo-solutions.it/geoserver/wfs
- source_srs: EPSG:32632
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- source_options:
-# OGR_WFS_VERSION: 1.1.0
- OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: gml_id
- layer: unesco:Unesco_point
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: WFS
+ source: WFS:https://demo.geo-solutions.it/geoserver/wfs
+ source_srs: EPSG:32632
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ source_options:
+ # OGR_WFS_VERSION: 1.1.0
+ OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN: NO
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: gml_id
+ layer: unesco:Unesco_point
ogr_gpkg_poi:
type: collection
@@ -293,25 +297,26 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: GPKG
- source: tests/data/poi_portugal.gpkg
- source_srs: EPSG:4326
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: osm_id
- layer: poi_portugal
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: GPKG
+ source: tests/data/poi_portugal.gpkg
+ source_srs: EPSG:4326
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: osm_id
+ layer: poi_portugal
sf_311incidents:
@@ -334,24 +339,25 @@ resources:
temporal:
begin:
end: null # or empty
- provider:
- name: OGR
- data:
- source_type: ESRIJSON
- source: ESRIJSON:http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0/query?where=objectid+%3D+objectid&outfields=*&f=json
- source_srs: EPSG:4326
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
-
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
-
- id_field: objectid
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: ESRIJSON
+ source: ESRIJSON:http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0/query?where=objectid+%3D+objectid&outfields=*&f=json
+ source_srs: EPSG:4326
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+
+ id_field: objectid
cases_italy_per_region_from_github:
title: "Cases in Italy - DPC GitHub"
@@ -373,27 +379,28 @@ resources:
begin: 2020-01-01T00:00:00Z
end: # or empty
- provider:
- name: OGR
- data:
- source_type: CSV
- source: /vsicurl/https://raw.githubusercontent.com/pcm-dpc/COVID-19/master/dati-regioni/dpc-covid19-ita-regioni.csv
- source_srs: EPSG:4326
- target_srs: EPSG:4326
- source_capabilities:
- paging: True
- open_options:
- X_POSSIBLE_NAMES: long
- Y_POSSIBLE_NAMES: lat
- gdal_ogr_options:
- EMPTY_AS_NULL: NO
- GDAL_CACHEMAX: 64
- # GDAL_HTTP_PROXY: (optional proxy)
- # GDAL_PROXY_AUTH: (optional auth for remote WFS)
- CPL_DEBUG: NO
- id_field: fid
- time_field: data
- layer: dpc-covid19-ita-regioni
+ providers:
+ - type: feature
+ name: OGR
+ data:
+ source_type: CSV
+ source: /vsicurl/https://raw.githubusercontent.com/pcm-dpc/COVID-19/master/dati-regioni/dpc-covid19-ita-regioni.csv
+ source_srs: EPSG:4326
+ target_srs: EPSG:4326
+ source_capabilities:
+ paging: True
+ open_options:
+ X_POSSIBLE_NAMES: long
+ Y_POSSIBLE_NAMES: lat
+ gdal_ogr_options:
+ EMPTY_AS_NULL: NO
+ GDAL_CACHEMAX: 64
+ # GDAL_HTTP_PROXY: (optional proxy)
+ # GDAL_PROXY_AUTH: (optional auth for remote WFS)
+ CPL_DEBUG: NO
+ id_field: fid
+ time_field: data
+ layer: dpc-covid19-ita-regioni
hello-world:
type: process
diff --git a/tests/test_api.py b/tests/test_api.py
index a2d4c34..7ee6196 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -246,7 +246,7 @@ def test_get_collection_queryables(config, api_):
assert len(queryables['queryables']) == 6
# test with provider filtered properties
- api_.config['resources']['obs']['provider']['properties'] = ['stn_id']
+ api_.config['resources']['obs']['providers'][0]['properties'] = ['stn_id']
rsp_headers, code, response = api_.get_collection_queryables(
req_headers, {'f': 'json'}, 'obs')
diff --git a/tests/test_util.py b/tests/test_util.py
index 20bd079..4e99668 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -115,3 +115,45 @@ def test_get_breadcrumbs():
def test_path_basename():
assert util.get_path_basename('/path/to/file.txt') == 'file.txt'
assert util.get_path_basename('/path/to/dir') == 'dir'
+
+
+def test_filter_dict_by_key_value():
+ with open(get_test_file_path('pygeoapi-test-config.yml')) as fh:
+ d = util.yaml_load(fh)
+
+ collections = util.filter_dict_by_key_value(d['resources'],
+ 'type', 'collection')
+ assert len(collections) == 1
+
+ notfound = util.filter_dict_by_key_value(d['resources'],
+ 'type', 'foo')
+
+ assert len(notfound) == 0
+
+
+def test_get_provider_by_type():
+ with open(get_test_file_path('pygeoapi-test-config.yml')) as fh:
+ d = util.yaml_load(fh)
+
+ p = util.get_provider_by_type(d['resources']['obs']['providers'],
+ 'feature')
+
+ assert isinstance(p, dict)
+ assert p['type'] == 'feature'
+ assert p['name'] == 'CSV'
+
+ with pytest.raises(RuntimeError):
+ p = util.get_provider_by_type(d['resources']['obs']['providers'],
+ 'something-else')
+
+
+def test_get_provider_default():
+ with open(get_test_file_path('pygeoapi-test-config.yml')) as fh:
+ d = util.yaml_load(fh)
+
+ pd = util.get_provider_default(d['resources']['obs']['providers'])
+
+ assert pd['type'] == 'feature'
+ assert pd['name'] == 'CSV'
+
+ pd = util.get_provider_default(d['resources']['obs']['providers'])