Introduction
As a background you might want first to check a good introduction about OGC API Features or a video about the OGC API standard family, both provided by OGC (The Open Geospatial Consortium) itself.
The following diagram describes a decision flowchart to select a client class and a feature source to access GeoJSON feature collections and feature items:
Below you can find few step-by-step instructions how to get started in scenarios represented in the decision flowchart.
π» Static GeoJSON local resource
// 1. Get a feature source using an accessor to a file.final source = GeoJSONFeatures.any(() async => File('...').readAsString());
// 2. Access feature items.final items = await source.itemsAll();
// 3. Get an iterable of feature objects.final features = items.collection.features;
// 4. Loop through features (each with id, properties and geometry)for (final feat in features) { print('Feature ${feat.id} with geometry: ${feat.geometry}');}
π Static GeoJSON web resource
// 1. Get a feature source from a web resource using http.final source = GeoJSONFeatures.http(location: Uri.parse('...'));
// 2. Access feature items.final items = await source.itemsAll();
// 3. Get an iterable of feature objects.final features = items.collection.features;
// 4. Loop through features (each with id, properties and geometry)for (final feat in features) { print('Feature ${feat.id} with geometry: ${feat.geometry}');}
π Web API service conforming to OGC API Features
// 1. Get a client instance for a Web API endpoint.final client = OGCAPIFeatures.http(endpoint: Uri.parse('...'));
// 2. Access/check metadata (meta, OpenAPI, conformance, collections) as needed.final conformance = await client.conformance();if (!conformance.conformsToFeaturesCore(geoJSON: true)) { return; // not conforming to core and GeoJSON - so return}
// 3. Get a feature source for a specific collection.final source = await client.collection('my_collection');
// 4. Access (and check) metadata for this collection.final meta = await source.meta();print('Collection title: ${meta.title}');
// 5. Access feature items.final items = await source.itemsAll(limit: 100);
// 6. Check response metadata.print('Timestamp: ${items.timeStamp}');
// 7. Get an iterable of feature objects.final features = items.collection.features;
// 8. Loop through features (each with id, properties and geometry)for (final feat in features) { print('Feature ${feat.id} with geometry: ${feat.geometry}');}
For the step 5 other alternatives are:
- Use
source.items()
to get feature items by a filtered query (ie. bbox). - Use
source.itemById()
to get a single feature by an identifier. - Use
source.itemsAllPaged()
orsource.itemsPaged()
for accessing paged feature sets.
In the step 6 itβs also possible to get links to related resources, and optionally also to get a number of matched or returned features in a response.
π Using the standard HTTP RetryClient
When accessing static GeoJSON web resources or an OGC API Features service, itβs
also possible to define a retry policy using the standard http
package.
However you must also manage the life cycle of such a HTTP client instance by
ensuring itβs closed after making API calls.
A sample accessing OGC API Features service with custom HTTP client:
// Create an instance of the standard HTTP retry client for API calls final httpClient = RetryClient(http.Client(), retries: 4);
try { // 1. Get a client instance for a Web API endpoint. final client = OGCAPIFeatures.http( // set HTTP client (if not set the default `http.Client()` is used) client: httpClient,
// an URI to the landing page of the service endpoint: Uri.parse('...'), );
// 2. Access/check metadata (meta, OpenAPI, conformance, collections) as needed. final conformance = await client.conformance(); if (!conformance.conformsToFeaturesCore(geoJSON: true)) { return; // not conforming to core and GeoJSON - so return }
// 3. Get a feature source for a specific collection. final source = await client.collection('my_collection');
// ... other steps just like previously demonstrated ...
} finally { // ensure the HTTP client is closed after using httpClient.close(); }
This example of using a retry client requires also following imports:
import 'package:http/http.dart' as http;import 'package:http/retry.dart';