.Net implementation of the OGC API family of standards
OGC API standards define modular API building blocks to spatially enable Web APIs in a consistent way. The OpenAPI specification is used to define the API building blocks.
Currently, this project implements the following standards:
Standard | Data Providers |
---|---|
OGC API - Features - Part 1: Core | Microsoft SQL Server 2012+ Azure SQL Database PostgreSQL/PostGis |
OGC API - Features - Part 2: Coordinate Reference Systems by Reference | Independent |
OGC API - Features - Part 4: Create, Replace, Update and Delete | Microsoft SQL Server 2012+ Azure SQL Database PostgreSQL/PostGis |
OGC API - Tiles - Part 1: Core | Sqlite/MbTiles |
This project uses:
- ASP.NET Core 8 for building web API
- NetTopologySuite for the features representation
- ProjNET for coordinate conversions
- OpenAPI.NET for OpenAPI documents generation
NuGet packages:
This implementation supports automatic API generation from metadata descriptions. To generate API, you must:
- Create ASP.NET Core WebAPI project
- Install necessary NuGet packages
- Register providers in ConfigureServices method. For example, to publish data from PostgreSQL you must add PostGis provider:
services.AddOgcApiPostGisProvider();
- Register OpenAPI and configure API:
services.AddOgcApi("ogcapi.json");
- Add controllers in ConfigureServices method:
services.AddControllers().AddOgcApiControllers();
This implementation uses attribute routing. All API endpoints will be accessible by the path /api/ogc.
API configuration can be made by configuration file named ogcsettings.json that has the following structure:
Configuration example
{
"LandingPage": {
"Title": "OGC API Implementation",
"Description": "The implementation of the OGC API family of standards that being developed to make it easy for anyone to provide geospatial data to the web",
"Version": "1.0",
"ContactName": "OGC API",
"ContactUrl": "https://www.example.com/",
"ApiDocumentPage": "/api/ogc/index.html",
"ApiDescriptionPage": "/api/ogc/swagger.json"
},
"Collections": [
{
"Id": "Test",
"Title": "Test collection",
"Features": {
"Crs": [
"http://www.opengis.net/def/crs/OGC/1.3/CRS84",
"http://www.opengis.net/def/crs/EPSG/0/3857"
],
"StorageCrs": "http://www.opengis.net/def/crs/EPSG/0/3857",
"Storage": {
"Type": "PostGis",
"ConnectionString": "Host=localhost;User Id=postgre;Password=myStrongP@ssword;Database=Tests;Port=5432;Timeout=50;",
"Schema": "test",
"Table": "test_table",
"GeometryColumn": "geom",
"GeometrySrid": 3857,
"GeometryDataType": "geometry",
"GeometryGeoJsonType": "MultiPolygon",
"IdentifierColumn": "id",
"Properties": [
"name",
"region"
]
}
},
"Tiles": {
"Crs": "http://www.opengis.net/def/crs/EPSG/0/3857",
"Storage": {
"Type": "MbTiles",
"FileName": "TilesData\\data.mbtiles"
}
}
}
]
}
The Landing page element provides links to:
- the API definition (Swagger documentation and JSON description pages)
- the Conformance declaration (path /conformance, link relation conformance), and
- the Collections (path /collections, link relation data).
The Conformance declaration states the conformance classes from standards or community specifications identified by a URI that the API conforms to.
In the landing page options, you must specify:
- Title
- Description
- Version - API version
- ContactName - name of the data owner or API developer
- ContactUrl - URL to the data owner or API developer site
- ApiDocumentPage - URL to the API definition (Swagger or custom HTML page with API description)
- ApiDescriptionPage - URL to the API documentation (OpenAPI JSON)
In collection options, you must specify:
- Id - unique identifier of the collection
- Title
- Features options that dependents on the data provider
- Tiles options that dependents on the data provider
Collection can be:
- features only. All data will be published as GeoJson objects
- tiles only. Collection in this case will be published as MapBox Vector Tiles
- hybrid: features + tiles. That means that API consumer can use tiles API for fast data queries and features API to get precise objects coordinates or modify objects
Tiles and features providers for one collection can be different. For example, you can create collection that publishes features from the database, but the tiles can be taken from mbtiles file.
OGC API - Features is a multi-part standard that offers the capability to create, modify, and query spatial data on the Web. It specifies requirements and recommendations for APIs that want to follow a standard way of sharing feature data.
OGC API Features provide access to collections of geospatial data based on OpenAPI 3.
Currently, only the database providers are supported: Sql Server, PostgreSQL/PostGis.
Use can publish geospatial data to the web from any table or view. Each table or view is treated as a separate data source. To provide settings, you must set options.
Feature collection options include:
- Crs - supported coordinate systems for the operations
- StorageCrs - coordinate system used by data provider to store features
Storage options include:
- ConnectionString - connection string for the source database. Defined for each source or table
- Schema - table or view schema
- Table - table name
- GeometryColumn - name of the column in the table containing spatial data
- GeometryDataType - can be geometry or geography
- GeometryGeoJsonType - OGC compatible geometry type, used to make OpenAPI GeoJson definition
- IdentifierColumn - name of the identifier column in the table
- Properties - array of any additional columns to publish
Options example
{
"Id": "Test",
"Title": "Test collection",
"Features": {
"Crs": [
"http://www.opengis.net/def/crs/OGC/1.3/CRS84",
"http://www.opengis.net/def/crs/EPSG/0/3857"
],
"StorageCrs": "http://www.opengis.net/def/crs/EPSG/0/3857",
"Storage": {
"Type": "PostGis",
"ConnectionString": "Host=localhost;User Id=postgre;Password=myStrongP@ssword;Database=Tests;Port=5432;Timeout=50;",
"Schema": "test",
"Table": "test_table",
"GeometryColumn": "geom",
"GeometrySrid": 3857,
"GeometryDataType": "geometry",
"GeometryGeoJsonType": "MultiPolygon",
"IdentifierColumn": "id",
"Properties": [
"name",
"region"
]
}
}
}
By default, all collections defined in the configuration file support only GET requests. To allow data modification operation to the features, you must include in the data provider configuration the following elements:
- AllowCreate - to allow Create/Insert operation for the collection
- AllowReplace - to allow Replace operation for the collection
- AllowUpdate - to allow Update operation for the collection
- AllowDelete - to allow Delete operation for the collection
Defining one or more of these options automatically expands API to the OGC API - Features - Part 4: Create, Replace, Update and Delete
Options example
{
"Id": "Test",
"Title": "Test collection",
"Features": {
"Crs": [
"http://www.opengis.net/def/crs/OGC/1.3/CRS84",
"http://www.opengis.net/def/crs/EPSG/0/3857"
],
"StorageCrs": "http://www.opengis.net/def/crs/EPSG/0/3857",
"Storage": {
"Type": "PostGis",
"ConnectionString": "Host=localhost;User Id=postgre;Password=myStrongP@ssword;Database=Tests;Port=5432;Timeout=50;",
"Schema": "test",
"Table": "test_table",
"GeometryColumn": "geom",
"GeometrySrid": 3857,
"GeometryDataType": "geometry",
"GeometryGeoJsonType": "MultiPolygon",
"IdentifierColumn": "id",
"Properties": [
"name",
"region"
]
"AllowCreate": true,
"AllowUpdate": true
}
}
}
You can restrict access to the features by providing predicates that will be included in WHERE statement for all database queries. To do this you must include in the features storage configuration the following settings: ApiKeyPredicateForGet, ApiKeyPredicateForCreate, ApiKeyPredicateForUpdate, ApiKeyPredicateForDelete.
All predicates can contain @ApiKey parameter that is used to filter allowed features in the data source. This parameter can be, for example, user name or session id.
Options example
{
"Id": "Test",
"Title": "Test collection",
"Features": {
"Crs": [
"http://www.opengis.net/def/crs/OGC/1.3/CRS84",
"http://www.opengis.net/def/crs/EPSG/0/3857"
],
"StorageCrs": "http://www.opengis.net/def/crs/EPSG/0/3857",
"Storage": {
"Type": "PostGis",
"ConnectionString": "Host=localhost;User Id=postgre;Password=myStrongP@ssword;Database=Tests;Port=5432;Timeout=50;",
"Schema": "test",
"Table": "test_table",
"GeometryColumn": "geom",
"GeometrySrid": 3857,
"GeometryDataType": "geometry",
"GeometryGeoJsonType": "MultiPolygon",
"IdentifierColumn": "id",
"Properties": [
"name",
"region"
]
"AllowCreate": true,
"AllowUpdate": true,
"ApiKeyPredicateForGet": "EXISTS(SELECT * FROM users WHERE id = @ApiKey",
"ApiKeyPredicateForCreate": "EXISTS(SELECT * FROM users WHERE id = @ApiKey",
"ApiKeyPredicateForUpdate": "EXISTS(SELECT * FROM users WHERE id = @ApiKey"
}
}
}
Current implementation supports only MapBox Vector Tiles to publish through API. Vector tiles must be stored in MbTiles format. You can generate tiles from GeoJson files by tippecanoe.
You can add tiles API to the existing collection or create a new collection that will contain only tiles without features API.
Tiles API options include:
- Crs - coordinate system used to store tiles
- Type - currently only MbTiles supported
- FileName - path to the MbTiles file
Options example
{
"Id": "Test",
"Title": "Test collection",
"Features": {
"Crs": [
"http://www.opengis.net/def/crs/OGC/1.3/CRS84",
"http://www.opengis.net/def/crs/EPSG/0/3857"
],
"StorageCrs": "http://www.opengis.net/def/crs/EPSG/0/3857",
"Storage": {
"Type": "PostGis",
"ConnectionString": "Host=localhost;User Id=postgre;Password=myStrongP@ssword;Database=Tests;Port=5432;Timeout=50;",
"Schema": "test",
"Table": "test_table",
"GeometryColumn": "geom",
"GeometrySrid": 3857,
"GeometryDataType": "geometry",
"GeometryGeoJsonType": "MultiPolygon",
"IdentifierColumn": "id",
"Properties": [
"name",
"region"
]
}
},
"Tiles": {
"Crs": "http://www.opengis.net/def/crs/EPSG/0/3857",
"Storage": {
"Type": "MbTiles",
"FileName": "TilesData\\data.mbtiles"
}
}
}
Swashbuckle.AspNetCore can be used for the Swagger web page automatic generation To do this add Swagger configuration in Configure method of your Startup class:
app.UseSwaggerUI(swaggerOptions =>
{
swaggerOptions.RoutePrefix = "api";
swaggerOptions.SwaggerEndpoint("ogc/swagger.json", "OGC API");
});
OpenAPI json definition is available on /api/ogc/swagger.json route in your application.
All OGC API controllers use policy with "OgcApi" name. Policy can be configured in ConfigureServices method:
services.AddCors(c => c.AddPolicy(name: "OgcApi", options =>
{
options.AllowAnyMethod().AllowAnyHeader();
}));
Don't forget to add
app.UseCors("OgcApi");
in Configure method.
API supports any coordinate system identified by SRID. Each coordinate system must have corresponding URI. To add your custom coordinate system, modify file SRID.csv provided by the NuGet package.
Currently, this project contains tests for the data providers. Testing the entire API can be done by OGC API - Features Conformance Test Suite
A test application is included in the repository (SampleWebApplication). It is recommended to use docker-compose debugging to run it. Included containers:
- Sql Server as a database
- Tomcat with TEAM Engine and OGC API - Features test suite
After launching the application, you can use the following links:
- https://localhost/api/index.html - to test the API
- http://localhost:8082/teamengine - TEAM engine application
To run tests in the TEAM engine, you must use the internal address: http://samplewebapplication:8080/api/ogc The instructions for launching TEAM engine are given here in the section Docker: https://cite.opengeospatial.org/teamengine/about/ogcapi-features-1.0/1.0/site/