using System; using System.Collections.Generic; using GeoAPI.Coordinates; using NPack; using NPack.Interfaces; namespace NetTopologySuite.Coordinates { using IVector2D = IVector; using IVectorD = IVector; public struct BufferedCoordinate : ICoordinate3D, ICoordinate, IBufferedVector, IEquatable, IComparable, IComputable { private readonly static Int32[] _ordTable2D = new Int32[] { 0, 1, -1, 2 }; private readonly Int32? _id; private readonly BufferedCoordinateFactory _factory; private readonly Boolean _isHomogeneous; private readonly Boolean _hasZ; //internal BufferedCoordinate(BufferedCoordinateFactory factory, Int32 index, Boolean hasZ) // : this(factory, index, hasZ, false) { } internal BufferedCoordinate(BufferedCoordinateFactory factory, Int32 index, Boolean hasZ, Boolean isHomogeneous) { _factory = factory; _id = index; _isHomogeneous = isHomogeneous; _hasZ = hasZ; } public BufferedCoordinate Clone() { return _factory.Create(this); } public Double Dot(BufferedCoordinate vector) { return _factory.Dot(this, vector); } public BufferedCoordinate Cross(BufferedCoordinate vector) { return _factory.Homogenize(_factory.Cross(this, vector)); } public override Boolean Equals(Object obj) { if (obj == null) { return false; } if (obj is BufferedCoordinate) { BufferedCoordinate other = (BufferedCoordinate)obj; return Equals(other); } ICoordinate2D coord2D = obj as ICoordinate2D; if (coord2D != null) { return ((ICoordinate2D)this).Equals(coord2D); } ICoordinate coord = obj as ICoordinate; if (coord != null) { return ((ICoordinate)this).Equals(coord); } IVectorD vector = obj as IVectorD; if (vector != null) { return ((IVectorD)this).Equals(coord); } IMatrix matrix = obj as IMatrix; if (matrix != null) { return ((IMatrix)this).Equals(coord); } return false; } public override String ToString() { if (IsEmpty) { return "Empty"; } return _isHomogeneous ? (_hasZ ? String.Format("({0}, {1}, {2}, {3})", X, Y, Z, W) : String.Format("({0}, {1}, {2})", X, Y, W)) : (_hasZ ? String.Format("({0}, {1}, {2})", X, Y, Z) : String.Format("({0}, {1})", X, Y)); } public override Int32 GetHashCode() { return _id.GetHashCode() ^ _isHomogeneous.GetHashCode() ^ _factory.GetHashCode(); } internal BufferedCoordinateFactory BufferedCoordinateFactory { get { return _factory; } } public ICoordinateFactory Factory { get { return _factory; } } internal static BufferedCoordinate Homogenize(BufferedCoordinate coordinate) { return !coordinate._id.HasValue ? coordinate : new BufferedCoordinate(coordinate._factory, coordinate._id.Value, coordinate._hasZ, true); } internal static BufferedCoordinate Dehomogenize(BufferedCoordinate coordinate) { return !coordinate._id.HasValue ? coordinate : new BufferedCoordinate(coordinate._factory, coordinate._id.Value, coordinate._hasZ, false); } #region IBufferedVector Members public IVectorBuffer GetBuffer() { return _factory; } public Int32 Index { get { return _id.Value; } } public Boolean ValueEquals(BufferedCoordinate other) { return IsEmpty == other.IsEmpty && _isHomogeneous == other._isHomogeneous && this[Ordinates.X] == other[Ordinates.X] && this[Ordinates.Y] == other[Ordinates.Y]; } #endregion #region ICoordinate3D Members public Double Z { get { return _id == null || !_hasZ ? Double.NaN : _factory.GetOrdinate(_id.Value, 2); } } public Double Distance(ICoordinate3D other) { throw new NotImplementedException(); } public void GetComponents(out Double x, out Double y, out Double z, out Double w) { x = Double.NaN; y = Double.NaN; z = Double.NaN; w = 1.0; if (!_id.HasValue) { return; } DoubleComponent x1, y1, z1, w1; _factory.GetComponents(_id.Value, out x1, out y1, out z1, out w1); x = (Double)x1; y = (Double)y1; z = _hasZ ? (Double)z1 : z; w = _isHomogeneous ? (Double)w1 : w; } #endregion #region ICoordinate2D Members public Double X { get { return _id == null ? Double.NaN : _factory.GetOrdinate(_id.Value, 0); } } public Double Y { get { return _id == null ? Double.NaN : _factory.GetOrdinate(_id.Value, 1); } } public Double W { get { return _id == null || !_isHomogeneous ? Double.NaN : _factory.GetOrdinate(_id.Value, _hasZ ? 3 : 2); } } public void GetComponents(out Double x, out Double y, out Double w) { DoubleComponent a, b, c; GetComponents(out a, out b, out c); x = (Double)a; y = (Double)b; w = (Double)c; } public void GetComponents(out DoubleComponent a, out DoubleComponent b) { DoubleComponent c; GetComponents(out a, out b, out c); } public void GetComponents(out DoubleComponent x, out DoubleComponent y, out DoubleComponent w) { x = Double.NaN; y = Double.NaN; w = 1.0; if (!_id.HasValue) { return; } DoubleComponent x1, y1, w1; _factory.GetComponents(_id.Value, out x1, out y1, out w1); x = x1; y = y1; w = _hasZ ? w1 : _isHomogeneous ? w1 : w; } public void GetComponents(out DoubleComponent a, out DoubleComponent b, out DoubleComponent c, out DoubleComponent d) { throw new System.NotImplementedException(); } public Double Distance(ICoordinate2D other) { throw new NotImplementedException(); } #endregion #region ICoordinate Members public Boolean ContainsOrdinate(Ordinates ordinate) { switch (ordinate) { case Ordinates.X: case Ordinates.Y: return true; case Ordinates.W: return _isHomogeneous; case Ordinates.Z: return _hasZ; default: return false; } } public Double Distance(ICoordinate other) { return Distance(_factory.Create(other)); } public Boolean IsEmpty { get { return _id == null; } } public Double this[Ordinates ordinate] { get { return _id == null ? Double.NaN : _factory.GetOrdinate(_id.Value, _hasZ ? (Int32)ordinate : _ordTable2D[(Int32)ordinate]); } } ICoordinate ICoordinate.Zero { get { return _factory.GetZero(); } } #endregion #region IEquatable Members Boolean IEquatable.Equals(ICoordinate other) { if (other is BufferedCoordinate) { return Equals((BufferedCoordinate)other); } if (other == null) { return false; } return other[Ordinates.X] == this[Ordinates.X] && other[Ordinates.Y] == this[Ordinates.Y]; } #endregion #region IComparable Members Int32 IComparable.CompareTo(ICoordinate other) { if (other == null) { return 1; } if (other.ComponentCount > ComponentCount) { return -1; } Int32 compare = X.CompareTo(other[Ordinates.X]); if (compare == 0) { compare = Y.CompareTo(other[Ordinates.Y]); } return compare; } #endregion #region IComparable Members Int32 IComparable.CompareTo(ICoordinate2D other) { if (other == null) { return 1; } Int32 compare = X.CompareTo(other.X); if (compare == 0) { compare = Y.CompareTo(other.Y); } return compare; } #endregion #region IEquatable Members Boolean IEquatable.Equals(ICoordinate2D other) { if (other == null) { return false; } return other.X == X && other.Y == Y; } #endregion #region IEquatable Members public Boolean Equals(BufferedCoordinate other) { return _id == other._id && _factory == other._factory; } #endregion #region IComparable Members public Int32 CompareTo(BufferedCoordinate other) { //jd: reinstated tests against empty coordinates as many unit tests rely on this if (_id == null && other._id == null) return 0; // Empty coordinates don't compare if (other._id == null) { return 1; //throw new ArgumentException("Cannot compare to the empty coordinate"); } if (_id == null) { return -1; //throw new InvalidOperationException( // "This coordinate is empty and cannot be compared"); } // Since the coordinates are stored in lexicograpic order, // the index comparison works to compare coordinates // first by X, then by Y; return _factory.Compare(this, other); } #endregion #region IComputable Members public BufferedCoordinate Abs() { return _factory.Create(Math.Abs(X), Math.Abs(Y)); } public BufferedCoordinate Set(Double value) { throw new NotSupportedException(); } #endregion #region INegatable Members public BufferedCoordinate Negative() { return _factory.Create(-X, -Y); } #endregion #region ISubtractable Members public BufferedCoordinate Subtract(BufferedCoordinate b) { return Add(b.Negative()); } #endregion #region IHasZero Members public BufferedCoordinate Zero { get { return _factory.GetZero(); } } #endregion #region IAddable Members public BufferedCoordinate Add(BufferedCoordinate b) { return _factory.Add(this, b); } #endregion #region IDivisible Members public BufferedCoordinate Divide(BufferedCoordinate b) { throw new NotSupportedException(); //return BufferedCoordinateFactory.Divide(this, b); } #endregion #region IDivisible Members public BufferedCoordinate Divide(Double b) { return _factory.Divide(this, b); } #endregion #region IHasOne Members public BufferedCoordinate One { get { return _factory.GetOne(); } } #endregion #region IMultipliable Members public BufferedCoordinate Multiply(BufferedCoordinate b) { return _factory.Cross(this, b); } #endregion #region IMultipliable Members public BufferedCoordinate Multiply(Double b) { return _factory.Create(X * b, Y * b); } #endregion #region IBooleanComparable Members public Boolean GreaterThan(BufferedCoordinate value) { return _factory.GreaterThan(this, value); } public Boolean GreaterThanOrEqualTo(BufferedCoordinate value) { return _factory.GreaterThanOrEqualTo(this, value); } public Boolean LessThan(BufferedCoordinate value) { return _factory.LessThan(this, value); } public Boolean LessThanOrEqualTo(BufferedCoordinate value) { return _factory.LessThanOrEqualTo(this, value); } #endregion #region IExponential Members public BufferedCoordinate Exp() { throw new NotImplementedException(); } public BufferedCoordinate Log() { throw new NotImplementedException(); } public BufferedCoordinate Log(Double newBase) { throw new NotImplementedException(); } public BufferedCoordinate Power(Double exponent) { throw new NotImplementedException(); } public BufferedCoordinate Sqrt() { throw new NotImplementedException(); } #endregion #region IComputable Members ICoordinate IComputable.Set(Double value) { throw new NotImplementedException(); } #endregion #region IComputable Members ICoordinate IComputable.Abs() { throw new NotImplementedException(); } ICoordinate IComputable.Set(Double value) { throw new NotImplementedException(); } #endregion #region INegatable Members ICoordinate INegatable.Negative() { throw new NotImplementedException(); } #endregion #region ISubtractable Members ICoordinate ISubtractable.Subtract(ICoordinate b) { throw new NotImplementedException(); } #endregion #region IHasZero Members ICoordinate IHasZero.Zero { get { throw new NotImplementedException(); } } #endregion #region IAddable Members ICoordinate IAddable.Add(ICoordinate b) { if (b is BufferedCoordinate) { return Add((BufferedCoordinate)b); } throw new NotImplementedException(); } #endregion #region IDivisible Members ICoordinate IDivisible.Divide(ICoordinate b) { throw new NotImplementedException(); } #endregion #region IHasOne Members ICoordinate IHasOne.One { get { return One; } } #endregion #region IMultipliable Members ICoordinate IMultipliable.Multiply(ICoordinate b) { throw new NotImplementedException(); } #endregion #region IBooleanComparable Members bool IBooleanComparable.GreaterThan(ICoordinate value) { throw new NotImplementedException(); } bool IBooleanComparable.GreaterThanOrEqualTo(ICoordinate value) { throw new NotImplementedException(); } bool IBooleanComparable.LessThan(ICoordinate value) { throw new NotImplementedException(); } bool IBooleanComparable.LessThanOrEqualTo(ICoordinate value) { throw new NotImplementedException(); } #endregion #region IExponential Members ICoordinate IExponential.Exp() { throw new NotImplementedException(); } ICoordinate IExponential.Log() { throw new NotImplementedException(); } ICoordinate IExponential.Log(Double newBase) { throw new NotImplementedException(); } ICoordinate IExponential.Power(Double exponent) { throw new NotImplementedException(); } ICoordinate IExponential.Sqrt() { throw new NotImplementedException(); } #endregion #region IMultipliable Members ICoordinate IMultipliable.Multiply(Double b) { throw new NotImplementedException(); } #endregion #region IDivisible Members ICoordinate IDivisible.Divide(Double b) { throw new NotImplementedException(); } #endregion #region ICoordinate Members //ICoordinate ICoordinate.Divide(Double value) //{ // return Divide(value); //} #endregion #region IVectorD Members public Int32 ComponentCount { get { return _isHomogeneous ? (_hasZ ? 4 : 3) : (_hasZ ? 3 : 2); } } DoubleComponent[] IVectorD.Components { get { return getComponents(); } set { throw new NotSupportedException(); } } IVectorD IVectorD.Negative() { return Negative(); } DoubleComponent IVectorD.this[Int32 index] { get { return this[index]; } set { this[index] = value; } } #endregion #region IMatrix Members IMatrix IMatrix.Clone() { return ((IVectorD)this).Clone(); } Int32 IMatrix.ColumnCount { get { throw new NotImplementedException(); } } Double IMatrix.Determinant { get { throw new NotImplementedException(); } } MatrixFormat IMatrix.Format { get { throw new NotImplementedException(); } } IMatrix IMatrix.GetMatrix(Int32[] rowIndexes, Int32 startColumn, Int32 endColumn) { throw new NotImplementedException(); } IMatrix IMatrix.Inverse { get { throw new InvalidOperationException("Inverse doesn't exist for this matrix."); } } Boolean IMatrix.IsInvertible { get { return false; } } Boolean IMatrix.IsSingular { get { return true; } } Boolean IMatrix.IsSquare { get { return false; } } Boolean IMatrix.IsSymmetrical { get { return false; } } Int32 IMatrix.RowCount { get { throw new NotImplementedException(); } } IMatrix IMatrix.Transpose() { throw new NotImplementedException(); } DoubleComponent IMatrix.this[Int32 row, Int32 column] { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } #endregion #region INegatable> Members IMatrix INegatable>.Negative() { return Negative(); } #endregion #region ISubtractable> Members IMatrix ISubtractable>.Subtract(IMatrix b) { throw new NotImplementedException(); } #endregion #region IHasZero> Members IMatrix IHasZero>.Zero { get { return Zero; } } #endregion #region IAddable> Members IMatrix IAddable>.Add(IMatrix b) { throw new NotImplementedException(); } #endregion #region IDivisible> Members IMatrix IDivisible>.Divide(IMatrix b) { throw new NotImplementedException(); } #endregion #region IHasOne> Members IMatrix IHasOne>.One { get { return One; } } #endregion #region IMultipliable> Members IMatrix IMultipliable>.Multiply(IMatrix b) { throw new NotImplementedException(); } #endregion #region IEquatable> Members Boolean IEquatable>.Equals(IMatrix other) { throw new NotImplementedException(); } #endregion #region IEnumerable Members public IEnumerator GetEnumerator() { yield return X; yield return Y; if (_isHomogeneous) { yield return this[Ordinates.W]; } } #endregion #region IEnumerable Members System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion #region INegatable Members IVectorD INegatable.Negative() { return _factory.Create(-X, -Y); } #endregion #region ISubtractable Members IVectorD ISubtractable.Subtract(IVectorD b) { throw new NotImplementedException(); } #endregion #region IHasZero Members IVectorD IHasZero.Zero { get { return Zero; } } #endregion #region IAddable Members IVectorD IAddable.Add(IVectorD b) { throw new NotImplementedException(); } #endregion #region IDivisible Members IVectorD IDivisible.Divide(IVectorD b) { throw new NotImplementedException(); } #endregion #region IHasOne Members IVectorD IHasOne.One { get { return One; } } #endregion #region IMultipliable Members IVectorD IMultipliable.Multiply(IVectorD b) { throw new NotImplementedException(); } #endregion #region IConvertible Members TypeCode IConvertible.GetTypeCode() { return TypeCode.Object; } Boolean IConvertible.ToBoolean(IFormatProvider provider) { throw new NotImplementedException(); } Byte IConvertible.ToByte(IFormatProvider provider) { throw new NotImplementedException(); } Char IConvertible.ToChar(IFormatProvider provider) { throw new NotImplementedException(); } DateTime IConvertible.ToDateTime(IFormatProvider provider) { throw new NotImplementedException(); } Decimal IConvertible.ToDecimal(IFormatProvider provider) { throw new NotImplementedException(); } Double IConvertible.ToDouble(IFormatProvider provider) { throw new NotImplementedException(); } Int16 IConvertible.ToInt16(IFormatProvider provider) { throw new NotImplementedException(); } Int32 IConvertible.ToInt32(IFormatProvider provider) { throw new NotImplementedException(); } Int64 IConvertible.ToInt64(IFormatProvider provider) { throw new NotImplementedException(); } SByte IConvertible.ToSByte(IFormatProvider provider) { throw new NotImplementedException(); } Single IConvertible.ToSingle(IFormatProvider provider) { throw new NotImplementedException(); } String IConvertible.ToString(IFormatProvider provider) { throw new NotImplementedException(); } Object IConvertible.ToType(Type conversionType, IFormatProvider provider) { throw new NotImplementedException(); } UInt16 IConvertible.ToUInt16(IFormatProvider provider) { throw new NotImplementedException(); } UInt32 IConvertible.ToUInt32(IFormatProvider provider) { throw new NotImplementedException(); } UInt64 IConvertible.ToUInt64(IFormatProvider provider) { throw new NotImplementedException(); } #endregion #region IComparable> Members Int32 IComparable>.CompareTo(IMatrix other) { throw new NotImplementedException(); } #endregion #region IComputable> Members IMatrix IComputable>.Abs() { throw new NotImplementedException(); } IMatrix IComputable>.Set(Double value) { throw new NotImplementedException(); } #endregion #region IBooleanComparable> Members Boolean IBooleanComparable>.GreaterThan(IMatrix value) { throw new NotImplementedException(); } Boolean IBooleanComparable>.GreaterThanOrEqualTo(IMatrix value) { throw new NotImplementedException(); } Boolean IBooleanComparable>.LessThan(IMatrix value) { throw new NotImplementedException(); } Boolean IBooleanComparable>.LessThanOrEqualTo(IMatrix value) { throw new NotImplementedException(); } #endregion #region IExponential> Members IMatrix IExponential>.Exp() { throw new NotImplementedException(); } IMatrix IExponential>.Log() { throw new NotImplementedException(); } IMatrix IExponential>.Log(Double newBase) { throw new NotImplementedException(); } IMatrix IExponential>.Power(Double exponent) { throw new NotImplementedException(); } IMatrix IExponential>.Sqrt() { throw new NotImplementedException(); } #endregion #region IComputable Members IVectorD IComputable.Abs() { throw new NotImplementedException(); } IVectorD IComputable.Set(Double value) { throw new NotImplementedException(); } #endregion #region IComputable Members IVectorD IComputable.Set(Double value) { throw new NotImplementedException(); } #endregion #region IBooleanComparable Members Boolean IBooleanComparable.GreaterThan(IVectorD value) { throw new NotImplementedException(); } Boolean IBooleanComparable.GreaterThanOrEqualTo(IVectorD value) { throw new NotImplementedException(); } Boolean IBooleanComparable.LessThan(IVectorD value) { throw new NotImplementedException(); } Boolean IBooleanComparable.LessThanOrEqualTo(IVectorD value) { throw new NotImplementedException(); } #endregion #region IExponential Members IVectorD IExponential.Exp() { throw new NotImplementedException(); } IVectorD IExponential.Log() { throw new NotImplementedException(); } IVectorD IExponential.Log(Double newBase) { throw new NotImplementedException(); } IVectorD IExponential.Power(Double exponent) { throw new NotImplementedException(); } IVectorD IExponential.Sqrt() { throw new NotImplementedException(); } #endregion #region IEquatable Members Boolean IEquatable.Equals(IVectorD other) { throw new NotImplementedException(); } #endregion #region IComparable Members Int32 IComparable.CompareTo(IVectorD other) { throw new NotImplementedException(); } #endregion #region IDivisible Members IVectorD IDivisible.Divide(Double b) { return _factory.Divide(this, b); } #endregion #region IMultipliable Members IVectorD IMultipliable.Multiply(Double b) { throw new NotImplementedException(); } #endregion #region IAddable Members public BufferedCoordinate Add(Double b) { return _factory.Add(this, b); } #endregion #region ISubtractable Members public BufferedCoordinate Subtract(Double b) { return _factory.Add(this, -b); } #endregion #region IAddable Members IVectorD IAddable.Add(Double b) { return Add(b); } #endregion #region ISubtractable Members IVectorD ISubtractable.Subtract(Double b) { return Subtract(b); } #endregion #region IAddable Members ICoordinate IAddable.Add(Double b) { return Add(b); } #endregion #region ISubtractable Members ICoordinate ISubtractable.Subtract(Double b) { return Subtract(b); } #endregion #region IVector2D Members DoubleComponent[] IVector2D.Components { get { return getComponents(); } set { throw new NotSupportedException(); } } public DoubleComponent this[Int32 index] { get { return _id == null ? Double.NaN : _factory.GetOrdinate(_id.Value, index); } set { throw new NotSupportedException(); } } #endregion #region IComputable Members IVector2D IComputable.Set(Double value) { throw new NotImplementedException(); } #endregion #region IComputable Members IVector2D IComputable.Abs() { throw new NotImplementedException(); } IVector2D IComputable.Set(Double value) { throw new NotImplementedException(); } #endregion #region INegatable Members IVector2D INegatable.Negative() { throw new NotImplementedException(); } #endregion #region ISubtractable Members public IVector2D Subtract(IVector2D b) { throw new NotImplementedException(); } #endregion #region IHasZero Members IVector2D IHasZero.Zero { get { throw new NotImplementedException(); } } #endregion #region IAddable Members public IVector2D Add(IVector2D b) { throw new NotImplementedException(); } #endregion #region IDivisible Members IVector2D IDivisible.Divide(IVector2D b) { throw new NotImplementedException(); } #endregion #region IHasOne Members IVector2D IHasOne.One { get { throw new NotImplementedException(); } } #endregion #region IMultipliable Members IVector2D IMultipliable.Multiply(IVector2D b) { throw new NotImplementedException(); } #endregion #region IBooleanComparable Members Boolean IBooleanComparable.GreaterThan(IVector2D value) { throw new NotImplementedException(); } Boolean IBooleanComparable.GreaterThanOrEqualTo(IVector2D value) { throw new NotImplementedException(); } Boolean IBooleanComparable.LessThan(IVector2D value) { throw new NotImplementedException(); } Boolean IBooleanComparable.LessThanOrEqualTo(IVector2D value) { throw new NotImplementedException(); } #endregion #region IExponential Members IVector2D IExponential.Exp() { throw new NotImplementedException(); } IVector2D IExponential.Log() { throw new NotImplementedException(); } IVector2D IExponential.Log(Double newBase) { throw new NotImplementedException(); } IVector2D IExponential.Power(Double exponent) { throw new NotImplementedException(); } IVector2D IExponential.Sqrt() { throw new NotImplementedException(); } #endregion #region IAddable> Members IVector2D IAddable.Add(Double b) { throw new NotImplementedException(); } #endregion #region ISubtractable> Members IVector2D ISubtractable.Subtract(Double b) { throw new NotImplementedException(); } #endregion #region IMultipliable> Members IVector2D IMultipliable.Multiply(Double b) { throw new NotImplementedException(); } #endregion #region IDivisible> Members IVector2D IDivisible.Divide(Double b) { throw new NotImplementedException(); } #endregion #region IEquatable Members Boolean IEquatable.Equals(IVector2D other) { throw new NotImplementedException(); } #endregion #region IComparable Members Int32 IComparable.CompareTo(IVector2D other) { throw new NotImplementedException(); } #endregion #region IVectorD Members IVectorD IVectorD.Clone() { return Clone(); } #endregion #region ICoordinate Members public Double Distance(BufferedCoordinate other) { return _factory.Distance(this, other); } DoubleComponent ICoordinate.this[Int32 index] { get { return this[index]; } } #endregion private DoubleComponent[] getComponents() { DoubleComponent x, y, z; if (!_hasZ) { GetComponents(out x, out y); return new[] { x, y, (DoubleComponent)1 }; } GetComponents(out x, out y, out z); return new[] {x, y, z, (DoubleComponent)1}; } #region IComparable Members public int CompareTo(ICoordinate3D other) { throw new NotImplementedException(); } #endregion #region IEquatable Members public bool Equals(ICoordinate3D other) { throw new NotImplementedException(); } #endregion } }