CRS support
Starting with version 0.15.0, pygeoapi fully supports OGC API - Features - Part 2: Coordinate Reference Systems by Reference.
This enables the import and export of any data according to dedicated projections.
A "projection" is specified with a Coordinate Reference System (CRS) identifier. These are in URI formats
like http://www.opengis.net/def/crs/OGC/1.3/CRS84
(basically WGS84 in longitude, latitude axis order)
or the "OpenGIS" format like http://www.opengis.net/def/crs/EPSG/0/4258
. Note that the "EPSG:" format like EPSG:4326
is outside the scope of the OGC standard.
In particular CRS support allows for the following:
- to specify the CRS in which the data is stored, in pygeoapi the
storageCRS
config option - to specify the list of CRSs in which Feature data can be retrieved, in pygeoapi the
crs
config option - to publish these CRSs in the collection metadata
- the
crs=
query parameter for a collection or collection item - the
bbox-crs=
query parameter to indicate that thebbox=
parameter is encoded in that CRS - the HTTP response header
Content-Crs
denotes the CRS of the Feature(s) in the data returned
So although GeoJSON mandates WGS84 in longitude, latitude order, the client and server may still agree on other CRSs.
Under the hood, pygeoapi uses the well-known pyproj Python wrapper to the PROJ library.
Read more in the pygeoapi documentation in the CRS Chapter.
Exercise
Adding CRS support to pygeoapi collections for the provider
type feature
is as simple as
for example extending the Exercise 2 config with this snippet:
crs:
- http://www.opengis.net/def/crs/OGC/1.3/CRS84
- http://www.opengis.net/def/crs/EPSG/0/4258
- http://www.opengis.net/def/crs/EPSG/0/3857
- http://www.opengis.net/def/crs/EPSG/0/4326
storage_crs: http://www.opengis.net/def/crs/OGC/1.3/CRS84
Axis
Axis order (are coordinates it longitude, latitude or latitude, longitude order?) in projections is often a source of confusion.
However the URI format is quite clear on this, at least more than the EPSG:
format.
So http://www.opengis.net/def/crs/OGC/1.3/CRS84 is longitude, latitude order, while
http://www.opengis.net/def/crs/EPSG/0/4326 is latitude, longitude order.
In the config below, we basically indicate that the data is stored in WGS84 (longitude, latitude axis order) and can be retrieved
in CRSs like http://www.opengis.net/def/crs/EPSG/0/4258
(ETRS89 latitude, longitude axis order) etc.
Add CRS to a pygeoapi configuration
Open the pygeoapi configuration file in a text editor.
Find the line # START - EXERCISE 2 - firenze-terrain
Update the dataset section with CRS support by replacing it with the snippet below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
Now we can inspect the collection metadata and retrieve Features in various CRSs. We can even do this in the Swagger UI, but using the browser is quite fast and clear.
Metadata
Collection Metadata
Open the URL: http://localhost:5000/collections/firenze-terrains-vec Your configured CRSs are displayed at the bottom of the page: "Reference Systems" and "Storage CRS".
See these in JSON format, also at the bottom: http://localhost:5000/collections/firenze-terrains-vec?f=json
.
.
"crs":[
"http://www.opengis.net/def/crs/OGC/1.3/CRS84",
"http://www.opengis.net/def/crs/EPSG/0/4258",
"http://www.opengis.net/def/crs/EPSG/0/3857",
"http://www.opengis.net/def/crs/EPSG/0/4326"
],
"storageCRS":"http://www.opengis.net/def/crs/OGC/1.3/CRS84"
}
Reproject Features
Using the CRS query parameter
Open the URL: http://localhost:5000/collections/firenze-terrains-vec/items?f=json&crs=http://www.opengis.net/def/crs/EPSG/0/4258
This is ETRS89, similar to WGS84, but for the European Continent (Datum) and in lat,lon order. This is e.g. used in INSPIRE.
See these in JSON format, also at the bottom:
"type":"FeatureCollection",
"features":[
{
"type":"Feature",
"geometry":{
"type":"MultiPolygon",
"coordinates":[
[
[
[
43.77805936835436,
11.23486287997071
],
[
43.77809089595012,
11.2348943159564
],
[
43.77810038978989,
11.23491359066035
],
[
43.77705757917591,
11.2368990806804
.
.
"crs":[
"http://www.opengis.net/def/crs/OGC/1.3/CRS84",
"http://www.opengis.net/def/crs/EPSG/0/4258",
"http://www.opengis.net/def/crs/EPSG/0/3857",
"http://www.opengis.net/def/crs/EPSG/0/4326"
],
"storageCRS":"http://www.opengis.net/def/crs/OGC/1.3/CRS84"
}
If you open the browser development console, you can observe the HTTP response header:
Content-Crs: <http://www.opengis.net/def/crs/EPSG/0/4258>
(The CRS URI is always enclosed in <
>
)