/// <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(")"); } }
/* * private void SLOWCheckHolesNotNested(Polygon p) * { * * for (int i = 0; i < p.GetNumInteriorRing(); i++) * { * LinearRing innerHole = p.GetInteriorRingN( i ); * Coordinates innerHolePts = innerHole.GetCoordinates(); * for (int j = 0; j < p.GetNumInteriorRing(); j++) * { * // don't test hole against itself! * if (i == j) continue; * * LinearRing searchHole = p.GetInteriorRingN( j ); * * // if envelopes don't overlap, holes are not nested * if (! innerHole.GetEnvelopeInternal().Overlaps(searchHole.GetEnvelopeInternal())) * continue; * * Coordinates searchHolePts = searchHole.GetCoordinates(); * Coordinate innerholePt = FindPtNotNode(innerHolePts, searchHole, _arg[0]); * //Assert.isTrue(innerholePt != null, "Unable to find a hole point not a node of the search hole"); * bool inside = _cga.IsPointInPolygon(innerholePt, searchHolePts); * if ( inside ) * { * _validErr = new TopologyValidationError( * TopologyValidationError.NestedHoles, * innerholePt); * return; * } * } * } * } */ /// <summary> /// Test that no element polygon is wholly in the interior of another element polygon. /// </summary> /// <remarks> /// TODO: It handles the case that one polygon is nested inside a hole of another. /// /// Preconditions: /// <ul> /// <li>shells do not partially overlap</li> /// <li>shells do not touch along an edge</li> /// <li>no duplicate rings exist</li> /// </ul> /// This routine relies on the fact that while polygon shells may touch at one or /// more vertices, they cannot touch at ALL vertices. /// </remarks> /// <param name="mp"></param> /// <param name="graph"></param> private void CheckShellsNotNested(MultiPolygon mp, GeometryGraph graph) { for (int i = 0; i < mp.GetNumGeometries(); i++) { Polygon p = (Polygon)mp.GetGeometryN(i); LinearRing shell = (LinearRing)p.GetExteriorRing(); for (int j = 0; j < mp.GetNumGeometries(); 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); }
/// <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> /// Writes a multipolygon. /// </summary> /// <param name="mp">The mulitpolygon to be written.</param> private void WriteMultiPolygon(MultiPolygon mp, byte format) { //Get the number of polygons in this multipolygon. int numpolygons = mp.GetNumGeometries(); //Write the number of polygons. _bWriter.Write(numpolygons); //Loop on the number of polygons. for (int i = 0; i < numpolygons; i++) { //Write the polygon header _bWriter.Write(format); _bWriter.Write(6); //Write each polygon. WritePolygon((Polygon)mp[i], format); } }
/// <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"); } }