using System; using System.Text; using GeoAPI.Geometries; namespace GisSharpBlog.NetTopologySuite.Geometries { /// /// The ICoordinateSequence implementation that Geometrys use by default. /// In this implementation, Coordinates returned by ToArray and Coordinate are live -- /// modifications to them are actually changing the /// CoordinateSequence's underlying data. /// [Serializable] public class CoordinateArraySequence : ICoordinateSequence { protected ICoordinate[] coordinates; /// /// Constructs a sequence based on the given array (the array is not copied). /// /// The coordinate array that will be referenced. public CoordinateArraySequence(ICoordinate[] coordinates) { this.coordinates = coordinates; if (coordinates == null) this.coordinates = new ICoordinate[0]; } /// /// Constructs a sequence of a given size, populated with new Coordinates. /// /// The size of the sequence to create. public CoordinateArraySequence(int size) { coordinates = new ICoordinate[size]; for (int i = 0; i < size; i++) coordinates[i] = new Coordinate(); } /// /// Constructs a sequence based on the given array (the array is not copied). /// /// The coordinate array that will be referenced. public CoordinateArraySequence(ICoordinateSequence coordSeq) { if (coordSeq != null) coordinates = new ICoordinate[coordSeq.Count]; else coordinates = new ICoordinate[0]; for (int i = 0; i < coordinates.Length; i++) coordinates[i] = coordSeq.GetCoordinateCopy(i); } /// /// Returns the dimension (number of ordinates in each coordinate) for this sequence. /// /// public int Dimension { get { return 3; } } /// /// Get the Coordinate with index i. /// /// The index of the coordinate. /// The requested Coordinate instance. public ICoordinate GetCoordinate(int i) { return coordinates[i]; } /// /// Get a copy of the Coordinate with index i. /// /// The index of the coordinate. /// A copy of the requested Coordinate. public virtual ICoordinate GetCoordinateCopy(int i) { return new Coordinate(coordinates[i]); } /// /// Copies the i'th coordinate in the sequence to the supplied Coordinate. /// Only the first two dimensions are copied. /// /// The index of the coordinate to copy. /// A Coordinate to receive the value. public void GetCoordinate(int index, ICoordinate coord) { coord.X = coordinates[index].X; coord.Y = coordinates[index].Y; } /// /// Returns ordinate X (0) of the specified coordinate. /// /// /// /// The value of the X ordinate in the index'th coordinate. /// public double GetX(int index) { return coordinates[index].X; } /// /// Returns ordinate Y (1) of the specified coordinate. /// /// /// /// The value of the Y ordinate in the index'th coordinate. /// public double GetY(int index) { return coordinates[index].Y; } /// /// Returns the ordinate of a coordinate in this sequence. /// Ordinate indices 0 and 1 are assumed to be X and Y. /// Ordinates indices greater than 1 have user-defined semantics /// (for instance, they may contain other dimensions or measure values). /// /// The coordinate index in the sequence. /// The ordinate index in the coordinate (in range [0, dimension-1]). /// public double GetOrdinate(int index, Ordinates ordinate) { switch (ordinate) { case Ordinates.X: return coordinates[index].X; case Ordinates.Y: return coordinates[index].Y; case Ordinates.Z: return coordinates[index].Z; default: return Double.NaN; } } /// /// Creates a deep copy of the object. /// /// The deep copy. public virtual object Clone() { ICoordinate[] cloneCoordinates = GetClonedCoordinates(); return new CoordinateArraySequence(cloneCoordinates); } /// /// /// /// protected ICoordinate[] GetClonedCoordinates() { ICoordinate[] cloneCoordinates = new ICoordinate[Count]; for (int i = 0; i < coordinates.Length; i++) cloneCoordinates[i] = (ICoordinate) coordinates[i].Clone(); return cloneCoordinates; } /// /// Returns the length of the coordinate sequence. /// public int Count { get { return coordinates.Length; } } /// /// Sets the value for a given ordinate of a coordinate in this sequence. /// /// The coordinate index in the sequence. /// The ordinate index in the coordinate (in range [0, dimension-1]). /// The new ordinate value. public void SetOrdinate(int index, Ordinates ordinate, double value) { switch (ordinate) { case Ordinates.X: coordinates[index].X = value; break; case Ordinates.Y: coordinates[index].Y = value; break; case Ordinates.Z: coordinates[index].Z = value; break; default: throw new ArgumentException("invalid ordinate index: " + ordinate); } } /// ///This method exposes the internal Array of Coordinate Objects. /// /// public ICoordinate[] ToCoordinateArray() { return coordinates; } /// /// Expands the given Envelope to include the coordinates in the sequence. /// Allows implementing classes to optimize access to coordinate values. /// /// The envelope to expand. /// A reference to the expanded envelope. public IEnvelope ExpandEnvelope(IEnvelope env) { for (int i = 0; i < coordinates.Length; i++ ) env.ExpandToInclude(coordinates[i]); return env; } /// /// Returns the string representation of the coordinate array. /// /// public override string ToString() { if (coordinates.Length > 0) { StringBuilder strBuf = new StringBuilder(17 * coordinates.Length); strBuf.Append('('); strBuf.Append(coordinates[0]); for (int i = 1; i < coordinates.Length; i++) { strBuf.Append(", "); strBuf.Append(coordinates[i]); } strBuf.Append(')'); return strBuf.ToString(); } else return "()"; } } }