Geospatial Data Structures, tools and Utilities for Dart and Flutter

Geospatial data structures (features, geometry and metadata) and utilities to parse GeoJSON and WKT (Well-known text representation of geometry) data.

The package supports representing both geographic (decimal degrees or longitude-latitude) and projected (or cartesian XYZ) coordinates in 2D and 3D. There are also classes for temporal data (instants and intervals) and feature objects (or geospatial entities) containing properties and geometry.

This package is at BETA stage, interfaces not fully final yet.

Introduction

You might first want to learn basics of geospatial geometry types on the Wikipedia page about WKT representation of geometry.

Geometry primitives supported by this library package (with samples adapted from the samples of the Wikipedia source):

Geometry | Shape | Samples to create instances ----------- | ----------- | --------------------------- Point | | Point2(x: 30.0, y: 10.0)
Point2.from([30.0, 10.0])
Point2.parse('30 10') LineString | | LineString.parse('30 10, 10 30, 40 40', Point2.geometry) Polygon | | Polygon.parse('(30 10, 40 40, 20 40, 10 20, 30 10)', Point2.geometry) Polygon (with a hole) | | Polygon.parse('(35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30)', Point2.geometry)

Also multipart geometry classes are provided:

Geometry | Shape | Samples to create instances ----------- | ----------- | --------------------------- MultiPoint | | MultiPoint.parse('10 40, 40 30, 20 20, 30 10', Point2.geometry) MultiLineString | | MultiLineString.parse('(10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10)', Point2.geometry) MultiPolygon | | MultiPolygon.parse('((30 20, 45 40, 10 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5))', Point2.geometry) MultiPolygon (with a hole) | | MultiPolygon.parse('((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20))', Point2.geometry) GeometryCollection | | GeometryCollection.from(<Geometry>[Point2i(x: 40, y: 10), LineString.make([[10, 10], [20, 20], [10, 40]], Point2i.geometry), Polygon.parse('(40 40, 20 45, 45 30, 40 40)', Point2i.geometry)])

Geometry types introduced above are based on the Simple Feature Access - Part 1: Common Architecture standard by The Open Geospatial Consortium (OGC).

The next section describes alternative representations for points, with either projected or geographic coordinates. Also other geometry types, metadata classes, and feature objects or geospatial entities are discussed below.

Usage

Cartesian or projected points

The abstract base class for all point geometries is Point. It's implemented by following concrete classes to represent projected or cartesian (XYZ) coordinates with an optional measure (m) coordinate:

Class | Coordinates | x | y | z | m ----------- | ----------- | - | - | - | - Point2 | num | + | + | |
Point2m | num | + | + | | + Point3 | num | + | + | + |
Point3m | num | + | + | + | + Point2i | int | + | + | |
Point3i | int | + | + | + |

Points are created by geometry parsers or point factory implementations. Each point geometry class has also multiple factory constructors.

For example Point3 can be created in many ways:

  // Projected point with X, Y and Z coordinates in two ways.
  Point3(x: 708221.0, y: 5707225.0, z: 45.0);
  Point3.xyz(708221.0, 5707225.0, 45.0);

  // The same point created from `Iterable<num>`.
  Point3.from([708221.0, 5707225.0, 45.0]);

  // The same point parsed from WKT compatible text.
  // Actually WKT representation would be : "POINT (708221.0 5707225.0 45.0)",
  // but this parser takes only coordinate data between paranthesis.
  Point3.parse('708221.0 5707225.0 45.0');

  // The `parse` method throws when text is invalid, but `tryParse` returns null
  // in such case. This can be utilized for fallbacks.
  Point3.tryParse('nop') ?? Point3.parse('708221.0 5707225.0 45.0');

  // The same point parsed using the WKT parser for projected geometries.
  // Here `wktProjected` is a global constant for a WKT factory implementation.
  wktProjected.parse('POINT Z (708221.0 5707225.0 45.0)');

All other point classes have similar constructors.

Geographic points

The base class for all geographic point geometries is GeoPoint, that extends also Point. Geographic coordinates are longitude (lon) and latitude (lat), in degrees and preferable always in this order. Elevation (elev) in meters and measure (m) coordinates are optional.

Latitude and Longitude of the Earth

Class | Coordinates | lon | lat | elev | m ------------ | ------------- | --- | --- | ---- | - GeoPoint2 | double | + | + | |
GeoPoint2m | double | + | + | | + GeoPoint3 | double | + | + | + |
GeoPoint3m | double | + | + | + | +

See below how to create GeoPoint3m instances (other classes in similar ways):

  // Geographic point with longitude, latitude, elevation and measure.
  GeoPoint3m(lon: -0.0014, lat: 51.4778, elev: 45.0, m: 123.0);
  GeoPoint3m.lonLatElevM(-0.0014, 51.4778, 45.0, 123.0);

  // Someone might want to represent latitude before longitude, it's fine too.
  GeoPoint3m.latLonElevM(51.4778, -0.0014, 45.0, 123.0);

  // When creating from value array, the order is: lon, lat, elev, m.
  GeoPoint3m.from([-0.0014, 51.4778, 45.0, 123.0]);

  // Also here it's possible to parse from WKT compatible text.
  GeoPoint3m.parse('-0.0014 51.4778 45.0 123.0');

  // The WKT parser for geographic coordinates parses full representations.
  wktGeographic.parse('POINT ZM (-0.0014 51.4778 45.0 123.0)');

