private void AppendCoordinates(StringBuilder builder, CoordinateSequence coordinates) { for (var i = 0; i < coordinates.Count; i++) { if (i > 0) builder.Append(", "); AppendCoordinate(builder, coordinates[i]); } }
public Distance CalculateLength(CoordinateSequence coordinates) { var distance = 0d; for (var i = 1; i < coordinates.Count; i++) { var result = CalculateOrthodromicLineInternal(coordinates[i - 1], coordinates[i]); if (result != null) distance += result[0]; } return new Distance(distance); }
public Area CalculateArea(CoordinateSequence coordinates) { var area = 0.0; if (coordinates.Count > 3 && coordinates.IsClosed) { for (var i = 0; i < coordinates.Count - 1; i++) { var p1 = coordinates[i]; var p2 = coordinates[i + 1]; area += (p2.Longitude - p1.Longitude).ToRadians() * (2 + Math.Sin(p1.Latitude.ToRadians()) + Math.Sin(p2.Latitude.ToRadians())); } area = area * Radius * Radius / 2.0; } return new Area(area); }
/** * Returns the measure length of the segment. This method assumes that the * length of the LineString is defined by the absolute value of (last * coordinate - first coordinate) in the CoordinateSequence. If either * measure is not defined or the CoordinateSequence contains no coordinates, * then Double.NaN is returned. If there is only 1 element in the * CoordinateSequence, then 0 is returned. * * @return The measure length of the LineString */ public double GetMLength() { if (CoordinateSequence.Count == 0) { return(Double.NaN); } if (CoordinateSequence.Count == 1) { return(0.0D); } int lastIndex = CoordinateSequence.Count - 1; double begin = CoordinateSequence.GetOrdinate(0, Ordinates.M); double end = CoordinateSequence.GetOrdinate(lastIndex, Ordinates.M); return((Double.IsNaN(begin) || Double.IsNaN(end)) ? Double.NaN : Math.Abs(end - begin)); }
public override CoordinateSequence Edit(CoordinateSequence coordSeq, Geometry geometry, GeometryFactory targetFactory) { if (_geometryLinesMap.ContainsKey(geometry)) { var pts = _geometryLinesMap[geometry]; // Assert: pts should always have length > 0 bool isValidPts = IsValidSize(pts, geometry); if (!isValidPts) { return(null); } return(targetFactory.CoordinateSequenceFactory.Create(pts)); } //TODO: should this return null if no matching snapped line is found // probably should never reach here? return(coordSeq); }
public Area CalculateArea(CoordinateSequence coordinates) { var area = 0.0; if (coordinates.Count > 3 && coordinates.IsClosed) { for (var i = 0; i < coordinates.Count - 1; i++) { var p1 = coordinates[i]; var p2 = coordinates[i + 1]; area += (p2.Longitude - p1.Longitude).ToRadians() * (2 + Math.Sin(p1.Latitude.ToRadians()) + Math.Sin(p2.Latitude.ToRadians())); } area = area * Radius * Radius / 2.0; } return(new Area(area)); }
/// <summary> /// Transforms the coordinate at <paramref name="index"/> of <paramref name="sequence"/> to the tile coordinate system. /// The return value is the position relative to the local point at (<paramref name="currentX"/>, <paramref name="currentY"/>). /// </summary> /// <param name="sequence">The input sequence</param> /// <param name="index">The index of the coordinate to transform</param> /// <param name="currentX">The current horizontal component of the cursor location. This value is updated.</param> /// <param name="currentY">The current vertical component of the cursor location. This value is updated.</param> /// <returns>The position relative to the local point at (<paramref name="currentX"/>, <paramref name="currentY"/>).</returns> public (int x, int y) Transform(CoordinateSequence sequence, int index, ref int currentX, ref int currentY) { var lon = sequence.GetOrdinate(index, Ordinate.X); var lat = sequence.GetOrdinate(index, Ordinate.Y); var meters = WebMercatorHandler.LatLonToMeters(lat, lon); var pixels = WebMercatorHandler.MetersToPixels(meters, _tile.Zoom, (int)_extent); int localX = (int)(pixels.x - _left); int localY = (int)(_top - pixels.y); int dx = localX - currentX; int dy = localY - currentY; currentX = localX; currentY = localY; return(dx, dy); }
private CoordinateSequence[] ReadSinglePointSequences(TileGeometryTransform tgs, IList <uint> geometry, int numSequences, ref int currentIndex, ref int currentX, ref int currentY) { var res = new CoordinateSequence[numSequences]; var currentPosition = (currentX, currentY); for (int i = 0; i < numSequences; i++) { res[i] = _factory.CoordinateSequenceFactory.Create(1, 2); currentPosition = ParseOffset(currentPosition, geometry, ref currentIndex); TransformOffsetAndAddToSequence(tgs, currentPosition, res[i], 0); } currentX = currentPosition.currentX; currentY = currentPosition.currentY; return(res); }
public static bool IsCCW(Geometry g) { CoordinateSequence pts = null; if (g is Polygon) { pts = ((Polygon)g).ExteriorRing.CoordinateSequence; } else if (g is LineString && ((LineString)g).IsClosed) { pts = ((LineString)g).CoordinateSequence; } if (pts == null) { return(false); } return(Orientation.IsCCW(pts)); }
public void Filter(CoordinateSequence seq, int i) { if (i <= 0) { return; } // extract LineSegment var p0 = seq.GetCoordinate(i - 1); var p1 = seq.GetCoordinate(i); bool isBorder = Intersects(_envelope, p0, p1) && !ContainsProperly(_envelope, p0, p1); if (isBorder) { var seg = new LineSegment(p0, p1); _segments.Add(seg); } }
/// <summary> /// Evaluates the <see cref="Interval"/> of the <paramref name="ordinate"/>-values in /// <paramref name="sequence"/> and writes it using the provided <paramref name="writer"/> /// </summary> /// <param name="sequence">The sequence</param> /// <param name="ordinate">The ordinate</param> /// <param name="writer">The writer</param> protected void WriteInterval(CoordinateSequence sequence, Ordinate ordinate, BinaryWriter writer) { Interval interval; if (!sequence.TryGetOrdinateIndex(ordinate, out int ordinateIndex)) { interval = ordinate == Ordinate.M ? Interval.Create(ShapeFileConstants.NoDataValue) : Interval.Create(double.NaN); } else if (ordinate == Ordinate.M) { double val = sequence.GetOrdinate(0, ordinateIndex); if (double.IsNaN(val)) { val = ShapeFileConstants.NoDataValue; } interval = Interval.Create(val); for (int i = 1, cnt = sequence.Count; i < cnt; i++) { val = sequence.GetOrdinate(i, ordinateIndex); if (double.IsNaN(val)) { val = ShapeFileConstants.NoDataValue; } interval = interval.ExpandedByValue(val); } } else { double val = sequence.GetOrdinate(0, ordinateIndex); interval = Interval.Create(val); for (int i = 1, cnt = sequence.Count; i < cnt; i++) { interval = interval.ExpandedByValue(sequence.GetOrdinate(i, ordinateIndex)); } } writer.Write(interval.Min); writer.Write(interval.Max); }
public void Filter(CoordinateSequence seq) { if (!seq.HasZ) { // if no Z then short-circuit evaluation Done = true; return; } for (int i = 0; i < seq.Count; i++) { // if Z not populated then assign using model if (double.IsNaN(seq.GetZ(i))) { double z = _em.GetZ(seq.GetOrdinate(i, Ordinate.X), seq.GetOrdinate(i, Ordinate.Y)); seq.SetOrdinate(i, Ordinate.Z, z); } } }
/// <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, CoordinateSequence line) { var lineIntersector = new RobustLineIntersector(); var p0 = line.CreateCoordinate(); var p1 = p0.Copy(); 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); }
private static void AddFacetSequences(Geometry geom, CoordinateSequence pts, List <FacetSequence> sections) { int i = 0; int size = pts.Count; while (i <= size - 1) { int end = i + FacetSequenceSize + 1; // if only one point remains after this section, include it in this // section if (end >= size - 1) { end = size; } var sect = new FacetSequence(geom, pts, i, end); sections.Add(sect); i = i + FacetSequenceSize; } }
/// <summary> /// /// </summary> /// <param name="seq0"></param> /// <param name="seq1"></param> /// <returns></returns> public bool HasIntersection(CoordinateSequence seq0, CoordinateSequence 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="coordinates"></param> /// <param name="writer"></param> protected void WriteCoordinates(CoordinateSequence coordinates, XmlWriter writer) { writer.WriteStartElement(GMLElements.gmlPrefix, _gmlVersion == GMLVersion.Two ? "coordinates" : "posList", GMLElements.gmlNS); var sb = new StringBuilder(); string coordsFormatter = _gmlVersion == GMLVersion.Two ? "{0},{1} " : "{0} {1} "; for (int i = 0, cnt = coordinates.Count; i < cnt; i++) { sb.AppendFormat(NumberFormatter, coordsFormatter, coordinates.GetX(i), coordinates.GetY(i)); } // remove the trailing space. if (sb.Length > 0) { --sb.Length; } writer.WriteString($"{sb}"); writer.WriteEndElement(); }
/// <summary> /// Determines the <see cref="Geometries.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, CoordinateSequence ring) { var counter = new RayCrossingCounter(p); var p1 = ring.CreateCoordinate(); var p2 = ring.CreateCoordinate(); int count = ring.Count; for (int i = 1; i < count; i++) { ring.GetCoordinate(i, p1); ring.GetCoordinate(i - 1, p2); counter.CountSegment(p1, p2); if (counter.IsOnSegment) { return(counter.Location); } } return(counter.Location); }
public LineString Linearize(double tolerance) { // use the cached one if we are asked for the default geometry tolerance bool isDefaultTolerance = CoordinateSequences.Arc.Equals(tolerance, this.tolerance); if (linearized != null && isDefaultTolerance) { return(linearized); } CoordinateSequence cs = GetLinearizedCoordinateSequence(tolerance); LineString result = new LineString(cs, Factory); if (isDefaultTolerance) { linearized = result; } return(result); }
protected static void WriteCoords(CoordinateSequence points, BinaryWriter file, List <double> zList, List <double> mList) { for (int i = 0; i < points.Count; i++) { file.Write(points.GetX(i)); file.Write(points.GetY(i)); zList?.Add(points.HasZ ? points.GetZ(i) : 0); if (!(mList is null)) { double m = points.GetM(i); if (m.Equals(Coordinate.NullOrdinate)) { m = NoDataValue; } mList.Add(m); } } }
/// <summary> /// Write a <see cref="CoordinateSequence"/>. /// </summary> /// <param name="sequence">The coordinate sequence to write</param> /// <param name="emitSize">A flag indicating if the size of <paramref name="sequence"/> should be written, too.</param> /// <param name="writer">The writer.</param> protected void Write(CoordinateSequence sequence, bool emitSize, BinaryWriter writer) { if (emitSize) { writer.Write(sequence.Count); } // zm-values if not provided by sequence double ordinateZ = Coordinate.NullOrdinate; double ordinateM = Coordinate.NullOrdinate; // test if zm-values are provided by sequence bool getZ = sequence.HasZ; bool getM = sequence.HasM; // test if zm-values should be emitted bool writeZ = (HandleOrdinates & Ordinates.Z) == Ordinates.Z; bool writeM = (HandleOrdinates & Ordinates.M) == Ordinates.M; for (int index = 0; index < sequence.Count; index++) { writer.Write(sequence.GetOrdinate(index, 0)); writer.Write(sequence.GetOrdinate(index, 1)); if (writeZ) { if (getZ) { ordinateZ = sequence.GetZ(index); } writer.Write(ordinateZ); } if (writeM) { if (getM) { ordinateM = sequence.GetM(index); } writer.Write(ordinateM); } } }
private static Ordinates CheckOrdinates(CoordinateSequence sequence) { if (sequence == null || sequence.Count == 0) { return(Ordinates.None); } var result = Ordinates.XY; if (sequence.HasZ && !double.IsNaN(sequence.GetZ(0))) { result |= Ordinates.Z; } if (sequence.HasM && !double.IsNaN(sequence.GetM(0))) { result |= Ordinates.M; } return(result); }
/// <inheritdoc /> public void Filter(CoordinateSequence seq, int i) { if (_checkOrdinateFlags.HasFlag(Ordinates.Z) && !_outputOrdinates.HasFlag(Ordinates.Z)) { if (!double.IsNaN(seq.GetZ(i))) { _outputOrdinates |= Ordinates.Z; } } if (_checkOrdinateFlags.HasFlag(Ordinates.M) && !_outputOrdinates.HasFlag(Ordinates.M)) { if (!double.IsNaN(seq.GetM(i))) { _outputOrdinates |= Ordinates.M; if (_alwaysEmitZWithM) { _outputOrdinates |= Ordinates.Z; } } } }
private void WriteRing(StringBuilder sb, LineString component) { if (component is ICurvedGeometry <LineString> curved) { sb.Append(curved.ToCurvedText()); } else { sb.Append("("); CoordinateSequence cs = component.CoordinateSequence; for (int i = 0; i < cs.Count; ++i) { sb.Append(cs.GetX(i) + " " + cs.GetY(i)); //TODO: ZM? if (i < cs.Count - 1) { sb.Append(", "); } } sb.Append(")"); } }
/** * 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(CoordinateSequence seq) { int n = seq.Count; var sum = new CoordinateZ(0, 0, 0); var p1 = new CoordinateZ(0, 0, 0); var p2 = new CoordinateZ(0, 0, 0); for (int 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> /// Tries to add another sequence onto the start or end of this one. /// If it succeeds, the other sequence may also be modified and /// should be considered "spent". /// </summary> /// <param name="other">CoordinateSequence.</param> public bool TryAdd(CoordinateSequence other) { if (LastNode == other.FirstNode) { //add the sequence at the end _nodes.RemoveAt(_nodes.Count - 1); AddAll(other); MergeTags(other.Tags); return(true); } if (LastNode == other.LastNode) { //add the sequence backwards at the end _nodes.RemoveAt(_nodes.Count - 1); other.Reverse(); AddAll(other); MergeTags(other.Tags); return(true); } if (FirstNode == other.LastNode) { //add the sequence at the beginning _nodes.RemoveAt(0); AddAll(0, other); MergeTags(other.Tags); return(true); } if (FirstNode == other.FirstNode) { //add the sequence backwards at the beginning _nodes.RemoveAt(0); other.Reverse(); AddAll(0, other); MergeTags(other.Tags); return(true); } return(false); }
// If X or Y is null, return an empty Point private Point makePointValid(Point point) { CoordinateSequence sequence = point.CoordinateSequence; GeometryFactory factory = point.Factory; CoordinateSequenceFactory csFactory = factory.CoordinateSequenceFactory; if (sequence.Count == 0) { return(point); } else if (Double.IsNaN(sequence.GetOrdinate(0, 0)) || Double.IsNaN(sequence.GetOrdinate(0, 1))) { return(factory.CreatePoint(csFactory.Create(0, sequence.Dimension))); } else if (sequence.Count == 1) { return(point); } else { throw new Exception(); //throw new RuntimeException("JTS cannot Create a point from a CoordinateSequence containing several points"); } }
void IEntireCoordinateSequenceFilter.Filter(CoordinateSequence seq) { /* * This logic also handles skipping Point geometries */ for (int index = 1; index < seq.Count; index++) { var p0 = seq.GetCoordinate(index - 1); var p1 = seq.GetCoordinate(index); double delx = (p1.X - p0.X) / _numSubSegs; double dely = (p1.Y - p0.Y) / _numSubSegs; for (int i = 0; i < _numSubSegs; i++) { double x = p0.X + i * delx; double y = p0.Y + i * dely; var pt = new Coordinate(x, y); var minPtDist = new PointPairDistance(); DistanceToPoint.ComputeDistance(_geom, pt, minPtDist); _maxPtDist.SetMaximum(minPtDist); } } }
private static void DoTest(CoordinateSequence forward, CoordinateSequence 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 = ToOrdinateArray(forward.Ordinates); int j = forward.Count; for (int 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 override CoordinateSequence TransformCoordinates(CoordinateSequence coords, Geometry parent) { return(_transform(coords)); }
/// <summary> /// Tests whether a point lies inside or on a ring. The ring may be oriented in /// either direction. A point lying exactly on the ring boundary is considered /// to be inside the ring. /// <para/> /// This method does <i>not</i> first check the point against the envelope of /// the ring. /// </summary> /// <param name="p">The point to check for ring inclusion</param> /// <param name="ring">A <c>CoordinateSequence</c> representing the ring (which must have /// first point identical to last point)</param> /// <returns><c>true</c> if p is inside ring</returns> public static bool IsInRing(Coordinate p, CoordinateSequence ring) { return(LocateInRing(p, ring) != Location.Exterior); }
public Distance CalculateLength(CoordinateSequence coordinates) { throw new NotImplementedException(); }
/// <summary> /// Determines whether a point lies in the interior, on the boundary, or in the /// exterior of a ring.The ring may be oriented in either direction. /// <para/> /// This method does<i> not</i> first check the point against the envelope of /// the ring. /// </summary> /// <param name="p">The point to check for ring inclusion</param> /// <param name="ring">A <c>CoordinateSequence</c> representing the ring (which must have /// first point identical to last point)</param> public static Location LocateInRing(Coordinate p, CoordinateSequence ring) { return(RayCrossingCounter.LocatePointInRing(p, ring)); }
public LineString(CoordinateSequence coordinates) { Coordinates = coordinates ?? new CoordinateSequence(); }
private void AppendLineStringInner(StringBuilder builder, CoordinateSequence lineString) { if (lineString.IsEmpty) { builder.Append("EMPTY"); return; } builder.Append("("); AppendCoordinates(builder, lineString); builder.Append(")"); }
private void WriteCoordinates(CoordinateSequence coordinates, WkbBinaryWriter writer) { writer.Write((uint)coordinates.Count); foreach (var coordinate in coordinates) WriteCoordinate(coordinate, writer); }
public void SetMeasureAtIndex(int index, double m) { CoordinateSequence.SetOrdinate(index, Ordinate.M, m); this.GeometryChanged(); }
private IEnumerable<double[]> WriteCoordinates(CoordinateSequence sequence) { return sequence.Select(WriteCoordinate).ToArray(); }
public LinearRing() { Coordinates = new CoordinateSequence(); }
public LineString(IEnumerable<Coordinate> coordinates) { Coordinates = new CoordinateSequence(coordinates); }
public Area CalculateArea(CoordinateSequence coordinates) { return _sphereCalculator.CalculateArea(coordinates); }
public LinearRing(CoordinateSequence coordinates) : base(coordinates) { if (coordinates != null && !coordinates.IsEmpty && !coordinates.IsClosed) throw new ArgumentException("The Coordinate Sequence must be closed to form a Linear Ring"); }
private void CheckCS(CoordinateSequence cs, Geometry geom) { Assert.That(IsEqual(cs, ExtractCS(geom)), Is.True); }
public LinearRing(IEnumerable<Coordinate> items) { Coordinates = new CoordinateSequence(items); }