Index: src/Common/NetTopologySuite/LinearReferencing/LinearLocation.cs =================================================================== diff -u -r8f6ae890fed8e8eae3a32f9c0498a10f82e0ddf9 -r5fc71a385897af92ccb092f2f969b5709afab85a --- src/Common/NetTopologySuite/LinearReferencing/LinearLocation.cs (.../LinearLocation.cs) (revision 8f6ae890fed8e8eae3a32f9c0498a10f82e0ddf9) +++ src/Common/NetTopologySuite/LinearReferencing/LinearLocation.cs (.../LinearLocation.cs) (revision 5fc71a385897af92ccb092f2f969b5709afab85a) @@ -14,65 +14,24 @@ public class LinearLocation : IComparable, IComparable, ICloneable { /// - /// Gets a location which refers to the end of a linear . + /// Initializes a new instance of the class: + /// creates a location referring to the start of a linear geometry. /// - /// The linear geometry. - /// A new LinearLocation. - public static LinearLocation GetEndLocation(IGeometry linear) + public LinearLocation() { - if (! (linear is ILineString || linear is IMultiLineString)) - { - string message = String.Format("Expected {0} or {1}, but was {2}", - typeof(ILineString), typeof(IMultiLineString), linear.GetType()); - throw new ArgumentException(message, "linear"); - } - LinearLocation loc = new LinearLocation(); - loc.SetToEnd(linear); - return loc; + SegmentFraction = 0.0; + SegmentIndex = 0; + ComponentIndex = 0; } /// - /// Computes the of a point a given fraction - /// along the line segment (p0, p1). - /// If the fraction is greater than 1.0 the last - /// point of the segment is returned. - /// If the fraction is less than or equal to 0.0 the first point - /// of the segment is returned. - /// - /// The first point of the line segment. - /// The last point of the line segment. - /// The length to the desired point. - /// - public static ICoordinate PointAlongSegmentByFraction(ICoordinate p0, ICoordinate p1, double fraction) - { - if (fraction <= 0.0) return p0; - if (fraction >= 1.0) return p1; - - double x = (p1.X - p0.X) * fraction + p0.X; - double y = (p1.Y - p0.Y) * fraction + p0.Y; - // interpolate Z value. If either input Z is NaN, result z will be NaN as well. - double z = (p1.Z - p0.Z) * fraction + p0.Z; - return new Coordinate(x, y, z); - } - - private int componentIndex = 0; - private int segmentIndex = 0; - private double segmentFraction = 0.0; - - /// /// Initializes a new instance of the class: /// creates a location referring to the start of a linear geometry. /// - public LinearLocation() { } - - /// - /// Initializes a new instance of the class: - /// creates a location referring to the start of a linear geometry. - /// /// Index of the segment. /// The segment fraction. public LinearLocation(int segmentIndex, double segmentFraction) : - this(0, segmentIndex, segmentFraction) { } + this(0, segmentIndex, segmentFraction) {} /// /// Initializes a new instance of the class: @@ -83,43 +42,85 @@ /// The segment fraction. public LinearLocation(int componentIndex, int segmentIndex, double segmentFraction) { - this.componentIndex = componentIndex; - this.segmentIndex = segmentIndex; - this.segmentFraction = segmentFraction; + ComponentIndex = componentIndex; + SegmentIndex = segmentIndex; + SegmentFraction = segmentFraction; Normalize(); } /// - /// Ensures the individual values are locally valid. - /// Does not ensure that the indexes are valid for - /// a particular linear geometry. + /// Gets the component index for this location. /// - private void Normalize() + public int ComponentIndex { get; private set; } + + /// + /// Gets the segment index for this location. + /// + public int SegmentIndex { get; private set; } + + /// + /// Gets the segment fraction for this location. + /// + public double SegmentFraction { get; private set; } + + /// + /// Tests whether this location refers to a vertex: + /// returns true if the location is a vertex. + /// + public bool IsVertex { - if (segmentFraction < 0.0) - segmentFraction = 0.0; - - if (segmentFraction > 1.0) - segmentFraction = 1.0; - - if (componentIndex < 0) + get { - componentIndex = 0; - segmentIndex = 0; - segmentFraction = 0.0; + return SegmentFraction <= 0.0 || SegmentFraction >= 1.0; } + } - if (segmentIndex < 0) + /// + /// Gets a location which refers to the end of a linear . + /// + /// The linear geometry. + /// A new LinearLocation. + public static LinearLocation GetEndLocation(IGeometry linear) + { + if (!(linear is ILineString || linear is IMultiLineString)) { - segmentIndex = 0; - segmentFraction = 0.0; + string message = String.Format("Expected {0} or {1}, but was {2}", + typeof(ILineString), typeof(IMultiLineString), linear.GetType()); + throw new ArgumentException(message, "linear"); } + LinearLocation loc = new LinearLocation(); + loc.SetToEnd(linear); + return loc; + } - if (segmentFraction == 1.0) + /// + /// Computes the of a point a given fraction + /// along the line segment (p0, p1). + /// If the fraction is greater than 1.0 the last + /// point of the segment is returned. + /// If the fraction is less than or equal to 0.0 the first point + /// of the segment is returned. + /// + /// The first point of the line segment. + /// The last point of the line segment. + /// The length to the desired point. + /// + public static ICoordinate PointAlongSegmentByFraction(ICoordinate p0, ICoordinate p1, double fraction) + { + if (fraction <= 0.0) { - segmentFraction = 0.0; - segmentIndex += 1; + return p0; } + if (fraction >= 1.0) + { + return p1; + } + + double x = (p1.X - p0.X)*fraction + p0.X; + double y = (p1.Y - p0.Y)*fraction + p0.Y; + // interpolate Z value. If either input Z is NaN, result z will be NaN as well. + double z = (p1.Z - p0.Z)*fraction + p0.Z; + return new Coordinate(x, y, z); } /// @@ -128,17 +129,17 @@ /// A linear geometry. public void Clamp(IGeometry linear) { - if (componentIndex >= linear.NumGeometries) + if (ComponentIndex >= linear.NumGeometries) { SetToEnd(linear); return; } - if (segmentIndex >= linear.NumPoints) + if (SegmentIndex >= linear.NumPoints) { - ILineString line = (ILineString) linear.GetGeometryN(componentIndex); - segmentIndex = line.NumPoints - 1; - segmentFraction = 1.0; + ILineString line = (ILineString) linear.GetGeometryN(ComponentIndex); + SegmentIndex = line.NumPoints - 1; + SegmentFraction = 1.0; } } @@ -151,19 +152,25 @@ /// The minimum allowable distance to a vertex. public void SnapToVertex(IGeometry linearGeom, double minDistance) { - if (segmentFraction <= 0.0 || segmentFraction >= 1.0) + if (SegmentFraction <= 0.0 || SegmentFraction >= 1.0) + { return; + } double segLen = GetSegmentLength(linearGeom); - double lenToStart = segmentFraction * segLen; + double lenToStart = SegmentFraction*segLen; double lenToEnd = segLen - lenToStart; - + if (lenToStart <= lenToEnd && lenToStart < minDistance) - segmentFraction = 0.0; + { + SegmentFraction = 0.0; + } else if (lenToEnd <= lenToStart && lenToEnd < minDistance) - segmentFraction = 1.0; + { + SegmentFraction = 1.0; + } } - + /// /// Gets the length of the segment in the given /// Geometry containing this location. @@ -172,12 +179,14 @@ /// The length of the segment. public double GetSegmentLength(IGeometry linearGeom) { - ILineString lineComp = (ILineString) linearGeom.GetGeometryN(componentIndex); + ILineString lineComp = (ILineString) linearGeom.GetGeometryN(ComponentIndex); // ensure segment index is valid - int segIndex = segmentIndex; - if (segmentIndex >= lineComp.NumPoints - 1) + int segIndex = SegmentIndex; + if (SegmentIndex >= lineComp.NumPoints - 1) + { segIndex = lineComp.NumPoints - 2; + } ICoordinate p0 = lineComp.GetCoordinateN(segIndex); ICoordinate p1 = lineComp.GetCoordinateN(segIndex + 1); @@ -191,58 +200,13 @@ /// The linear geometry to set. public void SetToEnd(IGeometry linear) { - componentIndex = linear.NumGeometries - 1; - ILineString lastLine = (ILineString) linear.GetGeometryN(componentIndex); - segmentIndex = lastLine.NumPoints - 1; - segmentFraction = 1.0; + ComponentIndex = linear.NumGeometries - 1; + ILineString lastLine = (ILineString) linear.GetGeometryN(ComponentIndex); + SegmentIndex = lastLine.NumPoints - 1; + SegmentFraction = 1.0; } - - /// - /// Gets the component index for this location. - /// - public int ComponentIndex - { - get - { - return componentIndex; - } - } /// - /// Gets the segment index for this location. - /// - public int SegmentIndex - { - get - { - return segmentIndex; - } - } - - /// - /// Gets the segment fraction for this location. - /// - public double SegmentFraction - { - get - { - return segmentFraction; - } - } - - /// - /// Tests whether this location refers to a vertex: - /// returns true if the location is a vertex. - /// - public bool IsVertex - { - get - { - return segmentFraction <= 0.0 || segmentFraction >= 1.0; - } - } - - /// /// Gets the along the /// given linear which is /// referenced by this location. @@ -251,12 +215,14 @@ /// The at the location. public ICoordinate GetCoordinate(IGeometry linearGeom) { - ILineString lineComp = (ILineString) linearGeom.GetGeometryN(componentIndex); - ICoordinate p0 = lineComp.GetCoordinateN(segmentIndex); - if (segmentIndex >= lineComp.NumPoints - 1) + ILineString lineComp = (ILineString) linearGeom.GetGeometryN(ComponentIndex); + ICoordinate p0 = lineComp.GetCoordinateN(SegmentIndex); + if (SegmentIndex >= lineComp.NumPoints - 1) + { return p0; - ICoordinate p1 = lineComp.GetCoordinateN(segmentIndex + 1); - return PointAlongSegmentByFraction(p0, p1, segmentFraction); + } + ICoordinate p1 = lineComp.GetCoordinateN(SegmentIndex + 1); + return PointAlongSegmentByFraction(p0, p1, SegmentFraction); } /// @@ -267,67 +233,27 @@ /// true if this location is valid. public bool IsValid(IGeometry linearGeom) { - if (componentIndex < 0 || componentIndex >= linearGeom.NumGeometries) + if (ComponentIndex < 0 || ComponentIndex >= linearGeom.NumGeometries) + { return false; - ILineString lineComp = (ILineString) linearGeom.GetGeometryN(componentIndex); - if (segmentIndex < 0 || segmentIndex > lineComp.NumPoints) + } + ILineString lineComp = (ILineString) linearGeom.GetGeometryN(ComponentIndex); + if (SegmentIndex < 0 || SegmentIndex > lineComp.NumPoints) + { return false; - if (segmentIndex == lineComp.NumPoints && segmentFraction != 0.0) + } + if (SegmentIndex == lineComp.NumPoints && SegmentFraction != 0.0) + { return false; - if (segmentFraction < 0.0 || segmentFraction > 1.0) + } + if (SegmentFraction < 0.0 || SegmentFraction > 1.0) + { return false; + } return true; } /// - /// Compares the current instance with another object of the same type. - /// - /// - /// The LineStringLocation with which this - /// Coordinate is being compared. - /// - /// - /// A negative integer, zero, or a positive integer as this - /// LineStringLocation is less than, equal to, - /// or greater than the specified LineStringLocation. - /// - /// - /// is not the same type as this instance. - /// - public int CompareTo(object obj) - { - LinearLocation other = (LinearLocation) obj; - return CompareTo(other); - } - - /// - /// Compares the current instance with another object of the same type. - /// - /// - /// The LineStringLocation with which this - /// Coordinate is being compared. - /// - /// - /// A negative integer, zero, or a positive integer as this - /// LineStringLocation is less than, equal to, - /// or greater than the specified LineStringLocation. - /// - public int CompareTo(LinearLocation other) - { - // compare component indices - if (componentIndex < other.ComponentIndex) return -1; - if (componentIndex > other.ComponentIndex) return 1; - // compare segments - if (segmentIndex < other.SegmentIndex) return -1; - if (segmentIndex > other.SegmentIndex) return 1; - // same segment, so compare segment fraction - if (segmentFraction < other.SegmentFraction) return -1; - if (segmentFraction > other.SegmentFraction) return 1; - // same location - return 0; - } - - /// /// Compares this object with the specified index values for order. /// /// The component index. @@ -340,14 +266,32 @@ public int CompareLocationValues(int componentIndex1, int segmentIndex1, double segmentFraction1) { // compare component indices - if (componentIndex < componentIndex1) return -1; - if (componentIndex > componentIndex1) return 1; + if (ComponentIndex < componentIndex1) + { + return -1; + } + if (ComponentIndex > componentIndex1) + { + return 1; + } // compare segments - if (segmentIndex < segmentIndex1) return -1; - if (segmentIndex > segmentIndex1) return 1; + if (SegmentIndex < segmentIndex1) + { + return -1; + } + if (SegmentIndex > segmentIndex1) + { + return 1; + } // same segment, so compare segment fraction - if (segmentFraction < segmentFraction1) return -1; - if (segmentFraction > segmentFraction1) return 1; + if (SegmentFraction < segmentFraction1) + { + return -1; + } + if (SegmentFraction > segmentFraction1) + { + return 1; + } // same location return 0; } @@ -371,25 +315,146 @@ int componentIndex1, int segmentIndex1, double segmentFraction1) { // compare component indices - if (componentIndex0 < componentIndex1) return -1; - if (componentIndex0 > componentIndex1) return 1; + if (componentIndex0 < componentIndex1) + { + return -1; + } + if (componentIndex0 > componentIndex1) + { + return 1; + } // compare segments - if (segmentIndex0 < segmentIndex1) return -1; - if (segmentIndex0 > segmentIndex1) return 1; + if (segmentIndex0 < segmentIndex1) + { + return -1; + } + if (segmentIndex0 > segmentIndex1) + { + return 1; + } // same segment, so compare segment fraction - if (segmentFraction0 < segmentFraction1) return -1; - if (segmentFraction0 > segmentFraction1) return 1; + if (segmentFraction0 < segmentFraction1) + { + return -1; + } + if (segmentFraction0 > segmentFraction1) + { + return 1; + } // same location return 0; } - + /// /// Copies this location. /// /// A copy of this location. public object Clone() { - return new LinearLocation(segmentIndex, segmentFraction); + return new LinearLocation(SegmentIndex, SegmentFraction); } + + /// + /// Compares the current instance with another object of the same type. + /// + /// + /// The LineStringLocation with which this + /// Coordinate is being compared. + /// + /// + /// A negative integer, zero, or a positive integer as this + /// LineStringLocation is less than, equal to, + /// or greater than the specified LineStringLocation. + /// + /// + /// is not the same type as this instance. + /// + public int CompareTo(object obj) + { + LinearLocation other = (LinearLocation) obj; + return CompareTo(other); + } + + /// + /// Compares the current instance with another object of the same type. + /// + /// + /// The LineStringLocation with which this + /// Coordinate is being compared. + /// + /// + /// A negative integer, zero, or a positive integer as this + /// LineStringLocation is less than, equal to, + /// or greater than the specified LineStringLocation. + /// + public int CompareTo(LinearLocation other) + { + // compare component indices + if (ComponentIndex < other.ComponentIndex) + { + return -1; + } + if (ComponentIndex > other.ComponentIndex) + { + return 1; + } + // compare segments + if (SegmentIndex < other.SegmentIndex) + { + return -1; + } + if (SegmentIndex > other.SegmentIndex) + { + return 1; + } + // same segment, so compare segment fraction + if (SegmentFraction < other.SegmentFraction) + { + return -1; + } + if (SegmentFraction > other.SegmentFraction) + { + return 1; + } + // same location + return 0; + } + + /// + /// Ensures the individual values are locally valid. + /// Does not ensure that the indexes are valid for + /// a particular linear geometry. + /// + private void Normalize() + { + if (SegmentFraction < 0.0) + { + SegmentFraction = 0.0; + } + + if (SegmentFraction > 1.0) + { + SegmentFraction = 1.0; + } + + if (ComponentIndex < 0) + { + ComponentIndex = 0; + SegmentIndex = 0; + SegmentFraction = 0.0; + } + + if (SegmentIndex < 0) + { + SegmentIndex = 0; + SegmentFraction = 0.0; + } + + if (SegmentFraction == 1.0) + { + SegmentFraction = 0.0; + SegmentIndex += 1; + } + } } -} +} \ No newline at end of file