Skip to content

Commit

Permalink
refactor(geobase): equalsCoord, equals2D, equals3D defined by Bounded #…
Browse files Browse the repository at this point in the history
  • Loading branch information
navispatial committed Aug 30, 2023
1 parent 3981a19 commit ce52384
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 118 deletions.
1 change: 1 addition & 0 deletions dart/geobase/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ NOTE: Version 0.6.0 currently [under development](https://github.com/navibyte/ge
🧩 Features:
* [Add copyWith (and map) methods to coordinate, meta, feature and geometry classes #189](https://github.com/navibyte/geospatial/issues/189)
* [Populating and unpopulating bounds in geometries and feature objects #197](https://github.com/navibyte/geospatial/issues/197)
* [Testing feature and geometry equality #188](https://github.com/navibyte/geospatial/issues/188)

⚠️ Breaking changes:
* [Allow a position stored as "Position" in Point, and a bounding box as "Box" in Geometry classes #192](https://github.com/navibyte/geospatial/issues/192)
Expand Down
47 changes: 47 additions & 0 deletions dart/geobase/lib/src/vector_data/model/bounded/bounded.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Docs: https://github.com/navibyte/geospatial

import '/src/codes/coords.dart';
import '/src/constants/epsilon.dart';
import '/src/coordinates/base/box.dart';
import '/src/coordinates/projection/projection.dart';

Expand Down Expand Up @@ -107,4 +108,50 @@ abstract class Bounded {
/// projecting geometries. If [bounds] is null, then it's null after
/// projecting too.
Bounded project(Projection projection);

/// Returns true if this and [other] contain exactly same coordinate values
/// (or both are empty) in the same order and with the same coordinate type.
bool equalsCoords(Bounded other);

/// True if this bounded object equals with [other] by testing 2D coordinates
/// of all geometries (that must be in same order in both objects) contained
/// directly or by child objects.
///
/// Returns false if this and [other] are not of the same bounded object type.
///
/// Returns false if this or [other] contain "empty geometry"
/// ([isEmptyByGeometry] true).
///
/// Differences on 2D coordinate values (ie. x and y, or lon and lat) between
/// this and [other] must be within [toleranceHoriz].
///
/// Tolerance values must be positive (>= 0.0).
bool equals2D(
Bounded other, {
double toleranceHoriz = defaultEpsilon,
});

/// True if this bounded object equals with [other] by testing 3D coordinates
/// of all geometries (that must be in same order in both objects) contained
/// directly or by child objects.
///
/// Returns false if this and [other] are not of the same bounded object type.
///
/// Returns false if this or [other] contain "empty geometry"
/// ([isEmptyByGeometry] true).
///
/// Returns false if this or [other] do not contain 3D coordinates.
///
/// Differences on 2D coordinate values (ie. x and y, or lon and lat) between
/// this and [other] must be within [toleranceHoriz].
///
/// Differences on vertical coordinate values (ie. z or elev) between
/// this and [other] must be within [toleranceVert].
///
/// Tolerance values must be positive (>= 0.0).
bool equals3D(
Bounded other, {
double toleranceHoriz = defaultEpsilon,
double toleranceVert = defaultEpsilon,
});
}
40 changes: 12 additions & 28 deletions dart/geobase/lib/src/vector_data/model/feature/feature.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import '/src/vector/content/feature_content.dart';
import '/src/vector/content/geometry_content.dart';
import '/src/vector/encoding/text_format.dart';
import '/src/vector/formats/geojson/geojson_format.dart';
import '/src/vector_data/model/bounded/bounded.dart';
import '/src/vector_data/model/geometry/geometry.dart';
import '/src/vector_data/model/geometry/geometry_builder.dart';

Expand Down Expand Up @@ -344,9 +345,9 @@ class Feature<T extends Geometry> extends FeatureObject {
);
}

/// Returns true if this and [other] contain exactly same coordinate values
/// (or both are empty) in the same order and with the same coordinate type.
bool equalsCoords(Feature other) {
@override
bool equalsCoords(Bounded other) {
if (other is! Feature) return false;
if (identical(this, other)) return true;

if (bounds != null && other.bounds != null && !(bounds! == other.bounds!)) {
Expand All @@ -367,21 +368,14 @@ class Feature<T extends Geometry> extends FeatureObject {
return true;
}

/// True if this feature equals with [other] by testing 2D coordinates of the
/// [geometry].
///
/// Returns false if this or [other] contain a null or "empty" geometry object
/// in `geometry`.
///
/// Differences on 2D coordinate values (ie. x and y, or lon and lat) between
/// this and [other] must be within [toleranceHoriz].
///
/// Tolerance values must be positive (>= 0.0).
@override
bool equals2D(
Feature other, {
Bounded other, {
double toleranceHoriz = defaultEpsilon,
}) {
assertTolerance(toleranceHoriz);
if (other is! Feature) return false;
if (isEmptyByGeometry || other.isEmptyByGeometry) return false;

// test bounding boxes if both have it
if (bounds != null &&
Expand Down Expand Up @@ -412,26 +406,16 @@ class Feature<T extends Geometry> extends FeatureObject {
return true;
}

/// True if this feature equals with [other] by testing 3D coordinates of the
/// [geometry] object.
///
/// Returns false if this or [other] contain a null, "empty" or non-3D
/// geometry object in `geometry`.
///
/// Differences on 2D coordinate values (ie. x and y, or lon and lat) between
/// this and [other] must be within [toleranceHoriz].
///
/// Differences on vertical coordinate values (ie. z or elev) between
/// this and [other] must be within [toleranceVert].
///
/// Tolerance values must be positive (>= 0.0).
@override
bool equals3D(
Feature other, {
Bounded other, {
double toleranceHoriz = defaultEpsilon,
double toleranceVert = defaultEpsilon,
}) {
assertTolerance(toleranceHoriz);
assertTolerance(toleranceVert);
if (other is! Feature) return false;
if (isEmptyByGeometry || other.isEmptyByGeometry) return false;

// test bounding boxes if both have it
if (bounds != null &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import '/src/utils/tolerance.dart';
import '/src/vector/content/feature_content.dart';
import '/src/vector/encoding/text_format.dart';
import '/src/vector/formats/geojson/geojson_format.dart';
import '/src/vector_data/model/bounded/bounded.dart';
import '/src/vector_data/model/geometry/geometry.dart';

import 'feature.dart';
Expand Down Expand Up @@ -342,9 +343,9 @@ class FeatureCollection<E extends Feature> extends FeatureObject {
);
}

/// Returns true if this and [other] contain exactly same coordinate values
/// (or both are empty) in the same order and with the same coordinate type.
bool equalsCoords(FeatureCollection other) {
@override
bool equalsCoords(Bounded other) {
if (other is! FeatureCollection) return false;
if (identical(this, other)) return true;

if (bounds != null && other.bounds != null && !(bounds! == other.bounds!)) {
Expand All @@ -363,19 +364,14 @@ class FeatureCollection<E extends Feature> extends FeatureObject {
return true;
}

/// True if this feature collection equals with [other] by testing 2D
/// coordinates of geometries of [features] (that must be in same order in
/// both collections) contained.
///
/// Differences on 2D coordinate values (ie. x and y, or lon and lat) between
/// this and [other] must be within [toleranceHoriz].
///
/// Tolerance values must be positive (>= 0.0).
@override
bool equals2D(
FeatureCollection other, {
Bounded other, {
double toleranceHoriz = defaultEpsilon,
}) {
assertTolerance(toleranceHoriz);
if (other is! FeatureCollection) return false;
if (isEmptyByGeometry || other.isEmptyByGeometry) return false;

// test bounding boxes if both have it
if (bounds != null &&
Expand Down Expand Up @@ -405,24 +401,16 @@ class FeatureCollection<E extends Feature> extends FeatureObject {
return true;
}

/// True if this feature collection equals with [other] by testing 3D
/// coordinates of geometries of [features] (that must be in same order in
/// both collections) contained.
///
/// Differences on 2D coordinate values (ie. x and y, or lon and lat) between
/// this and [other] must be within [toleranceHoriz].
///
/// Differences on vertical coordinate values (ie. z or elev) between
/// this and [other] must be within [toleranceVert].
///
/// Tolerance values must be positive (>= 0.0).
@override
bool equals3D(
FeatureCollection other, {
Bounded other, {
double toleranceHoriz = defaultEpsilon,
double toleranceVert = defaultEpsilon,
}) {
assertTolerance(toleranceHoriz);
assertTolerance(toleranceVert);
if (other is! FeatureCollection) return false;
if (isEmptyByGeometry || other.isEmptyByGeometry) return false;

// test bounding boxes if both have it
if (bounds != null &&
Expand Down
45 changes: 0 additions & 45 deletions dart/geobase/lib/src/vector_data/model/geometry/geometry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import 'dart:typed_data';
import 'package:meta/meta.dart';

import '/src/codes/geom.dart';
import '/src/constants/epsilon.dart';
import '/src/coordinates/projection/projection.dart';
import '/src/coordinates/reference/coord_ref_sys.dart';
import '/src/vector/content/geometry_content.dart';
Expand Down Expand Up @@ -133,50 +132,6 @@ abstract class Geometry extends Bounded {
return encoder.toBytes();
}

/// Returns true if this and [other] contain exactly same coordinate values
/// (or both are empty) in the same order and with the same coordinate type.
bool equalsCoords(Geometry other);

/// True if this geometry equals with [other] by testing 2D coordinates of all
/// positions (that must be in same order in both geometries).
///
/// Returns false if this and [other] are not of the same geometry type.
///
/// Returns false if this or [other] is an "empty geometry"
/// ([isEmptyByGeometry] true).
///
/// Differences on 2D coordinate values (ie. x and y, or lon and lat) between
/// this and [other] must be within [toleranceHoriz].
///
/// Tolerance values must be positive (>= 0.0).
bool equals2D(
Geometry other, {
double toleranceHoriz = defaultEpsilon,
});

/// True if this geometry equals with [other] by testing 3D coordinates of all
/// positions (that must be in same order in both geometries).
///
/// Returns false if this and [other] are not of the same geometry type.
///
/// Returns false if this or [other] is an "empty geometry"
/// ([isEmptyByGeometry] true).
///
/// Returns false if this or [other] do not contain 3D coordinates.
///
/// Differences on 2D coordinate values (ie. x and y, or lon and lat) between
/// this and [other] must be within [toleranceHoriz].
///
/// Differences on vertical coordinate values (ie. z or elev) between
/// this and [other] must be within [toleranceVert].
///
/// Tolerance values must be positive (>= 0.0).
bool equals3D(
Geometry other, {
double toleranceHoriz = defaultEpsilon,
double toleranceVert = defaultEpsilon,
});

/// The string representation of this geometry object as specified by
/// [GeoJSON].
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import '/src/vector/encoding/binary_format.dart';
import '/src/vector/encoding/text_format.dart';
import '/src/vector/formats/geojson/geojson_format.dart';
import '/src/vector/formats/wkb/wkb_format.dart';
import '/src/vector_data/model/bounded/bounded.dart';

import 'geometry.dart';
import 'geometry_builder.dart';
Expand Down Expand Up @@ -269,7 +270,7 @@ class GeometryCollection<E extends Geometry> extends Geometry {
);

@override
bool equalsCoords(Geometry other) {
bool equalsCoords(Bounded other) {
if (other is! GeometryCollection) return false;
if (identical(this, other)) return true;
if (bounds != null && other.bounds != null && !(bounds! == other.bounds!)) {
Expand All @@ -288,7 +289,7 @@ class GeometryCollection<E extends Geometry> extends Geometry {

@override
bool equals2D(
Geometry other, {
Bounded other, {
double toleranceHoriz = defaultEpsilon,
}) {
assertTolerance(toleranceHoriz);
Expand Down Expand Up @@ -321,7 +322,7 @@ class GeometryCollection<E extends Geometry> extends Geometry {

@override
bool equals3D(
Geometry other, {
Bounded other, {
double toleranceHoriz = defaultEpsilon,
double toleranceVert = defaultEpsilon,
}) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import '/src/vector/encoding/text_format.dart';
import '/src/vector/formats/geojson/default_format.dart';
import '/src/vector/formats/geojson/geojson_format.dart';
import '/src/vector/formats/wkb/wkb_format.dart';
import '/src/vector_data/model/bounded/bounded.dart';

import 'geometry.dart';
import 'geometry_builder.dart';
Expand Down Expand Up @@ -257,7 +258,7 @@ class LineString extends SimpleGeometry {
// NOTE: coordinates as raw data

@override
bool equalsCoords(Geometry other) {
bool equalsCoords(Bounded other) {
if (other is! LineString) return false;
if (identical(this, other)) return true;
if (bounds != null && other.bounds != null && !(bounds! == other.bounds!)) {
Expand All @@ -270,7 +271,7 @@ class LineString extends SimpleGeometry {

@override
bool equals2D(
Geometry other, {
Bounded other, {
double toleranceHoriz = defaultEpsilon,
}) {
assertTolerance(toleranceHoriz);
Expand All @@ -294,7 +295,7 @@ class LineString extends SimpleGeometry {

@override
bool equals3D(
Geometry other, {
Bounded other, {
double toleranceHoriz = defaultEpsilon,
double toleranceVert = defaultEpsilon,
}) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import '/src/vector/encoding/text_format.dart';
import '/src/vector/formats/geojson/default_format.dart';
import '/src/vector/formats/geojson/geojson_format.dart';
import '/src/vector/formats/wkb/wkb_format.dart';
import '/src/vector_data/model/bounded/bounded.dart';

import 'geometry.dart';
import 'geometry_builder.dart';
Expand Down Expand Up @@ -285,7 +286,7 @@ class MultiLineString extends SimpleGeometry {
// NOTE: coordinates as raw data

@override
bool equalsCoords(Geometry other) {
bool equalsCoords(Bounded other) {
if (other is! MultiLineString) return false;
if (identical(this, other)) return true;
if (bounds != null && other.bounds != null && !(bounds! == other.bounds!)) {
Expand All @@ -304,7 +305,7 @@ class MultiLineString extends SimpleGeometry {

@override
bool equals2D(
Geometry other, {
Bounded other, {
double toleranceHoriz = defaultEpsilon,
}) {
assertTolerance(toleranceHoriz);
Expand Down Expand Up @@ -337,7 +338,7 @@ class MultiLineString extends SimpleGeometry {

@override
bool equals3D(
Geometry other, {
Bounded other, {
double toleranceHoriz = defaultEpsilon,
double toleranceVert = defaultEpsilon,
}) {
Expand Down
Loading

0 comments on commit ce52384

Please sign in to comment.