public void Test3DPointSerialization() { var factory = GeometryFactory.Default; var point1 = factory.CreatePoint(new CoordinateZM(1, 2, 3, 4)); var feature1 = new Feature(point1, null); Feature feature2; using (var ms = new MemoryStream()) { var serializer = GeoJsonSerializer.Create(factory, 3); using (var writer = new StreamWriter(ms, Encoding.UTF8, 1024, true)) using (var jsonWriter = new JsonTextWriter(writer)) { serializer.Serialize(jsonWriter, feature1); } ms.Position = 0; using (var reader = new StreamReader(ms, Encoding.UTF8, true, 1024, true)) using (var jsonReader = new JsonTextReader(reader)) { feature2 = serializer.Deserialize <Feature>(jsonReader); } } Assert.That(feature2.Geometry, Is.InstanceOf <Point>()); var point2 = (Point)feature2.Geometry; Assert.That(point2.CoordinateSequence.HasZ); Assert.That(CoordinateSequences.IsEqual(point1.CoordinateSequence, point2.CoordinateSequence)); // GeoJSON doesn't support M, so there should NOT be an M present in round-trip. Assert.That(!point2.CoordinateSequence.HasM); }
private static void DoTestIsRing(CoordinateSequenceFactory factory, int dimension) { // arrange var ring = CreateCircle(factory, dimension, new Coordinate(), 5); var noRing = CreateCircularString(factory, dimension, new Coordinate(), 5, 0.1, 22); var empty = CreateAlmostRing(factory, dimension, 0); var incomplete1 = CreateAlmostRing(factory, dimension, 1); var incomplete2 = CreateAlmostRing(factory, dimension, 2); var incomplete3 = CreateAlmostRing(factory, dimension, 3); var incomplete4a = CreateAlmostRing(factory, dimension, 4); var incomplete4b = CoordinateSequences.EnsureValidRing(factory, incomplete4a); // act bool isRingRing = CoordinateSequences.IsRing(ring); bool isRingNoRing = CoordinateSequences.IsRing(noRing); bool isRingEmpty = CoordinateSequences.IsRing(empty); bool isRingIncomplete1 = CoordinateSequences.IsRing(incomplete1); bool isRingIncomplete2 = CoordinateSequences.IsRing(incomplete2); bool isRingIncomplete3 = CoordinateSequences.IsRing(incomplete3); bool isRingIncomplete4a = CoordinateSequences.IsRing(incomplete4a); bool isRingIncomplete4b = CoordinateSequences.IsRing(incomplete4b); // assert Assert.IsTrue(isRingRing); Assert.IsTrue(!isRingNoRing); Assert.IsTrue(isRingEmpty); Assert.IsTrue(!isRingIncomplete1); Assert.IsTrue(!isRingIncomplete2); Assert.IsTrue(!isRingIncomplete3); Assert.IsTrue(!isRingIncomplete4a); Assert.IsTrue(isRingIncomplete4b); }
private static void DoTestCopy(CoordinateSequenceFactory factory, int dimension) { // arrange var sequence = CreateSequenceFromOrdinates(factory, dimension); if (sequence.Count <= 7) { TestContext.WriteLine("sequence has a size of " + sequence.Count + ". Execution of this test needs a sequence " + "with more than 6 coordinates."); return; } var fullCopy = factory.Create(sequence.Count, dimension, 0); var partialCopy = factory.Create(sequence.Count - 5, dimension, 0); // act CoordinateSequences.Copy(sequence, 0, fullCopy, 0, sequence.Count); CoordinateSequences.Copy(sequence, 2, partialCopy, 0, partialCopy.Count); // assert for (int i = 0; i < fullCopy.Count; i++) { CheckCoordinateAt(sequence, i, fullCopy, i, dimension); } for (int i = 0; i < partialCopy.Count; i++) { CheckCoordinateAt(sequence, 2 + i, partialCopy, i, dimension); } // ToDo test if dimensions don't match }
public void CrossAndIntersectionTest() { // Arrange var gf = new GeometryFactory(new PrecisionModel(100000000)); var closestCoordinate = new Coordinate(152608, 594957); var closestLine = gf.CreateLineString(new[] { new Coordinate(152348, 595130), new Coordinate(152421, 595061), new Coordinate(152455, 595033), new Coordinate(152524, 595001), new Coordinate(152593, 594973), new Coordinate(152622, 594946), new Coordinate(152634, 594930), new Coordinate(152641, 594921), new Coordinate(152649, 594910), new Coordinate(152863, 594623), new Coordinate(152873, 594607) }); var indexedLine = new NetTopologySuite.LinearReferencing.LengthIndexedLine(closestLine); double projectedIndex = indexedLine.Project(closestCoordinate); var coordinateToAdd = indexedLine.ExtractPoint(projectedIndex); gf.PrecisionModel.MakePrecise(coordinateToAdd); var line = gf.CreateLineString(new[] { new Coordinate(152503, 594904), coordinateToAdd }); ToImage(0, closestLine, line, GeometryFactory.Default.CreatePoint(coordinateToAdd)); // act var intersectionPt = line.Intersection(closestLine).Coordinate; gf.PrecisionModel.MakePrecise(intersectionPt); // assert intersection point is equal to coordinate to add Assert.AreEqual(coordinateToAdd, intersectionPt); // act insertion of coordinate to add var lip = new NetTopologySuite.LinearReferencing.LocationIndexOfPoint(closestLine); var ll = lip.IndexOf(coordinateToAdd); if (!ll.IsVertex) { var cl = (ILineString)closestLine; var cls = cl.Factory.CoordinateSequenceFactory.Create(cl.CoordinateSequence.Count + 1, cl.CoordinateSequence.Ordinates); CoordinateSequences.Copy(cl.CoordinateSequence, 0, cls, 0, ll.SegmentIndex + 1); cls.SetOrdinate(ll.SegmentIndex + 1, Ordinate.X, coordinateToAdd.X); cls.SetOrdinate(ll.SegmentIndex + 1, Ordinate.Y, coordinateToAdd.Y); CoordinateSequences.Copy(cl.CoordinateSequence, ll.SegmentIndex + 1, cls, ll.SegmentIndex + 2, cl.CoordinateSequence.Count - ll.SegmentIndex - 1); closestLine = gf.CreateLineString(cls); } ToImage(1, closestLine, line, GeometryFactory.Default.CreatePoint(coordinateToAdd)); Assert.IsTrue(line.Touches(closestLine)); Assert.IsFalse(line.Crosses(closestLine)); }
/// <summary> /// Reads a coordinate sequence from the stream, which length is not yet known. /// </summary> /// <param name="reader">The binary reader</param> /// <param name="factory">The geometry factory to use for geometry creation.</param> /// <param name="precisionModel">The precision model used to make x- and y-ordinates precise.</param> /// <param name="receivedOrdinates">The ordinates to read. <see cref="Ordinates.XY"/> are always read.</param> /// <returns>The coordinate sequence</returns> protected CoordinateSequence ReadCoordinateSequenceRing(BinaryReader reader, CoordinateSequenceFactory factory, PrecisionModel precisionModel, Ordinates receivedOrdinates) { int numPoints = reader.ReadInt32(); var sequence = ReadCoordinateSequence(reader, factory, precisionModel, numPoints, receivedOrdinates); return(!RepairRings || CoordinateSequences.IsRing(sequence) ? sequence : CoordinateSequences.EnsureValidRing(factory, sequence)); }
IGeometry InsertPoint(IGeometry geom, Coordinate point) { if (!(geom is ILineal)) { throw new InvalidOperationException(); } var lil = new LocationIndexedLine(geom); var ll = lil.Project(point); var element = (ILineString)geom.GetGeometryN(ll.ComponentIndex); var oldSeq = element.CoordinateSequence; var newSeq = element.Factory.CoordinateSequenceFactory.Create( oldSeq.Count + 1, oldSeq.Dimension); var j = 0; if (ll.SegmentIndex == 0 && ll.SegmentFraction == 0) { if (ll.GetSegment(element).P0.Distance(point) == 0) { return(geom); } newSeq.SetCoordinate(0, point); CoordinateSequences.Copy(oldSeq, 0, newSeq, 1, oldSeq.Count); } else if (ll.SegmentIndex == oldSeq.Count - 1 && ll.SegmentFraction == 0) { if (ll.GetSegment(element).P0.Distance(point) == 0) { return(geom); } CoordinateSequences.Copy(oldSeq, 0, newSeq, 0, oldSeq.Count); newSeq.SetCoordinate(oldSeq.Count, point); } else { if (ll.IsVertex) { return(geom); } CoordinateSequences.Copy(oldSeq, 0, newSeq, 0, ll.SegmentIndex + 1); newSeq.SetCoordinate(ll.SegmentIndex + 1, point); CoordinateSequences.Copy(oldSeq, ll.SegmentIndex + 1, newSeq, ll.SegmentIndex + 2, newSeq.Count - 2 - ll.SegmentIndex); } var lines = new List <IGeometry>(); LineStringExtracter.GetLines(geom, lines); lines[ll.ComponentIndex] = geom.Factory.CreateLineString(newSeq); if (lines.Count == 1) { return(lines[0]); } return(geom.Factory.BuildGeometry(lines)); }
public void TestCopyToSmallerDim() { var csFactory = new PackedCoordinateSequenceFactory(); var cs3D = CreateTestSequence(csFactory, 10, 3); var cs2D = csFactory.Create(10, 2, 0); CoordinateSequences.Copy(cs3D, 0, cs2D, 0, cs2D.Count); Assert.IsTrue(CoordinateSequences.IsEqual(cs2D, cs3D)); }
public void TestCopyToLargerDim() { PackedCoordinateSequenceFactory csFactory = new PackedCoordinateSequenceFactory(); ICoordinateSequence cs2D = CreateTestSequence(csFactory, 10, 2); ICoordinateSequence cs3D = csFactory.Create(10, 3); CoordinateSequences.Copy(cs2D, 0, cs3D, 0, cs3D.Count); Assert.IsTrue(CoordinateSequences.IsEqual(cs2D, cs3D)); }
/// <summary> /// Creates an array of <c>Point</c>s having the given <c>Coordinate</c>s. /// </summary> /// <param name="coordinates"> /// The <c>Coordinate</c>s with which to create the <c>Point</c>s /// </param> /// <param name="factory">The factory to create the points</param> /// <returns> /// <c>Point</c>s created using this <c>WKTReader</c> /// s <c>GeometryFactory</c>. /// </returns> private IPoint[] ToPoints(ICoordinateSequence coordinates, IGeometryFactory factory) { var points = new IPoint[coordinates.Count]; for (var i = 0; i < coordinates.Count; i++) { var cs = _coordinateSequencefactory.Create(1, coordinates.Ordinates); CoordinateSequences.Copy(coordinates, i, cs, 0, 1); points[i] = factory.CreatePoint(cs); } return(points); }
private static CoordinateSequence InsertTopologyExceptionPoint(Coordinate coord, CoordinateSequence seq, CoordinateSequenceFactory 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 static LogEventPropertyValue WriteCoordinateSequence( CoordinateSequence?sequence, bool multiple, OrientationIndex orientation = OrientationIndex.None ) { if (sequence == null) { return(new ScalarValue(null)); } var values = new List <LogEventPropertyValue>(); if (multiple) { if ((orientation == OrientationIndex.Clockwise && Orientation.IsCCW(sequence)) || (orientation == OrientationIndex.CounterClockwise && !Orientation.IsCCW(sequence))) { CoordinateSequences.Reverse(sequence); } } var hasZ = sequence.HasZ; for (var i = 0; i < sequence.Count; i++) { var value = new List <LogEventPropertyValue>(3); value.Add(new ScalarValue(sequence.GetX(i))); value.Add(new ScalarValue(sequence.GetY(i))); if (hasZ) { var z = sequence.GetZ(i); if (!double.IsNaN(z)) { value.Add(new ScalarValue(z)); } } if (multiple) { values.Add(new SequenceValue(value)); } else { values = value; break; } } return(new SequenceValue(values)); }
private static void DoTestIndexOf(CoordinateSequenceFactory factory, int dimension) { // arrange var sequence = CreateSequenceFromOrdinates(factory, dimension); // act & assert var coordinates = sequence.ToCoordinateArray(); for (int i = 0; i < sequence.Count; i++) { Assert.AreEqual(i, CoordinateSequences.IndexOf(coordinates[i], sequence)); } }
/// <summary> /// Function to read a coordinate sequence that is supposed to form a ring. /// </summary> /// <param name="reader">The reader</param> /// <param name="size">The number of ordinates</param> /// <param name="cs">The coordinate system</param> /// <returns>The read coordinate sequence.</returns> protected CoordinateSequence ReadCoordinateSequenceRing(BinaryReader reader, int size, CoordinateSystem cs) { var seqence = ReadCoordinateSequence(reader, size, cs); if (_isStrict) { return(seqence); } if (CoordinateSequences.IsRing(seqence)) { return(seqence); } return(CoordinateSequences.EnsureValidRing(_sequenceFactory, seqence)); }
/// <summary> /// Function to read a coordinate sequence that is supposed to serve a line string. /// </summary> /// <param name="reader">The reader</param> /// <param name="size">The number of ordinates</param> /// <param name="cs">The coordinate system</param> /// <returns>The read coordinate sequence.</returns> protected CoordinateSequence ReadCoordinateSequenceLineString(BinaryReader reader, int size, CoordinateSystem cs) { var seq = ReadCoordinateSequence(reader, size, cs); if (_isStrict) { return(seq); } if (seq.Count == 0 || seq.Count >= 2) { return(seq); } return(CoordinateSequences.Extend(_geometryServices.DefaultCoordinateSequenceFactory, seq, 2)); }
/// <summary> /// /// </summary> /// <param name="collection"></param> /// <returns></returns> private static ICoordinateSequence BuildSequence(IGeometryCollection collection) { var seq = collection.Factory.CoordinateSequenceFactory.Create(collection.NumPoints, DetectOrdinates(collection)); var count = 0; for (var i = 0; i < collection.Count; i++) { var tmp = collection.GetGeometryN(i); ICoordinateSequence tmpSeq = null; switch (tmp.OgcGeometryType) { case OgcGeometryType.Point: tmpSeq = ((IPoint)tmp).CoordinateSequence; break; case OgcGeometryType.LineString: tmpSeq = ((ILineString)tmp).CoordinateSequence; break; case OgcGeometryType.Polygon: var poly = (IPolygon)tmp; tmpSeq = poly.ExteriorRing.CoordinateSequence; if (poly.NumInteriorRings > 0) { CoordinateSequences.Copy(tmpSeq, 0, seq, count, tmpSeq.Count); int j; for (j = 0; j < poly.NumInteriorRings - 1; j++) { tmpSeq = poly.GetInteriorRingN(j).CoordinateSequence; CoordinateSequences.Copy(tmpSeq, 0, seq, count, tmpSeq.Count); count += tmpSeq.Count; } tmpSeq = poly.GetInteriorRingN(j).CoordinateSequence; } break; default: throw new ArgumentException("Invalid geometry type"); } if (tmpSeq != null) { CoordinateSequences.Copy(tmpSeq, 0, seq, count, tmpSeq.Count); count += tmpSeq.Count; } } return(seq); }
private static void DoTestReverse(CoordinateSequenceFactory factory, int dimension) { // arrange var sequence = CreateSequenceFromOrdinates(factory, dimension); var reversed = sequence.Copy(); // act CoordinateSequences.Reverse(reversed); // assert for (int i = 0; i < sequence.Count; i++) { CheckCoordinateAt(sequence, i, reversed, sequence.Count - i - 1, dimension); } }
/// <summary> /// Reads a coordinate sequence from the stream, which length is not yet known. /// </summary> /// <param name="reader">The binary reader</param> /// <param name="factory">The geometry factory to use for geometry creation.</param> /// <param name="precisionModel">The precision model used to make x- and y-ordinates precise.</param> /// <param name="ordinates">The ordinates to read. <see cref="Ordinates.XY"/> are always read.</param> /// <returns>The coordinate sequence</returns> protected ICoordinateSequence ReadCoordinateSequenceRing(BinaryReader reader, ICoordinateSequenceFactory factory, IPrecisionModel precisionModel, Ordinates ordinates) { var numPoints = reader.ReadInt32(); var sequence = ReadCoordinateSequence(reader, factory, precisionModel, numPoints, ordinates); if (!RepairRings) { return(sequence); } if (CoordinateSequences.IsRing(sequence)) { return(sequence); } return(CoordinateSequences.EnsureValidRing(factory, sequence)); }
private void WriteCoordinateSequence(Utf8JsonWriter writer, CoordinateSequence sequence, JsonSerializerOptions options, bool multiple = true, OrientationIndex orientation = OrientationIndex.None) { //writer.WritePropertyName("coordinates"); if (sequence == null) { writer.WriteNullValue(); return; } if (multiple) { writer.WriteStartArray(); if (orientation == OrientationIndex.Clockwise && Orientation.IsCCW(sequence) || orientation == OrientationIndex.CounterClockwise && !Orientation.IsCCW(sequence)) { CoordinateSequences.Reverse(sequence); } } bool hasZ = sequence.HasZ; for (int i = 0; i < sequence.Count; i++) { writer.WriteStartArray(); writer.WriteNumberValue(sequence.GetX(i)); writer.WriteNumberValue(sequence.GetY(i)); if (hasZ) { double z = sequence.GetZ(i); if (!double.IsNaN(z)) { writer.WriteNumberValue(sequence.GetZ(i)); } } writer.WriteEndArray(); if (!multiple) { break; } } if (multiple) { writer.WriteEndArray(); } }
/// <summary> /// Writes <paramref name="polygon"/> to a stream using <paramref name="writer"/> /// </summary> /// <param name="polygon">The polygon to write</param> /// <param name="writer">The writer to use</param> public void Write(IPolygon polygon, BinaryWriter writer) { writer.Write((int)ShapeGeometryType.Polygon); // Write BoundingBox WriteBoundingBox(polygon.EnvelopeInternal, writer); // Write NumParts and NumPoints writer.Write((int)(polygon.NumInteriorRings + 1)); writer.Write((int)polygon.NumPoints); // Write IndexParts int count = 0; writer.Write((int)count); var seq = polygon.Factory.CoordinateSequenceFactory.Create(polygon.NumPoints, polygon.ExteriorRing.CoordinateSequence.Ordinates); // Gather coordinate information var ring = polygon.ExteriorRing.CoordinateSequence; CoordinateSequences.Copy(ring, 0, seq, count, ring.Count); // If we have interior rings write the index parts and gather coordinate information if (polygon.NumInteriorRings > 0) { // Write exterior shell index count += ring.Count; writer.Write((int)count); // Gather coordinates and write interior shell index for (int i = 0; i < polygon.NumInteriorRings; i++) { // Write internal holes index ring = polygon.GetInteriorRingN(i).CoordinateSequence; CoordinateSequences.Copy(ring, 0, seq, count, ring.Count); if (i < polygon.NumInteriorRings - 1) { count += ring.Count; writer.Write((int)count); } } } // Write Coordinates WriteCoordinates(seq, writer, Ordinates.XY); }
private static ILineString ExtendLine(ILineString line, double startDist, double endDist) { var numPts = (startDist > 0 ? 1 : 0) + (endDist > 0 ? 1 : 0); if (numPts == 0) { return(line); } var cs = line.Factory.CoordinateSequenceFactory.Create(line.CoordinateSequence.Count + numPts, line.CoordinateSequence.Dimension); var offset = 0; if (startDist > 0) { var rad = Azimuth(line.Coordinates[1], line.Coordinates[0]); var coords = new[] { Traverse(line.Coordinates[0], rad, startDist) }; var startSeq = line.Factory.CoordinateSequenceFactory.Create(coords); CoordinateSequences.Copy(startSeq, 0, cs, offset++, 1); } CoordinateSequences.Copy(line.CoordinateSequence, 0, cs, offset, line.CoordinateSequence.Count); offset += line.CoordinateSequence.Count; if (endDist > 0) { var endPoints = new [] { line.Coordinates[line.Coordinates.Length - 2], line.Coordinates[line.Coordinates.Length - 1] }; var rad = Azimuth(endPoints[0], endPoints[1]); var coords = new[] { Traverse(endPoints[1], rad, endDist) }; var es = line.Factory.CoordinateSequenceFactory.Create(coords); CoordinateSequences.Copy(es, 0, cs, offset, 1); } return(line.Factory.CreateLineString(cs)); }
private static void DoTestMinCoordinateIndex(CoordinateSequenceFactory factory, int dimension) { var sequence = CreateSequenceFromOrdinates(factory, dimension); if (sequence.Count <= 6) { TestContext.WriteLine("sequence has a size of " + sequence.Count + ". Execution of this test needs a sequence " + "with more than 5 coordinates."); return; } int minIndex = sequence.Count / 2; sequence.SetOrdinate(minIndex, 0, 5); sequence.SetOrdinate(minIndex, 1, 5); Assert.AreEqual(minIndex, CoordinateSequences.MinCoordinateIndex(sequence)); Assert.AreEqual(minIndex, CoordinateSequences.MinCoordinateIndex(sequence, 2, sequence.Count - 2)); }
private static void DoTestScroll(CoordinateSequenceFactory factory, int dimension) { // arrange var sequence = CreateCircularString(factory, dimension, new Coordinate(20, 20), 7d, 0.1, 22); var scrolled = sequence.Copy(); // act CoordinateSequences.Scroll(scrolled, 12); // assert int io = 12; for (int @is = 0; @is < scrolled.Count - 1; @is++) { CheckCoordinateAt(sequence, io, scrolled, @is, dimension); io++; io %= scrolled.Count; } }
private static void DoTestScrollRing(CoordinateSequenceFactory factory, int dimension) { // arrange //TestContext.WriteLine("Testing '" + factory.getClass().getSimpleName() + "' with dim=" +dimension ); var sequence = CreateCircle(factory, dimension, new Coordinate(10, 10), 9d); var scrolled = sequence.Copy(); // act CoordinateSequences.Scroll(scrolled, 12); // assert int io = 12; for (int @is = 0; @is < scrolled.Count - 1; @is++) { CheckCoordinateAt(sequence, io, scrolled, @is, dimension); io++; io %= scrolled.Count - 1; } CheckCoordinateAt(scrolled, 0, scrolled, scrolled.Count - 1, dimension); }
/// <summary> /// Writes <paramref name="multiLineString"/> to a stream using <paramref name="writer"/> /// </summary> /// <param name="multiLineString">The multi linestring to write</param> /// <param name="writer">The writer to use</param> public void Write(IMultiLineString multiLineString, BinaryWriter writer) { writer.Write((int)ShapeGeometryType.LineString); // Write BoundingBox WriteBoundingBox(multiLineString.EnvelopeInternal, writer); // Write NumParts and NumPoints writer.Write((int)multiLineString.NumGeometries); writer.Write((int)multiLineString.NumPoints); // Write IndexParts int count = 0; writer.Write((int)count); var seq = multiLineString.Factory.CoordinateSequenceFactory.Create(multiLineString.NumPoints, ((ILineString)multiLineString[0]).CoordinateSequence.Ordinates); // Write linestrings index for (int i = 0; i < multiLineString.NumGeometries; i++) { // Write internal holes index var ls = ((ILineString)multiLineString.GetGeometryN(i)).CoordinateSequence; CoordinateSequences.Copy(ls, 0, seq, count, ls.Count); count += ls.Count; if (count == multiLineString.NumPoints) { break; } writer.Write((int)count); } // Write Coordinates Write(multiLineString.Coordinates, writer); }
public override string ToString() { return(CoordinateSequences.ToString(this)); }
private static IEnumerable <uint> Encode(CoordinateSequence sequence, TileGeometryTransform tgt, ref int currentX, ref int currentY, bool ring = false, bool ccw = false) { // how many parameters for LineTo command int count = sequence.Count; // if we have a ring we need to check orientation if (ring) { if (ccw != Algorithm.Orientation.IsCCW(sequence)) { sequence = sequence.Copy(); CoordinateSequences.Reverse(sequence); } } var encoded = new List <uint>(); // Start point encoded.Add(GenerateCommandInteger(MapboxCommandType.MoveTo, 1)); var position = tgt.Transform(sequence, 0, ref currentX, ref currentY); encoded.Add(GenerateParameterInteger(position.x)); encoded.Add(GenerateParameterInteger(position.y)); // Add LineTo command (stub) int lineToCount = 0; encoded.Add(GenerateCommandInteger(MapboxCommandType.LineTo, lineToCount)); for (int i = 1; i < count; i++) { position = tgt.Transform(sequence, i, ref currentX, ref currentY); if (position.x != 0 || position.y != 0) { encoded.Add(GenerateParameterInteger(position.x)); encoded.Add(GenerateParameterInteger(position.y)); lineToCount++; } } if (lineToCount > 0) { encoded[3] = GenerateCommandInteger(MapboxCommandType.LineTo, lineToCount); } // Validate encoded data if (ring) { // A ring has 1 MoveTo and 1 LineTo command. // A ring is only valid if we have at least 3 points, otherwise collapse if (encoded.Count - 2 >= 6) { encoded.Add(GenerateCommandInteger(MapboxCommandType.ClosePath, 1)); } else { encoded.Clear(); } } else { // A line has 1 MoveTo and 1 LineTo command. // A line is valid if it has at least 2 points if (encoded.Count - 2 < 4) { encoded.Clear(); } } return(encoded); }