/// <summary> /// Computes the signed area for a ring. The signed area is positive if the /// <list type="Table"> /// <listheader> /// <term>value</term> /// <description>meaning</description> /// </listheader> /// <item><term>> 0</term> /// <description>The ring is oriented clockwise (CW)</description></item> /// <item><term>< 0</term> /// <description>The ring is oriented counter clockwise (CCW)</description></item> /// <item><term>== 0</term> /// <description>The ring is degenerate or flat</description></item> /// </list> /// ring is oriented CW, negative if the ring is oriented CCW, and zero if the /// ring is degenerate or flat. /// </summary> /// <param name="ring">The coordinates forming the ring</param> /// <returns>The signed area of the ring</returns> public static double OfRingSigned(ICoordinateSequence ring) { var n = ring.Count; if (n < 3) { return(0.0); } /** * Based on the Shoelace formula. * http://en.wikipedia.org/wiki/Shoelace_formula */ var p0 = new Coordinate(); var p1 = new Coordinate(); var p2 = new Coordinate(); ring.GetCoordinate(0, p1); ring.GetCoordinate(1, p2); var x0 = p1.X; p2.X -= x0; var sum = 0.0; for (var i = 1; i < n - 1; i++) { p0.Y = p1.Y; p1.X = p2.X; p1.Y = p2.Y; ring.GetCoordinate(i + 1, p2); p2.X -= x0; sum += p1.X * (p0.Y - p2.Y); } return(sum / 2.0); }
/// <summary> /// Computes the length of a <c>LineString</c> specified by a sequence of points. /// </summary> /// <param name="pts">The points specifying the <c>LineString</c></param> /// <returns>The length of the <c>LineString</c></returns> public static double OfLine(ICoordinateSequence pts) { // optimized for processing CoordinateSequences int n = pts.Count; if (n <= 1) { return(0.0); } double len = 0.0; var p = new Coordinate(); pts.GetCoordinate(0, p); double x0 = p.X; double y0 = p.Y; for (int i = 1; i < n; i++) { pts.GetCoordinate(i, p); double x1 = p.X; double y1 = p.Y; double dx = x1 - x0; double dy = y1 - y0; len += Math.Sqrt(dx * dx + dy * dy); x0 = x1; y0 = y1; } return(len); }
public void Filter(ICoordinateSequence seq, int i) { if (i == 0) return; seq.GetCoordinate(i - 1, p0); seq.GetCoordinate(i, p1); rcc.CountSegment(p0, p1); }
public void Filter(ICoordinateSequence seq, int index) { /** * This logic also handles skipping Point geometries */ if (index == 0) { return; } var p0 = seq.GetCoordinate(index - 1); var p1 = seq.GetCoordinate(index); var delx = (p1.X - p0.X) / _numSubSegs; var dely = (p1.Y - p0.Y) / _numSubSegs; for (var i = 0; i < _numSubSegs; i++) { var x = p0.X + i * delx; var y = p0.Y + i * dely; var pt = new Coordinate(x, y); _minPtDist.Initialize(); DistanceToPoint.ComputeDistance(_geom, pt, _minPtDist); _maxPtDist.SetMaximum(_minPtDist); } }
private static void WriteCompressedXY(ICoordinateSequence coordinateSequence, GaiaExport export, BinaryWriter bw) { var wd = export.WriteDouble; // Write initial coordinate var cprev = coordinateSequence.GetCoordinate(0); wd(bw, cprev.X, cprev.Y); var ws = export.WriteSingle; var maxIndex = coordinateSequence.Count - 1; if (maxIndex <= 0) { return; } for (var i = 1; i < maxIndex; i++) { var c = coordinateSequence.GetCoordinate(i); var fx = (float)(c.X - cprev.X); var fy = (float)(c.Y - cprev.Y); ws(bw, fx, fy); cprev = c; } // Write last coordinate cprev = coordinateSequence.GetCoordinate(maxIndex); wd(bw, cprev.X, cprev.Y); }
private static void WriteCompressedXYZM(ICoordinateSequence coordinateSequence, GaiaExport export, BinaryWriter bw) { var wd = export.WriteDouble; // Write initial coordinate var cprev = coordinateSequence.GetCoordinate(0); var mprev = coordinateSequence.GetOrdinate(0, Ordinate.M); wd(bw, cprev.X, cprev.Y, cprev.Z, mprev); var maxIndex = coordinateSequence.Count - 1; if (maxIndex <= 0) { return; } var ws = export.WriteSingle; for (var i = 1; i < maxIndex; i++) { var c = coordinateSequence.GetCoordinate(i); var fx = (float)(c.X - cprev.X); var fy = (float)(c.Y - cprev.Y); var fz = (float)(c.Z - cprev.Z); var fm = (float)(coordinateSequence.GetOrdinate(i, Ordinate.M) - mprev); ws(bw, fx, fy, fz, fm); cprev = c; } cprev = coordinateSequence.GetCoordinate(maxIndex); mprev = coordinateSequence.GetOrdinate(maxIndex, Ordinate.M); wd(bw, cprev.X, cprev.Y, cprev.Z, mprev); }
public void TestClone() { ICoordinateSequence s1 = CoordinateArraySequenceFactory.Instance.Create( new[] { new Coordinate(1, 2), new Coordinate(3, 4) }); ICoordinateSequence s2 = (ICoordinateSequence)s1.Clone(); Assert.IsTrue(s1.GetCoordinate(0).Equals(s2.GetCoordinate(0))); Assert.IsTrue(s1.GetCoordinate(0) != s2.GetCoordinate(0)); }
public void Filter(ICoordinateSequence seq, int i) { if (i == 0) { return; } seq.GetCoordinate(i - 1, p0); seq.GetCoordinate(i, p1); rcc.CountSegment(p0, p1); }
/// <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); }
private void Add(ILineString lineString) { ICoordinateSequence seq = lineString.CoordinateSequence; for (int i = 1; i < seq.Count; i++) { Coordinate prev = seq.GetCoordinate(i - 1); Coordinate curr = seq.GetCoordinate(i); graph.AddEdge(prev, curr); } }
public void Filter(ICoordinateSequence seq, int i) { // compare to vertex CheckVertexDistance(seq.GetCoordinate(i)); // compare to segment, if this is one if (i > 0) { CheckSegmentDistance(seq.GetCoordinate(i - 1), seq.GetCoordinate(i)); } }
private static ICoordinateSequence InsertTopologyExceptionPoint(Coordinate coord, ICoordinateSequence seq, ICoordinateSequenceFactory factory) { var res = factory.Create(2 * seq.Count, seq.Ordinates); if (Replace(seq.GetCoordinate(0), coord)) { res.SetOrdinate(0, Ordinate.X, coord.X); res.SetOrdinate(0, Ordinate.Y, coord.Y); res.SetOrdinate(0, Ordinate.Z, coord.Z); } else { res.SetOrdinate(0, Ordinate.X, seq.GetOrdinate(0, Ordinate.X)); res.SetOrdinate(0, Ordinate.Y, seq.GetOrdinate(0, Ordinate.Y)); res.SetOrdinate(0, Ordinate.Z, seq.GetOrdinate(0, Ordinate.Z)); } var last = res.GetCoordinate(0); int off = 0; for (int i = 1; i < seq.Count; i++) { var curr = seq.GetCoordinate(i); bool add = true; if (Replace(curr, coord)) { res.SetOrdinate(i + off, Ordinate.X, coord.X); res.SetOrdinate(i + off, Ordinate.Y, coord.Y); res.SetOrdinate(i + off, Ordinate.Z, coord.Z); add = false; } else if (last.Distance(coord) + coord.Distance(curr) <= 1.000000000000000000001 * last.Distance(curr)) { res.SetOrdinate(i + off, Ordinate.X, coord.X); res.SetOrdinate(i + off, Ordinate.Y, coord.Y); res.SetOrdinate(i + off, Ordinate.Z, coord.Z); off += 1; } if (add) { res.SetOrdinate(i + off, Ordinate.X, seq.GetOrdinate(i, Ordinate.X)); res.SetOrdinate(i + off, Ordinate.Y, seq.GetOrdinate(i, Ordinate.Y)); res.SetOrdinate(i + off, Ordinate.Z, seq.GetOrdinate(i, Ordinate.Z)); } last = curr; } var tmp = factory.Create(seq.Count + off, seq.Ordinates); CoordinateSequences.Copy(res, 0, tmp, 0, tmp.Count); return(tmp); }
private void ExtractPoints(ILineString line, double offsetDistance, IList <Coordinate> offsetPts) { ICoordinateSequence coordinateSequence = line.CoordinateSequence; int maxIndex = coordinateSequence.Count - 1; for (int i = 0; i < maxIndex; i++) { ComputeOffsetPoints( coordinateSequence.GetCoordinate(i), coordinateSequence.GetCoordinate(i + 1), offsetDistance, offsetPts); } }
public void TestCloneDimension2() { ICoordinateSequence s1 = CoordinateArraySequenceFactory.Instance.Create(2, 2); s1.SetOrdinate(0, Ordinate.X, 1); s1.SetOrdinate(0, Ordinate.Y, 2); s1.SetOrdinate(1, Ordinate.X, 3); s1.SetOrdinate(1, Ordinate.Y, 4); ICoordinateSequence s2 = (ICoordinateSequence)s1.Clone(); Assert.IsTrue(s1.Dimension == s2.Dimension); Assert.IsTrue(s1.GetCoordinate(0).Equals(s2.GetCoordinate(0))); Assert.IsTrue(s1.GetCoordinate(0) != s2.GetCoordinate(0)); }
/// <summary> /// /// </summary> /// <param name="geom"></param> protected override void Visit(IGeometry geom) { if (!(geom is Polygon)) { return; } IEnvelope elementEnv = geom.EnvelopeInternal; if (!rectEnv.Intersects(elementEnv)) { return; } // test each corner of rectangle for inclusion Coordinate rectPt = new Coordinate(); for (int i = 0; i < 4; i++) { rectSeq.GetCoordinate(i, rectPt); if (!elementEnv.Contains(rectPt)) { continue; } // check rect point in poly (rect is known not to touch polygon at this point) if (SimplePointInAreaLocator.ContainsPointInPolygon(rectPt, (Polygon)geom)) { containsPoint = true; return; } } }
/// <summary> /// Computes the length of a linestring specified by a sequence of points. /// </summary> /// <param name="pts">The points specifying the linestring.</param> /// <returns>The length of the linestring.</returns> public static double Length(ICoordinateSequence pts) { if (pts.Count < 1) { return(0.0); } double sum = 0.0; for (int i = 1; i < pts.Count; i++) { sum += pts.GetCoordinate(i).Distance(pts.GetCoordinate(i - 1)); } return(sum); }
/// <summary> /// Determines the <see cref="Location"/> of a point in a ring. /// </summary> /// <param name="p">The point to test</param> /// <param name="ring">A coordinate sequence forming a ring</param> /// <returns>The location of the point in the ring</returns> public static Location LocatePointInRing(Coordinate p, ICoordinateSequence ring) { var counter = new RayCrossingCounter(p); var p1 = new Coordinate(); var p2 = new Coordinate(); for (var i = 1; i < ring.Count; i++) { ring.GetCoordinate(i, p1); ring.GetCoordinate(i - 1, p2); counter.CountSegment(p1, p2); if (counter.IsOnSegment) return counter.Location; } return counter.Location; }
/// <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 void Filter(ICoordinateSequence seq, int index) { if (index == 0) { return; } var p0 = seq.GetCoordinate(index - 1); var p1 = seq.GetCoordinate(index); var midPt = new Coordinate( (p0.X + p1.X) / 2, (p0.Y + p1.Y) / 2); minPtDist.Initialize(); DistanceToPointFinder.ComputeDistance(geom, midPt, minPtDist); maxPtDist.SetMaximum(minPtDist); }
/// <summary> /// /// </summary> /// <param name="seq0"></param> /// <param name="seq1"></param> /// <returns></returns> public bool HasIntersection(ICoordinateSequence seq0, ICoordinateSequence seq1) { for (int i = 1; i < seq0.Count && ! hasIntersection; i++) { seq0.GetCoordinate(i - 1, pt00); seq0.GetCoordinate(i, pt01); for (int j = 1; j < seq1.Count && ! hasIntersection; j++) { seq1.GetCoordinate(j - 1, pt10); seq1.GetCoordinate(j, pt11); li.ComputeIntersection(pt00, pt01, pt10, pt11); if (li.HasIntersection) hasIntersection = true; } } return hasIntersection; }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <returns></returns> private bool IsLineStringContainedInBoundary(ILineString line) { ICoordinateSequence seq = line.CoordinateSequence; ICoordinate p0 = new Coordinate(); ICoordinate p1 = new Coordinate(); for (int i = 0; i < seq.Count - 1; i++) { seq.GetCoordinate(i, p0); seq.GetCoordinate(i + 1, p1); if (!IsLineSegmentContainedInBoundary(p0, p1)) { return(false); } } return(true); }
public static MCoordinate[] Copy(ICoordinateSequence coordSeq) { MCoordinate[] copy = new MCoordinate[coordSeq.Count]; for (int i = 0; i < coordSeq.Count; i++) { copy[i] = new MCoordinate(coordSeq.GetCoordinate(i)); } return copy; }
public static MCoordinate[] Copy(ICoordinateSequence coordSeq) { MCoordinate[] copy = new MCoordinate[coordSeq.Count]; for (int i = 0; i < coordSeq.Count; i++) { copy[i] = new MCoordinate(coordSeq.GetCoordinate(i)); } return(copy); }
/// <summary> /// Tests whether a point lies on the line defined by a list of /// coordinates. /// </summary> /// <param name="p">The point to test</param> /// <param name="line">The line coordinates</param> /// <returns> /// <c>true</c> if the point is a vertex of the line or lies in the interior /// of a line segment in the line /// </returns> public static bool IsOnLine(Coordinate p, ICoordinateSequence line) { var lineIntersector = new RobustLineIntersector(); var p0 = new Coordinate(); var p1 = new Coordinate(); int n = line.Count; for (int i = 1; i < n; i++) { line.GetCoordinate(i - 1, p0); line.GetCoordinate(i, p1); lineIntersector.ComputeIntersection(p, p0, p1); if (lineIntersector.HasIntersection) { return(true); } } return(false); }
/// <summary> /// /// </summary> /// <param name="seq0"></param> /// <param name="seq1"></param> /// <returns></returns> public bool HasIntersection(ICoordinateSequence seq0, ICoordinateSequence seq1) { for (int i = 1; i < seq0.Count && !_hasIntersection; i++) { seq0.GetCoordinate(i - 1, pt00); seq0.GetCoordinate(i, pt01); for (int j = 1; j < seq1.Count && !_hasIntersection; j++) { seq1.GetCoordinate(j - 1, pt10); seq1.GetCoordinate(j, pt11); li.ComputeIntersection(pt00, pt01, pt10, pt11); if (li.HasIntersection) { _hasIntersection = true; } } } return(_hasIntersection); }
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)); } }
/// <summary> /// Determines the <see cref="Location"/> of a point in a ring. /// </summary> /// <param name="p">The point to test</param> /// <param name="ring">A coordinate sequence forming a ring</param> /// <returns>The location of the point in the ring</returns> public static Location LocatePointInRing(Coordinate p, ICoordinateSequence ring) { var counter = new RayCrossingCounter(p); var p1 = new Coordinate(); var p2 = new Coordinate(); for (var i = 1; i < ring.Count; i++) { ring.GetCoordinate(i, p1); ring.GetCoordinate(i - 1, p2); counter.CountSegment(p1, p2); if (counter.IsOnSegment) { return(counter.Location); } } return(counter.Location); }
private bool IsWithinToleranceOfBoundary(Coordinate pt) { for (int i = 0; i < _linework.NumGeometries; i++) { ILineString line = (ILineString)_linework.GetGeometryN(i); ICoordinateSequence seq = line.CoordinateSequence; for (int j = 0; j < seq.Count - 1; j++) { seq.GetCoordinate(j, _seg.P0); seq.GetCoordinate(j + 1, _seg.P1); double dist = _seg.Distance(pt); if (dist <= _boundaryDistanceTolerance) { return(true); } } } return(false); }
/** * Adds a double array to list. * * <p> * The double array will contain all the ordinates in the Coordiante * sequence. * </p> * * @param list * @param sequence */ private static void AddCoordinates(List <double[]> list, ICoordinateSequence sequence) { for (int i = 0; i < sequence.Count; i++) { Coordinate coord = sequence.GetCoordinate(i); list.Add(Double.IsNaN(coord.Z) ? new[] { coord.X, coord.Y } : new[] { coord.X, coord.Y, coord.Z }); } }
/** * Computes an average normal vector from a list of polygon coordinates. * Uses Newell's method, which is based * on the fact that the vector with components * equal to the areas of the projection of the polygon onto * the Cartesian axis planes is normal. * * @param seq the sequence of coordinates for the polygon * @return a normal vector */ private static Vector3D AverageNormal(ICoordinateSequence seq) { var n = seq.Count; var sum = new Coordinate(0, 0, 0); var p1 = new Coordinate(0, 0, 0); var p2 = new Coordinate(0, 0, 0); for (var i = 0; i < n - 1; i++) { seq.GetCoordinate(i, p1); seq.GetCoordinate(i + 1, p2); sum.X += (p1.Y - p2.Y) * (p1.Z + p2.Z); sum.Y += (p1.Z - p2.Z) * (p1.X + p2.X); sum.Z += (p1.X - p2.X) * (p1.Y + p2.Y); } sum.X /= n; sum.Y /= n; sum.Z /= n; var norm = Vector3D.Create(sum).Normalize(); return norm; }
public IGeometry Densify(double segLength) { newCoords = new CoordinateList(); ICoordinateSequence seq = inputLine.CoordinateSequence; Coordinate p0 = new Coordinate(); Coordinate p1 = new Coordinate(); seq.GetCoordinate(0, p0); newCoords.Add(new Coordinate(p0)); for (int i = 0; i < seq.Count - 1; i++) { seq.GetCoordinate(i, p0); seq.GetCoordinate(i + 1, p1); Densify(p0, p1, segLength); } Coordinate[] newPts = newCoords.ToCoordinateArray(); return(inputLine.Factory.CreateLineString(newPts)); }
private void Add(ILineString lineString) { if (_factory == null) { _factory = lineString.Factory; } ICoordinateSequence seq = lineString.CoordinateSequence; for (int i = 1; i < seq.Count; i++) { Coordinate prev = seq.GetCoordinate(i - 1); Coordinate curr = seq.GetCoordinate(i); DissolveHalfEdge e = (DissolveHalfEdge)_graph.AddEdge(prev, curr); // Record source initial segments, so that they can be reflected in output when needed // (i.e. during formation of isolated rings) if (i == 1) { e.SetStart(); } } }
/** * Computes an average normal vector from a list of polygon coordinates. * Uses Newell's method, which is based * on the fact that the vector with components * equal to the areas of the projection of the polygon onto * the Cartesian axis planes is normal. * * @param seq the sequence of coordinates for the polygon * @return a normal vector */ private static Vector3D AverageNormal(ICoordinateSequence seq) { var n = seq.Count; var sum = new Coordinate(0, 0, 0); var p1 = new Coordinate(0, 0, 0); var p2 = new Coordinate(0, 0, 0); for (var i = 0; i < n - 1; i++) { seq.GetCoordinate(i, p1); seq.GetCoordinate(i + 1, p2); sum.X += (p1.Y - p2.Y) * (p1.Z + p2.Z); sum.Y += (p1.Z - p2.Z) * (p1.X + p2.X); sum.Z += (p1.X - p2.X) * (p1.Y + p2.Y); } sum.X /= n; sum.Y /= n; sum.Z /= n; var norm = Vector3D.Create(sum).Normalize(); return(norm); }
/// <summary> /// Returns the minimum coordinate, using the usual lexicographic comparison. /// </summary> /// <param name="seq">The coordinate sequence to search</param> /// <returns>The minimum coordinate in the sequence, found using <see cref="Coordinate.CompareTo(Coordinate)"/></returns> public static Coordinate MinCoordinate(ICoordinateSequence seq) { Coordinate minCoord = null; for (int i = 0; i < seq.Count; i++) { var testCoord = seq.GetCoordinate(i); if (minCoord == null || minCoord.CompareTo(testCoord) > 0) { minCoord = testCoord; } } return(minCoord); }
/// <summary> /// Computes the distance from a point to a sequence of line segments. /// </summary> /// <param name="p">A point</param> /// <param name="line">A sequence of contiguous line segments defined by their vertices</param> /// <returns>The minimum distance between the point and the line segments</returns> public static double PointToSegmentString(Coordinate p, ICoordinateSequence line) { if (line.Count == 0) { throw new ArgumentException( "Line array must contain at least one vertex"); } // this handles the case of length = 1 var lastStart = line.GetCoordinate(0); double minDistance = p.Distance(lastStart); for (int i = 1; i < line.Count - 1; i++) { var currentEnd = line.GetCoordinate(i); double dist = DistanceComputer.PointToSegment(p, lastStart, currentEnd); if (dist < minDistance) { minDistance = dist; } lastStart = currentEnd; } return(minDistance); }
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"); } }
private static void WriteCompressedXY(ICoordinateSequence coordinateSequence, GaiaExport export, BinaryWriter bw) { var wd = export.WriteDouble; // Write initial coordinate var cprev = coordinateSequence.GetCoordinate(0); wd(bw, cprev.X, cprev.Y); var ws = export.WriteSingle; var maxIndex = coordinateSequence.Count - 1; if (maxIndex <= 0) return; for (var i = 1; i < maxIndex; i++) { var c = coordinateSequence.GetCoordinate(i); var fx = (float)(c.X - cprev.X); var fy = (float)(c.Y - cprev.Y); ws(bw, fx, fy); cprev = c; } // Write last coordinate cprev = coordinateSequence.GetCoordinate(maxIndex); wd(bw, cprev.X, cprev.Y); }
private static void WriteCompressedXYZM(ICoordinateSequence coordinateSequence, GaiaExport export, BinaryWriter bw) { var wd = export.WriteDouble; // Write initial coordinate var cprev = coordinateSequence.GetCoordinate(0); var mprev = coordinateSequence.GetOrdinate(0, Ordinate.M); wd(bw, cprev.X, cprev.Y, cprev.Z, mprev); var maxIndex = coordinateSequence.Count - 1; if (maxIndex <= 0) return; var ws = export.WriteSingle; for (var i = 1; i < maxIndex; i++) { var c = coordinateSequence.GetCoordinate(i); var fx = (float)(c.X - cprev.X); var fy = (float)(c.Y - cprev.Y); var fz = (float)(c.Z - cprev.Z); var fm = (float)(coordinateSequence.GetOrdinate(i, Ordinate.M) - mprev); ws(bw, fx, fy, fz, fm); cprev = c; } cprev = coordinateSequence.GetCoordinate(maxIndex); mprev = coordinateSequence.GetOrdinate(maxIndex, Ordinate.M); wd(bw, cprev.X, cprev.Y, cprev.Z, mprev); }
/// <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; }
public void Filter(ICoordinateSequence seq, int index) { if (index == 0) return; var p0 = seq.GetCoordinate(index - 1); var p1 = seq.GetCoordinate(index); var midPt = new Coordinate( (p0.X + p1.X) / 2, (p0.Y + p1.Y) / 2); minPtDist.Initialize(); DistanceToPointFinder.ComputeDistance(geom, midPt, minPtDist); maxPtDist.SetMaximum(minPtDist); }
/** * Adds a double array to list. * * <p> * The double array will contain all the ordinates in the Coordiante * sequence. * </p> * * @param list * @param sequence */ private static void AddCoordinates(List<double[]> list, ICoordinateSequence sequence) { for (int i = 0; i < sequence.Count; i++) { Coordinate coord = sequence.GetCoordinate(i); list.Add(Double.IsNaN(coord.Z) ? new[] {coord.X, coord.Y} : new[] {coord.X, coord.Y, coord.Z}); } }
public void Filter(ICoordinateSequence seq, int index) { /** * This logic also handles skipping Point geometries */ if (index == 0) return; var p0 = seq.GetCoordinate(index - 1); var p1 = seq.GetCoordinate(index); var delx = (p1.X - p0.X) / _numSubSegs; var dely = (p1.Y - p0.Y) / _numSubSegs; for (var i = 0; i < _numSubSegs; i++) { var x = p0.X + i * delx; var y = p0.Y + i * dely; var pt = new Coordinate(x, y); _minPtDist.Initialize(); DistanceToPoint.ComputeDistance(_geom, pt, _minPtDist); _maxPtDist.SetMaximum(_minPtDist); } }
/// <summary> /// Computes the length of a linestring specified by a sequence of points. /// </summary> /// <param name="pts">The points specifying the linestring</param> /// <returns>The length of the linestring</returns> public static double Length(ICoordinateSequence pts) { // optimized for processing CoordinateSequences int n = pts.Count; if (n <= 1) return 0.0; double len = 0.0; var p0 = pts.GetCoordinate(0); for (int i = 1; i < n; i++) { var p1 = pts.GetCoordinate(i); len += p1.Distance(p0); p0 = p1; } return len; }
/// <summary> /// Computes the length of a linestring specified by a sequence of points. /// </summary> /// <param name="pts">The points specifying the linestring</param> /// <returns>The length of the linestring</returns> public static double Length(ICoordinateSequence pts) { // optimized for processing CoordinateSequences int n = pts.Count; if (n <= 1) return 0.0; double len = 0.0; var p = new Coordinate(); pts.GetCoordinate(0, p); double x0 = p.X; double y0 = p.Y; for (int i = 1; i < n; i++) { pts.GetCoordinate(i, p); double x1 = p.X; double y1 = p.Y; double dx = x1 - x0; double dy = y1 - y0; len += Math.Sqrt(dx * dx + dy * dy); x0 = x1; y0 = y1; } return len; }
/// <summary> /// Computes the length of a linestring specified by a sequence of points. /// </summary> /// <param name="pts">The points specifying the linestring.</param> /// <returns>The length of the linestring.</returns> public static double Length(ICoordinateSequence pts) { if (pts.Count < 1) return 0.0; double sum = 0.0; for (int i = 1; i < pts.Count; i++) sum += pts.GetCoordinate(i).Distance(pts.GetCoordinate(i - 1)); return sum; }
/// <summary> /// Computes the signed area for a ring. /// <remarks> /// <para> /// The signed area is /// </para> /// <list type="Table"> /// <item>positive</item><description>if the ring is oriented CW</description> /// <item>negative</item><description>if the ring is oriented CCW</description> /// <item>zero</item><description>if the ring is degenerate or flat</description> /// </list> /// </remarks> /// </summary> /// <param name="ring">The coordinates forming the ring</param> /// <returns>The signed area of the ring</returns> public static double SignedArea(ICoordinateSequence ring) { var n = ring.Count; if (n < 3) return 0.0; /** * Based on the Shoelace formula. * http://en.wikipedia.org/wiki/Shoelace_formula */ var p0 = new Coordinate(); var p1 = new Coordinate(); var p2 = new Coordinate(); ring.GetCoordinate(0, p1); ring.GetCoordinate(1, p2); var x0 = p1.X; p2.X -= x0; var sum = 0.0; for (var i = 1; i < n - 1; i++) { p0.Y = p1.Y; p1.X = p2.X; p1.Y = p2.Y; ring.GetCoordinate(i + 1, p2); p2.X -= x0; sum += p1.X * (p0.Y - p2.Y); } return sum / 2.0; }
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; }
public ICoordinateSequence Transform(ICoordinateSequence coordinateSequence) { var clone = new Coordinate(); for (var i = 0; i < coordinateSequence.Count; i++) { clone.CoordinateValue = coordinateSequence.GetCoordinate(i); clone = Transform(clone); coordinateSequence.SetOrdinate(i, Ordinate.X, clone.X); coordinateSequence.SetOrdinate(i, Ordinate.Y, clone.Y); if (DimTarget > 2) coordinateSequence.SetOrdinate(i, Ordinate.Z, clone.Z); } return coordinateSequence; }
/// <summary> /// Creates a MultiPoint using the given CoordinateSequence; a null or empty CoordinateSequence will /// create an empty MultiPoint. /// </summary> /// <param name="coordinates">A CoordinateSequence possibly empty, or null.</param> public IMultiPoint CreateMultiPoint(ICoordinateSequence coordinates) { if (coordinates == null) coordinates = CoordinateSequenceFactory.Create(new ICoordinate[] { }); List<IPoint> points = new List<IPoint>(); for (int i = 0; i < coordinates.Count; i++) points.Add(CreatePoint(coordinates.GetCoordinate(i))); return CreateMultiPoint(points.ToArray()); }
/// <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; }