/// <summary> /// Writes <paramref name="multiPolygon"/> to a stream using <paramref name="writer"/> /// </summary> /// <param name="multiPolygon">The multi polygon to write</param> /// <param name="writer">The writer to use</param> public void Write(MultiPolygon multiPolygon, BinaryWriter writer) { writer.Write((int)ShapeGeometryType.Polygon); // Write BoundingBox WriteBoundingBox(multiPolygon.EnvelopeInternal, writer); // Write NumParts and NumPoints int numParts = multiPolygon.NumGeometries; // Exterior rings count for (int i = 0; i < multiPolygon.NumGeometries; i++) // Adding interior rings count { numParts += ((Polygon)multiPolygon.GetGeometryN(i)).NumInteriorRings; } writer.Write((int)numParts); writer.Write((int)multiPolygon.NumPoints); // Create a sequence for all coordinates var seq = multiPolygon.Factory.CoordinateSequenceFactory.Create( multiPolygon.NumPoints, DetectOrdinates(multiPolygon)); // Write IndexParts int count = 0; writer.Write((int)count); for (int i = 0; i < multiPolygon.NumGeometries; i++) { var polygon = (Polygon)multiPolygon.GetGeometryN(i); var shell = polygon.ExteriorRing; Copy(shell.CoordinateSequence, 0, seq, count, shell.NumPoints); count += shell.NumPoints; if (count == multiPolygon.NumPoints) { break; } writer.Write((int)count); for (int j = 0; j < polygon.NumInteriorRings; j++) { var hole = (LineString)polygon.GetInteriorRingN(j); Copy(hole.CoordinateSequence, 0, seq, count, shell.NumPoints); count += hole.NumPoints; if (count == multiPolygon.NumPoints) { break; } writer.Write((int)count); } } // Write Coordinates WriteCoordinates(seq, writer, seq.Ordinates); }
/// <summary> /// /// </summary> /// <param name="multiPolygon"></param> /// <param name="writer"></param> public virtual void Write(MultiPolygon multiPolygon, BinaryWriter writer) { writer.Write((int)ShapeGeometryTypes.Polygon); // Write BoundingBox WriteBoundingBox(multiPolygon, writer); // Write NumParts and NumPoints int numParts = multiPolygon.NumGeometries; // Exterior rings count for (int i = 0; i < multiPolygon.NumGeometries; i++) // Adding interior rings count { numParts += (multiPolygon.GetGeometryN(i) as Polygon).NumInteriorRings; } writer.Write((int)numParts); writer.Write((int)multiPolygon.NumPoints); // Write IndexParts int count = 0; writer.Write((int)count); for (int i = 0; i < multiPolygon.NumGeometries; i++) { Polygon polygon = multiPolygon.GetGeometryN(i) as Polygon; ILineString shell = polygon.ExteriorRing; count += shell.NumPoints; if (count == multiPolygon.NumPoints) { break; } writer.Write((int)count); for (int j = 0; j < polygon.NumInteriorRings; j++) { ILineString hole = polygon.GetInteriorRingN(j); count += hole.NumPoints; if (count == multiPolygon.NumPoints) { break; } writer.Write((int)count); } } // Write Coordinates for (int i = 0; i < multiPolygon.NumPoints; i++) { Write(multiPolygon.Coordinates[i], writer); } }
/// <summary> /// Converts a MultiPolygon to <MultiPolygon Text> format, then Appends to it to the writer. /// </summary> /// <param name="multiPolygon">The MultiPolygon to process.</param> /// <param name="level"></param> /// <param name="writer">The output stream to Append to.</param> protected void AppendMultiPolygonText(MultiPolygon multiPolygon, int level, StringWriter writer) { if (multiPolygon.IsEmpty()) { writer.Write("EMPTY"); } else { int level2 = level; bool doIndent = false; writer.Write("("); for (int i = 0; i < multiPolygon.GetNumGeometries(); i++) { if (i > 0) { writer.Write(", "); level2 = level + 1; doIndent = true; } //AppendPolygonText((Polygon) multiPolygon.GetGeometryN(i), level2, doIndent, writer); AppendPolygonText((Polygon)multiPolygon.GetGeometryN(i), level2, doIndent, writer); } writer.Write(")"); } }
/// <summary> /// Tests that no element polygon is wholly in the interior of another element polygon. /// Preconditions: /// Shells do not partially overlap. /// Shells do not touch along an edge. /// No duplicate rings exists. /// This routine relies on the fact that while polygon shells may touch at one or /// more vertices, they cannot touch at ALL vertices. /// </summary> private void CheckShellsNotNested(MultiPolygon mp, GeometryGraph graph) { for (int i = 0; i < mp.NumGeometries; i++) { Polygon p = (Polygon)mp.GetGeometryN(i); LinearRing shell = (LinearRing)p.ExteriorRing; for (int j = 0; j < mp.NumGeometries; j++) { if (i == j) { continue; } Polygon p2 = (Polygon)mp.GetGeometryN(j); CheckShellNotNested(shell, p2, graph); if (validErr != null) { return; } } } }
private void CheckValid(MultiPolygon g) { GeometryGraph graph = new GeometryGraph(0, g); CheckConsistentArea(graph); if (_validErr != null) { return; } CheckNoSelfIntersectingRings(graph); if (_validErr != null) { return; } for (int i = 0; i < g.GetNumGeometries(); i++) { Polygon p = (Polygon)g.GetGeometryN(i); CheckHolesInShell(p, graph); if (_validErr != null) { return; } } for (int i = 0; i < g.GetNumGeometries(); i++) { Polygon p = (Polygon)g.GetGeometryN(i); CheckHolesNotNested(p, graph); if (_validErr != null) { return; } } CheckShellsNotNested(g, graph); if (_validErr != null) { return; } CheckConnectedInteriors(graph); }
public void TestMultiPolygon1() { string wkt = "MULTIPOLYGON (((10 10, 10 20, 20 20, 20 15 , 10 10), (50 40, 50 50, 60 50, 60 40, 50 40)))"; GeometryFactory factory = new GeometryFactory(); IGeometry geometry = factory.CreateFromWKT(wkt); MultiPolygon multiPolygon = (MultiPolygon)geometry; //Assertion.AssertEquals("Multilinestring 1",2,multiPolygon.NumGeometries); IGeometry g = multiPolygon.GetGeometryN(0); Polygon poly1 = (Polygon)multiPolygon.GetGeometryN(0); LinearRing shell = poly1.Shell; LinearRing hole = poly1.Holes[0]; Assertion.AssertEquals("MPS 1", 10.0, shell.GetCoordinates()[0].X); Assertion.AssertEquals("MPS 2", 10.0, shell.GetCoordinates()[0].Y); Assertion.AssertEquals("MPS 3", 10.0, shell.GetCoordinates()[1].X); Assertion.AssertEquals("MPS 4", 20.0, shell.GetCoordinates()[1].Y); Assertion.AssertEquals("MPS 5", 20.0, shell.GetCoordinates()[2].Y); Assertion.AssertEquals("MPS 6", 20.0, shell.GetCoordinates()[2].Y); Assertion.AssertEquals("MPS 7", 20.0, shell.GetCoordinates()[3].X); Assertion.AssertEquals("MPS 8", 15.0, shell.GetCoordinates()[3].Y); Assertion.AssertEquals("MPS 9", 10.0, shell.GetCoordinates()[4].X); Assertion.AssertEquals("MPS 10", 10.0, shell.GetCoordinates()[4].Y); Assertion.AssertEquals("MPS 11", 50.0, hole.GetCoordinates()[0].X); Assertion.AssertEquals("MPS 12", 40.0, hole.GetCoordinates()[0].Y); Assertion.AssertEquals("MPS 13", 50.0, hole.GetCoordinates()[1].X); Assertion.AssertEquals("MPS 14", 50.0, hole.GetCoordinates()[1].Y); Assertion.AssertEquals("MPS 15", 60.0, hole.GetCoordinates()[2].X); Assertion.AssertEquals("MPS 16", 50.0, hole.GetCoordinates()[2].Y); Assertion.AssertEquals("MPS 17", 60.0, hole.GetCoordinates()[3].X); Assertion.AssertEquals("MPS 18", 40.0, hole.GetCoordinates()[3].Y); Assertion.AssertEquals("MPS 19", 50.0, hole.GetCoordinates()[4].X); Assertion.AssertEquals("MPS 20", 40.0, hole.GetCoordinates()[4].Y); string wkt2 = multiPolygon.ToText(); Assertion.AssertEquals("wkt", true, Compare.WktStrings(wkt, wkt2)); }
/// <summary> /// Mark all the edges for the edgeRings corresponding to the shells /// of the input polygons. Note only ONE ring gets marked for each shell. /// </summary> /// <param name="g"></param> /// <param name="graph"></param> private void VisitShellInteriors(Geometry g, PlanarGraph graph) { if (g is Polygon) { Polygon p = (Polygon)g; this.VisitInteriorRing(p.GetExteriorRing(), graph); } if (g is MultiPolygon) { MultiPolygon mp = (MultiPolygon)g; for (int i = 0; i < mp.GetNumGeometries(); i++) { Polygon p = (Polygon)mp.GetGeometryN(i); this.VisitInteriorRing(p.GetExteriorRing(), graph); } } }
} // public int Locate( Coordinate p, Geometry geom ) private void ComputeLocation(Coordinate p, Geometry geom) { if (geom is LineString) { UpdateLocationInfo(Locate(p, (LineString)geom)); } if (geom is LinearRing) { UpdateLocationInfo(Locate(p, (LinearRing)geom)); } else if (geom is Polygon) { UpdateLocationInfo(Locate(p, (Polygon)geom)); } else if (geom is MultiLineString) { MultiLineString ml = (MultiLineString)geom; for (int i = 0; i < ml.GetNumGeometries(); i++) { LineString l = (LineString)ml.GetGeometryN(i); UpdateLocationInfo(Locate(p, l)); } // for ( int i = 0; i < ml.NumGeometries; i++ ) } else if (geom is MultiPolygon) { MultiPolygon mpoly = (MultiPolygon)geom; for (int i = 0; i < mpoly.GetNumGeometries(); i++) { Polygon poly = (Polygon)mpoly.GetGeometryN(i); UpdateLocationInfo(Locate(p, poly)); } // for (int i = 0; i < mpoly.NumGeometries; i++) } else if (geom is GeometryCollection) { GeometryCollection gc = geom as GeometryCollection; foreach (Geometry g2 in gc) { if (g2 != geom) { ComputeLocation(p, g2); } } // foreach( Geometry g2 in gc ) } // else if ( geom is GeometryCollection ) } // private void ComputeLocation(Coordinate p, Geometry geom)
/// <summary> /// Transforms a <see cref="MultiPolygon"/> geometry. /// </summary> /// <param name="geom">The <c>MultiPolygon</c> to transform</param> /// <param name="parent">The parent geometry</param> /// <returns>A <c>MultiPolygon</c></returns> protected virtual Geometry TransformMultiPolygon(MultiPolygon geom, Geometry parent) { var transGeomList = new List <Geometry>(); for (int i = 0; i < geom.NumGeometries; i++) { var transformGeom = TransformPolygon((Polygon)geom.GetGeometryN(i), geom); if (transformGeom == null) { continue; } if (transformGeom.IsEmpty) { continue; } transGeomList.Add(transformGeom); } return(Factory.BuildGeometry(transGeomList)); }
/// <summary> /// Writes a MultiPolygon. /// </summary> /// <param name="mp">The mulitpolygon to be written.</param> /// <param name="bWriter">Stream to write to.</param> /// <param name="byteorder">Byte order</param> private static void WriteMultiPolygon(MultiPolygon mp, BinaryWriter bWriter, WkbByteOrder byteorder) { //Write the number of polygons. int num = mp.NumGeometries; WriteUInt32((uint)num, bWriter, byteorder); //Loop on the number of polygons. //NOTE: by contract, the first item returned // from GetEnumerator (i.e. using foreach) is the MultiPolygon itself! for (int i = 0; i < num; i++) { Polygon poly = (Polygon)mp.GetGeometryN(i); //Write polygon header bWriter.Write((byte)byteorder); WriteUInt32((uint)WKBGeometryType.wkbPolygon, bWriter, byteorder); //Write each polygon. WritePolygon(poly, bWriter, byteorder); } }
/// <summary> /// Converts a MultiPolygon to <MultiPolygon Text> format, then Appends to it to the writer. /// </summary> /// <param name="multiPolygon">The MultiPolygon to process.</param> /// <param name="writer">The output stream to Append to.</param> protected void AppendMultiPolygonText(MultiPolygon multiPolygon, TextWriter writer) { if (multiPolygon.IsEmpty()) { writer.Write("EMPTY"); } else { //writer.Write("M"); for (int i = 0; i < multiPolygon.GetNumGeometries(); i++) { /*if (i > 0 && (i<multiPolygon.GetNumGeometries()-1) ) * { * writer.Write(", "); * }*/ AppendPolygonText((Polygon)multiPolygon.GetGeometryN(i), writer); } //writer.Write("Z"); } }
/// <summary> /// Converts a MultiPolygon to <MultiPolygon Text> format, then Appends to it to the writer. /// </summary> /// <param name="MultiPolygon">The MultiPolygon to process.</param> /// <param name="writer">The output stream to Append to.</param> private static void AppendMultiPolygonText(MultiPolygon MultiPolygon, StringWriter writer) { if (MultiPolygon == null || MultiPolygon.IsEmpty) { writer.Write("EMPTY"); } else { writer.Write("("); for (int i = 0; i < MultiPolygon.NumGeometries; i++) { if (i > 0) { writer.Write(", "); } AppendPolygonText((Polygon)MultiPolygon.GetGeometryN(i), writer); } writer.Write(")"); } }