Skip to content

Commit

Permalink
refactor(geobase): added coordinates mixin to vector data #136, #137
Browse files Browse the repository at this point in the history
  • Loading branch information
navispatial committed Jul 28, 2022
1 parent 566c64a commit da9cefb
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 196 deletions.
19 changes: 19 additions & 0 deletions dart/geobase/lib/src/coordinates/base/position.dart
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,25 @@ abstract class Position extends Positionable {
toleranceVert: toleranceVert,
);

@override
String toString() {
final buf = StringBuffer()
..write(x)
..write(',')
..write(y);
if (is3D) {
buf
..write(',')
..write(z);
}
if (isMeasured) {
buf
..write(',')
..write(m);
}
return buf.toString();
}

// ---------------------------------------------------------------------------
// Static methods with default logic, used by Position, Projected and
// Geographic.
Expand Down
149 changes: 2 additions & 147 deletions dart/geobase/lib/src/vector_data/array/coordinates.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import '/src/coordinates/projected.dart';
import '/src/utils/format_validation.dart';
import '/src/utils/num.dart';

part 'coordinates_mixin.dart';
part 'geographic_coords.dart';
part 'position_array.dart';
part 'position_coords.dart';
Expand All @@ -24,153 +25,7 @@ part 'projected_coords.dart';
/// There are two known sub classes; [PositionCoords] containing coordinate
/// values of a single position and [PositionArray] containing coordinate values
/// of 0 to N positions.
class Coordinates implements Positionable, Iterable<double> {
final Iterable<double> _data;
final Coords _type;

/// Geospatial coordinate values as a view backed by [source].
///
/// An iterable collection of [source] may be represented by a [List] or any
/// [Iterable] with efficient `length` and `elementAt` implementations.
const Coordinates.view(Iterable<double> source, {Coords type = Coords.xy})
: _data = source,
_type = type;

// ---------------------------------------------------------------------------
// Positionable implementation

/// The coordinate type of coordinates values in this view.
@override
Coords get type => _type;

@override
int get spatialDimension => _type.spatialDimension;

@override
int get coordinateDimension => _type.coordinateDimension;

@override
bool get is3D => _type.is3D;

@override
bool get isMeasured => _type.isMeasured;

// ---------------------------------------------------------------------------
// Iterable<double> implementation

@override
double elementAt(int index) => _data.elementAt(index);

@override
int get length => _data.length;

@override
bool get isEmpty => _data.isEmpty;

@override
bool get isNotEmpty => _data.isNotEmpty;

@override
double get single => _data.single;

@override
Iterator<double> get iterator => _data.iterator;

@override
bool any(bool Function(double element) test) => _data.any(test);

@override
Iterable<R> cast<R>() => _data.cast<R>();

@override
bool contains(Object? element) => _data.contains(element);

@override
bool every(bool Function(double element) test) => _data.every(test);

@override
Iterable<T> expand<T>(Iterable<T> Function(double element) toElements) =>
_data.expand<T>(toElements);

@override
double get first => _data.first;

@override
double firstWhere(
bool Function(double element) test, {
double Function()? orElse,
}) =>
_data.firstWhere(test, orElse: orElse);

@override
T fold<T>(
T initialValue,
T Function(T previousValue, double element) combine,
) =>
_data.fold<T>(initialValue, combine);

@override
Iterable<double> followedBy(Iterable<double> other) =>
_data.followedBy(other);

@override
void forEach(void Function(double element) action) => _data.forEach(action);

@override
String join([String separator = '']) => _data.join(separator);

@override
double get last => _data.last;

@override
double lastWhere(
bool Function(double element) test, {
double Function()? orElse,
}) =>
_data.lastWhere(test, orElse: orElse);

@override
Iterable<T> map<T>(T Function(double e) toElement) => _data.map<T>(toElement);

@override
double reduce(double Function(double value, double element) combine) =>
_data.reduce(combine);

@override
double singleWhere(
bool Function(double element) test, {
double Function()? orElse,
}) =>
_data.singleWhere(test, orElse: orElse);

@override
Iterable<double> skip(int count) => _data.skip(count);

@override
Iterable<double> skipWhile(bool Function(double value) test) =>
_data.skipWhile(test);

@override
Iterable<double> take(int count) => _data.take(count);

@override
Iterable<double> takeWhile(bool Function(double value) test) =>
_data.takeWhile(test);

@override
List<double> toList({bool growable = true}) =>
_data.toList(growable: growable);

@override
Set<double> toSet() => _data.toSet();

@override
Iterable<double> where(bool Function(double element) test) =>
_data.where(test);

@override
Iterable<T> whereType<T>() => _data.whereType();
}
abstract class Coordinates extends Iterable<double> implements Positionable {}

