} // private void PlacePolygonHoles( EdgeRing shell, ArrayList minEdgeRings ) /// <summary> /// For all rings in the input list, /// determine whether the ring is a shell or a hole /// and add it to the appropriate list. /// Due to the way the DirectedEdges were linked, /// a ring is a shell if it is oriented CW, a hole otherwise. /// </summary> /// <param name="edgeRings"></param> /// <param name="shellList"></param> /// <param name="freeHoleList"></param> private void SortShellsAndHoles(ArrayList edgeRings, ref ArrayList shellList, ref ArrayList freeHoleList) { foreach (object obj in edgeRings) { EdgeRing er = (EdgeRing)obj; er.SetInResult(); if (er.IsHole) { freeHoleList.Add(er); } else { shellList.Add(er); } } // foreach ( object obj in edgeRings ) } // private void SortShellsAndHoles(ArrayList edgeRings, ArrayList shellList, ArrayList freeHoleList)
/// <summary> /// For all rings in the input list, /// determine whether the ring is a shell or a hole /// and add it to the appropriate list. /// Due to the way the DirectedEdges were linked, /// a ring is a shell if it is oriented CW, a hole otherwise. /// </summary> /// <param name="edgeRings"></param> /// <param name="shellList"></param> /// <param name="freeHoleList"></param> private void SortShellsAndHoles(IList edgeRings, IList shellList, IList freeHoleList) { for (IEnumerator it = edgeRings.GetEnumerator(); it.MoveNext();) { EdgeRing er = (EdgeRing)it.Current; er.SetInResult(); if (er.IsHole) { freeHoleList.Add(er); } else { shellList.Add(er); } } }
/// <summary> /// This method determines finds a containing shell for all holes /// which have not yet been assigned to a shell. /// These "free" holes should /// all be properly contained in their parent shells, so it is safe to use the /// findEdgeRingContaining method. /// (This is the case because any holes which are NOT /// properly contained (i.e. are connected to their /// parent shell) would have formed part of a MaximalEdgeRing /// and been handled in a previous step). /// </summary> private void PlaceFreeHoles(EdgeRingCollection shellList, EdgeRingCollection freeHoleList) { for (IEdgeRingEnumerator it = freeHoleList.GetEnumerator(); it.MoveNext();) { EdgeRing hole = it.Current; // only place this hole if it doesn't yet have a shell if (hole.Shell == null) { EdgeRing shell = FindEdgeRingContaining(hole, shellList); Debug.Assert(shell != null, "unable to assign hole to a shell"); hole.Shell = shell; } } }
/// <summary> /// This method takes a list of MinimalEdgeRings derived from a MaximalEdgeRing, /// and tests whether they form a Polygon. This is the case if there is a single shell /// in the list. In this case the shell is returned. /// The other possibility is that they are a series of connected holes, in which case /// no shell is returned. /// </summary> /// <returns>The shell EdgeRing, if there is one<br/> or /// <value>null</value>, if all the rings are holes.</returns> private static EdgeRing FindShell(IEnumerable <EdgeRing> minEdgeRings) { int shellCount = 0; EdgeRing shell = null; foreach (/*Minimal*/ EdgeRing er in minEdgeRings) { if (!er.IsHole) { shell = er; shellCount++; } } Assert.IsTrue(shellCount <= 1, "found two shells in MinimalEdgeRing list"); return(shell); }
private void FindValidRings(ArrayList edgeRingList, ArrayList validEdgeRingList, GeometryList invalidRingList) { for (IEnumerator i = edgeRingList.GetEnumerator(); i.MoveNext();) { EdgeRing er = (EdgeRing)i.Current; if (er.IsValid) { validEdgeRingList.Add(er); } else { invalidRingList.Add(er.LineString); } } }
/// <summary> /// This method determines finds a containing shell for all holes /// which have not yet been assigned to a shell. /// These "free" holes should /// all be properly contained in their parent shells, so it is safe to use the /// <c>findEdgeRingContaining</c> method. /// (This is the case because any holes which are NOT /// properly contained (i.e. are connected to their /// parent shell) would have formed part of a MaximalEdgeRing /// and been handled in a previous step). /// </summary> /// <param name="shellList"></param> /// <param name="freeHoleList"></param> private static void PlaceFreeHoles(IList <EdgeRing> shellList, IEnumerable <EdgeRing> freeHoleList) { foreach (EdgeRing hole in freeHoleList) { // only place this hole if it doesn't yet have a shell if (hole.Shell == null) { EdgeRing shell = FindEdgeRingContaining(hole, shellList); //Assert.IsTrue(shell != null, "unable to assign hole to a shell"); if (shell == null) { throw new TopologyException("unable to assign hole to a shell", hole.GetCoordinate(0)); } hole.Shell = shell; } } }
} // private void SortShellsAndHoles(ArrayList edgeRings, ArrayList shellList, ArrayList freeHoleList) /// <summary> /// This method determines finds a containing shell for all holes /// which have not yet been assigned to a shell.</summary> /// <remarks> /// These "free" holes should /// all be <b>properly</b> contained in their parent shells, so it is safe to use the /// FindEdgeRingContaining method. /// (This is the case because any holes which are NOT /// properly contained (i.e. are connected to their /// parent shell) would have formed part of a MaximalEdgeRing /// and been handled in a previous step). /// </remarks> /// <param name="freeHoleList"></param> private void PlaceFreeHoles(ArrayList freeHoleList) { foreach (object obj in freeHoleList) { EdgeRing hole = (EdgeRing)obj; // only place this hole if it doesn't yet have a shell if (hole.Shell == null) { EdgeRing shell = FindEdgeRingContaining(hole); if (shell == null) { throw new InvalidOperationException("Unable to assign hole to a shell."); } hole.Shell = shell; } // if ( hole.Shell == null ) } // foreach ( object obj in freeHoleList ) } // private void PlaceFreeHoles( ArrayList freeHoleList )
private void FindShellsAndHoles(ArrayList edgeRingList) { holeList = new ArrayList(); shellList = new ArrayList(); for (IEnumerator i = edgeRingList.GetEnumerator(); i.MoveNext();) { EdgeRing er = (EdgeRing)i.Current; if (er.Hole) { holeList.Add(er); } else { shellList.Add(er); } } }
/// <summary> /// This method takes a list of MinimalEdgeRings derived from a MaximalEdgeRing, /// and tests whether they form a Polygon. This is the case if there is a single shell /// in the list. In this case the shell is returned. /// The other possibility is that they are a series of connected holes, in which case /// no shell is returned. /// </summary> /// <returns>The shell EdgeRing, if there is one.</returns> /// <returns><c>null</c>, if all the rings are holes.</returns> private EdgeRing FindShell(IList minEdgeRings) { int shellCount = 0; EdgeRing shell = null; for (IEnumerator it = minEdgeRings.GetEnumerator(); it.MoveNext();) { EdgeRing er = (MinimalEdgeRing)it.Current; if (!er.IsHole) { shell = er; shellCount++; } } Assert.IsTrue(shellCount <= 1, "found two shells in MinimalEdgeRing list"); return(shell); }
/// <summary> For all rings in the input list, /// determine whether the ring is a shell or a hole /// and Add it to the appropriate list. /// Due to the way the DirectedEdges were linked, /// a ring is a shell if it is oriented CW, a hole otherwise. /// </summary> private void SortShellsAndHoles(EdgeRingCollection edgeRings, EdgeRingCollection shellList, EdgeRingCollection freeHoleList) { for (IEdgeRingEnumerator it = edgeRings.GetEnumerator(); it.MoveNext();) { EdgeRing er = it.Current; // er.SetInResult(); if (er.IsHole) { freeHoleList.Add(er); } else { shellList.Add(er); } } }
/// <summary> /// This method takes a list of MinimalEdgeRings derived from a MaximalEdgeRing, /// and tests whether they form a Polygon. This is the case if there is a single shell /// in the list. In this case the shell is returned. /// The other possibility is that they are a series of connected holes, in which case /// no shell is returned. /// </summary> /// <returns> Returns the shell EdgeRing, if there is one, /// or null, if all the rings are holes, /// </returns> private EdgeRing FindShell(EdgeRingCollection minEdgeRings) { int shellCount = 0; EdgeRing shell = null; for (IEdgeRingEnumerator it = minEdgeRings.GetEnumerator(); it.MoveNext();) { EdgeRing er = it.Current; if (!er.IsHole) { shell = er; shellCount++; } } Debug.Assert(shellCount <= 1, "found two shells in MinimalEdgeRing list"); return(shell); }
/// <summary> /// Find the innermost enclosing shell EdgeRing containing the argument EdgeRing, if any. /// The innermost enclosing ring is the <i>smallest</i> enclosing ring. /// The algorithm used depends on the fact that: /// ring A contains ring B iff envelope(ring A) contains envelope(ring B). /// This routine is only safe to use if the chosen point of the hole /// is known to be properly contained in a shell /// (which is guaranteed to be the case if the hole does not touch its shell). /// </summary> /// <param name="testEr"></param> /// <param name="shellList"></param> /// <returns>Containing EdgeRing, if there is one <br/> or /// <c>null</c> if no containing EdgeRing is found.</returns> private static EdgeRing FindEdgeRingContaining(EdgeRing testEr, IEnumerable <EdgeRing> shellList) { var teString = testEr.LinearRing; var testEnv = teString.EnvelopeInternal; var testPt = teString.GetCoordinateN(0); EdgeRing minShell = null; Envelope minShellEnv = null; foreach (var tryShell in shellList) { var tryShellRing = tryShell.LinearRing; var tryShellEnv = tryShellRing.EnvelopeInternal; // the hole envelope cannot equal the shell envelope // (also guards against testing rings against themselves) if (tryShellEnv.Equals(testEnv)) { continue; } // hole must be contained in shell if (!tryShellEnv.Contains(testEnv)) { continue; } bool isContained = false; if (PointLocation.IsInRing(testPt, tryShellRing.Coordinates)) { isContained = true; } // check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minShellEnv.Contains(tryShellEnv)) { minShell = tryShell; minShellEnv = tryShellEnv; } } } return(minShell); }
} // private ArrayList BuildMinimalEdgeRings( ArrayList maxEdgeRings, ArrayList shellList, ArrayList freeHoleList ) /// <summary> /// This method takes a list of MinimalEdgeRings derived from a MaximalEdgeRing, /// and tests whether they form a Polygon. This is the case if there is a single shell /// in the list. In this case the shell is returned. /// The other possibility is that they are a series of connected holes, in which case /// no shell is returned. /// </summary> /// <param name="minEdgeRings"></param> /// <returns> /// The shell EdgeRing, if there is one /// Null, if all the rings are holes /// </returns> private EdgeRing FindShell(ArrayList minEdgeRings) { int shellCount = 0; EdgeRing shell = null; foreach (object obj in minEdgeRings) { EdgeRing er = (MinimalEdgeRing)obj; if (!er.IsHole) { shell = er; shellCount++; } } if (!(shellCount <= 1)) { throw new InvalidOperationException("Found two shells in MinimalEdgeRing list."); } return(shell); } // private EdgeRing FindShell( ArrayList minEdgeRings )
/// <summary> /// Find the innermost enclosing shell EdgeRing containing the argument EdgeRing, /// if any. The innermost enclosing ring is the smallest enclosing ring. /// The algorithm used depends on the fact that: /// <para> /// ring A contains ring B iff envelope(ring A) contains envelope(ring B) /// </para> /// This routine is only safe to use if the chosen point of the hole /// is known to be properly contained in a shell /// (which is guaranteed to be the case if the hole does not touch its shell) /// </summary> /// <returns> Returns the containing EdgeRing, if there is one or /// <see langword="null"/> if no containing EdgeRing is found. /// </returns> private EdgeRing FindEdgeRingContaining(EdgeRing testEr, EdgeRingCollection shellList) { LinearRing testRing = testEr.Ring; Envelope testEnv = testRing.Bounds; Coordinate testPt = testRing.GetCoordinate(0); EdgeRing minShell = null; Envelope minEnv = null; for (IEdgeRingEnumerator it = shellList.GetEnumerator(); it.MoveNext();) { EdgeRing tryShell = it.Current; LinearRing tryRing = tryShell.Ring; Envelope tryEnv = tryRing.Bounds; if (minShell != null) { minEnv = minShell.Ring.Bounds; } bool isContained = false; if (tryEnv.Contains(testEnv) && CGAlgorithms.IsPointInRing(testPt, tryRing.Coordinates)) { isContained = true; } // check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) { minShell = tryShell; } } } return(minShell); }
} // private void PlaceFreeHoles( ArrayList freeHoleList ) /// <summary> /// Find the innermost enclosing shell EdgeRing containing the argument EdgeRing, if any. /// The innermost enclosing ring is the <i>smallest</i> enclosing ring.</summary> /// <remarks> /// <para>The algorithm used depends on the fact that: /// /// ring A contains ring B iff envelope(ring A) contains envelope(ring B) /// </para> /// <para>This routine is only safe to use if the chosen point of the hole /// is known to be properly contained in a shell /// (which is guaranteed to be the case if the hole does not touch its shell)</para> /// </remarks> /// <param name="testEr"></param> /// <returns> /// Containing EdgeRing, if there is one /// Null if no containing EdgeRing is found /// </returns> private EdgeRing FindEdgeRingContaining(EdgeRing testEr) { LinearRing testRing = testEr.GetLinearRing(); Envelope testEnv = testRing.GetEnvelopeInternal(); Coordinate testPt = testRing.GetCoordinateN(0); EdgeRing minShell = null; Envelope minEnv = null; foreach (object obj in _shellList) { EdgeRing tryShell = (EdgeRing)obj; LinearRing tryRing = tryShell.GetLinearRing(); Envelope tryEnv = tryRing.GetEnvelopeInternal(); if (minShell != null) { minEnv = minShell.GetLinearRing().GetEnvelopeInternal(); } bool isContained = false; if (tryEnv.Contains(testEnv) && _cga.IsPointInRing(testPt, tryRing.GetCoordinates())) { isContained = true; } // check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) { minShell = tryShell; } } } // foreach ( object obj in _shellList ) return(minShell); } // private EdgeRing FindEdgeRingContaining( EdgeRing testEr )
/// <summary> Check if any shell ring has an unvisited edge. /// A shell ring is a ring which is not a hole and which has the interior /// of the parent area on the RHS. /// (Note that there may be non-hole rings with the interior on the LHS, /// since the interior of holes will also be polygonized into CW rings /// by the LinkAllDirectedEdges() step) /// </summary> /// <returns> true if there is an unvisited edge in a non-hole ring /// </returns> private bool HasUnvisitedShellEdge(ArrayList edgeRings) { int nRings = edgeRings.Count; for (int i = 0; i < nRings; i++) { EdgeRing er = (EdgeRing)edgeRings[i]; // don't check hole rings if (er.IsHole) { continue; } ArrayList edges = er.Edges; DirectedEdge de = (DirectedEdge)edges[0]; // don't check CW rings which are holes if (de.Label.GetLocation(0, Position.Right) != LocationType.Interior) { continue; } // the edgeRing is CW ring which surrounds the INT of the area, so check all // edges have been visited. If any are unvisited, this is a disconnected part of the interior int nEdges = edges.Count; for (int j = 0; j < nEdges; j++) { de = (DirectedEdge)edges[j]; if (!de.Visited) { disconnectedRingcoord = de.Coordinate; return(true); } } } return(false); }
public override void SetEdgeRing(DirectedEdge de, EdgeRing er) { de.EdgeRing = er; }