Point series

Other geometries are composed of point geometries in different structures. PointSeries is a collection class with a series of points and it can represent a geometry path, a line string, an outer or inner linear ring of a polygon, a multi point, a vertex array or any any other collection for points.

  // A point series of `Point2` composed of list of points that are of `Point2`
  // or it's sub classes.
  PointSeries<Point2>.from([
    Point2(x: 10.0, y: 10.0),
    Point2(x: 20.0, y: 20.0),
    Point2m(x: 30.0, y: 30.0, m: 5.0),
    Point3(x: 40.0, y: 40.0, z: 40.0),
    Point3m(x: 50.0, y: 50.0, z: 50.0, m: 5.0),
  ]);

  // Making a point series of `Point3` from a list of a list of nums.
  PointSeries.make(
    // three points each with x, y and z coordinates
    [
      [10.0, 11.0, 12.0],
      [20.0, 21.0, 22.0],
      [30.0, 31.0, 32.0],
    ],
    // This is `PointFactory` that converts `Iterable<num>` to a point instance,
    // in this example using a factory creating `Point3` instances.
    Point3.geometry,
  );

  // Parsing a point series of `GeoPoint` from WKT compatible text with
  // `GeoPoint3` as a concrete point class.
  PointSeries<GeoPoint>.parse(
      '10.0 11.0 12.0, 20.0 21.0 22.0, 30.0 31.0 32.0', GeoPoint3.geometry);

The PointSeries class is not extending the Geometry class, but it's used by actual geometry classes, described in following sections, as a building block.

Line strings

A line string contains a chain of points, implemented using PointSeries.

You can use LineString.any factory constructor to create a line string with any chain, or LineString.ring constructor to create a linear ring with a closed chain. Both constructors simply take an instance of PointSeries.

Or below are examples of more direct ways to construct line strings:

  // This makes a a line string of `Point3m` from a list of points.
  LineString.make(
    [
      [10.0, 11.0, 12.0, 5.1],
      [20.0, 21.0, 22.0, 5.2],
      [30.0, 31.0, 32.0, 5.3],
    ],
    Point3m.geometry,
  );

  // Parsing using the WKT factory produces the result as the previous sample.
  wktProjected.parse<Point3m>('LINESTRING ZM (10.0 11.0 12.0 5.1, '
      '20.0 21.0 22.0 5.2, 30.0 31.0 32.0 5.3)');

Polygons

A polygon contains one exterior boundary and optional interior boundaries (representing holes). All boundaries are linear rings implemented as LineString instances each with a closed chain of points as a ring.

The default constructor of Polygon takes a series of LineString instances, with at least an exterior boundary at index 0.

Other ways to construct polygons are familiar from previous samples:

  // Making a polygon of `GeoPoint2` from a list of a list of a list of nums:
  Polygon.make(
    [
      // this is an exterior boundary or an outer ring
      [
        [35, 10],
        [45, 45],
        [15, 40],
        [10, 20],
        [35, 10]
      ],
      // this is an interior boundary or an inner ring representing a hole
      [
        [20, 30],
        [35, 35],
        [30, 20],
        [20, 30]
      ],
    ],
    GeoPoint2.geometry,
  );

  // The same polygon geometry as above, but parsed from a WKT compatible text.
  Polygon.parse(
      '(35 10, 45 45, 15 40, '
      '10 20, 35 10) (20 30, 35 35, 30 20, 20 30)',
      GeoPoint2.geometry);

Multi geometries

Multi points, multi line strings and multi polygons can also be constructed in similar ways described already for other geometries. Also parsed from text:

  // A multi point of `GeoPoint2` with four lon-lat points.
  MultiPoint.parse('10 40, 40 30, 20 20, 30 10', GeoPoint2.geometry);

  // A multi line string of `Point2` with two line strings.
  MultiLineString.parse(
      '(10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10)', Point2.geometry);

  // A multi polygon of `GeoPoint2` with two polygon (both with exterior 
  // boundary without holes).
  MultiPolygon.parse(
      '((30 20, 45 40, 10 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5))',
      GeoPoint2.geometry);

There is also GeometryCollection:

  // A geometry collection can contain any other geometry types. Items for such
  // a collection can be constructed using different ways.
  GeometryCollection.from(<Geometry>[
    // A point with integer values using a constructor with named parameters.
    Point2i(x: 40, y: 10),
    // A line string made from a list of points (each a list of nums).
    LineString.make([
      [10, 10],
      [20, 20],
      [10, 40]
    ], Point2i.geometry),
    // A polygon parsed from WKT compatible text.
    Polygon.parse('(40 40, 20 45, 45 30, 40 40)', Point2i.geometry)
  ]);

Spatial bounds

Bounding boxes or spatial bounds objects can be represented in 2D or 3D, and with an optional measure coordinates.

