/// <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 <br/> /// or <value>null</value> if no containing EdgeRing is found.</returns> public static EdgeRing FindEdgeRingContaining(EdgeRing testEr, IList <EdgeRing> shellList) { var testRing = testEr.Ring; var testEnv = testRing.EnvelopeInternal; //var testPt = testRing.GetCoordinateN(0); EdgeRing minShell = null; Envelope minShellEnv = null; foreach (var tryShell in shellList) { var tryShellRing = tryShell.Ring; var tryShellEnv = tryShellRing.EnvelopeInternal; if (minShell != null) { minShellEnv = minShell.Ring.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; } var testPt = CoordinateArrays.PointNotInList(testRing.Coordinates, tryShellRing.Coordinates); var isContained = PointLocation.IsInRing(testPt, tryShellRing.Coordinates); // check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minShellEnv.Contains(tryShellEnv)) { minShell = tryShell; minShellEnv = minShell.Ring.EnvelopeInternal; } } } return(minShell); }
/// <summary> /// Updates the included status for currently non-included shells /// based on whether they are adjacent to an included shell. /// </summary> internal void UpdateIncluded() { if (IsHole) { return; } for (int i = 0; i < _deList.Count; i++) { PolygonizeDirectedEdge de = (PolygonizeDirectedEdge)_deList[i]; EdgeRing adjShell = ((PolygonizeDirectedEdge)de.Sym).Ring.Shell; if (adjShell != null && adjShell.IsIncludedSet) { // adjacent ring has been processed, so set included to inverse of adjacent included IsIncluded = !adjShell.IsIncluded; return; } } }