Skip to content

Latest commit

 

History

History

geodata

pub package License style: very good analysis

Equirectangular projection

Geospatial feature service Web APIs with support for GeoJSON and OGC API Features clients for Dart.

Features

✨ New (2024-11-10): The stable version 1.3.0 with some refactoring (the dependecy to equatable removed, the constraint on http is now >=0.13.0 <2.0.0 instead of ^0.13.0 that did not allow latest 1.0+ versions), code maintenance and documentation updates.

✨ New (2024-05-26): The new documentation website (geospatial.navibyte.dev) for the geodata package documentation published along with the stable version 1.2.0.

✨ New (2024-04-22): The stable version 1.1.0 adds support for Newline-delimited GeoJSON. See the related blog post about geobase changes.

Key features:

  • 🪄 Client-side data source abstraction for geospatial feature service Web APIs.
  • 🌐 The GeoJSON client to read features from static web resources and local files, supports also Newline-delimited GeoJSON data.
  • 🌎 The OGC API Features client to access metadata and feature items from a compliant geospatial Web API providing GeoJSON data.

Client-side support for the OGC API Features standard:

Standard part Support in this package
OGC API - Features - Part 1: Core Supported for accessing metadata and GeoJSON feature collections.
OGC API - Features - Part 2: Coordinate Reference Systems by Reference Supported.
OGC API - Features - Part 3: Filtering
Common Query Language (CQL2)
Partially supported (conformance classes, queryables, features filter).

Documentation

Comprehensive guidance on how to use this package and about Geospatial tools for Dart (the package is part of) is available on the geospatial.navibyte.dev website.

Shortcuts to the geodata package documentation by chapters:

See also overview topics about Geospatial tools for Dart:

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 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}');
}

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}');
}

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() or source.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';

Usage

The package requires at least Dart SDK 2.17, and it supports all Dart and Flutter platforms.

Add the dependency in your pubspec.yaml:

dependencies:
  geodata: ^1.4.0

Import it:

import `package:geodata/geodata.dart`

There are also partial packages containing only a certain subset. See the Packages section below.

Other documentation:

📚 Concepts: If coordinates, geometries, features and feature collections are unfamiliar concepts, you might want to read more about geometries, geospatial features and GeoJSON in the geobase package documentation.

🚀 Samples: The Geospatial demos for Dart repository contains more sample code showing also how to use this package!

Packages

The geodata library contains also following partial packages, that can be used to import only a certain subset instead of the whole geodata package:

Package Exports also Description
common Common data structures and helpers (for links, metadata, paged responses).
core Metadata and data source abstractions of geospatial Web APIs (ie. features).
formats OpenAPI document and Common Query Language (CQL2) formats (partial support).
geojson_client common, core A client-side data source to read GeoJSON data from web and file resources.
ogcapi_features_client common, core, formats A client-side data source to read features from OGC API Features services.

External packages geodata is depending on:

  • geobase for base geospatial data structures
  • http for a http client
  • meta for annotations

Reference

Documentation

Please see the geospatial.navibyte.dev website for the geodata package documentation.

Authors

This project is authored by Navibyte.

More information and other links are available at the geospatial repository from GitHub.

License

This project is licensed under the "BSD-3-Clause"-style license.

Please see the LICENSE.