Bounds samples with projected or cartesian coordinates:

  // Bounds (2D) or bounding box from minimum and maximum 2D projected points.
  Bounds.of(min: Point2(x: 10.0, y: 10.0), max: Point2(x: 20.0, y: 20.0));

  // Bounds (3D) made from a list of list of nums.
  Bounds.make([[10.0, 10.0, 10.0], [20.0, 20.0, 20.0]], Point3.geometry);

  // Bounds (3D with measure) parsed from WKT compatible text.
  Bounds.parse('10.0 10.0 10.0 5.0, 20.0 20.0 20.0 5.0', Point3m.geometry);

Bounds samples with geographic coordinates:

  // Geographical bounds (-20.0 .. 20.0 in longitude, 50.0 .. 60.0 in latitude).
  GeoBounds.bboxLonLat(-20.0, 50.0, 20.0, 60.0);

  // The same bounds created of 2D geographic point instances.
  GeoBounds.of(
      min: GeoPoint2(lon: -20.0, lat: 50.0),
      max: GeoPoint2(lon: 20.0, lat: 60.0));

Temporal instants and intervals

Temporal data can be represented as instants (a time stamp) and intervals (an open or a closed interval between time stamps).

  // Temporal instants can be created from `DateTime` or parsed from text.
  Instant(DateTime.utc(2020, 10, 31, 09, 30));
  Instant.parse('2020-10-31 09:30Z');

  // Temporal intervals (open-started, open-ended, closed).
  Interval.openStart(DateTime.utc(2020, 10, 31));
  Interval.openEnd(DateTime.utc(2020, 10, 01));
  Interval.closed(DateTime.utc(2020, 10, 01), DateTime.utc(2020, 10, 31));

  // Same intervals parsed (by the "start/end" format, ".." for open limits).
  Interval.parse('../2020-10-31');
  Interval.parse('2020-10-01/..');
  Interval.parse('2020-10-01/2020-10-31');

Coordinate reference system identifiers

A Coordinate reference system (CRS) is a coordinate-based local, regional or global system used to locate geographical entities.

Currently the support for CRSs in this library is very limited. However it's possible to create identifiers (with more support coming in future releases):

  • CRS object created with an identifier: CRS.id('urn:ogc:def:crs:EPSG::4326')
  • CRS84 constant refers to http://www.opengis.net/def/crs/OGC/1.3/CRS84
    • WGS 84 longitude-latitude
  • CRS84h constant refers to http://www.opengis.net/def/crs/OGC/0/CRS84h
    • WGS 84 longitude-latitude-height

Extents

Extent objects have both spatial bounds and temporal interval, and they are useful in metadata structures for geospatial data sources.

  // An extent with spatial (WGS 84 longitude-latitude) and temporal parts.
  Extent.single(
    crs: CRS84,
    bounds: GeoBounds.bboxLonLat(-20.0, 50.0, 20.0, 60.0),
    interval: Interval.parse('../2020-10-31'),
  );

  // An extent with multiple spatial bounds and temporal interval segments.
  Extent.multi(crs: CRS84, allBounds: [
    GeoBounds.bboxLonLat(-20.0, 50.0, 20.0, 60.0),
    GeoBounds.bboxLonLat(40.0, 50.0, 60.0, 60.0),
  ], allIntervals: [
    Interval.parse('2020-10-01/2020-10-05'),
    Interval.parse('2020-10-27/2020-10-31'),
  ]);

Geospatial features

According to the OGC Glossary a geospatial feature is a digital representation of a real world entity. It has a spatial domain, a temporal domain, or a spatial/temporal domain as one of its attributes. Examples of features include almost anything that can be placed in time and space, including desks, buildings, cities, trees, forest stands, ecosystems, delivery vehicles, snow removal routes, oil wells, oil pipelines, oil spill, and so on.

Below is an illustration of features in a simple vector map. Wells are features with a point geometry, rivers with a line string (or polyline) geometry, and finally lakes are features with a polygon geometry. Features normally contain also an identifier and other attributes (or properties) along with a geometry.

The external attributes package has a Entity class that represents a structured data entity that has an optional identification by an Identifier object and contains associated property values in a PropertyMap object.

The Feature class of this package extends Entity, and has also geospatial geometry and bounds as fields along with id and properties fields. That is a feature is a geospatial entity object.

  // Geospatial feature with an identification, a point geometry and properties.
  Feature.view(
    id: 'ROG',
    geometry: GeoPoint3(lon: -0.0014, lat: 51.4778, elev: 45.0),
    properties: <String, dynamic>{
      'title': 'Royal Observatory',
      'place': 'Greenwich',
      'city': 'London',
      'isMuseum': true,
      'measure': 5.79,
    },
  );

Naturally, the geometry field could also contain other geometries described earlier, not just points.

Parsing GeoJSON data

GeoJSON, as described by Wikipedia, is an open standard format designed for representing simple geographical features, along with their non-spatial attributes.

See also the official GeoJSON website. As specified by the referenced RFC 7946 standard, all GeoJSON geometries use WGS 84 geographic coordinates. Alternative coordinate reference systems can also be used when involved parties have a prior arrangement of using other systems.

