From f479745dfb3b2406f8685bb0effac9b87deafd79 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 May 2025 21:25:13 +0000 Subject: [PATCH 1/2] Initial plan for issue From 3eaf1b1c8c91cb4a97ea9b36a4e4276f0f03385a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 May 2025 21:49:47 +0000 Subject: [PATCH 2/2] Remove Z and M properties from Coordinate structure and update core functionality Co-authored-by: lukaskabrt <2894161+lukaskabrt@users.noreply.github.com> --- src/SpatialLite.Core/API/Coordinate.cs | 160 ++++------- src/SpatialLite.Core/API/Envelope.cs | 256 +++++------------- src/SpatialLite.Core/API/IGeometry.cs | 44 ++- .../Algorithms/Sphere2DCalculator.cs | 12 +- src/SpatialLite.Core/Geometries/Geometry.cs | 46 ++-- .../Geometries/GeometryCollection.cs | 32 +-- src/SpatialLite.Core/Geometries/LineString.cs | 30 +- src/SpatialLite.Core/Geometries/Point.cs | 109 +++----- src/SpatialLite.Core/Geometries/Polygon.cs | 32 +-- src/SpatialLite.Core/IO/WkbReader.cs | 20 +- src/SpatialLite.Core/IO/WkbWriter.cs | 28 +- src/SpatialLite.Core/IO/WktReader.cs | 48 ++-- src/SpatialLite.Core/IO/WktWriter.cs | 24 +- .../API/CoordinateTests.cs | 112 ++------ 14 files changed, 287 insertions(+), 666 deletions(-) diff --git a/src/SpatialLite.Core/API/Coordinate.cs b/src/SpatialLite.Core/API/Coordinate.cs index 73780ab..ffb48f8 100644 --- a/src/SpatialLite.Core/API/Coordinate.cs +++ b/src/SpatialLite.Core/API/Coordinate.cs @@ -1,99 +1,39 @@ using System; namespace SpatialLite.Core.API { - /// - /// Represents a location in the coordinate space. - /// - /// - /// A Coordinate may include a M value. The M value allows an application to associate some measure with the Coordinate. - /// - public struct Coordinate : IEquatable { - - /// - /// Represents an empty coordinate. - /// - /// - /// The empty coordinate has all coordinates equal to NaN. - /// - public static Coordinate Empty = new Coordinate(double.NaN, double.NaN, double.NaN, double.NaN); - - /// - /// Initializes a new instance of the Coordinate struct with X, Y ordinates. - /// - /// X-coordinate value. - /// Y-coordinate value. - public Coordinate(double x, double y) { - X = x; - Y = y; - Z = double.NaN; - M = double.NaN; + /// + /// Represents a location in the coordinate space. + /// + public struct Coordinate : IEquatable { + + /// + /// Represents an empty coordinate. + /// + /// + /// The empty coordinate has all coordinates equal to NaN. + /// + public static Coordinate Empty = new Coordinate(double.NaN, double.NaN); + + /// + /// Initializes a new instance of the Coordinate struct with X, Y ordinates. + /// + /// X-coordinate value. + /// Y-coordinate value. + public Coordinate(double x, double y) { + X = x; + Y = y; } - /// - /// Initializes a new instance of the Coordinate struct with X, Y, Z ordinates. - /// - /// X-coordinate value. - /// Y-coordinate value. - /// Z-coordinate value. - public Coordinate(double x, double y, double z) { - X = x; - Y = y; - Z = z; - M = double.NaN; - } - - /// - /// Initializes a new instance of the Coordinate struct with X, Y, Z ordinates and M value. - /// - /// X-coordinate value. - /// Y-coordinate value. - /// Z-coordinate value. - /// Measured value associated with the Coordinate. - public Coordinate(double x, double y, double z, double m) { - X = x; - Y = y; - Z = z; - M = m; - } - - /// - /// Gets the X-coordinate - /// - public double X { get; set; } - - /// - /// Gets the Y-coordinate - /// + /// + /// Gets the X-coordinate + /// + public double X { get; set; } + + /// + /// Gets the Y-coordinate + /// public double Y { get; set; } - /// - /// Gets the Z-coordinate - /// - public double Z { get; set; } - - /// - /// Gets the M value - /// - public double M { get; set; } - - /// - /// Gets a value indicating whether this coordinate has assigned coordinate. - /// - public bool Is3D { - get { - return !double.IsNaN(this.Z); - } - } - - /// - /// Gets a value indicating whether this coordinate has assigned value. - /// - public bool IsMeasured { - get { - return !double.IsNaN(this.M); - } - } - /// /// Determiens whether specific Coordinates values are equal /// @@ -114,12 +54,12 @@ public bool IsMeasured { return !(lhs == rhs); } - /// - /// Returns a string that represents the current Coordinate. - /// - /// A string that represents the current Coordinate - public override string ToString() { - return string.Format(System.Globalization.CultureInfo.InvariantCulture, "[{0}; {1}; {2}, {3}]", this.X, this.Y, this.Z, this.M); + /// + /// Returns a string that represents the current Coordinate. + /// + /// A string that represents the current Coordinate + public override string ToString() { + return string.Format(System.Globalization.CultureInfo.InvariantCulture, "[{0}; {1}]", this.X, this.Y); } /// @@ -136,24 +76,22 @@ public override bool Equals(object obj) { return this.Equals(other.Value); } - /// - /// Determines whether two Coordinate values are equal. - /// - /// The Coordinate to compare with the current Coordinate - /// true if the specified Coordinate is equal to the current Coordinate; otherwise, false. - public bool Equals(Coordinate other) { - return ((this.X == other.X) || (double.IsNaN(this.X) && double.IsNaN(other.X))) && - ((this.Y == other.Y) || (double.IsNaN(this.Y) && double.IsNaN(other.Y))) && - ((this.Z == other.Z) || (double.IsNaN(this.Z) && double.IsNaN(other.Z))) && - ((this.M == other.M) || (double.IsNaN(this.M) && double.IsNaN(other.M))); + /// + /// Determines whether two Coordinate values are equal. + /// + /// The Coordinate to compare with the current Coordinate + /// true if the specified Coordinate is equal to the current Coordinate; otherwise, false. + public bool Equals(Coordinate other) { + return ((this.X == other.X) || (double.IsNaN(this.X) && double.IsNaN(other.X))) && + ((this.Y == other.Y) || (double.IsNaN(this.Y) && double.IsNaN(other.Y))); } - /// - /// Serves as a hash function for the Coordinate structure. - /// - /// Hash code for current Coordinate value. - public override int GetHashCode() { - return X.GetHashCode() + 7 * Y.GetHashCode() + 13 * Z.GetHashCode() + 17 * M.GetHashCode(); + /// + /// Serves as a hash function for the Coordinate structure. + /// + /// Hash code for current Coordinate value. + public override int GetHashCode() { + return X.GetHashCode() + 7 * Y.GetHashCode(); } /// diff --git a/src/SpatialLite.Core/API/Envelope.cs b/src/SpatialLite.Core/API/Envelope.cs index dfa5815..7815479 100644 --- a/src/SpatialLite.Core/API/Envelope.cs +++ b/src/SpatialLite.Core/API/Envelope.cs @@ -11,15 +11,11 @@ public class Envelope { /// public static Envelope Empty = new Envelope(); - private const int XIndex = 0; - private const int YIndex = 1; - private const int ZIndex = 2; - private const int MIndex = 3; - - private double[][] _bounds = new double[][] { - new double[] { double.NaN, double.NaN }, - new double[] { double.NaN, double.NaN }, - new double[] { double.NaN, double.NaN }, + private const int XIndex = 0; + private const int YIndex = 1; + + private double[][] _bounds = new double[][] { + new double[] { double.NaN, double.NaN }, new double[] { double.NaN, double.NaN } }; /// @@ -28,12 +24,12 @@ public class Envelope { public Envelope() { } - /// - /// Initializes a new instance of the Envelope class with the single coordinate. - /// - /// The coordinate used initialize Envelope - public Envelope(Coordinate coord) { - this.Initialize(coord.X, coord.X, coord.Y, coord.Y, coord.Z, coord.Z, coord.M, coord.M); + /// + /// Initializes a new instance of the Envelope class with the single coordinate. + /// + /// The coordinate used initialize Envelope + public Envelope(Coordinate coord) { + this.Initialize(coord.X, coord.X, coord.Y, coord.Y); } /// @@ -44,12 +40,12 @@ public Envelope(IEnumerable coords) { this.Extend(coords); } - /// - /// Initializes a new instance of the Envelope class as copy of specified Envelope. - /// - /// The Envelope object whose values are to be copied. - public Envelope(Envelope source) { - this.Initialize(source.MinX, source.MaxX, source.MinY, source.MaxY, source.MinZ, source.MaxZ, source.MinM, source.MaxM); + /// + /// Initializes a new instance of the Envelope class as copy of specified Envelope. + /// + /// The Envelope object whose values are to be copied. + public Envelope(Envelope source) { + this.Initialize(source.MinX, source.MaxX, source.MinY, source.MaxY); } /// @@ -78,39 +74,11 @@ public double MinY { /// public double MaxY { get { return _bounds[YIndex][1]; } - } - - /// - /// Gets Envelope's minimal z-coordinate. - /// - public double MinZ { - get { return _bounds[ZIndex][0]; } - } - - /// - /// Gets Envelope's maximal z-coordinate. - /// - public double MaxZ { - get { return _bounds[ZIndex][1]; } - } - - /// - /// Gets Envelope's minimal m-coordinate. - /// - public double MinM { - get { return _bounds[MIndex][0]; } - } - - /// - /// Gets Envelope's maximal m-coordinate. - /// - public double MaxM { - get { return _bounds[MIndex][1]; } - } - - /// - /// Returns the difference between the maximum and minimum x values. - /// + } + + /// + /// Returns the difference between the maximum and minimum x values. + /// /// max x - min x, or 0 if this is a null Envelope. public double Width { get { @@ -145,29 +113,21 @@ public bool IsEmpty { } } - /// - /// Extends this Envelope to cover specified Coordinate. - /// - /// The Coordinate to be covered by extended Envelope. - public void Extend(Coordinate coord) { - if (double.IsNaN(_bounds[XIndex][0]) || double.IsNaN(_bounds[YIndex][0])) { - _bounds[XIndex][0] = _bounds[XIndex][1] = coord.X; - _bounds[YIndex][0] = _bounds[YIndex][1] = coord.Y; - _bounds[ZIndex][0] = _bounds[ZIndex][1] = coord.Z; - _bounds[MIndex][0] = _bounds[MIndex][1] = coord.M; - } else { - if (coord.X < _bounds[XIndex][0]) { _bounds[XIndex][0] = coord.X; } - if (coord.X > _bounds[XIndex][1]) { _bounds[XIndex][1] = coord.X; } - - if (coord.Y < _bounds[YIndex][0]) { _bounds[YIndex][0] = coord.Y; } - if (coord.Y > _bounds[YIndex][1]) { _bounds[YIndex][1] = coord.Y; } - - if (coord.Z < _bounds[ZIndex][0]) { _bounds[ZIndex][0] = coord.Z; } - if (coord.Z > _bounds[ZIndex][1]) { _bounds[ZIndex][1] = coord.Z; } - - if (coord.M < _bounds[MIndex][0]) { _bounds[MIndex][0] = coord.M; } - if (coord.M > _bounds[MIndex][1]) { _bounds[MIndex][1] = coord.M; } - } + /// + /// Extends this Envelope to cover specified Coordinate. + /// + /// The Coordinate to be covered by extended Envelope. + public void Extend(Coordinate coord) { + if (double.IsNaN(_bounds[XIndex][0]) || double.IsNaN(_bounds[YIndex][0])) { + _bounds[XIndex][0] = _bounds[XIndex][1] = coord.X; + _bounds[YIndex][0] = _bounds[YIndex][1] = coord.Y; + } else { + if (coord.X < _bounds[XIndex][0]) { _bounds[XIndex][0] = coord.X; } + if (coord.X > _bounds[XIndex][1]) { _bounds[XIndex][1] = coord.X; } + + if (coord.Y < _bounds[YIndex][0]) { _bounds[YIndex][0] = coord.Y; } + if (coord.Y > _bounds[YIndex][1]) { _bounds[YIndex][1] = coord.Y; } + } } /// @@ -180,36 +140,24 @@ public void Extend(IEnumerable coords) { } } - /// - /// Extends this Envelope to cover specified Envelope. - /// - /// The Envelope to be covered by extended Envelope. - public void Extend(Envelope envelope) { - if (double.IsNaN(_bounds[XIndex][0]) || double.IsNaN(_bounds[YIndex][0])) { - _bounds[XIndex][0] = envelope.MinX; - _bounds[XIndex][1] = envelope.MaxX; - - _bounds[YIndex][0] = envelope.MinY; - _bounds[YIndex][1] = envelope.MaxY; - - _bounds[ZIndex][0] = envelope.MinZ; - _bounds[ZIndex][1] = envelope.MaxZ; - - _bounds[MIndex][0] = envelope.MinM; - _bounds[MIndex][1] = envelope.MaxM; - } else { - if (envelope.MinX < _bounds[XIndex][0]) { _bounds[XIndex][0] = envelope.MinX; } - if (envelope.MaxX > _bounds[XIndex][1]) { _bounds[XIndex][1] = envelope.MaxX; } - - if (envelope.MinY < _bounds[YIndex][0]) { _bounds[YIndex][0] = envelope.MinY; } - if (envelope.MaxY > _bounds[YIndex][1]) { _bounds[YIndex][1] = envelope.MaxY; } - - if (envelope.MinZ < _bounds[ZIndex][0]) { _bounds[ZIndex][0] = envelope.MinZ; } - if (envelope.MaxZ > _bounds[ZIndex][1]) { _bounds[ZIndex][1] = envelope.MaxZ; } - - if (envelope.MinM < _bounds[MIndex][0]) { _bounds[MIndex][0] = envelope.MinM; } - if (envelope.MaxM > _bounds[MIndex][1]) { _bounds[MIndex][1] = envelope.MaxM; } - } + /// + /// Extends this Envelope to cover specified Envelope. + /// + /// The Envelope to be covered by extended Envelope. + public void Extend(Envelope envelope) { + if (double.IsNaN(_bounds[XIndex][0]) || double.IsNaN(_bounds[YIndex][0])) { + _bounds[XIndex][0] = envelope.MinX; + _bounds[XIndex][1] = envelope.MaxX; + + _bounds[YIndex][0] = envelope.MinY; + _bounds[YIndex][1] = envelope.MaxY; + } else { + if (envelope.MinX < _bounds[XIndex][0]) { _bounds[XIndex][0] = envelope.MinX; } + if (envelope.MaxX > _bounds[XIndex][1]) { _bounds[XIndex][1] = envelope.MaxX; } + + if (envelope.MinY < _bounds[YIndex][0]) { _bounds[YIndex][0] = envelope.MinY; } + if (envelope.MaxY > _bounds[YIndex][1]) { _bounds[YIndex][1] = envelope.MaxY; } + } } /// @@ -226,20 +174,16 @@ public override bool Equals(object obj) { return this.Equals(other); } - /// - /// Determines whether two Envelope instances are equal. - /// - /// The Envelope to compare with the current Envelope - /// true if the specified Envelope is equal to the current Envelope; otherwise, false. - public bool Equals(Envelope other) { - return ((this.MinX == other.MinX) || (double.IsNaN(this.MinX) && double.IsNaN(other.MinX))) && - ((this.MinY == other.MinY) || (double.IsNaN(this.MinY) && double.IsNaN(other.MinY))) && - ((this.MinZ == other.MinZ) || (double.IsNaN(this.MinZ) && double.IsNaN(other.MinZ))) && - ((this.MinM == other.MinM) || (double.IsNaN(this.MinM) && double.IsNaN(other.MinM))) && - ((this.MaxX == other.MaxX) || (double.IsNaN(this.MaxX) && double.IsNaN(other.MaxX))) && - ((this.MaxY == other.MaxY) || (double.IsNaN(this.MaxY) && double.IsNaN(other.MaxY))) && - ((this.MaxZ == other.MaxZ) || (double.IsNaN(this.MaxZ) && double.IsNaN(other.MaxZ))) && - ((this.MaxM == other.MaxM) || (double.IsNaN(this.MaxM) && double.IsNaN(other.MaxM))); + /// + /// Determines whether two Envelope instances are equal. + /// + /// The Envelope to compare with the current Envelope + /// true if the specified Envelope is equal to the current Envelope; otherwise, false. + public bool Equals(Envelope other) { + return ((this.MinX == other.MinX) || (double.IsNaN(this.MinX) && double.IsNaN(other.MinX))) && + ((this.MinY == other.MinY) || (double.IsNaN(this.MinY) && double.IsNaN(other.MinY))) && + ((this.MaxX == other.MaxX) || (double.IsNaN(this.MaxX) && double.IsNaN(other.MaxX))) && + ((this.MaxY == other.MaxY) || (double.IsNaN(this.MaxY) && double.IsNaN(other.MaxY))); } /// @@ -325,67 +269,15 @@ public void Initialize(double x1, double x2, double y1, double y2) { var sortedY = this.SortCoordinates(y1, y2); _bounds[YIndex][0] = sortedY[0]; _bounds[YIndex][1] = sortedY[1]; - } - - /// - /// Initializes MinX, MaxX, MinY, MaxY, MinZ and MaxZ properties from the given coordinates. - /// - /// First x-coordinate. - /// Second x-coordinate. - /// First y-coordinate. - /// Second y-coordinate. - /// First z-coordinate. - /// Second z-coordinate. - public void Initialize(double x1, double x2, double y1, double y2, double z1, double z2) { - var sortedX = this.SortCoordinates(x1, x2); - _bounds[XIndex][0] = sortedX[0]; - _bounds[XIndex][1] = sortedX[1]; - - var sortedY = this.SortCoordinates(y1, y2); - _bounds[YIndex][0] = sortedY[0]; - _bounds[YIndex][1] = sortedY[1]; - - var sortedZ = this.SortCoordinates(z1, z2); - _bounds[ZIndex][0] = sortedZ[0]; - _bounds[ZIndex][1] = sortedZ[1]; - } - - /// - /// Initializes MinX, MaxX, MinY, MaxY, MinZ and MaxZ properties from the given coordinates. - /// - /// First x-coordinate. - /// Second x-coordinate. - /// First y-coordinate. - /// Second y-coordinate. - /// First z-coordinate. - /// Second z-coordinate. - /// First measure value. - /// Second measure value. - public void Initialize(double x1, double x2, double y1, double y2, double z1, double z2, double m1, double m2) { - var sortedX = this.SortCoordinates(x1, x2); - _bounds[XIndex][0] = sortedX[0]; - _bounds[XIndex][1] = sortedX[1]; - - var sortedY = this.SortCoordinates(y1, y2); - _bounds[YIndex][0] = sortedY[0]; - _bounds[YIndex][1] = sortedY[1]; - - var sortedZ = this.SortCoordinates(z1, z2); - _bounds[ZIndex][0] = sortedZ[0]; - _bounds[ZIndex][1] = sortedZ[1]; - - var sortedM = this.SortCoordinates(m1, m2); - _bounds[MIndex][0] = sortedM[0]; - _bounds[MIndex][1] = sortedM[1]; - } - - /// - /// Sorts two coordinates - /// - /// First coordinate. - /// Second coordinate. - /// Array with sorted coordinates - [min, max] - /// If any value is double.NaN the other is used for min and max. + } + + /// + /// Sorts two coordinates + /// + /// First coordinate. + /// Second coordinate. + /// Array with sorted coordinates - [min, max] + /// If any value is double.NaN the other is used for min and max. private double[] SortCoordinates(double c1, double c2) { if (double.IsNaN(c1)) { c1 = c2; diff --git a/src/SpatialLite.Core/API/IGeometry.cs b/src/SpatialLite.Core/API/IGeometry.cs index 460e8d8..446ccd9 100644 --- a/src/SpatialLite.Core/API/IGeometry.cs +++ b/src/SpatialLite.Core/API/IGeometry.cs @@ -1,32 +1,22 @@ using System.Collections.Generic; namespace SpatialLite.Core.API { - /// - /// Defines common properties and methods for all geometry objects. - /// - public interface IGeometry { - /// - /// Gets a value indicating whether the IGeometry object has Z coordinates. - /// - bool Is3D { get; } - - /// - /// Gets a value indicating whether the IGeometry object has M values. - /// - bool IsMeasured { get; } - - /// - /// Computes envelope of the IGeometry object. The envelope is defined as a minimal bounding box for a geometry. - /// - /// - /// Returns an object that specifies the minimal bounding box of the IGeometry object. - /// - Envelope GetEnvelope(); - - /// - /// Gets collection of all of this IGeometry object - /// - /// the collection of all of this object - IEnumerable GetCoordinates(); + /// + /// Defines common properties and methods for all geometry objects. + /// + public interface IGeometry { + /// + /// Computes envelope of the IGeometry object. The envelope is defined as a minimal bounding box for a geometry. + /// + /// + /// Returns an object that specifies the minimal bounding box of the IGeometry object. + /// + Envelope GetEnvelope(); + + /// + /// Gets collection of all of this IGeometry object + /// + /// the collection of all of this object + IEnumerable GetCoordinates(); } } diff --git a/src/SpatialLite.Core/Algorithms/Sphere2DCalculator.cs b/src/SpatialLite.Core/Algorithms/Sphere2DCalculator.cs index cd1baa3..18dc2de 100644 --- a/src/SpatialLite.Core/Algorithms/Sphere2DCalculator.cs +++ b/src/SpatialLite.Core/Algorithms/Sphere2DCalculator.cs @@ -5,12 +5,12 @@ namespace SpatialLite.Core.Algorithms { /// /// Provides methods for calculating distance and area on the surface of a sphere. - /// - /// - /// - /// All calulations ignore coordinate. - /// - /// All coordinate are expected to be a long/lat pairs in degrees. + /// + /// + /// + /// All calculations use only X and Y coordinates. + /// + /// All coordinate are expected to be a long/lat pairs in degrees. /// public class Sphere2DCalculator : IDimensionsCalculator { diff --git a/src/SpatialLite.Core/Geometries/Geometry.cs b/src/SpatialLite.Core/Geometries/Geometry.cs index 4a4cee2..a94d63e 100644 --- a/src/SpatialLite.Core/Geometries/Geometry.cs +++ b/src/SpatialLite.Core/Geometries/Geometry.cs @@ -3,33 +3,23 @@ using SpatialLite.Core.API; namespace SpatialLite.Core.Geometries { - /// - /// Represetns the base class for all geometry object. - /// - public abstract class Geometry : IGeometry { - - /// - /// Gets a value indicating whether this has Z-coordinates. - /// - public abstract bool Is3D { get; } - - /// - /// Gets a value indicating whether this has M values. - /// - public abstract bool IsMeasured { get; } - - /// - /// Computes envelope of the IGeometry object. The envelope is defined as a minimal bounding box for a geometry. - /// - /// - /// Returns an object that specifies the minimal bounding box of the Geometry object. - /// - public abstract Envelope GetEnvelope(); - - /// - /// Gets collection of all of this IGeometry object - /// - /// the collection of all of this object - public abstract IEnumerable GetCoordinates(); + /// + /// Represetns the base class for all geometry object. + /// + public abstract class Geometry : IGeometry { + + /// + /// Computes envelope of the IGeometry object. The envelope is defined as a minimal bounding box for a geometry. + /// + /// + /// Returns an object that specifies the minimal bounding box of the Geometry object. + /// + public abstract Envelope GetEnvelope(); + + /// + /// Gets collection of all of this IGeometry object + /// + /// the collection of all of this object + public abstract IEnumerable GetCoordinates(); } } diff --git a/src/SpatialLite.Core/Geometries/GeometryCollection.cs b/src/SpatialLite.Core/Geometries/GeometryCollection.cs index d2457de..2d2aa5e 100644 --- a/src/SpatialLite.Core/Geometries/GeometryCollection.cs +++ b/src/SpatialLite.Core/Geometries/GeometryCollection.cs @@ -27,33 +27,11 @@ public GeometryCollection() public GeometryCollection(IEnumerable geometries) : base() { _geometries = new List(geometries); - } - - /// - /// Gets a value indicating whether the this "/> has Z ordinates set. - /// - /// - /// Is3D returns true if any of the geometries contained in this GeometryCollection has Z ordinate set. - /// - public override bool Is3D { - get { - return _geometries.Any(geometry => geometry.Is3D); - } - } - - /// - /// Gets a value indicating whether this has M values. - /// - /// - /// IsMeasured returns true if any of the geometries in this GeometryCollection has M value set. - /// - public override bool IsMeasured { - get { return _geometries.Any(c => c.IsMeasured); } - } - - /// - /// Gets the list of IGeometry objects in this collection - /// + } + + /// + /// Gets the list of IGeometry objects in this collection + /// public List Geometries { get { return _geometries; diff --git a/src/SpatialLite.Core/Geometries/LineString.cs b/src/SpatialLite.Core/Geometries/LineString.cs index 7a9f164..aad4a6c 100644 --- a/src/SpatialLite.Core/Geometries/LineString.cs +++ b/src/SpatialLite.Core/Geometries/LineString.cs @@ -27,31 +27,11 @@ public LineString(IEnumerable coords) _coordinates = new CoordinateList(coords); } - /// - /// Gets a value indicating whether the this has Z-coordinates set. - /// - /// - /// Is3D returns true if any of the coordinates in this LineString has Z-coordinate set. - /// - public override bool Is3D { - get { return _coordinates.Any(c => c.Is3D); } - } - - /// - /// Gets a value indicating whether this has M values. - /// - /// - /// IsMeasured returns true if any of the coordinates in this LineString has M value set. - /// - public override bool IsMeasured { - get { return _coordinates.Any(c => c.IsMeasured); } - } - - /// - /// Gets the list of çoordinates that define this LisneString - /// - public virtual ICoordinateList Coordinates { - get { return _coordinates; } + /// + /// Gets the list of çoordinates that define this LisneString + /// + public virtual ICoordinateList Coordinates { + get { return _coordinates; } } /// diff --git a/src/SpatialLite.Core/Geometries/Point.cs b/src/SpatialLite.Core/Geometries/Point.cs index 6656f88..6a6fb0d 100644 --- a/src/SpatialLite.Core/Geometries/Point.cs +++ b/src/SpatialLite.Core/Geometries/Point.cs @@ -17,81 +17,44 @@ public Point() : base() { } - /// - /// Initializes a new instance of the Point class with specified X and Y coordinates in WSG84 coordinate reference system. - /// - /// The X-coordinate of the Point - /// The Y-coordinate of the Point - public Point(double x, double y) - : base() { - _position = new Coordinate(x, y); + /// + /// Initializes a new instance of the Point class with specified X and Y coordinates in WSG84 coordinate reference system. + /// + /// The X-coordinate of the Point + /// The Y-coordinate of the Point + public Point(double x, double y) + : base() { + _position = new Coordinate(x, y); + } + + /// + /// Initializes a new instance of the Point class with specific Position in WSG84 coordinate reference system. + /// + /// The position of this Point + public Point(Coordinate position) + : base() { + _position = position; } - /// - /// Initializes a new instance of the Point class with specified X, Y and Z coordinates in WSG84 coordinate reference system. - /// - /// The X-coordinate of the Point - /// The Y-coordinate of the Point - /// The Z-coordinate of the Point - public Point(double x, double y, double z) - : base() { - _position = new Coordinate(x, y, z); - } - - /// - /// Initializes a new instance of the Point class with specified X, Y, Z coordinates and M value in WSG84 coordinate reference system. - /// - /// The X-coordinate of the Point - /// The Y-coordinate of the Point - /// The Z-coordinate of the Point - /// The measured value of the Point - public Point(double x, double y, double z, double m) - : base() { - _position = new Coordinate(x, y, z, m); - } - - /// - /// Initializes a new instance of the Point class with specific Position in WSG84 coordinate reference system. - /// - /// The position of this Point - public Point(Coordinate position) - : base() { - _position = position; - } - - /// - /// Gets or sets position of this Point - /// - public Coordinate Position { - get { - return _position; - } - - set { - _position = value; - } - } - - /// - /// Gets a value indicating whether the this Point has Z-coordinate set. - /// - public override bool Is3D { - get { return _position.Is3D; } - } - - /// - /// Gets a value indicating whether the this Point has M value set. - /// - public override bool IsMeasured { - get { return _position.IsMeasured; } - } - - /// - /// Returns Envelope, that covers this Point. - /// - /// Envelope, that covers this Point. - public override Envelope GetEnvelope() { - return new Envelope(this.Position); + /// + /// Gets or sets position of this Point + /// + public Coordinate Position { + get { + return _position; + } + + set { + _position = value; + } + } + + /// + /// Returns Envelope, that covers this Point. + /// + /// Envelope, that covers this Point. + public override Envelope GetEnvelope() { + return new Envelope(this.Position); } /// diff --git a/src/SpatialLite.Core/Geometries/Polygon.cs b/src/SpatialLite.Core/Geometries/Polygon.cs index 507bf50..4c86e3e 100644 --- a/src/SpatialLite.Core/Geometries/Polygon.cs +++ b/src/SpatialLite.Core/Geometries/Polygon.cs @@ -48,30 +48,14 @@ ICoordinateList IPolygon.ExteriorRing { /// IEnumerable IPolygon.InteriorRings { get { return this.InteriorRings; } - } - - /// - /// Gets a value indicating whether the this has Z-coordinate set. - /// - public override bool Is3D { - //TODO consider using InteriorRings as well - get { return this.ExteriorRing != null && this.ExteriorRing.Any(c => c.Is3D); } - } - - /// - /// Gets a value indicating whether this has M values. - /// - public override bool IsMeasured { - //TODO consider using InteriorRings as well - get { return this.ExteriorRing != null && this.ExteriorRing.Any(c => c.IsMeasured); } - } - - /// - /// Computes envelope of the Polygon object. The envelope is defined as a minimal bounding box for a geometry. - /// - /// - /// Returns an object that specifies the minimal bounding box of the Polygon object. - /// + } + + /// + /// Computes envelope of the Polygon object. The envelope is defined as a minimal bounding box for a geometry. + /// + /// + /// Returns an object that specifies the minimal bounding box of the Polygon object. + /// public override Envelope GetEnvelope() { return this.ExteriorRing.Count == 0 ? new Envelope() : new Envelope(this.ExteriorRing); } diff --git a/src/SpatialLite.Core/IO/WkbReader.cs b/src/SpatialLite.Core/IO/WkbReader.cs index 0179683..c44d0f7 100644 --- a/src/SpatialLite.Core/IO/WkbReader.cs +++ b/src/SpatialLite.Core/IO/WkbReader.cs @@ -152,13 +152,19 @@ public T Read() where T : Geometry { /// Bool value indicating whether Coordinate has Z value. /// Bool value indicating whether Coordinate has M value. /// Parsed Coordinate. - private static Coordinate ReadCoordinate(BinaryReader reader, bool is3D, bool isMeasured) { - double x = reader.ReadDouble(); - double y = reader.ReadDouble(); - double z = is3D ? reader.ReadDouble() : double.NaN; - double m = isMeasured ? reader.ReadDouble() : double.NaN; - - return new Coordinate(x, y, z, m); + private static Coordinate ReadCoordinate(BinaryReader reader, bool is3D, bool isMeasured) { + double x = reader.ReadDouble(); + double y = reader.ReadDouble(); + + // Skip Z and M coordinates if they exist in the binary data + if (is3D) { + reader.ReadDouble(); // Skip Z + } + if (isMeasured) { + reader.ReadDouble(); // Skip M + } + + return new Coordinate(x, y); } /// diff --git a/src/SpatialLite.Core/IO/WkbWriter.cs b/src/SpatialLite.Core/IO/WkbWriter.cs index 703c8b3..d5b709d 100644 --- a/src/SpatialLite.Core/IO/WkbWriter.cs +++ b/src/SpatialLite.Core/IO/WkbWriter.cs @@ -143,17 +143,9 @@ private static void Write(IGeometry geometry, BinaryWriter writer) { /// /// The Coordinate to write. /// The BinaryWriter used to write geometry to the output. - private static void WriteCoordinate(Coordinate coordinate, BinaryWriter writer) { - writer.Write(coordinate.X); - writer.Write(coordinate.Y); - - if (coordinate.Is3D) { - writer.Write(coordinate.Z); - } - - if (coordinate.IsMeasured) { - writer.Write(coordinate.M); - } + private static void WriteCoordinate(Coordinate coordinate, BinaryWriter writer) { + writer.Write(coordinate.X); + writer.Write(coordinate.Y); } /// @@ -282,18 +274,8 @@ private static void WriteGeometryCollection(IGeometryCollection colle /// The geometry object. /// WkbGeometryType for the 2D, non-measured version of the geometry object. /// The WkbGeometryType of the geometry object. - private static WkbGeometryType AdjustGeometryType(IGeometry geometry, WkbGeometryType baseType) { - WkbGeometryType result = baseType; - - if (geometry.Is3D) { - result += 1000; - } - - if (geometry.IsMeasured) { - result += 2000; - } - - return result; + private static WkbGeometryType AdjustGeometryType(IGeometry geometry, WkbGeometryType baseType) { + return baseType; } /// diff --git a/src/SpatialLite.Core/IO/WktReader.cs b/src/SpatialLite.Core/IO/WktReader.cs index d9d96a2..a19b502 100644 --- a/src/SpatialLite.Core/IO/WktReader.cs +++ b/src/SpatialLite.Core/IO/WktReader.cs @@ -227,33 +227,27 @@ private static List ParsePoints(WktTokensBuffer tokens, bool is3D, bool i /// bool value indicating whether coordinate beeing parsed has m-value. /// A coordinate specified by tokens. /// {} {}]]> - private static Coordinate ParseCoordinate(WktTokensBuffer tokens, bool is3D, bool isMeasured) { - WktToken t = WktReader.Expect(TokenType.NUMBER, tokens); - double x = double.Parse(t.Value, _invarianCulture); - - WktReader.Expect(TokenType.WHITESPACE, tokens); - - t = WktReader.Expect(TokenType.NUMBER, tokens); - double y = double.Parse(t.Value, _invarianCulture); - - double z = double.NaN; - double m = double.NaN; - - if (is3D) { - WktReader.Expect(TokenType.WHITESPACE, tokens); - - t = WktReader.Expect(TokenType.NUMBER, tokens); - z = double.Parse(t.Value, _invarianCulture); - } - - if (isMeasured) { - WktReader.Expect(TokenType.WHITESPACE, tokens); - - t = WktReader.Expect(TokenType.NUMBER, tokens); - m = double.Parse(t.Value, _invarianCulture); - } - - return new Coordinate(x, y, z, m); + private static Coordinate ParseCoordinate(WktTokensBuffer tokens, bool is3D, bool isMeasured) { + WktToken t = WktReader.Expect(TokenType.NUMBER, tokens); + double x = double.Parse(t.Value, _invarianCulture); + + WktReader.Expect(TokenType.WHITESPACE, tokens); + + t = WktReader.Expect(TokenType.NUMBER, tokens); + double y = double.Parse(t.Value, _invarianCulture); + + // Skip Z and M values if they exist in the WKT data + if (is3D) { + WktReader.Expect(TokenType.WHITESPACE, tokens); + WktReader.Expect(TokenType.NUMBER, tokens); // Skip Z + } + + if (isMeasured) { + WktReader.Expect(TokenType.WHITESPACE, tokens); + WktReader.Expect(TokenType.NUMBER, tokens); // Skip M + } + + return new Coordinate(x, y); } /// diff --git a/src/SpatialLite.Core/IO/WktWriter.cs b/src/SpatialLite.Core/IO/WktWriter.cs index 3301000..2449390 100644 --- a/src/SpatialLite.Core/IO/WktWriter.cs +++ b/src/SpatialLite.Core/IO/WktWriter.cs @@ -127,17 +127,7 @@ protected static void Write(IGeometry geometry, TextWriter writer) { private static void AppendCoordinate(Coordinate coordinate, TextWriter writer) { writer.Write(coordinate.X.ToString(_invariantCulture)); writer.Write(' '); - writer.Write(coordinate.Y.ToString(_invariantCulture)); - - if (coordinate.Is3D) { - writer.Write(' '); - writer.Write(coordinate.Z.ToString(_invariantCulture)); - } - - if (coordinate.IsMeasured) { - writer.Write(' '); - writer.Write(coordinate.M.ToString(_invariantCulture)); - } + writer.Write(coordinate.Y.ToString(_invariantCulture)); } /// @@ -442,16 +432,8 @@ private static void AppendGeometryCollectionText(IGeometryCollection /// The geometry to examine. /// The string representing dimension of the geometry - empty string for 2D geometry, 'm' for measured geometry, 'z' for 3D geometry. private static string GetDimensionText(IGeometry geometry) { - string dimension = string.Empty; - - if (geometry.Is3D) { - dimension += "z"; - } - - if (geometry.IsMeasured) { - dimension += "m"; - } - + string dimension = string.Empty; + return dimension; } diff --git a/src/Tests.SpatialLite.Core/API/CoordinateTests.cs b/src/Tests.SpatialLite.Core/API/CoordinateTests.cs index 947e936..b2f86f8 100644 --- a/src/Tests.SpatialLite.Core/API/CoordinateTests.cs +++ b/src/Tests.SpatialLite.Core/API/CoordinateTests.cs @@ -16,82 +16,32 @@ public class CoordinateTests { double mValue = 100.4; [Fact] - public void Constructor_XY_SetsXYValuesAndZMNaN() { + public void Constructor_XY_SetsXYValues() { Coordinate target = new Coordinate(xCoordinate, yCoordinate); Assert.Equal(xCoordinate, target.X); Assert.Equal(yCoordinate, target.Y); - Assert.Equal(double.NaN, target.Z); - Assert.Equal(double.NaN, target.M); - } - - [Fact] - public void Constructor_XYZ_SetsXYZValuesAndMNaN() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate); - - Assert.Equal(xCoordinate, target.X); - Assert.Equal(yCoordinate, target.Y); - Assert.Equal(zCoordinate, target.Z); - Assert.Equal(double.NaN, target.M); - } - - [Fact] - public void Constructor_XYZM_SetsXYZMValues() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); - - Assert.Equal(xCoordinate, target.X); - Assert.Equal(yCoordinate, target.Y); - Assert.Equal(zCoordinate, target.Z); - Assert.Equal(mValue, target.M); - } - - [Fact] - public void Is3D_ReturnsFalseForNaNZCoordinate() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate); - - Assert.False(target.Is3D); - } - - [Fact] - public void Is3D_ReturnsTrueFor3D() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate); - - Assert.True(target.Is3D); - } - - [Fact] - public void IsMeasured_ReturnsFalseForNaNMCoordinate() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate); - - Assert.False(target.IsMeasured); - } - - [Fact] - public void IsMeasured_ReturnsTrueForMeasuredCoordinate() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); - - Assert.True(target.IsMeasured); } [Fact] public void Equals_ReturnsTrueForCoordinateWithTheSameOrdinates() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); - Coordinate other = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); + Coordinate target = new Coordinate(xCoordinate, yCoordinate); + Coordinate other = new Coordinate(xCoordinate, yCoordinate); Assert.True(target.Equals(other)); } [Fact] public void Equals_ReturnsTrueForNaNCoordinates() { - Coordinate target = new Coordinate(double.NaN, double.NaN, double.NaN, double.NaN); - Coordinate other = new Coordinate(double.NaN, double.NaN, double.NaN, double.NaN); + Coordinate target = new Coordinate(double.NaN, double.NaN); + Coordinate other = new Coordinate(double.NaN, double.NaN); Assert.True(target.Equals(other)); } [Fact] public void Equals_ReturnsFalseForNull() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); + Coordinate target = new Coordinate(xCoordinate, yCoordinate); object other = null; Assert.False(target.Equals(other)); @@ -99,7 +49,7 @@ public void Equals_ReturnsFalseForNull() { [Fact] public void Equals_ReturnsFalseForOtherObjectType() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); + Coordinate target = new Coordinate(xCoordinate, yCoordinate); object other = "string"; Assert.False(target.Equals(other)); @@ -107,88 +57,80 @@ public void Equals_ReturnsFalseForOtherObjectType() { [Fact] public void Equals_ReturnsFalseForCoordinateWithDifferentOrdinates() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); - Coordinate other = new Coordinate(xCoordinate + 1, yCoordinate + 1, zCoordinate + 1, mValue + 1); + Coordinate target = new Coordinate(xCoordinate, yCoordinate); + Coordinate other = new Coordinate(xCoordinate + 1, yCoordinate + 1); Assert.False(target.Equals(other)); } [Fact] public void Equals2D_ReturnsTrueForCoordinateWithTheSameOrdinates() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); - Coordinate other = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); - - Assert.True(target.Equals2D(other)); - } - - [Fact] - public void Equals2D_ReturnsTrueForCoordinateWithTheDifferentZMOrdinates() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); - Coordinate other = new Coordinate(xCoordinate, yCoordinate, zCoordinate + 1, mValue + 1); + Coordinate target = new Coordinate(xCoordinate, yCoordinate); + Coordinate other = new Coordinate(xCoordinate, yCoordinate); Assert.True(target.Equals2D(other)); } [Fact] public void Equals2D_ReturnsTrueForNaNCoordinates() { - Coordinate target = new Coordinate(double.NaN, double.NaN, double.NaN, double.NaN); - Coordinate other = new Coordinate(double.NaN, double.NaN, double.NaN, double.NaN); + Coordinate target = new Coordinate(double.NaN, double.NaN); + Coordinate other = new Coordinate(double.NaN, double.NaN); Assert.True(target.Equals2D(other)); } [Fact] public void Equals2D_ReturnsFalseForCoordinateWithDifferentXYOrdinates() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); - Coordinate other = new Coordinate(xCoordinate + 1, yCoordinate + 1, zCoordinate, mValue); + Coordinate target = new Coordinate(xCoordinate, yCoordinate); + Coordinate other = new Coordinate(xCoordinate + 1, yCoordinate + 1); Assert.False(target.Equals2D(other)); } [Fact] public void EqualsOperator_ReturnsTrueForCoordinateWithTheSameOrdinates() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); - Coordinate other = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); + Coordinate target = new Coordinate(xCoordinate, yCoordinate); + Coordinate other = new Coordinate(xCoordinate, yCoordinate); Assert.True(target == other); } [Fact] public void EqualsOperator_ReturnsTrueForNaNCoordinates() { - Coordinate target = new Coordinate(double.NaN, double.NaN, double.NaN, double.NaN); - Coordinate other = new Coordinate(double.NaN, double.NaN, double.NaN, double.NaN); + Coordinate target = new Coordinate(double.NaN, double.NaN); + Coordinate other = new Coordinate(double.NaN, double.NaN); Assert.True(target == other); } [Fact] public void EqualsOperator_ReturnsFalseForCoordinateWithDifferentOrdinates() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); - Coordinate other = new Coordinate(xCoordinate + 1, yCoordinate + 1, zCoordinate + 1, mValue + 1); + Coordinate target = new Coordinate(xCoordinate, yCoordinate); + Coordinate other = new Coordinate(xCoordinate + 1, yCoordinate + 1); Assert.False(target == other); } [Fact] public void NotEqualsOperator_ReturnsFalseForCoordinateWithTheSameOrdinates() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); - Coordinate other = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); + Coordinate target = new Coordinate(xCoordinate, yCoordinate); + Coordinate other = new Coordinate(xCoordinate, yCoordinate); Assert.False(target != other); } [Fact] public void NotEqualsOperator_ReturnsFalseForNaNCoordinates() { - Coordinate target = new Coordinate(double.NaN, double.NaN, double.NaN, double.NaN); - Coordinate other = new Coordinate(double.NaN, double.NaN, double.NaN, double.NaN); + Coordinate target = new Coordinate(double.NaN, double.NaN); + Coordinate other = new Coordinate(double.NaN, double.NaN); Assert.False(target != other); } [Fact] public void NotEqualsOperator_ReturnsTrueForCoordinateWithDifferentOrdinates() { - Coordinate target = new Coordinate(xCoordinate, yCoordinate, zCoordinate, mValue); - Coordinate other = new Coordinate(xCoordinate + 1, yCoordinate + 1, zCoordinate + 1, mValue + 1); + Coordinate target = new Coordinate(xCoordinate, yCoordinate); + Coordinate other = new Coordinate(xCoordinate + 1, yCoordinate + 1); Assert.True(target != other); }