forked from navibyte/geospatial
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgeodata_example.dart
157 lines (140 loc) · 5 KB
/
geodata_example.dart
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright (c) 2020-2021 Navibyte (https://navibyte.com). All rights reserved.
// Use of this source code is governed by a “BSD-3-Clause”-style license that is
// specified in the LICENSE file.
//
// Docs: https://github.com/navibyte/geospatial
// ignore_for_file: avoid_print
// ignore_for_file: avoid_catches_without_on_clauses
import 'package:equatable/equatable.dart';
import 'package:attributes/entity.dart';
import 'package:attributes/values.dart';
import 'package:datatools/fetch_http.dart';
import 'package:geocore/geo.dart';
import 'package:geocore/feature.dart';
import 'package:geodata/geojson_features.dart';
import 'package:geodata/oapi_features.dart';
/*
To test run this from command line:
GeoJSON (file) resource as a data source:
dart example/geodata_example.dart geojson https://earthquake.usgs.gov/earthquakes/feed/v1.0/ summary/2.5_day.geojson 3 items
OGC API Features data sources:
dart example/geodata_example.dart oapif https://demo.pygeoapi.io/master/ lakes 2 items
dart example/geodata_example.dart oapif https://demo.pygeoapi.io/master/ lakes 2 items id 3
dart example/geodata_example.dart oapif https://www.ldproxy.nrw.de/kataster/ verwaltungseinheit 2 items bbox 7,50.6,7.2,50.8
dart example/geodata_example.dart oapif https://weather.obs.fmibeta.com/ fmi_aws_observations 2 items bbox 23,62,24,63
More demo APIs (however this page seems to be somewhat outdated, be careful!):
https://github.com/opengeospatial/ogcapi-features/blob/master/implementations.md
*/
const _defaultOperation = 'items';
const _defaultLimit = 2;
const _defaultMaxPagedResults = 2;
/// A simple example to read features from standard OGC API Features services.
Future<void> main(List<String> args) async {
// configure Equatable to apply toString() default impls
EquatableConfig.stringify = true;
// check enough args
if (args.length < 3) {
print('Args: {source} {baseUrl} {collectionIds} '
'[limit] [operation] [param] [value]');
print('Allowed sources: oapif, geojson');
return;
}
// parse args
final sourceType = args[0];
final baseURL = args[1];
final collectionIds = args[2].split(',');
final limit = args.length >= 4 ? int.tryParse(args[3]) : _defaultLimit;
final operation = args.length >= 5 ? args[4] : _defaultOperation;
var maxPagedResults = _defaultMaxPagedResults;
var filter = FeatureFilter(
limit: limit,
);
if (args.length >= 7) {
switch (args[5]) {
case 'id':
filter = FeatureFilter(
limit: limit,
id: Identifier.fromString(args[6]),
);
maxPagedResults = 1;
break;
case 'bbox':
final bbox = args[6].split(',');
if (bbox.length == 4 || bbox.length == 6) {
filter = FeatureFilter(
limit: limit,
bounds: GeoBounds.from(bbox.map<num>(valueToDouble)),
);
}
break;
}
}
try {
// Create a fetcher to read data from an endpoint.
final client = HttpFetcher.simple(
endpoints: [Uri.parse(baseURL)],
);
// Create a feature source for plain GeoJSON or OGC API Features (OAPIF)
final FeatureSource source;
switch (sourceType) {
case 'geojson':
// GeoJSON source for a plain resource (the resource provides only
// items, metadata is setup here as statically)
source = FeatureSourceGeoJSON.of(
client: client,
meta: DataSourceMeta.collectionIds(
collectionIds,
title: 'Sample GeoJSON service',
));
break;
case 'oapif':
// OGC API Features source (the service provides both meta and items)
source = FeatureServiceOAPIF.of(
client: client,
);
break;
default:
throw ArgumentError('Unknow source type $sourceType');
}
// Loop over all collections
for (final collectionId in collectionIds) {
// Execute an operation
switch (operation) {
case 'items':
// fetch feature items as paged results, max rounds by maxPagedResults
var round = 0;
var available = true;
var items = await source.itemsPaged(collectionId, filter: filter);
do {
_printFeatures(items.current);
if (items.hasNext) {
// get next set
items = await items.next();
} else {
available = false;
}
} while (available && ++round < maxPagedResults);
break;
}
}
} catch (e, st) {
print('Calling $baseURL failed: $e');
print(st);
}
}
void _printFeatures(FeatureItems items) {
print('Features:');
if (items.meta.numberMatched != null) {
print(' number matched ${items.meta.numberMatched}');
print(' number returned ${items.meta.numberReturned}');
}
items.features.forEach(_printFeature);
}
void _printFeature(Feature f) {
print('Feature with id: ${f.id}');
print(' geometry: ${f.geometry}');
print(' properties:');
for (final key in f.properties.keys) {
print(' $key: ${f.properties[key]}');
}
}