Below is an example with sample GeoJSON data and code to parse it.

Imports:

import 'package:geocore/parse_geojson.dart';

The sample code:

  // sample GeoJSON data
  const sample = '''
    {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "id": "ROG",
          "geometry": {
            "type": "Point",
            "coordinates": [-0.0014, 51.4778, 45.0]  
          },
          "properties": {
            "title": "Royal Observatory",
            "place": "Greenwich",
            "city": "London"
          }
        }  
      ]
    }
  ''';

  // parse FeatureCollection using the default GeoJSON factory
  final fc = geoJSON.featureCollection(sample);

  // loop through features and print id, geometry and properties for each
  for (final f in fc.features) {
    print('Feature with id: ${f.id}');
    print('  geometry: ${f.geometry}');
    print('  properties:');
    for (final key in f.properties.keys) {
      print('    $key: ${f.properties[key]}');
    }
  }

At this stage the package supports reading following GeoJSON elements:

  • FeatureCollection
  • Feature
  • Point, LineString and Polygon
  • MultiPoint, MultiLineString and MultiPolygon
  • GeometryCollection

Parsing WKT data

Well-known text representation of geometry (WKT) is a text markup language for representing vector geometry objects. It's specified by the Simple Feature Access - Part 1: Common Architecture standard.

WKT representations for coordinate data has already been discussed on previous sections introducing geometry objects. Geometry classes have factory constructors that allows parsing coordinate values from WKT compatible text (like a point using Point2.parse('100.0 200.0') factory).

When parsing full WKT geometry text representations, with a geometry type id and coordinate values, the WktFactory class can be used. There are two global constants of class instances for different use cases:

Global constant | Use cases --------------- | --------- wktProjected | Parsing geometries with projected or cartesian coordinates. wktGeographic | Parsing geometries with geographic coordinates (like WGS 84).

Imports:

import 'package:geocore/parse_wkt.dart';

Samples to parse from WKT text representation of geometry:

  // Parse projected points from WKT (result is different concrete classes).
  wktProjected.parse('POINT (100.0 200.0)'); // => Point2
  wktProjected.parse('POINT M (100.0 200.0 5.0)'); // => Point2m
  wktProjected.parse('POINT (100.0 200.0 300.0)'); // => Point3
  wktProjected.parse('POINT Z (100.0 200.0 300.0)'); // => Point3
  wktProjected.parse('POINT ZM (100.0 200.0 300.0 5.0)'); // => Point3m

  // Parse geographical line string, from (10.0 50.0) to (11.0 51.0).
  wktGeographic.parse('LINESTRING (10.0 50.0, 11.0 51.0)');

  // Parse geographical polygon with a hole. 
  wktGeographic.parse('POLYGON ((40 15, 50 50, 15 45, 10 15, 40 15),'
      ' (25 25, 25 40, 35 30, 25 25))');

Supported WKT geometry types: POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON. Please note that GEOMETRYCOLLECTION is not (yet) supported.

Package

This is a Dart code package named geocore under the geospatial repository.

The package supports Dart null-safety and using it requires at least Dart 2.12 from the stable channel. Please see the official null-safety migration guide.

In the pubspec.yaml of your project add the dependency:

dependencies:
  geocore: ^0.7.0

All dependencies used by geocore are also ready for null-safety!

The package is associated with and depending on the attributes package containing non-geospatial data structures that are extended and utilized by the geocore to provide geospatial data structures and utilities.

Libraries

The package contains following mini-libraries:

Library | Description -------------------- | ----------- base | Geometry classes including points, bounds, line strings, polygons and more. crs | Classes to represent coordinate reference system (CRS) identifiers. feature | Feature and FeatureCollection to handle dynamic geospatial data objects. geo | Geographic points and bounds classes to represent longitude-latitude data meta_extent | Metadata structures to handle extents with spatial and temporal parts. parse_factory | Base interfaces and implementations for geospatial data factories. parse_geojson | Geospatial data factory to parse GeoJSON from text strings. parse_wkt | Geospatial data factory to parse WKT from text strings.

For example to access a mini library you should use an import like:

import 'package:geocore/base.dart';

To use all libraries of the package:

import 'package:geocore/geocore.dart';

Authors

This project is authored by Navibyte.

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

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add geocore

With Flutter:

 $ flutter pub add geocore

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):


dependencies:
  geocore: ^0.7.0

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:geocore/geocore.dart';

example/geocore_example.dart

// 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, avoid_redundant_argument_values
// ignore_for_file: cascade_invocations

import 'package:equatable/equatable.dart';

import 'package:geocore/geocore.dart';

/*
To test run this from command line: 

dart example/geocore_example.dart
*/

void main() {
  // configure Equatable to apply toString() default impls
  EquatableConfig.stringify = true;

  // call simple demos
  _parseGeoJSON();
  _readmeIntro();
}

