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 "()";
}
}
}