navibyte / geospatial

Geospatial data structures, tools and utilities for Dart and Flutter.
Other
52 stars 5 forks source link

Testing feature and geometry equality #188

Closed navispatial closed 1 year ago

navispatial commented 1 year ago

See #146 that contained equalsCoords, equals2D and equals3D methods for feature and geometry classes, and partially also different coordinate position and position arrays classes.

Position / Geographic / Projected/ PositionCoords and Box /GeoBox/ProjBox/BoxCoordsalso has the standard equality operator and hash functions. For exampleGeographicandProjectedimplement using static functions provided byPosition`:

  @override
  bool operator ==(Object other) =>
      other is Position && Position.testEquals(this, other);

  @override
  int get hashCode => Position.hash(this);

Using equality operator for position arrays and large coordinate data (including also geometries and features that contain coordinate data) is potentially a performance issue if need to loop through large about of positions and coordinate values.

Because of this, there are separate equalsCoords, equals2D and equals3D. Using this it's possible to test geometries.

But Feature (and FeatureCollection) may contain also other data:

Testing these is possible by testing data got from getters, but some easier method might be handy.

For example Feature already has:

  /// 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.
  ///
  /// If [ignoreCustomGeometries] is true, then [customGeometries] are ignored
  /// in testing.
  bool equalsCoords(
    Feature other, {
    bool ignoreCustomGeometries = false,
  });

  /// True if this feature equals with [other] by testing 2D coordinates of the
  /// [geometry] object (and any [customGeometries] possibly contained).
  ///
  /// If [ignoreCustomGeometries] is true, then [customGeometries] are ignored
  /// in testing.
  ///
  /// 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).
  bool equals2D(
    Feature other, {
    double toleranceHoriz = defaultEpsilon,
    bool ignoreCustomGeometries = false,
  });

  /// True if this feature equals with [other] by testing 3D coordinates of the
  /// [geometry] object (and any [customGeometries] possibly contained).
  ///
  /// If [ignoreCustomGeometries] is true, then [customGeometries] are ignored
  /// in testing.
  ///
  /// 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).
  bool equals3D(
    Feature other, {
    double toleranceHoriz = defaultEpsilon,
    double toleranceVert = defaultEpsilon,
    bool ignoreCustomGeometries = false,
  });

There could be also following test methods for Feature:

  /// Returns true if this and [other] feature equals by testing feature members.
  /// 
  /// Parameters:
  /// * [ignoreId]: if set true, then `id` of features is not tested for equality
  /// * [ignoreProperties]: if set true, then `properties` of features is not tested for equality
  /// * [ignoreGeometry]: if set true, then `id` of features is not tested for equality
  /// * [ignoreCustom]: if set true, then `custom` properties of features is not tested for equality
  /// * [ignoreCustomGeometries]: if set true, then `customGeometries` of features is not tested for equality
  /// 
  /// Testing geometries is implemented by delegating testing to [equalsCoords].
  /// 
  /// Testing properties and custom properties tests `Map<String, dynamic>` values using a deep equality method.
  bool equalsBy(
    Feature other, {
    bool ignoreId = false,
    bool ignoreProperties = false,
    bool ignoreCustom = false,
    bool ignoreGeometry = false,
    bool ignoreCustomGeometries = false,
  });

  /// Returns true if this contains same property values as [properties].
  /// 
  /// Parameters:
  /// * [ignoreProperties]: if set true, then `properties` of this feature is not tested for equality
  /// * [ignoreCustom]: if set true, then `custom` properties of this feature is not tested for equality
  bool containsProperties(Map<String, dynamic> properties, {
    bool ignoreProperties = false,
    bool ignoreCustom = false,
  };

Maybe some other too, to be defined...

navispatial commented 1 year ago

Implemented in geobase 0.6.0