void _parseGeoJSON() {
  print('Parse GeoJSON sample data.');

  // sample GeoJSON data
  const sample = '''
    {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "id": "ROG",
          "geometry": {
            "type": "Point",
            "coordinates": [-0.0014, 51.4778, 45.0]  
          },
          "properties": {
            "title": "Royal Observatory",
            "place": "Greenwich",
            "city": "London",
            "isMuseum": true,
            "code": "000",
            "founded": 1675,
            "prime": "1884-10-22", 
            "measure": 5.79
          }
        }  
      ]
    }
  ''';

  // parse FeatureCollection using the default GeoJSON factory
  final fc = geoJSON.featureCollection(sample);

  // loop through features and print id, geometry and properties for each
  for (final f in fc.features) {
    print('Feature with id: ${f.id}');
    print('  geometry: ${f.geometry}');
    print('  properties:');
    for (final key in f.properties.keys) {
      print('    $key: ${f.properties[key]}');
    }
  }
}

void _readmeIntro() {
  // Some samples for README
  //    (https://github.com/navibyte/geospatial/tree/main/dart/geocore).
  // Note that following samples are just created, not used, even printed.

  // -----------

  // Projected point with X, Y and Z coordinates in two ways.
  Point3(x: 708221.0, y: 5707225.0, z: 45.0);
  Point3.xyz(708221.0, 5707225.0, 45.0);

  // The same point created from `Iterable<num>`.
  Point3.from([708221.0, 5707225.0, 45.0]);

  // The same point parsed from WKT compatible text.
  // Actually WKT representation would be : "POINT (708221.0 5707225.0 45.0)",
  // but this parser takes only coordinate data between paranthesis.
  Point3.parse('708221.0 5707225.0 45.0');

  // The `parse` method throws when text is invalid, but `tryParse` returns null
  // in such case. This can be utilized for fallbacks.
  Point3.tryParse('nop') ?? Point3.parse('708221.0 5707225.0 45.0');

  // The same point parsed using the WKT parser for projected geometries.
  // Here `wktProjected` is a global constant for a WKT factory implementation.
  wktProjected.parse('POINT Z (708221.0 5707225.0 45.0)');

  // -----------

  // Geographic point with longitude, latitude, elevation and measure.
  GeoPoint3m(lon: -0.0014, lat: 51.4778, elev: 45.0, m: 123.0);
  GeoPoint3m.lonLatElevM(-0.0014, 51.4778, 45.0, 123.0);

  // Someone might want to represent latitude before longitude, it's fine too.
  GeoPoint3m.latLonElevM(51.4778, -0.0014, 45.0, 123.0);

  // When creating from value array, the order is: lon, lat, elev, m.
  GeoPoint3m.from([-0.0014, 51.4778, 45.0, 123.0]);

  // Also here it's possible to parse from WKT compatible text.
  GeoPoint3m.parse('-0.0014 51.4778 45.0 123.0');

  // The WKT parser for geographic coordinates parses full representations.
  wktGeographic.parse('POINT ZM (-0.0014 51.4778 45.0 123.0)');

  // -----------

  // A point series of `Point2` composed of list of points that are of `Point2`
  // or it's sub classes.
  PointSeries<Point2>.from([
    Point2(x: 10.0, y: 10.0),
    Point2(x: 20.0, y: 20.0),
    Point2m(x: 30.0, y: 30.0, m: 5.0),
    Point3(x: 40.0, y: 40.0, z: 40.0),
    Point3m(x: 50.0, y: 50.0, z: 50.0, m: 5.0),
  ]);

  // Making a point series of `Point3` from a list of a list of nums.
  PointSeries.make(
    // three points each with x, y and z coordinates
    [
      [10.0, 11.0, 12.0],
      [20.0, 21.0, 22.0],
      [30.0, 31.0, 32.0],
    ],
    // This is `PointFactory` that converts `Iterable<num>` to a point instance,
    // in this example using a factory creating `Point3` instances.
    Point3.geometry,
  );

  // Parsing a point series of `GeoPoint` from WKT compatible text with
  // `GeoPoint3` as a concrete point class.
  PointSeries<GeoPoint>.parse(
      '10.0 11.0 12.0, 20.0 21.0 22.0, 30.0 31.0 32.0', GeoPoint3.geometry);

  // -----------

  // This makes a a line string of `Point3m` from a list of points.
  LineString.make(
    [
      [10.0, 11.0, 12.0, 5.1],
      [20.0, 21.0, 22.0, 5.2],
      [30.0, 31.0, 32.0, 5.3],
    ],
    Point3m.geometry,
  );

  // Parsing using the WKT factory produces the result as the previous sample.
  wktProjected.parse<Point3m>('LINESTRING ZM (10.0 11.0 12.0 5.1, '
      '20.0 21.0 22.0 5.2, 30.0 31.0 32.0 5.3)');

  // -----------

  // Making a polygon of `GeoPoint2` from a list of a list of a list of nums:
  Polygon.make(
    [
      // this is an exterior boundary or an outer ring
      [
        [35, 10],
        [45, 45],
        [15, 40],
        [10, 20],
        [35, 10]
      ],
      // this is an interior boundary or an inner ring representing a hole
      [
        [20, 30],
        [35, 35],
        [30, 20],
        [20, 30]
      ],
    ],
    GeoPoint2.geometry,
  );

  // The same polygon geometry as above, but parsed from a WKT compatible text.
  Polygon.parse(
      '(35 10, 45 45, 15 40, '
      '10 20, 35 10) (20 30, 35 35, 30 20, 20 30)',
      GeoPoint2.geometry);

  // -----------

  // A multi point of `GeoPoint2` with four lon-lat points.
  MultiPoint.parse('10 40, 40 30, 20 20, 30 10', GeoPoint2.geometry);

  // A multi line string of `Point2` with two line strings.
  MultiLineString.parse(
      '(10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10)', Point2.geometry);

  // A multi polygon of `GeoPoint2` with two polygon (both with exterior
  // boundary without holes).
  MultiPolygon.parse(
      '((30 20, 45 40, 10 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5))',
      GeoPoint2.geometry);

  // A geometry collection can contain any other geometry types. Items for such
  // a collection can be constructed using different ways.
  GeometryCollection.from(<Geometry>[
    // A point with integer values using a constructor with named parameters.
    Point2i(x: 40, y: 10),
    // A line string made from a list of points (each a list of nums).
    LineString.make([
      [10, 10],
      [20, 20],
      [10, 40]
    ], Point2i.geometry),
    // A polygon parsed from WKT compatible text.
    Polygon.parse('(40 40, 20 45, 45 30, 40 40)', Point2i.geometry)
  ]);

  GeometryCollection.from(<Geometry>[
    Point2i(x: 40, y: 10),
    LineString.make([
      [10, 10],
      [20, 20],
      [10, 40]
    ], Point2i.geometry),
    Polygon.parse('(40 40, 20 45, 45 30, 40 40)', Point2i.geometry)
  ]);

  // -----------

  // Bounds (2D) or bounding box from minimum and maximum 2D projected points.
  Bounds.of(min: Point2(x: 10.0, y: 10.0), max: Point2(x: 20.0, y: 20.0));

  // Bounds (3D) made from a list of list of nums.
  Bounds.make([
    [10.0, 10.0, 10.0],
    [20.0, 20.0, 20.0]
  ], Point3.geometry);

  // Bounds (3D with measure) parsed from WKT compatible text.
  Bounds.parse('10.0 10.0 10.0 5.0, 20.0 20.0 20.0 5.0', Point3m.geometry);

  // -----------

  // Geographical bounds (-20.0 .. 20.0 in longitude, 50.0 .. 60.0 in latitude).
  GeoBounds.bboxLonLat(-20.0, 50.0, 20.0, 60.0);

  // The same bounds created of 2D geographic point instances.
  GeoBounds.of(
      min: GeoPoint2(lon: -20.0, lat: 50.0),
      max: GeoPoint2(lon: 20.0, lat: 60.0));

  // -----------

  // Temporal instants can be created from `DateTime` or parsed from text.
  Instant(DateTime.utc(2020, 10, 31, 09, 30));
  Instant.parse('2020-10-31 09:30Z');

  // -----------

  // Temporal intervals (open-started, open-ended, closed).
  Interval.openStart(DateTime.utc(2020, 10, 31));
  Interval.openEnd(DateTime.utc(2020, 10, 01));
  Interval.closed(DateTime.utc(2020, 10, 01), DateTime.utc(2020, 10, 31));

  // Same intervals parsed (by the "start/end" format, ".." for open limits).
  Interval.parse('../2020-10-31');
  Interval.parse('2020-10-01/..');
  Interval.parse('2020-10-01/2020-10-31');

  // -----------

  // An extent with spatial (WGS 84 longitude-latitude) and temporal parts.
  Extent.single(
    crs: CRS84,
    bounds: GeoBounds.bboxLonLat(-20.0, 50.0, 20.0, 60.0),
    interval: Interval.parse('../2020-10-31'),
  );

  // An extent with multiple spatial bounds and temporal interval segments.
  Extent.multi(crs: CRS84, allBounds: [
    GeoBounds.bboxLonLat(-20.0, 50.0, 20.0, 60.0),
    GeoBounds.bboxLonLat(40.0, 50.0, 60.0, 60.0),
  ], allIntervals: [
    Interval.parse('2020-10-01/2020-10-05'),
    Interval.parse('2020-10-27/2020-10-31'),
  ]);

  // -----------

  // Geospatial feature with an identification, a point geometry and properties.
  Feature.view(
    id: 'ROG',
    geometry: GeoPoint3(lon: -0.0014, lat: 51.4778, elev: 45.0),
    properties: <String, dynamic>{
      'title': 'Royal Observatory',
      'place': 'Greenwich',
      'city': 'London',
      'isMuseum': true,
      'code': '000',
      'founded': 1675,
      'prime': DateTime.utc(1884, 10, 22),
      'measure': 5.79,
    },
  );

  // -----------

  // Parse projected points from WKT (result is different concrete classes).
  wktProjected.parse('POINT (100.0 200.0)'); // => Point2
  wktProjected.parse('POINT M (100.0 200.0 5.0)'); // => Point2m
  wktProjected.parse('POINT (100.0 200.0 300.0)'); // => Point3
  wktProjected.parse('POINT Z (100.0 200.0 300.0)'); // => Point3
  wktProjected.parse('POINT ZM (100.0 200.0 300.0 5.0)'); // => Point3m

  // Parse geographical line string, from (10.0 50.0) to (11.0 51.0).
  wktGeographic.parse('LINESTRING (10.0 50.0, 11.0 51.0)');

  // Parse geographical polygon with a hole.
  wktGeographic.parse('POLYGON ((40 15, 50 50, 15 45, 10 15, 40 15),'
      ' (25 25, 25 40, 35 30, 25 25))');
}

