/// <summary> /// Normalizes a <c>LineString</c>. A normalized <c>LineString</c> /// has the first point which is not equal to it's reflected point /// less than the reflected point. /// </summary> public override void Normalize() { for (int i = 0; i < _points.Count / 2; i++) { int j = _points.Count - 1 - i; // skip equal points on both ends if (!_points.GetCoordinate(i).Equals(_points.GetCoordinate(j))) { if (_points.GetCoordinate(i).CompareTo(_points.GetCoordinate(j)) > 0) { var copy = _points.Copy(); CoordinateSequences.Reverse(copy); _points = copy; } return; } } }
/// <summary> /// Checks a coordinate sequence for equality with this /// </summary> /// <param name="other">The coordinate sequence to test</param> /// <returns><c>true</c> if the coordinates in the coordinate sequence are equal to those in this buffer.</returns> public bool Equals(CoordinateSequence other) { if (other == null) { return(false); } /* * if (other.Ordinates != DefinedOrdinates) * return false; */ if (other.Count != Count) { return(false); } bool checkZ = HasZ && other.HasZ; bool checkM = HasM && other.HasM; for (int i = 0; i < _coordinates.Count; i++) { var coord = _coordinates[i]; if (coord.X != other.GetX(i) || coord.Y != other.GetY(i)) { return(false); } if (checkZ && !coord.Z.Equals(other.GetZ(i))) { return(false); } if (checkM && !coord.M.Equals(other.GetM(i))) { return(false); } } return(true); }
/// <summary> /// Returns the index of the minimum coordinate of the whole /// coordinate sequence, using the usual lexicographic comparison. /// </summary> /// <param name="seq">The coordinate sequence to search</param> /// <returns>The index of the minimum coordinate in the sequence, found using <see cref="Coordinate.CompareTo(Coordinate)"/></returns> public static int MinCoordinateIndex(CoordinateSequence seq) { return(MinCoordinateIndex(seq, 0, seq.Count - 1)); }
private static CoordinateSequence CreateClosedRing(CoordinateSequenceFactory fact, CoordinateSequence seq, int size) { var newseq = fact.Create(size, seq.Dimension, seq.Measures); int n = seq.Count; Copy(seq, 0, newseq, 0, n); // fill remaining coordinates with start point for (int i = n; i < size; i++) { Copy(seq, 0, newseq, i, 1); } return(newseq); }
/// <summary> /// Ensures that a CoordinateSequence forms a valid ring, /// returning a new closed sequence of the correct length if required. /// If the input sequence is already a valid ring, it is returned /// without modification. /// If the input sequence is too short or is not closed, /// it is extended with one or more copies of the start point. /// </summary> /// <param name="fact">The CoordinateSequenceFactory to use to create the new sequence</param> /// <param name="seq">The sequence to test</param> /// <returns>The original sequence, if it was a valid ring, or a new sequence which is valid.</returns> public static CoordinateSequence EnsureValidRing(CoordinateSequenceFactory fact, CoordinateSequence seq) { int n = seq.Count; // empty sequence is valid if (n == 0) { return(seq); } // too short - make a new one if (n <= 3) { return(CreateClosedRing(fact, seq, 4)); } bool isClosed = seq.GetOrdinate(0, 0) == seq.GetOrdinate(n - 1, 0) && seq.GetOrdinate(0, 1) == seq.GetOrdinate(n - 1, 1); if (isClosed) { return(seq); } // make a new closed ring return(CreateClosedRing(fact, seq, n + 1)); }
public override IGeometry Reverse() { var sequence = CoordinateSequence.Reversed(); return(Factory.CreateLinearRing(sequence)); }
/// <summary> /// Ensures that a CoordinateSequence forms a valid ring, /// returning a new closed sequence of the correct length if required. /// If the input sequence is already a valid ring, it is returned /// without modification. /// If the input sequence is too short or is not closed, /// it is extended with one or more copies of the start point. /// </summary> /// <param name="fact">The CoordinateSequenceFactory to use to create the new sequence</param> /// <param name="seq">The sequence to test</param> /// <returns>The original sequence, if it was a valid ring, or a new sequence which is valid.</returns> public static CoordinateSequence EnsureValidRing(CoordinateSequenceFactory fact, CoordinateSequence seq) { var n = seq.Count; // empty sequence is valid if (n == 0) { return(seq); } // too short - make a new one if (n <= 3) { return(CreateClosedRing(fact, seq, 4)); } var isClosed = Math.Abs(seq.GetOrdinate(0, Ordinate.X) - seq.GetOrdinate(n - 1, Ordinate.X)) < double.Epsilon && Math.Abs(seq.GetOrdinate(0, Ordinate.Y) - seq.GetOrdinate(n - 1, Ordinate.Y)) < double.Epsilon; if (isClosed) { return(seq); } // make a new closed ring return(CreateClosedRing(fact, seq, n + 1)); }
/// <summary> /// Constructs a <c>Polygon</c> with the given exterior boundary. /// </summary> /// <param name="coordinates">the outer boundary of the new <c>Polygon</c>, or /// <c>null</c> or an empty <c>LinearRing</c> if /// the empty geometry is to be created.</param> /// <returns>A <see cref="Polygon"/> object</returns> /// <exception cref="ArgumentException">If the boundary ring is invalid</exception> public virtual Polygon CreatePolygon(CoordinateSequence coordinates) { return(CreatePolygon(CreateLinearRing(coordinates))); }
/// <inheritdoc/> /// <remarks> /// The <see cref="Polygon.ExteriorRing"/> is guaranteed to be orientated counter-clockwise. /// </remarks> public override Polygon CreatePolygon(CoordinateSequence coordinates) { var ring = CreateLinearRing(coordinates, true); return(base.CreatePolygon(ring)); }
/// <summary> /// Creates a <c>Point</c> using the given <c>CoordinateSequence</c>; a null or empty /// CoordinateSequence will create an empty Point. /// </summary> /// <param name="coordinates">a CoordinateSequence (possibly empty), or null</param> /// <returns>A <see cref="Point"/> object</returns> public Point CreatePoint(CoordinateSequence coordinates) { return(new Point(coordinates, this)); }
/// <inheritdoc cref="Geometry.CopyInternal"/>> protected override IGeometry CopyInternal() { return(new LinearRing(CoordinateSequence.Copy(), Factory)); }
/// <summary> /// Constructs a <c>LinearRing</c> with the vertices specified /// by the given <see cref="CoordinateSequence"/>. /// </summary> /// <param name="points">A sequence points forming a closed and simple linestring, /// or <c>null</c> to create the empty geometry.</param> /// <param name="factory">The factory that creates this <c>LinearRing</c></param> /// <exception cref="ArgumentException">If the ring is not closed, or has too few points</exception> public LinearRing(CoordinateSequence points, GeometryFactory factory) : base(points, factory) { ValidateConstruction(); }
public ReversedCoordinateSequence(CoordinateSequence inner) : base(inner.Count, inner.Dimension, inner.Measures) { _inner = inner; }
/// <summary> /// Creates a LineString using the given CoordinateSequence. /// A null or empty CoordinateSequence creates an empty LineString. /// </summary> /// <param name="coordinates">A CoordinateSequence (possibly empty), or null.</param> /// <returns>A <see cref="LineString"/> object</returns> public virtual LineString CreateLineString(CoordinateSequence coordinates) { return(new LineString(coordinates, this)); }
/// <summary> /// Shifts the positions of the coordinates until the coordinate at <c>firstCoordinateIndex</c> /// is first. /// </summary> /// <param name="seq">The coordinate sequence to rearrange</param> /// <param name="indexOfFirstCoordinate">The index of the coordinate to make first</param> public static void Scroll(CoordinateSequence seq, int indexOfFirstCoordinate) { Scroll(seq, indexOfFirstCoordinate, IsRing(seq)); }
/// <summary> /// Creates a <c>LinearRing</c> using the given <c>CoordinateSequence</c>; a null or empty CoordinateSequence /// creates an empty LinearRing. The points must form a closed and simple /// linestring. Consecutive points must not be equal. /// </summary> /// <param name="coordinates">A CoordinateSequence (possibly empty), or null.</param> /// <returns>A <see cref="LinearRing"/> object</returns> /// <exception cref="ArgumentException"> If the ring is not closed, or has too few points</exception> public LinearRing CreateLinearRing(CoordinateSequence coordinates) { return(new LinearRing(coordinates, this)); }
/// <summary> /// Creates and returns a full copy of this <see cref="ILinearRing"/> object. /// (including all coordinates contained by it). /// </summary> /// <returns>A copy of this instance</returns> public override IGeometry Copy() { return(new LinearRing(CoordinateSequence.Copy(), Factory)); }