typedef _CreateAt<T> = T Function(
Iterable<double> coordinates, {
Expand Down
147 changes: 147 additions & 0 deletions dart/geobase/lib/src/vector_data/array/coordinates_mixin.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// 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

part of 'coordinates.dart';

mixin _CoordinatesMixin implements Coordinates {
Iterable<double> get _data;
Coords get _type;

// ---------------------------------------------------------------------------
// Positionable implementation

/// The coordinate type of coordinates values in this view.
@override
Coords get type => _type;

@override
int get spatialDimension => _type.spatialDimension;

@override
int get coordinateDimension => _type.coordinateDimension;

@override
bool get is3D => _type.is3D;

@override
bool get isMeasured => _type.isMeasured;

// ---------------------------------------------------------------------------
// Iterable<double> implementation

@override
double elementAt(int index) => _data.elementAt(index);

@override
int get length => _data.length;

@override
bool get isEmpty => _data.isEmpty;

@override
bool get isNotEmpty => _data.isNotEmpty;

@override
double get single => _data.single;

@override
Iterator<double> get iterator => _data.iterator;

@override
bool any(bool Function(double element) test) => _data.any(test);

@override
Iterable<R> cast<R>() => _data.cast<R>();

@override
bool contains(Object? element) => _data.contains(element);

@override
bool every(bool Function(double element) test) => _data.every(test);

@override
Iterable<T> expand<T>(Iterable<T> Function(double element) toElements) =>
_data.expand<T>(toElements);

@override
double get first => _data.first;

@override
double firstWhere(
bool Function(double element) test, {
double Function()? orElse,
}) =>
_data.firstWhere(test, orElse: orElse);

@override
T fold<T>(
T initialValue,
T Function(T previousValue, double element) combine,
) =>
_data.fold<T>(initialValue, combine);

@override
Iterable<double> followedBy(Iterable<double> other) =>
_data.followedBy(other);

@override
void forEach(void Function(double element) action) => _data.forEach(action);

@override
String join([String separator = '']) => _data.join(separator);

@override
double get last => _data.last;

@override
double lastWhere(
bool Function(double element) test, {
double Function()? orElse,
}) =>
_data.lastWhere(test, orElse: orElse);

@override
Iterable<T> map<T>(T Function(double e) toElement) => _data.map<T>(toElement);

@override
double reduce(double Function(double value, double element) combine) =>
_data.reduce(combine);

@override
double singleWhere(
bool Function(double element) test, {
double Function()? orElse,
}) =>
_data.singleWhere(test, orElse: orElse);

@override
Iterable<double> skip(int count) => _data.skip(count);

@override
Iterable<double> skipWhile(bool Function(double value) test) =>
_data.skipWhile(test);

@override
Iterable<double> take(int count) => _data.take(count);

@override
Iterable<double> takeWhile(bool Function(double value) test) =>
_data.takeWhile(test);

@override
List<double> toList({bool growable = true}) =>
_data.toList(growable: growable);

@override
Set<double> toSet() => _data.toSet();

@override
Iterable<double> where(bool Function(double element) test) =>
_data.where(test);

@override
Iterable<T> whereType<T>() => _data.whereType();
}
19 changes: 13 additions & 6 deletions dart/geobase/lib/src/vector_data/array/position_array.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@ part of 'coordinates.dart';
/// [data] to map coordinate values to custom position types.
///
/// See [Position] for description about supported coordinate values.
class PositionArray extends Coordinates {
/// Positions with coordinate values as a view backed by `source`.
class PositionArray with _CoordinatesMixin {
@override
final Iterable<double> _data;

@override
final Coords _type;

/// Positions with coordinate values as a view backed by [source].
///
/// The `source` collection contains coordinate values of positions as a flat
/// The [source] collection contains coordinate values of positions as a flat
/// structure. For example for `Coords.xyz` the first three coordinate values
/// are x, y and z of the first position, the next three coordinate values are
/// x, y and z of the second position, and so on.
Expand All @@ -31,14 +37,15 @@ class PositionArray extends Coordinates {
/// less coordinate values than `type.coordinateDimension`, then the view is
/// considered empty.
///
/// An iterable collection of `source` may be represented by a [List] or any
/// An iterable collection of [source] may be represented by a [List] or any
/// [Iterable] with efficient `length` and `elementAt` implementations. A lazy
/// iterable with a lot of coordinate values may produce very poor
/// performance.
///
/// See [Position] for description about supported coordinate values.
const PositionArray.view(super.source, {super.type = Coords.xy})
: super.view();
const PositionArray.view(Iterable<double> source, {Coords type = Coords.xy})
: _data = source,
_type = type;

/// Positions with coordinate values parsed from [text].
///
Expand Down
Loading

0 comments on commit da9cefb

Please sign in to comment.