#fluter  #dart #mobile-apps

What is GEEK

Buddha Community

Geospatial Data Structures, tools and Utilities for Dart and Flutter

Google's Flutter 1.20 stable announced with new features - Navoki

Flutter Google cross-platform UI framework has released a new version 1.20 stable.

Flutter is Google’s UI framework to make apps for Android, iOS, Web, Windows, Mac, Linux, and Fuchsia OS. Since the last 2 years, the flutter Framework has already achieved popularity among mobile developers to develop Android and iOS apps. In the last few releases, Flutter also added the support of making web applications and desktop applications.

Last month they introduced the support of the Linux desktop app that can be distributed through Canonical Snap Store(Snapcraft), this enables the developers to publish there Linux desktop app for their users and publish on Snap Store.  If you want to learn how to Publish Flutter Desktop app in Snap Store that here is the tutorial.

Flutter 1.20 Framework is built on Google’s made Dart programming language that is a cross-platform language providing native performance, new UI widgets, and other more features for the developer usage.

Here are the few key points of this release:

Performance improvements for Flutter and Dart

In this release, they have got multiple performance improvements in the Dart language itself. A new improvement is to reduce the app size in the release versions of the app. Another performance improvement is to reduce junk in the display of app animation by using the warm-up phase.

sksl_warm-up

