/// <summary> /// /// </summary> /// <param name="seq">The coordinate sequence</param> public void Filter(ICoordinateSequence seq, int i) { var xp = seq.GetOrdinate(i, Ordinate.X) + _trans.X; var yp = seq.GetOrdinate(i, Ordinate.Y) + _trans.Y; seq.SetOrdinate(i, Ordinate.X, xp); seq.SetOrdinate(i, Ordinate.Y, yp); }
/// <summary> /// Applies this transformation to the i'th coordinate /// in the given CoordinateSequence. /// </summary> ///<param name="seq"> a <code>CoordinateSequence</code></param> ///<param name="i"> the index of the coordinate to transform</param> public void Transform(ICoordinateSequence seq, int i) { double xp = _m00 * seq.GetOrdinate(i, Ordinate.X) + _m01 * seq.GetOrdinate(i, Ordinate.Y) + _m02; double yp = _m10 * seq.GetOrdinate(i, Ordinate.X) + _m11 * seq.GetOrdinate(i, Ordinate.Y) + _m12; seq.SetOrdinate(i, Ordinate.X, xp); seq.SetOrdinate(i, Ordinate.Y, yp); }
/// <summary> /// Creates a sequence based on the given coordinate sequence. /// </summary> /// <param name="coordSeq">The coordinate sequence.</param> /// <param name="ordinates">The ordinates to copy</param> public DotSpatialAffineCoordinateSequence(ICoordinateSequence coordSeq, Ordinates ordinates) { var count = coordSeq.Count; _xy = new double[2 * count]; if ((ordinates & Ordinates.Z) == Ordinates.Z) { _z = new double[count]; } if ((ordinates & Ordinates.M) == Ordinates.M) { _m = new double[count]; } var dsCoordSeq = coordSeq as DotSpatialAffineCoordinateSequence; if (dsCoordSeq != null) { double[] nullOrdinateArray = null; Buffer.BlockCopy(dsCoordSeq._xy, 0, _xy, 0, 16 * count); if ((ordinates & Ordinates.Z) == Ordinates.Z) { var copyOrdinateArray = dsCoordSeq.Z != null ? dsCoordSeq.Z : nullOrdinateArray = NullOrdinateArray(count); Buffer.BlockCopy(copyOrdinateArray, 0, _z, 0, 8 * count); } if ((ordinates & Ordinates.M) == Ordinates.M) { var copyOrdinateArray = dsCoordSeq.M != null ? dsCoordSeq.M : nullOrdinateArray ?? NullOrdinateArray(count); Buffer.BlockCopy(copyOrdinateArray, 0, _m, 0, 8 * count); } _ordinates = ordinates; return; } var j = 0; for (var i = 0; i < coordSeq.Count; i++) { _xy[j++] = coordSeq.GetX(i); _xy[j++] = coordSeq.GetY(i); if (_z != null) { _z[i] = coordSeq.GetOrdinate(i, Ordinate.Z); } if (_m != null) { _m[i] = coordSeq.GetOrdinate(i, Ordinate.M); } } }
public WpfPoint[] Transform(ICoordinateSequence modelSequence) { var res = new WpfPoint[modelSequence.Count]; for (var i = 0; i < modelSequence.Count; i++) { res[i] = Transform(modelSequence.GetOrdinate(i, Ordinate.X), modelSequence.GetOrdinate(i, Ordinate.Y)); } return res; }
/// <summary> /// Tests for equality using all supported accessors, /// to provides test coverage for them. /// </summary> /// <param name="seq"></param> /// <param name="coords"></param> /// <returns></returns> bool IsEqual(ICoordinateSequence seq, Coordinate[] coords) { if (seq.Count != coords.Length) { return(false); } Coordinate p = new Coordinate(); for (int i = 0; i < seq.Count; i++) { if (!coords[i].Equals(seq.GetCoordinate(i))) { return(false); } // Ordinate named getters if (coords[i].X != seq.GetX(i)) { return(false); } if (coords[i].Y != seq.GetY(i)) { return(false); } // Ordinate indexed getters if (coords[i].X != seq.GetOrdinate(i, Ordinate.X)) { return(false); } if (coords[i].Y != seq.GetOrdinate(i, Ordinate.Y)) { return(false); } if (coords[i].Z != seq.GetOrdinate(i, Ordinate.Z)) { return(false); } // Coordinate getter seq.GetCoordinate(i, p); if (coords[i].X != p.X) { return(false); } if (coords[i].Y != p.Y) { return(false); } //TODO: Remove commented line below when NTS supports Z ordinates in CoordinateArraySequence.GetCoordinate and PackedCoordinateSequence.GetCoordinate //if (coords[i].Z != p.Z) return false; } return(true); }
/// <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(ICoordinateSequence other) { if (other == null) { return(false); } /* * if (other.Ordinates != DefinedOrdinates) * return false; */ if (other.Count != Count) { return(false); } for (var i = 0; i < _coordinates.Count; i++) { if (_coordinates[i][0] != other.GetOrdinate(i, Ordinate.X) || _coordinates[i][1] != other.GetOrdinate(i, Ordinate.Y)) { return(false); } if (HasZ) { if ((other.Ordinates & Ordinates.Z) == Ordinates.Z) { if (!_coordinates[i][2].Equals(other.GetOrdinate(i, Ordinate.Z))) { return(false); } } if (HasM && (other.Ordinates & Ordinates.M) == Ordinates.M) { if (!_coordinates[i][3].Equals(other.GetOrdinate(i, Ordinate.M))) { return(false); } } } else { if (HasM && (other.Ordinates & Ordinates.Z) == Ordinates.Z) { if (!_coordinates[i][3].Equals(other.GetOrdinate(i, Ordinate.Z))) { return(false); } } } } return(true); }
public void Filter(ICoordinateSequence seq, int i) { var result = _transform.Transform( new[] { seq.GetOrdinate(i, Ordinate.X), seq.GetOrdinate(i, Ordinate.Y) }); seq.SetOrdinate(i, Ordinate.X, result[0]); seq.SetOrdinate(i, Ordinate.Y, result[1]); }
public WpfPoint[] Transform(ICoordinateSequence modelSequence) { var res = new WpfPoint[modelSequence.Count]; for (var i = 0; i < modelSequence.Count; i++) { res[i] = Transform(modelSequence.GetOrdinate(i, Ordinate.X), modelSequence.GetOrdinate(i, Ordinate.Y)); } return(res); }
/// <summary> /// Returns the index of <c>coordinate</c> in a <see cref="ICoordinateSequence"/> /// The first position is 0; the second, 1; etc. /// </summary> /// <param name="coordinate">The <c>Coordinate</c> to search for</param> /// <param name="seq">The coordinate sequence to search</param> /// <returns> /// The position of <c>coordinate</c>, or -1 if it is not found /// </returns> public static int IndexOf(Coordinate coordinate, ICoordinateSequence seq) { for (int i = 0; i < seq.Count; i++) { if (coordinate.X == seq.GetOrdinate(i, Ordinate.X) && coordinate.Y == seq.GetOrdinate(i, Ordinate.Y)) { return(i); } } return(-1); }
/// <summary> /// Swaps two coordinates in a sequence. /// </summary> /// <param name="seq"></param> /// <param name="i"></param> /// <param name="j"></param> public static void Swap(ICoordinateSequence seq, int i, int j) { if (i == j) return; for (int dim = 0; dim < seq.Dimension; dim++) { double tmp = seq.GetOrdinate(i, (Ordinates)dim); seq.SetOrdinate(i, (Ordinates)dim, seq.GetOrdinate(j, (Ordinates)dim)); seq.SetOrdinate(j, (Ordinates)dim, tmp); } }
/// <summary> /// Creates a sequence based on the given coordinate sequence. /// </summary> /// <param name="coordSeq">The coordinate sequence.</param> public DotSpatialAffineCoordinateSequence(ICoordinateSequence coordSeq) { var dsCoordSeq = coordSeq as DotSpatialAffineCoordinateSequence; var count = coordSeq.Count; if (dsCoordSeq != null) { _xy = new double[2 * count]; Buffer.BlockCopy(dsCoordSeq._xy, 0, _xy, 0, 16 * count); if (dsCoordSeq.Z != null) { _z = new double[dsCoordSeq.Count]; Buffer.BlockCopy(dsCoordSeq._z, 0, _z, 0, 8 * count); } if (dsCoordSeq.M != null) { _m = new double[dsCoordSeq.Count]; Buffer.BlockCopy(dsCoordSeq._m, 0, _m, 0, 8 * count); } _ordinates = dsCoordSeq._ordinates; return; } _xy = new double[2 * coordSeq.Count]; if ((coordSeq.Ordinates & Ordinates.Z) != 0) { _z = new double[coordSeq.Count]; } if ((coordSeq.Ordinates & Ordinates.M) != 0) { _m = new double[coordSeq.Count]; } var j = 0; for (var i = 0; i < coordSeq.Count; i++) { _xy[j++] = coordSeq.GetX(i); _xy[j++] = coordSeq.GetY(i); if (_z != null) { _z[i] = coordSeq.GetOrdinate(i, Ordinate.Z); } if (_m != null) { _m[i] = coordSeq.GetOrdinate(i, Ordinate.M); } } }
///<summary> /// Copies a coordinate of a <see cref="ICoordinateSequence"/> to another <see cref="ICoordinateSequence"/>. /// The sequences may contain different <see cref="Ordinates"/>; in this case only the common ordinates are copied. ///</summary> /// <param name="src">The sequence to copy coordinate from</param> /// <param name="srcPos">The index of the coordinate to copy</param> /// <param name="dest">The sequence to which the coordinate should be copied to</param> /// <param name="destPos">The index of the coordinate in <see paramref="dest"/></param> protected static void CopyCoord(ICoordinateSequence src, int srcPos, ICoordinateSequence dest, int destPos) { dest.SetOrdinate(destPos, Ordinate.X, src.GetOrdinate(srcPos, Ordinate.X)); dest.SetOrdinate(destPos, Ordinate.Y, src.GetOrdinate(srcPos, Ordinate.Y)); if ((src.Ordinates & dest.Ordinates & Ordinates.Z) == Ordinates.Z) { dest.SetOrdinate(destPos, Ordinate.Z, src.GetOrdinate(srcPos, Ordinate.Z)); } if ((src.Ordinates & dest.Ordinates & Ordinates.M) == Ordinates.M) { dest.SetOrdinate(destPos, Ordinate.M, src.GetOrdinate(srcPos, Ordinate.M)); } }
public ICoordinateSequence Transform(ICoordinateSequence coordinateSequence) { //use shortcut if possible var sequence = coordinateSequence as DotSpatialAffineCoordinateSequence; if (sequence != null) { return(TransformDotSpatialAffine(sequence)); } var xy = new double[2 * coordinateSequence.Count]; double[] z = null; if (!double.IsNaN(coordinateSequence.GetOrdinate(0, Ordinate.Z))) { z = new double[coordinateSequence.Count]; } var j = 0; for (var i = 0; i < coordinateSequence.Count; i++) { xy[j++] = coordinateSequence.GetOrdinate(i, Ordinate.X); xy[j++] = coordinateSequence.GetOrdinate(i, Ordinate.Y); if (z != null) { z[i] = coordinateSequence.GetOrdinate(i, Ordinate.Z); } } Reproject.ReprojectPoints(xy, z, Source, Target, 0, coordinateSequence.Count); var ret = (ICoordinateSequence)coordinateSequence.Clone(); j = 0; for (var i = 0; i < coordinateSequence.Count; i++) { ret.SetOrdinate(i, Ordinate.X, xy[j++]); ret.SetOrdinate(i, Ordinate.Y, xy[j++]); if (z != null && DimTarget > 2) { ret.SetOrdinate(i, Ordinate.Z, z[i]); } else { ret.SetOrdinate(i, Ordinate.Z, coordinateSequence.GetOrdinate(i, Ordinate.Z)); } } return(ret); }
private static void FixSpike(ICoordinateSequence seq, int fixIndex, int fixWithIndex) { seq.SetOrdinate(fixIndex, Ordinate.X, seq.GetOrdinate(fixWithIndex, Ordinate.X)); seq.SetOrdinate(fixIndex, Ordinate.Y, seq.GetOrdinate(fixWithIndex, Ordinate.Y)); if ((seq.Ordinates & Ordinates.Z) == Ordinates.Z) { seq.SetOrdinate(fixIndex, Ordinate.Z, seq.GetOrdinate(fixWithIndex, Ordinate.Z)); } if ((seq.Ordinates & Ordinates.M) == Ordinates.M) { seq.SetOrdinate(fixIndex, Ordinate.M, seq.GetOrdinate(fixWithIndex, Ordinate.M)); } }
/// <summary> /// Swaps two coordinates in a sequence. /// </summary> /// <param name="seq">seq the sequence to modify</param> /// <param name="i">the index of a coordinate to swap</param> /// <param name="j">the index of a coordinate to swap</param> public static void Swap(ICoordinateSequence seq, int i, int j) { if (i == j) { return; } for (int dim = 0; dim < seq.Dimension; dim++) { double tmp = seq.GetOrdinate(i, (Ordinate)dim); seq.SetOrdinate(i, (Ordinate)dim, seq.GetOrdinate(j, (Ordinate)dim)); seq.SetOrdinate(j, (Ordinate)dim, tmp); } }
/// <summary> /// Transforms a coordinate sequence. The input coordinate sequence remains unchanged. /// </summary> /// <param name="coordinateSequence">The coordinate sequence to transform.</param> /// <returns>The transformed coordinate sequence.</returns> public ICoordinateSequence Transform(ICoordinateSequence coordinateSequence) { //if (coordinateSequence) var xy = new double[coordinateSequence.Count * 2]; var numOrdinates = coordinateSequence.Dimension; var z = numOrdinates > 2 ? new double[coordinateSequence.Count] : null; var m = numOrdinates > 3 ? new double[coordinateSequence.Count] : null; var j = 0; for (var i = 0; i < coordinateSequence.Count; i++) { xy[j++] = coordinateSequence.GetX(i); xy[j++] = coordinateSequence.GetY(i); if (numOrdinates > 2) { z[i] = coordinateSequence.GetOrdinate(i, Ordinate.Z); } if (numOrdinates > 3) { m[i] = coordinateSequence.GetOrdinate(i, Ordinate.M); } } // Do the reprojection Reproject.ReprojectPoints(xy, z, _order[0], _order[1], 0, coordinateSequence.Count); // Set up result j = 0; var res = (ICoordinateSequence)coordinateSequence.Clone(); for (var i = 0; i < coordinateSequence.Count; i++) { res.SetOrdinate(i, Ordinate.X, xy[j++]); res.SetOrdinate(i, Ordinate.Y, xy[j++]); if (numOrdinates > 2) { res.SetOrdinate(i, Ordinate.Z, z[i]); } else if (numOrdinates > 3) { res.SetOrdinate(i, Ordinate.M, m[i]); } } // return it return(res); }
private static void CheckCoordinateAt(ICoordinateSequence seq1, int pos1, ICoordinateSequence seq2, int pos2, int dim) { Assert.AreEqual(seq1.GetOrdinate(pos1, Ordinate.X), seq2.GetOrdinate(pos2, Ordinate.X), "unexpected x-ordinate at pos " + pos2); Assert.AreEqual(seq1.GetOrdinate(pos1, Ordinate.Y), seq2.GetOrdinate(pos2, Ordinate.Y), "unexpected y-ordinate at pos " + pos2); // check additional ordinates for (int j = 2; j < dim; j++) { Assert.AreEqual(seq1.GetOrdinate(pos1, (Ordinate)j), seq2.GetOrdinate(pos2, (Ordinate)j), "unexpected " + j + "-ordinate at pos " + pos2); } }
/// <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 ICoordinateSequence EnsureValidRing(ICoordinateSequenceFactory fact, ICoordinateSequence 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> /// Copies a coordinate of a <see cref="ICoordinateSequence"/> to another <see cref="ICoordinateSequence"/>. /// The sequences must have the same dimension. ///</summary> /// <param name="src">The sequence to copy coordinate from</param> /// <param name="srcPos">The index of the coordinate to copy</param> /// <param name="dest">The sequence to which the coordinate should be copied to</param> /// <param name="destPos">The index of the coordinate in <see paramref="dest"/></param> public static void CopyCoord(ICoordinateSequence src, int srcPos, ICoordinateSequence dest, int destPos) { for (Ordinate dim = 0; (int)dim < src.Dimension; dim++) { dest.SetOrdinate(destPos, dim, src.GetOrdinate(srcPos, dim)); } }
public SpatialLite.Core.API.Coordinate ToCoordinate(ICoordinateSequence seq, int i) { var c = new SpatialLite.Core.API.Coordinate(); c.X = seq.GetX(i); c.Y = seq.GetY(i); if ((seq.Ordinates & Ordinates.Z) == Ordinates.Z) { c.Z = seq.GetOrdinate(i, Ordinate.Z); } if ((seq.Ordinates & Ordinates.M) == Ordinates.M) { c.M = seq.GetOrdinate(i, Ordinate.M); } return(c); }
/// <summary> /// Creates a string representation of a <see cref="ICoordinateSequence"/>. /// The format is: /// <para> /// ( ord0,ord1.. ord0,ord1,... ... ) /// </para> /// </summary> /// <param name="cs">the sequence to output</param> /// <returns>the string representation of the sequence</returns> public static string ToString(ICoordinateSequence cs) { int size = cs.Count; if (size == 0) { return("()"); } int dim = cs.Dimension; var sb = new StringBuilder(); sb.Append('('); for (int i = 0; i < size; i++) { if (i > 0) { sb.Append(" "); } for (int d = 0; d < dim; d++) { if (d > 0) { sb.Append(","); } double ordinate = cs.GetOrdinate(i, (Ordinate)d); sb.Append(string.Format("{0:0.#}", ordinate)); } } sb.Append(')'); return(sb.ToString()); }
/// <summary> /// Shifts the positions of the coordinates until the coordinate at <code>firstCoordinateIndex</code> /// is first. /// </summary> /// <param name="seq">The coordinate sequence to rearrange</param> /// <param name="indexOfFirstCoordinate">The index of the coordinate to make first</param> /// <param name="ensureRing">Makes sure that <paramref name="seq"/> will be a closed ring upon exit</param> public static void Scroll(ICoordinateSequence seq, int indexOfFirstCoordinate, bool ensureRing) { int i = indexOfFirstCoordinate; if (i <= 0) { return; } // make a copy of the sequence var copy = seq.Copy(); // test if ring, determine last index int last = ensureRing ? seq.Count - 1 : seq.Count; // fill in values for (int j = 0; j < last; j++) { for (int k = 0; k < seq.Dimension; k++) { seq.SetOrdinate(j, (Ordinate)k, copy.GetOrdinate((indexOfFirstCoordinate + j) % last, (Ordinate)k)); } } // Fix the ring (first == last) if (ensureRing) { for (int k = 0; k < seq.Dimension; k++) { seq.SetOrdinate(last, (Ordinate)k, seq.GetOrdinate(0, (Ordinate)k)); } } }
protected static ICoordinateSequence AddCoordinateToSequence(ICoordinateSequence sequence, ICoordinateSequenceFactory factory, double x, double y, double?z, double?m) { // Create a new sequence var newSequence = factory.Create(sequence.Count + 1, sequence.Ordinates); // Copy old values var ordinates = OrdinatesUtility.ToOrdinateArray(sequence.Ordinates); for (var i = 0; i < sequence.Count; i++) { foreach (var ordinate in ordinates) { newSequence.SetOrdinate(i, ordinate, sequence.GetOrdinate(i, ordinate)); } } // new coordinate newSequence.SetOrdinate(sequence.Count, Ordinate.X, x); newSequence.SetOrdinate(sequence.Count, Ordinate.Y, y); if (z.HasValue) { newSequence.SetOrdinate(sequence.Count, Ordinate.Z, z.Value); } if (m.HasValue) { newSequence.SetOrdinate(sequence.Count, Ordinate.M, m.Value); } return(newSequence); }
/** * Computes a point which is the average of all coordinates * in a sequence. * If the sequence lies in a single plane, * the computed point also lies in the plane. * * @param seq a coordinate sequence * @return a Coordinate with averaged ordinates */ private static Coordinate AveragePoint(ICoordinateSequence seq) { var a = new Coordinate(0, 0, 0); var n = seq.Count; for (var i = 0; i < n; i++) { a.X += seq.GetOrdinate(i, Ordinate.X); a.Y += seq.GetOrdinate(i, Ordinate.Y); a.Z += seq.GetOrdinate(i, Ordinate.Z); } a.X /= n; a.Y /= n; a.Z /= n; return(a); }
/// <summary> /// Function to return a coordinate sequence that is ensured to be closed. /// </summary> /// <param name="sequence">The base sequence</param> /// <param name="factory">The factory to use in case we need to create a new sequence</param> /// <returns>A closed coordinate sequence</returns> private static ICoordinateSequence EnsureClosedSequence(ICoordinateSequence sequence, ICoordinateSequenceFactory factory) { //This sequence won't serve a valid linear ring if (sequence.Count < 3) { return(null); } //The sequence is closed var start = sequence.GetCoordinate(0); var lastIndex = sequence.Count - 1; var end = sequence.GetCoordinate(lastIndex); if (start.Equals2D(end)) { return(sequence); } // The sequence is not closed // 1. Test for a little offset, in that case simply correct x- and y- ordinate values const double eps = 1E-7; if (start.Distance(end) < eps) { sequence.SetOrdinate(lastIndex, Ordinate.X, start.X); sequence.SetOrdinate(lastIndex, Ordinate.Y, start.Y); return(sequence); } // 2. Close the sequence by adding a new point, this is heavier var newSequence = factory.Create(sequence.Count + 1, sequence.Ordinates); var ordinates = OrdinatesUtility.ToOrdinateArray(sequence.Ordinates); for (var i = 0; i < sequence.Count; i++) { foreach (var ordinate in ordinates) { newSequence.SetOrdinate(i, ordinate, sequence.GetOrdinate(i, ordinate)); } } foreach (var ordinate in ordinates) { newSequence.SetOrdinate(sequence.Count, ordinate, sequence.GetOrdinate(0, ordinate)); } return(newSequence); }
/// <summary> /// Tests whether a <see cref="ICoordinateSequence"/> forms a valid <see cref="ILinearRing"/>, /// by checking the sequence length and closure /// (whether the first and last points are identical in 2D). /// Self-intersection is not checked. /// </summary> /// <param name="seq">The sequence to test</param> /// <returns>True if the sequence is a ring</returns> /// <seealso cref="ILinearRing"/> public static bool IsRing(ICoordinateSequence seq) { int n = seq.Count; if (n == 0) { return(true); } // too few points if (n <= 3) { return(false); } // test if closed return(seq.GetOrdinate(0, Ordinate.X) == seq.GetOrdinate(n - 1, Ordinate.X) && seq.GetOrdinate(0, Ordinate.Y) == seq.GetOrdinate(n - 1, Ordinate.Y)); }
public double GetOrdinate(int index, Ordinate ordinateIndex) { // Z ord is always 0 if (ordinateIndex > Ordinate.Y) { return(0); } return(_seq.GetOrdinate(index, _indexMap[(int)ordinateIndex])); }
private static void WriteXYZM(ICoordinateSequence coordinateSequence, GaiaExport export, BinaryWriter bw) { var wd = export.WriteDouble; for (var i = 0; i < coordinateSequence.Count; i++) { var c = coordinateSequence.GetCoordinate(i); wd(bw, c.X, c.Y, c.Z, coordinateSequence.GetOrdinate(i, Ordinate.M)); } }
private static double[] ToDoubleArray(ICoordinateSequence sequence, out double[] z) { var res = new double[sequence.Count * 2]; z = ((sequence.Ordinates & Ordinates.Z) == Ordinates.Z) ? new double[sequence.Count] : null; var j = 0; for (var i = 0; i < sequence.Count; i++) { res[j++] = sequence.GetOrdinate(i, Ordinate.X); res[j++] = sequence.GetOrdinate(i, Ordinate.Y); if (z != null) { z[i] = sequence.GetOrdinate(i, Ordinate.Z); } } return(res); }
private static double GetOrdinate(ICoordinateSequence sequence, Ordinate ordinate, int index) { var val = sequence.GetOrdinate(index, ordinate); if (ordinate == Ordinate.M && double.IsNaN(val)) { val = ShapeFileConstants.NoDataValue; } return(val); }
///<summary> /// Copies a coordinate of a <see cref="ICoordinateSequence"/> to another <see cref="ICoordinateSequence"/>. /// The sequences may have different dimensions; /// in this case only the common dimensions are copied. ///</summary> /// <param name="src">The sequence to copy coordinate from</param> /// <param name="srcPos">The index of the coordinate to copy</param> /// <param name="dest">The sequence to which the coordinate should be copied to</param> /// <param name="destPos">The index of the coordinate in <see paramref="dest"/></param> public static void CopyCoord(ICoordinateSequence src, int srcPos, ICoordinateSequence dest, int destPos) { int minDim = Math.Min(src.Dimension, dest.Dimension); for (int dim = 0; dim < minDim; dim++) { Ordinate ordinate = (Ordinate)dim; double value = src.GetOrdinate(srcPos, ordinate); dest.SetOrdinate(destPos, ordinate, value); } }
///<summary> /// Copies a coordinate of a <see cref="ICoordinateSequence"/> to another <see cref="ICoordinateSequence"/>. /// The sequences may have different dimensions; /// in this case only the common dimensions are copied. ///</summary> /// <param name="src">The sequence to copy coordinate from</param> /// <param name="srcPos">The index of the coordinate to copy</param> /// <param name="dest">The sequence to which the coordinate should be copied to</param> /// <param name="destPos">The index of the coordinate in <see paramref="dest"/></param> public static void CopyCoord(ICoordinateSequence src, int srcPos, ICoordinateSequence dest, int destPos) { int minDim = Math.Min(src.Dimension, dest.Dimension); for (int dim = 0; dim < minDim; dim++) { var ordinate = (Ordinate)dim; double value = src.GetOrdinate(srcPos, ordinate); dest.SetOrdinate(destPos, ordinate, value); } }
protected void Write(ICoordinateSequence sequence, bool emitSize, BinaryWriter writer) { if (emitSize) { writer.Write(sequence.Count); } // zm-values if not provided by sequence var ordinateZ = Coordinate.NullOrdinate; var ordinateM = Coordinate.NullOrdinate; // test if zm-values are provided by sequence var getZ = (sequence.Ordinates & Ordinates.Z) == Ordinates.Z; var getM = (sequence.Ordinates & Ordinates.M) == Ordinates.M; // test if zm-values should be emitted var writeZ = (HandleOrdinates & Ordinates.Z) == Ordinates.Z; var writeM = (HandleOrdinates & Ordinates.M) == Ordinates.M; for (var index = 0; index < sequence.Count; index++) { writer.Write(sequence.GetOrdinate(index, Ordinate.X)); writer.Write(sequence.GetOrdinate(index, Ordinate.Y)); if (writeZ) { if (getZ) { ordinateZ = sequence.GetOrdinate(index, Ordinate.Z); } writer.Write(ordinateZ); } if (writeM) { if (getM) { ordinateM = sequence.GetOrdinate(index, Ordinate.M); } writer.Write(ordinateM); } } }
private void AddCoordinate(SqlGeometryBuilder builder, ICoordinateSequence coordinates, int index) { var x = coordinates.GetOrdinate(index, Ordinate.X); var y = coordinates.GetOrdinate(index, Ordinate.Y); Double?z = null, m = null; if ((HandleOrdinates & Ordinates.Z) > 0) { z = coordinates.GetOrdinate(index, Ordinate.Z); if (Double.IsNaN(z.Value)) { z = 0d; } } if ((HandleOrdinates & Ordinates.M) > 0) { m = coordinates.GetOrdinate(index, Ordinate.M); if (Double.IsNaN(m.Value)) { m = 0d; } } if (index == 0) { builder.BeginFigure(x, y, z, m); } else { builder.AddLine(x, y, z, m); } if (index == coordinates.Count - 1) { builder.EndFigure(); } }
private static void DoTest(ICoordinateSequence forward, ICoordinateSequence reversed) { const double eps = 1e-12; Assert.AreEqual(forward.Count, reversed.Count, "Coordinate sequences don't have same size"); Assert.AreEqual(forward.Ordinates, reversed.Ordinates, "Coordinate sequences don't serve same ordinate values"); var ordinates = OrdinatesUtility.ToOrdinateArray(forward.Ordinates); var j = forward.Count; for (var i = 0; i < forward.Count; i++) { j--; foreach(var ordinate in ordinates) Assert.AreEqual(forward.GetOrdinate(i, ordinate), reversed.GetOrdinate(j, ordinate), eps, string.Format("{0} values are not within tolerance", ordinate)); var cf = forward.GetCoordinate(i); var cr = reversed.GetCoordinate(j); Assert.IsFalse(ReferenceEquals(cf, cr), "Coordinate sequences deliver same coordinate instances"); Assert.IsTrue(cf.Equals(cr), "Coordinate sequences do not provide equal coordinates"); } }
protected static ICoordinateSequence AddCoordinateToSequence(ICoordinateSequence sequence, ICoordinateSequenceFactory factory, double x, double y, double? z, double? m) { // Create a new sequence var newSequence = factory.Create(sequence.Count + 1, sequence.Ordinates); // Copy old values var ordinates = OrdinatesUtility.ToOrdinateArray(sequence.Ordinates); for (var i = 0; i < sequence.Count; i++) { foreach (var ordinate in ordinates) newSequence.SetOrdinate(i, ordinate, sequence.GetOrdinate(i, ordinate)); } // new coordinate newSequence.SetOrdinate(sequence.Count, Ordinate.X, x); newSequence.SetOrdinate(sequence.Count, Ordinate.Y, y); if (z.HasValue) newSequence.SetOrdinate(sequence.Count, Ordinate.Z, z.Value); if (m.HasValue) newSequence.SetOrdinate(sequence.Count, Ordinate.M, m.Value); return newSequence; }
protected static void WriteCoords(ICoordinateSequence points, BinaryWriter file, List<double> zList, List<double> mList) { for (var i = 0; i < points.Count; i++) { file.Write(points.GetOrdinate(i, Ordinate.X)); file.Write(points.GetOrdinate(i, Ordinate.Y)); if (zList != null) { if ((points.Ordinates & Ordinates.Z) != Ordinates.Z) zList.Add(0d); else zList.Add(points.GetOrdinate(i, Ordinate.Z)); } if (mList == null) continue; if ((points.Ordinates & Ordinates.M) != Ordinates.M) mList.Add(NoDataValue); else { var val = points.GetOrdinate(i, Ordinate.M); if (val.Equals(Coordinate.NullOrdinate)) val = NoDataValue; mList.Add(val); } } }
/// <summary> /// Creates a sequence based on the given coordinate sequence. /// </summary> /// <param name="coordSeq">The coordinate sequence.</param> public DotSpatialAffineCoordinateSequence(ICoordinateSequence coordSeq) { var dsCoordSeq = coordSeq as DotSpatialAffineCoordinateSequence; var count = coordSeq.Count; if (dsCoordSeq != null) { _xy = new double[2 * count]; Buffer.BlockCopy(dsCoordSeq._xy, 0, _xy, 0, 16 * count); if (dsCoordSeq.Z != null) { _z = new double[dsCoordSeq.Count]; Buffer.BlockCopy(dsCoordSeq._z, 0, _z, 0, 8 * count); } if (dsCoordSeq.M != null) { _m = new double[dsCoordSeq.Count]; Buffer.BlockCopy(dsCoordSeq._m, 0, _m, 0, 8 * count); } _ordinates = dsCoordSeq._ordinates; return; } _xy = new double[2 * coordSeq.Count]; if ((coordSeq.Ordinates & Ordinates.Z) != 0) _z = new double[coordSeq.Count]; if ((coordSeq.Ordinates & Ordinates.M) != 0) _m = new double[coordSeq.Count]; var j = 0; for (var i = 0; i < coordSeq.Count; i++) { _xy[j++] = coordSeq.GetX(i); _xy[j++] = coordSeq.GetY(i); if (_z != null) _z[i] = coordSeq.GetOrdinate(i, Ordinate.Z); if (_m != null) _m[i] = coordSeq.GetOrdinate(i, Ordinate.M); } }
///<summary> /// Rounds the Coordinates in the sequence to match the PrecisionModel ///</summary> public void Filter(ICoordinateSequence seq, int i) { seq.SetOrdinate(i, Ordinate.X, _precModel.MakePrecise(seq.GetOrdinate(i, Ordinate.X))); seq.SetOrdinate(i, Ordinate.Y, _precModel.MakePrecise(seq.GetOrdinate(i, Ordinate.Y))); }
private static void WriteSequence(ICoordinateSequence sequence, PostGis2GeometryHeader pgh, BinaryWriter writer, int numPoints) { if (numPoints == -1) { numPoints = sequence.Count; writer.Write(numPoints); } var ordinateIndices = pgh.OrdinateIndices; for (var i = 0; i < numPoints; i++) { foreach (var ordinateIndex in ordinateIndices) writer.Write(sequence.GetOrdinate(i, ordinateIndex)); } }
private static void Write(ICoordinateSequence sequence, Ordinates ordinates, BinaryWriter writer, bool justOne) { if (sequence == null || sequence.Count == 0) return; var length = (justOne ? 1 : sequence.Count); if (!justOne) writer.Write(length); for (var i = 0; i < length; i++) { writer.Write(sequence.GetOrdinate(i, Ordinate.X)); writer.Write(sequence.GetOrdinate(i, Ordinate.Y)); if ((ordinates & Ordinates.Z) != 0) { var z = sequence.GetOrdinate(i, Ordinate.Z); if (double.IsNaN(z)) z = 0d; writer.Write(z); } if ((ordinates & Ordinates.M) != 0) { var m = sequence.GetOrdinate(i, Ordinate.M); if (double.IsNaN(m)) m = 0d; writer.Write(m); } } }
private static Ordinates CheckOrdinates(ICoordinateSequence sequence) { if (sequence == null || sequence.Count == 0) return Ordinates.None; var result = Ordinates.XY; if ((sequence.Ordinates & Ordinates.Z) != 0) { if (!Double.IsNaN(sequence.GetOrdinate(0, Ordinate.Z))) result |= Ordinates.Z; } if ((sequence.Ordinates & Ordinates.M) != 0) { if (!Double.IsNaN(sequence.GetOrdinate(0, Ordinate.M))) result |= Ordinates.Z; } return result; }
/** * Computes a point which is the average of all coordinates * in a sequence. * If the sequence lies in a single plane, * the computed point also lies in the plane. * * @param seq a coordinate sequence * @return a Coordinate with averaged ordinates */ private static Coordinate AveragePoint(ICoordinateSequence seq) { var a = new Coordinate(0, 0, 0); var n = seq.Count; for (var i = 0; i < n; i++) { a.X += seq.GetOrdinate(i, Ordinate.X); a.Y += seq.GetOrdinate(i, Ordinate.Y); a.Z += seq.GetOrdinate(i, Ordinate.Z); } a.X /= n; a.Y /= n; a.Z /= n; return a; }
private static void TestCoordinateSequences(ICoordinateSequence orig, ICoordinateSequence trans) { Assert.AreNotSame(orig, trans, "Seqences are same"); Assert.AreEqual(orig.Count, trans.Count, "Sequences have different lengths"); Assert.AreEqual(orig.Ordinates, trans.Ordinates, "Sequences provide different ordinates"); var ordinates = OrdinatesUtility.ToOrdinateArray(orig.Ordinates); for (var i = 0; i < orig.Count; i++) { foreach (var ordinate in ordinates) { var v1 = orig.GetOrdinate(i, ordinate); var v2 = trans.GetOrdinate(i, ordinate); if (double.IsNaN(v1)) { Assert.IsTrue(double.IsNaN(v2)); continue; } if (double.IsPositiveInfinity(v1)) { Assert.IsTrue(double.IsPositiveInfinity(v2)); continue; } if (double.IsNegativeInfinity(v1)) { Assert.IsTrue(double.IsNegativeInfinity(v2)); continue; } Assert.AreNotEqual(v1, v2, "Sequences provide equal value for '{0}'", ordinate); } } }
/// <summary> /// Creates a string representation of a <see cref="ICoordinateSequence"/>. /// The format is: /// <para> /// ( ord0,ord1.. ord0,ord1,... ... ) /// </para> /// </summary> /// <param name="cs">the sequence to output</param> /// <returns>the string representation of the sequence</returns> public static String ToString(ICoordinateSequence cs) { int size = cs.Count; if (size == 0) return "()"; int dim = cs.Dimension; StringBuilder sb = new StringBuilder(); sb.Append('('); for (int i = 0; i < size; i++) { if (i > 0) sb.Append(" "); for (int d = 0; d < dim; d++) { if (d > 0) sb.Append(","); double ordinate = cs.GetOrdinate(i, (Ordinate)d); sb.Append(String.Format("{0:0.#}", ordinate)); } } sb.Append(')'); return sb.ToString(); }
/// <summary> /// Tests whether two <see cref="ICoordinateSequence"/>s are equal. /// To be equal, the sequences must be the same length. /// They do not need to be of the same dimension, /// but the ordinate values for the smallest dimension of the two /// must be equal. /// Two <c>NaN</c> ordinates values are considered to be equal. /// </summary> /// <param name="cs1">a CoordinateSequence</param> /// <param name="cs2">a CoordinateSequence</param> /// <returns><c>true</c> if the sequences are equal in the common dimensions</returns> public static bool IsEqual(ICoordinateSequence cs1, ICoordinateSequence cs2) { int cs1Size = cs1.Count; int cs2Size = cs2.Count; if (cs1Size != cs2Size) return false; int dim = Math.Min(cs1.Dimension, cs2.Dimension); for (int i = 0; i < cs1Size; i++) { for (int d = 0; d < dim; d++) { Ordinate ordinate = (Ordinate)d; double v1 = cs1.GetOrdinate(i, ordinate); double v2 = cs2.GetOrdinate(i, ordinate); if (cs1.GetOrdinate(i, ordinate) == cs2.GetOrdinate(i, ordinate)) continue; // special check for NaNs if (Double.IsNaN(v1) && Double.IsNaN(v2)) continue; return false; } } return true; }
/// <summary> /// Tests whether a <see cref="ICoordinateSequence"/> forms a valid <see cref="ILinearRing"/>, /// by checking the sequence length and closure /// (whether the first and last points are identical in 2D). /// Self-intersection is not checked. /// </summary> /// <param name="seq">The sequence to test</param> /// <returns>True if the sequence is a ring</returns> /// <seealso cref="ILinearRing"/> public static bool IsRing(ICoordinateSequence seq) { int n = seq.Count; if (n == 0) return true; // too few points if (n <= 3) return false; // test if closed return seq.GetOrdinate(0, Ordinate.X) == seq.GetOrdinate(n - 1, Ordinate.X) && seq.GetOrdinate(0, Ordinate.Y) == seq.GetOrdinate(n - 1, Ordinate.Y); }
static Coordinate[] Round(ICoordinateSequence seq, IPrecisionModel pm) { if (seq.Count == 0) return new Coordinate[0]; CoordinateList coordList = new CoordinateList(); // copy coordinates and reduce for (int i = 0; i < seq.Count; i++) { var coord = new Coordinate( seq.GetOrdinate(i, Ordinate.X), seq.GetOrdinate(i, Ordinate.Y)); pm.MakePrecise(coord); coordList.Add(coord, false); } Coordinate[] coords = coordList.ToCoordinateArray(); //TODO: what if seq is too short? return coords; }
protected static double[] CreateArray(ICoordinateSequence sequence, Ordinate ordinate) { var result = new double[sequence.Count]; for (var i = 0; i < result.Length; i++) result[i] = sequence.GetOrdinate(i, ordinate); return result; }
bool IsAllCoordsEqual(ICoordinateSequence seq, Coordinate coord) { for (int i = 0; i < seq.Count; i++) { if (!coord.Equals(seq.GetCoordinate(i))) return false; if (coord.X != seq.GetOrdinate(i, Ordinate.X)) return false; if (coord.Y != seq.GetOrdinate(i, Ordinate.Y)) return false; if (coord.Z != seq.GetOrdinate(i, Ordinate.Z)) return false; } return true; }
///<summary>Appends the i'th coordinate from the sequence to the writer</summary> /// <param name="seq">the <see cref="ICoordinateSequence"/> to process</param> /// <param name="i">the index of the coordinate to write</param> /// <param name="writer">writer the output writer to append to</param> ///<exception cref="IOException"></exception> private void AppendCoordinate(ICoordinateSequence seq, int i, TextWriter writer) { writer.Write(WriteNumber(seq.GetX(i)) + " " + WriteNumber(seq.GetY(i))); if (_outputDimension >= 3 && seq.Dimension >= 3) { double z = seq.GetOrdinate(i, Ordinate.Z); if (!Double.IsNaN(z)) { writer.Write(" "); writer.Write(WriteNumber(z)); } } }
private static double[] ToDoubleArray(ICoordinateSequence sequence, out double[] z) { var res = new double[sequence.Count*2]; z = ((sequence.Ordinates & Ordinates.Z) == Ordinates.Z) ? new double[sequence.Count] : null; var j = 0; for (var i = 0; i < sequence.Count; i++) { res[j++] = sequence.GetOrdinate(i, Ordinate.X); res[j++] = sequence.GetOrdinate(i, Ordinate.Y); if (z != null) z[i] = sequence.GetOrdinate(i, Ordinate.Z); } return res; }
/// <summary> /// Function to return a coordinate sequence that is ensured to be closed. /// </summary> /// <param name="sequence">The base sequence</param> /// <param name="factory">The factory to use in case we need to create a new sequence</param> /// <returns>A closed coordinate sequence</returns> private static ICoordinateSequence EnsureClosedSequence(ICoordinateSequence sequence, ICoordinateSequenceFactory factory) { //This sequence won't serve a valid linear ring if (sequence.Count < 3) return null; //The sequence is closed var start = sequence.GetCoordinate(0); var lastIndex = sequence.Count - 1; var end = sequence.GetCoordinate(lastIndex); if (start.Equals2D(end)) return sequence; // The sequence is not closed // 1. Test for a little offset, in that case simply correct x- and y- ordinate values const double eps = 1E-7; if (start.Distance(end) < eps) { sequence.SetOrdinate(lastIndex, Ordinate.X, start.X); sequence.SetOrdinate(lastIndex, Ordinate.Y, start.Y); return sequence; } // 2. Close the sequence by adding a new point, this is heavier var newSequence = factory.Create(sequence.Count + 1, sequence.Ordinates); var ordinates = OrdinatesUtility.ToOrdinateArray(sequence.Ordinates); for (var i = 0; i < sequence.Count; i++) { foreach (var ordinate in ordinates) newSequence.SetOrdinate(i, ordinate, sequence.GetOrdinate(i, ordinate)); } foreach (var ordinate in ordinates) newSequence.SetOrdinate(sequence.Count, ordinate, sequence.GetOrdinate(0, ordinate)); return newSequence; }
public ICoordinateSequence Transform(ICoordinateSequence coordinateSequence) { //use shortcut if possible var sequence = coordinateSequence as DotSpatialAffineCoordinateSequence; if (sequence != null) return TransformDotSpatialAffine(sequence); var xy = new double[2*coordinateSequence.Count]; double[] z = null; if (!double.IsNaN(coordinateSequence.GetOrdinate(0, Ordinate.Z))) z = new double[coordinateSequence.Count]; var j = 0; for (var i = 0; i < coordinateSequence.Count; i++) { xy[j++] = coordinateSequence.GetOrdinate(i, Ordinate.X); xy[j++] = coordinateSequence.GetOrdinate(i, Ordinate.Y); if (z != null) z[i] = coordinateSequence.GetOrdinate(i, Ordinate.Z); } Reproject.ReprojectPoints(xy, z, Source, Target, 0, coordinateSequence.Count); var ret = (ICoordinateSequence) coordinateSequence.Clone(); j = 0; for (var i = 0; i < coordinateSequence.Count; i++) { ret.SetOrdinate(i, Ordinate.X, xy[j++]); ret.SetOrdinate(i, Ordinate.Y, xy[j++]); if (z != null && DimTarget>2) ret.SetOrdinate(i, Ordinate.Z, z[i]); else ret.SetOrdinate(i,Ordinate.Z, coordinateSequence.GetOrdinate(i, Ordinate.Z)); } return ret; }
protected void Write(ICoordinateSequence sequence, bool emitSize, BinaryWriter writer) { if (emitSize) writer.Write(sequence.Count); // zm-values if not provided by sequence var ordinateZ = Coordinate.NullOrdinate; var ordinateM = Coordinate.NullOrdinate; // test if zm-values are provided by sequence var getZ = (sequence.Ordinates & Ordinates.Z) == Ordinates.Z; var getM = (sequence.Ordinates & Ordinates.M) == Ordinates.M; // test if zm-values should be emitted var writeZ = (HandleOrdinates & Ordinates.Z) == Ordinates.Z; var writeM = (HandleOrdinates & Ordinates.M) == Ordinates.M; for (var index = 0; index < sequence.Count; index++) { writer.Write(sequence.GetOrdinate(index, Ordinate.X)); writer.Write(sequence.GetOrdinate(index, Ordinate.Y)); if (writeZ) { if (getZ) ordinateZ = sequence.GetOrdinate(index, Ordinate.Z); writer.Write(ordinateZ); } if (writeM) { if (getM) ordinateM = sequence.GetOrdinate(index, Ordinate.M); writer.Write(ordinateM); } } }
private static void ToDotSpatial(ICoordinateSequence c, out double[] xy, out double[] z, out double[] m) { xy = new double[2 * c.Count]; z = ((c.Ordinates & Ordinates.Z) == Ordinates.Z) ? new double[c.Count] : null; m = ((c.Ordinates & Ordinates.M) == Ordinates.M) ? new double[c.Count] : null; var j = 0; for (var i = 0; i < c.Count; i++) { xy[j++] = c.GetOrdinate(i, Ordinate.X); xy[j++] = c.GetOrdinate(i, Ordinate.Y); } if (z != null) { for (var i = 0; i < c.Count; i++) xy[i] = c.GetOrdinate(i, Ordinate.Z); } if (m != null) { for (var i = 0; i < c.Count; i++) xy[i] = c.GetOrdinate(i, Ordinate.M); } }
private static ICoordinateSequence SetDimension(ICoordinateSequenceFactory fact, ICoordinateSequence seq, int dimension) { if (seq.Dimension == dimension) return seq; var res = fact.Create(seq.Count, dimension); dimension = Math.Min(dimension, seq.Dimension); for (var i = 0; i < seq.Count; i++) { for (var j = 0; j < dimension; j++) res.SetOrdinate(i, (Ordinate)j, seq.GetOrdinate(i, (Ordinate)j)); } return res; }
/// <summary> /// /// </summary> /// <param name="iCoordinateSequence"></param> /// <returns></returns> private static bool hasZ(ICoordinateSequence coords) { if (coords == null || coords.Count == 0) return false; int dimensions = coords.Dimension; if (coords.Dimension == 3) { // CoordinateArraySequence will always return 3, so we have to // check, if the third ordinate contains NaN, then the geom is actually 2-dimensional return Double.IsNaN(coords.GetOrdinate(0, Ordinates.Z)) ? false : true; } else return false; }
/// <summary> /// Tests for equality using all supported accessors, /// to provides test coverage for them. /// </summary> /// <param name="seq"></param> /// <param name="coords"></param> /// <returns></returns> bool IsEqual(ICoordinateSequence seq, Coordinate[] coords) { if (seq.Count != coords.Length) return false; Coordinate p = new Coordinate(); for (int i = 0; i < seq.Count; i++) { if (!coords[i].Equals(seq.GetCoordinate(i))) return false; // Ordinate named getters if (coords[i].X != seq.GetX(i)) return false; if (coords[i].Y != seq.GetY(i)) return false; // Ordinate indexed getters if (coords[i].X != seq.GetOrdinate(i, Ordinate.X)) return false; if (coords[i].Y != seq.GetOrdinate(i, Ordinate.Y)) return false; if (coords[i].Z != seq.GetOrdinate(i, Ordinate.Z)) return false; // Coordinate getter seq.GetCoordinate(i, p); if (coords[i].X != p.X) return false; if (coords[i].Y != p.Y) return false; //TODO: Remove commented line below when NTS supports Z ordinates in CoordinateArraySequence.GetCoordinate and PackedCoordinateSequence.GetCoordinate //if (coords[i].Z != p.Z) return false; } return true; }