-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(geobase): simple geometry data structures #133
- Loading branch information
1 parent
fb3a5e4
commit c512dff
Showing
16 changed files
with
865 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export 'model/bounded.dart'; | ||
export 'model/geometry.dart'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export 'bounded/bounded.dart'; |
27 changes: 27 additions & 0 deletions
27
dart/geobase/lib/src/vector_data/model/bounded/bounded.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright (c) 2020-2022 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 | ||
|
||
//import '/src/coordinates/base.dart'; | ||
|
||
/// A base interface for classes that know their bounding boxes. | ||
abstract class Bounded { | ||
/// Default `const` constructor to allow extending this abstract class. | ||
const Bounded(); | ||
|
||
/* | ||
/// The [bounds] for this object (could be calculated if not explicitely set). | ||
/// | ||
/// Please note that in some cases bounds could be pre-calculated but it's | ||
/// possible that accessing this property may cause extensive calculations. | ||
Box get bounds; | ||
/// The explicit [bounds] for this object when available. | ||
/// | ||
/// Accessing this should never trigger extensive calculations. That is, if | ||
/// bounds is not known, then returns the null value. | ||
Box? get boundsExplicit; | ||
*/ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export 'geometry/geometry.dart'; | ||
export 'geometry/geometry_builder.dart'; | ||
export 'geometry/geometry_collection.dart'; | ||
export 'geometry/linestring.dart'; | ||
export 'geometry/multi_linestring.dart'; | ||
export 'geometry/multi_point.dart'; | ||
export 'geometry/multi_polygon.dart'; | ||
export 'geometry/point.dart'; | ||
export 'geometry/polygon.dart'; |
22 changes: 22 additions & 0 deletions
22
dart/geobase/lib/src/vector_data/model/geometry/geometry.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// Copyright (c) 2020-2022 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 | ||
|
||
//import '/src/codes/geom.dart'; | ||
|
||
import 'package:meta/meta.dart'; | ||
|
||
import '/src/codes/geom.dart'; | ||
import '/src/vector_data/model/bounded.dart'; | ||
|
||
/// A base interface for geometry classes. | ||
@immutable | ||
abstract class Geometry extends Bounded { | ||
/// Default `const` constructor to allow extending this abstract class. | ||
const Geometry(); | ||
|
||
/// The geometry type. | ||
Geom get type; | ||
} |
181 changes: 181 additions & 0 deletions
181
dart/geobase/lib/src/vector_data/model/geometry/geometry_builder.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
// Copyright (c) 2020-2022 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 | ||
|
||
import '/src/codes/coords.dart'; | ||
import '/src/codes/geom.dart'; | ||
import '/src/coordinates/base.dart'; | ||
import '/src/vector/content.dart'; | ||
|
||
import 'geometry.dart'; | ||
import 'geometry_collection.dart'; | ||
import 'linestring.dart'; | ||
import 'multi_linestring.dart'; | ||
import 'multi_point.dart'; | ||
import 'multi_polygon.dart'; | ||
import 'point.dart'; | ||
import 'polygon.dart'; | ||
|
||
/// A builder to create geometry instances from [GeometryContent] stream. | ||
class GeometryBuilder with GeometryContent { | ||
final void Function(Geometry geom, {required int index, String? name}) | ||
_addGeometry; | ||
|
||
int _index = 0; | ||
|
||
GeometryBuilder._(this._addGeometry); | ||
|
||
void _add(Geometry geom, {String? name}) { | ||
_addGeometry.call(geom, index: _index++, name: name); | ||
} | ||
|
||
/// Builds a geometry list from the content stream provided by [geometries]. | ||
/// | ||
/// Only geometry objects of [T] are built, any other geometries are ignored. | ||
/// | ||
/// An optional expected [count], when given, specifies the number of geometry | ||
/// objects in a content stream. Note that when given the count MUST be exact. | ||
static List<T> buildList<T extends Geometry>( | ||
WriteGeometries geometries, { | ||
int? count, | ||
}) { | ||
final list = <T>[]; | ||
final builder = | ||
GeometryBuilder._((Geometry geom, {required int index, String? name}) { | ||
if (geom is T) { | ||
list.add(geom); | ||
} | ||
}); | ||
geometries.call(builder); | ||
return list; | ||
} | ||
|
||
/// Builds a geometry map from the content stream provided by [geometries]. | ||
/// | ||
/// Only geometry objects of [T] are built, any other geometries are ignored. | ||
/// | ||
/// A content stream on [GeometryContent] should provide also the `name` | ||
/// attribute for each geometry object. When `name` is not available, then | ||
/// an index as String is used a key. | ||
/// | ||
/// An optional expected [count], when given, specifies the number of geometry | ||
/// objects in a content stream. Note that when given the count MUST be exact. | ||
static Map<String, T> buildMap<T extends Geometry>( | ||
WriteGeometries geometries, { | ||
int? count, | ||
}) { | ||
final map = <String, T>{}; | ||
final builder = | ||
GeometryBuilder._((Geometry geom, {required int index, String? name}) { | ||
if (geom is T) { | ||
map[name ?? index.toString()] = geom; | ||
} | ||
}); | ||
geometries.call(builder); | ||
return map; | ||
} | ||
|
||
@override | ||
void point( | ||
Iterable<double> position, { | ||
Coords? type, | ||
String? name, | ||
}) { | ||
_add( | ||
Point.build(position, type: type), | ||
name: name, | ||
); | ||
} | ||
|
||
@override | ||
void lineString( | ||
Iterable<double> chain, { | ||
required Coords type, | ||
String? name, | ||
Box? bbox, | ||
}) { | ||
if (chain.length < 2) { | ||
// note: ignore empty geometries for this implementation | ||
} | ||
_add( | ||
LineString.build(chain, type: type), | ||
name: name, | ||
); | ||
} | ||
|
||
@override | ||
void polygon( | ||
Iterable<Iterable<double>> rings, { | ||
required Coords type, | ||
String? name, | ||
Box? bbox, | ||
}) { | ||
if (rings.isEmpty) { | ||
// note: ignore empty geometries for this implementation | ||
} | ||
_add( | ||
Polygon.build(rings, type: type), | ||
name: name, | ||
); | ||
} | ||
|
||
@override | ||
void multiPoint( | ||
Iterable<Iterable<double>> points, { | ||
required Coords type, | ||
String? name, | ||
Box? bbox, | ||
}) { | ||
_add( | ||
MultiPoint.build(points, type: type), | ||
name: name, | ||
); | ||
} | ||
|
||
@override | ||
void multiLineString( | ||
Iterable<Iterable<double>> lineStrings, { | ||
required Coords type, | ||
String? name, | ||
Box? bbox, | ||
}) { | ||
_add( | ||
MultiLineString.build(lineStrings, type: type), | ||
name: name, | ||
); | ||
} | ||
|
||
@override | ||
void multiPolygon( | ||
Iterable<Iterable<Iterable<double>>> polygons, { | ||
required Coords type, | ||
String? name, | ||
Box? bbox, | ||
}) { | ||
_add( | ||
MultiPolygon.build(polygons, type: type), | ||
name: name, | ||
); | ||
} | ||
|
||
@override | ||
void geometryCollection( | ||
WriteSimpleGeometries geometries, { | ||
Coords? type, | ||
int? count, | ||
String? name, | ||
Box? bbox, | ||
}) { | ||
_add( | ||
GeometryCollection.build(geometries, count: count), | ||
name: name, | ||
); | ||
} | ||
|
||
@override | ||
void emptyGeometry(Geom type, {String? name}) { | ||
// note: ignore empty geometries for this implementation | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
dart/geobase/lib/src/vector_data/model/geometry/geometry_collection.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Copyright (c) 2020-2022 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 | ||
|
||
import '/src/codes/geom.dart'; | ||
import '/src/vector/content.dart'; | ||
|
||
import 'geometry.dart'; | ||
import 'geometry_builder.dart'; | ||
|
||
/// A geometry collection with geometries. | ||
class GeometryCollection<E extends Geometry> extends Geometry { | ||
final List<E> _geometries; | ||
|
||
/// A geometry collection with [geometries]. | ||
const GeometryCollection(List<E> geometries) : _geometries = geometries; | ||
|
||
/// A geometry collection from the content stream provided by [geometries]. | ||
/// | ||
/// Only geometry objects of [E] are built, any other geometries are ignored. | ||
/// | ||
/// An optional expected [count], when given, specifies the number of geometry | ||
/// objects in a content stream. Note that when given the count MUST be exact. | ||
/// | ||
/// An example to build a geometry collection with two child geometries: | ||
/// ```dart | ||
/// GeometryCollection.build( | ||
/// count: 2, | ||
/// (geom) => geom | ||
/// ..point([10.123, 20.25]) | ||
/// ..polygon( | ||
/// [ | ||
/// [ | ||
/// 10.1, 10.1, | ||
/// 5.0, 9.0, | ||
/// 12.0, 4.0, | ||
/// 10.1, 10.1, | ||
/// ], | ||
/// ], | ||
/// type: Coords.xy, | ||
/// ), | ||
/// ); | ||
/// ``` | ||
/// | ||
/// An example to build a type geometry collection with points only: | ||
/// ```dart | ||
/// GeometryCollection<Point>.build( | ||
/// count: 3, | ||
/// (geom) => geom | ||
/// ..point([-1.1, -1.1]) | ||
/// ..point([2.1, -2.5]) | ||
/// ..point([3.5, -3.49]), | ||
/// ); | ||
/// ``` | ||
factory GeometryCollection.build( | ||
WriteGeometries geometries, { | ||
int? count, | ||
}) => | ||
GeometryCollection<E>( | ||
GeometryBuilder.buildList<E>(geometries, count: count), | ||
); | ||
|
||
@override | ||
Geom get type => Geom.geometryCollection; | ||
|
||
/// All geometry items in this geometry collection. | ||
List<E> get items => _geometries; | ||
|
||
// todo: ==, hashCode, toString | ||
} |
Oops, something went wrong.