If your app is junk information during the first run then the Skia Shading Language shader provides for pre-compilation as part of your app’s build. This can speed it up by more than 2x.

Added a better support of mouse cursors for web and desktop flutter app,. Now many widgets will show cursor on top of them or you can specify the type of supported cursor you want.

Autofill for mobile text fields

Autofill was already supported in native applications now its been added to the Flutter SDK. Now prefilled information stored by your OS can be used for autofill in the application. This feature will be available soon on the flutter web.

flutter_autofill

A new widget for interaction

InteractiveViewer is a new widget design for common interactions in your app like pan, zoom drag and drop for resizing the widget. Informations on this you can check more on this API documentation where you can try this widget on the DartPad. In this release, drag-drop has more features added like you can know precisely where the drop happened and get the position.

Updated Material Slider, RangeSlider, TimePicker, and DatePicker

In this new release, there are many pre-existing widgets that were updated to match the latest material guidelines, these updates include better interaction with Slider and RangeSliderDatePicker with support for date range and time picker with the new style.

flutter_DatePicker

New pubspec.yaml format

Other than these widget updates there is some update within the project also like in pubspec.yaml file format. If you are a flutter plugin publisher then your old pubspec.yaml  is no longer supported to publish a plugin as the older format does not specify for which platform plugin you are making. All existing plugin will continue to work with flutter apps but you should make a plugin update as soon as possible.

Preview of embedded Dart DevTools in Visual Studio Code

Visual Studio code flutter extension got an update in this release. You get a preview of new features where you can analyze that Dev tools in your coding workspace. Enable this feature in your vs code by _dart.previewEmbeddedDevTools_setting. Dart DevTools menu you can choose your favorite page embed on your code workspace.

Network tracking

The updated the Dev tools comes with the network page that enables network profiling. You can track the timings and other information like status and content type of your** network calls** within your app. You can also monitor gRPC traffic.

Generate type-safe platform channels for platform interop

Pigeon is a command-line tool that will generate types of safe platform channels without adding additional dependencies. With this instead of manually matching method strings on platform channel and serializing arguments, you can invoke native class and pass nonprimitive data objects by directly calling the Dartmethod.

There is still a long list of updates in the new version of Flutter 1.2 that we cannot cover in this blog. You can get more details you can visit the official site to know more. Also, you can subscribe to the Navoki newsletter to get updates on these features and upcoming new updates and lessons. In upcoming new versions, we might see more new features and improvements.

You can get more free Flutter tutorials you can follow these courses:

#dart #developers #flutter #app developed #dart devtools in visual studio code #firebase local emulator suite in flutter #flutter autofill #flutter date picker #flutter desktop linux app build and publish on snapcraft store #flutter pigeon #flutter range slider #flutter slider #flutter time picker #flutter tutorial #flutter widget #google flutter #linux #navoki #pubspec format #setup flutter desktop on windows

Terry  Tremblay

Terry Tremblay

1598396940

What is Flutter and why you should learn it?

Flutter is an open-source UI toolkit for mobile developers, so they can use it to build native-looking** Android and iOS** applications from the same code base for both platforms. Flutter is also working to make Flutter apps for Web, PWA (progressive Web-App) and Desktop platform (Windows,macOS,Linux).

