/// <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="shellList"></param> /// <param name="testEr"></param> /// <returns>Containing EdgeRing, if there is one, OR /// null if no containing EdgeRing is found.</returns> public static EdgeRing FindEdgeRingContaining(EdgeRing testEr, IList shellList) { ILinearRing teString = testEr.Ring; IEnvelope testEnv = teString.EnvelopeInternal; EdgeRing minShell = null; IEnvelope minEnv = null; for (IEnumerator it = shellList.GetEnumerator(); it.MoveNext(); ) { EdgeRing tryShell = (EdgeRing)it.Current; ILinearRing tryRing = tryShell.Ring; IEnvelope tryEnv = tryRing.EnvelopeInternal; if (minShell != null) minEnv = minShell.Ring.EnvelopeInternal; bool isContained = false; // the hole envelope cannot equal the shell envelope if (tryEnv.Equals(testEnv)) continue; Coordinate testPt = PtNotInList(teString.Coordinates, tryRing.Coordinates); 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; }
/// <summary> /// /// </summary> /// <param name="holeER"></param> /// <param name="shellList"></param> private static void AssignHoleToShell(EdgeRing holeER, IList shellList) { EdgeRing shell = EdgeRing.FindEdgeRingContaining(holeER, shellList); if (shell != null) shell.AddHole(holeER.Ring); }
/// <summary> /// /// </summary> /// <param name="startDE"></param> /// <returns></returns> private EdgeRing FindEdgeRing(PolygonizeDirectedEdge startDE) { PolygonizeDirectedEdge de = startDE; EdgeRing er = new EdgeRing(_factory); do { er.Add(de); de.Ring = er; de = de.Next; Assert.IsTrue(de != null, "found null DE in ring"); Assert.IsTrue(de == startDE || ! de.IsInRing, "found DE already in ring"); } while (de != startDE); return er; }