From 3775c1e695cbd3fa493e7b9d01f2d6d23dc58bc3 Mon Sep 17 00:00:00 2001 From: navibyte <88932567+navispatial@users.noreply.github.com> Date: Tue, 15 Nov 2022 19:11:30 +0200 Subject: [PATCH] feat(geodata): consistent factories for GeoJSON and OGC API Features clients #155 --- dart/geodata/CHANGELOG.md | 9 +++ dart/geodata/example/geodata_example.dart | 4 +- dart/geodata/example/geojson_example.dart | 4 +- .../client/geojson_feature_client.dart | 81 ++++++++++++++----- .../service/client/ogc_feature_client.dart | 52 ++++++++---- 5 files changed, 110 insertions(+), 40 deletions(-) diff --git a/dart/geodata/CHANGELOG.md b/dart/geodata/CHANGELOG.md index fc4a0c82..25ae6e12 100644 --- a/dart/geodata/CHANGELOG.md +++ b/dart/geodata/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.11.0 + +[geodata version 0.11.0 #162](https://github.com/navibyte/geospatial/issues/162) + +Under development, current pre-release: 0.11.0-dev.0 + +🧩 Features: +* [Consistent factories for GeoJSON and OGC API Features clients #155](https://github.com/navibyte/geospatial/issues/155) + ## 0.10.1 📚 Small documentation updates. Also a link to the [Geospatial demos for Dart](https://github.com/navibyte/geospatial_demos) repository. diff --git a/dart/geodata/example/geodata_example.dart b/dart/geodata/example/geodata_example.dart index 2ac53984..e4db752e 100644 --- a/dart/geodata/example/geodata_example.dart +++ b/dart/geodata/example/geodata_example.dart @@ -115,7 +115,7 @@ Future main(List args) async { print('Reading web resource at: $location'); // GeoJSON client for a data source - final source = geoJsonHttpClient(location: location); + final source = GeoJSONFeatures.http(location: location); switch (operation) { case 'items': // get actual data, a single feature or features @@ -135,7 +135,7 @@ Future main(List args) async { final endpoint = Uri.parse(baseURL); // OGC API Features client (the service provides both meta and items) - final service = ogcApiFeaturesHttpClient(endpoint: endpoint); + final service = OGCAPIFeatures.http(endpoint: endpoint); switch (operation) { case 'meta': diff --git a/dart/geodata/example/geojson_example.dart b/dart/geodata/example/geojson_example.dart index 013cca1f..9ed90198 100644 --- a/dart/geodata/example/geojson_example.dart +++ b/dart/geodata/example/geojson_example.dart @@ -19,7 +19,7 @@ Future main(List args) async { // read GeoJSON for earthquakes from web using HTTP(S) print('GeoJSON features from HTTP'); await _readFeatures( - geoJsonHttpClient( + GeoJSONFeatures.http( location: Uri.parse( 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/' '2.5_day.geojson', @@ -31,7 +31,7 @@ Future main(List args) async { print(''); print('GeoJSON features from file'); await _readFeatures( - geoJsonFutureClient( + GeoJSONFeatures.any( () async => File('test/usgs/summary/2.5_day.geojson').readAsString(), ), ); diff --git a/dart/geodata/lib/src/geojson/service/client/geojson_feature_client.dart b/dart/geodata/lib/src/geojson/service/client/geojson_feature_client.dart index bf2201f1..7d698726 100644 --- a/dart/geodata/lib/src/geojson/service/client/geojson_feature_client.dart +++ b/dart/geodata/lib/src/geojson/service/client/geojson_feature_client.dart @@ -6,32 +6,74 @@ import 'package:geobase/vector.dart'; import 'package:geobase/vector_data.dart'; -import 'package:http/http.dart' as http; +import 'package:http/http.dart' as _http; import '/src/common/paged.dart'; import '/src/common/service.dart'; import '/src/core/features.dart'; import '/src/utils/features.dart'; +/// A class with static factory methods to create feature sources conforming to +/// the GeoJSON format. +class GeoJSONFeatures { + /// A client for accessing a `GeoJSON` data resource at [location] via http(s) + /// conforming to [format]. + /// + /// The required [location] should refer to a web resource containing GeoJSON + /// compliant data. + /// + /// When given the optional [client] is used for http requests, otherwise the + /// default client of the `package:http/http.dart` package is used. + /// + /// When given [headers] are injected to http requests (however some can be + /// overridden by the feature source implementation). + /// + /// When [format] is not given, then [GeoJSON] with default settings is used + /// as a default. Note that currently only GeoJSON is supported, but it's + /// possible to inject another format implementation (or with custom + /// configuration) to the default one. + static BasicFeatureSource http({ + required Uri location, + _http.Client? client, + Map? headers, + TextReaderFormat format = GeoJSON.feature, + }) => + _GeoJSONFeatureSource( + location, + adapter: FeatureHttpAdapter( + client: client, + headers: headers, + ), + format: format, + ); + + /// A client for accessing a `GeoJSON` feature collection from any [source]; + /// + /// The source function returns a future that fetches data from a file, a web + /// resource or other sources. Contents must be GeoJSON compliant data. + /// + /// When [format] is not given, then [GeoJSON] with default settings is used + /// as a default. Note that currently only GeoJSON is supported, but it's + /// possible to inject another format implementation (or with custom + /// configuration) to the default one. + static BasicFeatureSource any( + Future Function() source, { + TextReaderFormat format = GeoJSON.feature, + }) => + _GeoJSONFeatureSource( + source, + format: format, + ); +} + /// A client for accessing a `GeoJSON` data resource at [location] via http(s) /// conforming to [format]. /// -/// The required [location] should refer to a web resource containing GeoJSON -/// compliant data. -/// -/// When given the optional [client] is used for http requests, otherwise the -/// default client of the `package:http/http.dart` package is used. -/// -/// When given [headers] are injected to http requests (however some can be -/// overridden by the feature source implementation). -/// -/// When [format] is not given, then [GeoJSON] with default settings is used as -/// a default. Note that currently only GeoJSON is supported, but it's possible -/// to inject another format implementation (or with custom configuration) to -/// the default one. +/// See [GeoJSONFeatures.http]. +@Deprecated('Use GeoJSONFeature.http instead.') BasicFeatureSource geoJsonHttpClient({ required Uri location, - http.Client? client, + _http.Client? client, Map? headers, TextReaderFormat format = GeoJSON.feature, }) => @@ -46,13 +88,8 @@ BasicFeatureSource geoJsonHttpClient({ /// A client for accessing a `GeoJSON` feature collection from [source]; /// -/// The source function returns a future that fetches data from a file, a web -/// resource or other sources. Contents must be GeoJSON compliant data. -/// -/// When [format] is not given, then [GeoJSON] with default settings is used as -/// a default. Note that currently only GeoJSON is supported, but it's possible -/// to inject another format implementation (or with custom configuration) to -/// the default one. +/// See [GeoJSONFeatures.any]. +@Deprecated('Use GeoJSONFeature.any instead.') BasicFeatureSource geoJsonFutureClient( Future Function() source, { TextReaderFormat format = GeoJSON.feature, diff --git a/dart/geodata/lib/src/ogcapi_features/service/client/ogc_feature_client.dart b/dart/geodata/lib/src/ogcapi_features/service/client/ogc_feature_client.dart index fdac0df0..d6a8a312 100644 --- a/dart/geodata/lib/src/ogcapi_features/service/client/ogc_feature_client.dart +++ b/dart/geodata/lib/src/ogcapi_features/service/client/ogc_feature_client.dart @@ -8,7 +8,7 @@ import 'package:geobase/coordinates.dart'; import 'package:geobase/meta.dart'; import 'package:geobase/vector.dart'; import 'package:geobase/vector_data.dart'; -import 'package:http/http.dart' as http; +import 'package:http/http.dart' as _http; import '/src/common/links.dart'; import '/src/common/paged.dart'; @@ -17,24 +17,48 @@ import '/src/core/data.dart'; import '/src/ogcapi_features/model.dart'; import '/src/utils/features.dart'; +/// A class with static factory methods to create feature sources conforming to +/// the OGC API Features standard. +class OGCAPIFeatures { + /// A client for accessing `OGC API Features` compliant sources via http(s) + /// conforming to [format]. + /// + /// The required [endpoint] should refer to a base url of a feature service. + /// + /// When given the optional [client] is used for http requests, otherwise the + /// default client of the `package:http/http.dart` package is used. + /// + /// When given [headers] are injected to http requests (however some can be + /// overridden by the feature service implementation). + /// + /// When [format] is not given, then [GeoJSON] with default settings is used + /// as a default. Note that currently only GeoJSON is supported, but it's + /// possible to inject another format implementation (or with custom + /// configuration) to the default one. + static OGCFeatureService http({ + required Uri endpoint, + _http.Client? client, + Map? headers, + TextReaderFormat format = GeoJSON.feature, + }) => + _OGCFeatureClientHttp( + endpoint, + adapter: FeatureHttpAdapter( + client: client, + headers: headers, + ), + format: format, + ); +} + /// A client for accessing `OGC API Features` compliant sources via http(s) /// conforming to [format]. /// -/// The required [endpoint] should refer to a base url of a feature service. -/// -/// When given the optional [client] is used for http requests, otherwise the -/// default client of the `package:http/http.dart` package is used. -/// -/// When given [headers] are injected to http requests (however some can be -/// overridden by the feature service implementation). -/// -/// When [format] is not given, then [GeoJSON] with default settings is used as -/// a default. Note that currently only GeoJSON is supported, but it's possible -/// to inject another format implementation (or with custom configuration) to -/// the default one. +/// See [OGCAPIFeatures.http]. +@Deprecated('Use GeoJSONFeature.http instead.') OGCFeatureService ogcApiFeaturesHttpClient({ required Uri endpoint, - http.Client? client, + _http.Client? client, Map? headers, TextReaderFormat format = GeoJSON.feature, }) =>