flutter-mobile-desktop-web-embedded_min

Flutter was officially released in December 2018. Since then, it has gone a much stronger flutter community.

There has been much increase in flutter developers, flutter packages, youtube tutorials, blogs, flutter examples apps, official and private events, and more. Flutter is now on top software repos based and trending on GitHub.

Flutter meaning?

What is Flutter? this question comes to many new developer’s mind.

humming_bird_dart_flutter

Flutter means flying wings quickly, and lightly but obviously, this doesn’t apply in our SDK.

So Flutter was one of the companies that were acquired by **Google **for around $40 million. That company was based on providing gesture detection and recognition from a standard webcam. But later when the Flutter was going to release in alpha version for developer it’s name was Sky, but since Google already owned Flutter name, so they rename it to Flutter.

Where Flutter is used?

Flutter is used in many startup companies nowadays, and even some MNCs are also adopting Flutter as a mobile development framework. Many top famous companies are using their apps in Flutter. Some of them here are

Dream11

Dream11

NuBank

NuBank

Reflectly app

Reflectly app

Abbey Road Studios

Abbey Road Studios

and many more other apps. Mobile development companies also adopted Flutter as a service for their clients. Even I was one of them who developed flutter apps as a freelancer and later as an IT company for mobile apps.

Flutter as a service

#dart #flutter #uncategorized #flutter framework #flutter jobs #flutter language #flutter meaning #flutter meaning in hindi #google flutter #how does flutter work #what is flutter

Siphiwe  Nair

Siphiwe Nair

1620466520

Your Data Architecture: Simple Best Practices for Your Data Strategy

If you accumulate data on which you base your decision-making as an organization, you should probably think about your data architecture and possible best practices.

If you accumulate data on which you base your decision-making as an organization, you most probably need to think about your data architecture and consider possible best practices. Gaining a competitive edge, remaining customer-centric to the greatest extent possible, and streamlining processes to get on-the-button outcomes can all be traced back to an organization’s capacity to build a future-ready data architecture.

In what follows, we offer a short overview of the overarching capabilities of data architecture. These include user-centricity, elasticity, robustness, and the capacity to ensure the seamless flow of data at all times. Added to these are automation enablement, plus security and data governance considerations. These points from our checklist for what we perceive to be an anticipatory analytics ecosystem.

#big data #data science #big data analytics #data analysis #data architecture #data transformation #data platform #data strategy #cloud data platform #data acquisition

Ian  Robinson

Ian Robinson

1624399200

Top 10 Big Data Tools for Data Management and Analytics

Introduction to Big Data

What exactly is Big Data? Big Data is nothing but large and complex data sets, which can be both structured and unstructured. Its concept encompasses the infrastructures, technologies, and Big Data Tools created to manage this large amount of information.

To fulfill the need to achieve high-performance, Big Data Analytics tools play a vital role. Further, various Big Data tools and frameworks are responsible for retrieving meaningful information from a huge set of data.

List of Big Data Tools & Frameworks

The most important as well as popular Big Data Analytics Open Source Tools which are used in 2020 are as follows:

  1. Big Data Framework
  2. Data Storage Tools
  3. Data Visualization Tools
  4. Big Data Processing Tools
  5. Data Preprocessing Tools
  6. Data Wrangling Tools
  7. Big Data Testing Tools
  8. Data Governance Tools
  9. Security Management Tools
  10. Real-Time Data Streaming Tools

#big data engineering #top 10 big data tools for data management and analytics #big data tools for data management and analytics #tools for data management #analytics #top big data tools for data management and analytics

Gerhard  Brink

Gerhard Brink

1624692167

Top 10 Big Data Tools for 2021!

In today’s tech world, data is everything. As the focus on data grows, it keeps multiplying by leaps and bounds each day. If earlier mounds of data were talked about in kilobytes and megabytes, today terabytes have become the base unit for organizational data. This coming in of big data has transformed paradigms of data storage, processing, and analytics.

Instead of only gathering and storing information that can offer crucial insights to meet short-term goals, an increasing number of enterprises are storing much larger amounts of data gathered from multiple resources across business processes. However, all this data is meaningless on its own. It can add value only when it is processed and analyzed the right way to draw point insights that can improve decision-making.

Processing and analyzing big data is not an easy task. If not handled correctly, big data can turn into an obstacle rather than an effective solution for businesses. Effective handling of big data management  requires to use of tools that can steer you toward tangible, substantial results. For that, you need a set of great big data tools that will not only solve this problem but also help you in producing substantial results.

Data storage tools, warehouses, and data lakes all play a crucial role in helping companies store and sort vast amounts of information. However, the true power of big data lies in its analytics. There are a host of big data tools in the market today to aid a business’ journey from gathering data to storing, processing, analyzing, and reporting it. Let’s take a closer look at some of the top big data tools that can help you inch closer to your goal of establishing data-driven decision-making and workflow processes.

Apache Hadoop

Apache Spark

Flink

Apache Storm

Apache Cassandra

#big data #big data tools #big data management #big data tool #top 10 big data tools for 2021! #top-big-data-tool