/// <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) { ILinearRing teString = testEr.Ring; Envelope testEnv = teString.EnvelopeInternal; 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 = CGAlgorithms.IsPointInRing(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> /// 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). /// <para/> /// To improve performance of this function the caller should /// make the passed shellList as small as possible(e.g. /// by using a spatial index filter beforehand). /// </summary> /// <param name="erList"></param> /// <param name="testEr"></param> /// <returns>Containing EdgeRing, if there is one <br/> /// or <c>null</c> if no containing EdgeRing is found.</returns> public static EdgeRing FindEdgeRingContaining(EdgeRing testEr, IList <EdgeRing> erList) { var testRing = testEr.Ring; var testEnv = testRing.EnvelopeInternal; //var testPt = testRing.GetCoordinateN(0); EdgeRing minRing = null; Envelope minRingEnv = null; foreach (var tryEdgeRing in erList) { var tryRing = tryEdgeRing.Ring; var tryRingEnv = tryRing.EnvelopeInternal; if (minRing != null) { minRingEnv = minRing.Ring.EnvelopeInternal; } // the hole envelope cannot equal the shell envelope // (also guards against testing rings against themselves) if (tryRingEnv.Equals(testEnv)) { continue; } // hole must be contained in shell if (!tryRingEnv.Contains(testEnv)) { continue; } var testPt = CoordinateArrays.PointNotInList(testRing.Coordinates, tryEdgeRing.Coordinates); bool isContained = tryEdgeRing.IsInRing(testPt); // check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minRing == null || minRingEnv.Contains(tryRingEnv)) { minRing = tryEdgeRing; minRingEnv = minRing.Ring.EnvelopeInternal; } } } return(minRing); }
/// <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) { ILinearRing teString = testEr.Ring; Envelope testEnv = teString.EnvelopeInternal; 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 = CGAlgorithms.IsPointInRing(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; } } }
/// <summary> /// /// </summary> /// <param name="startDE"></param> /// <returns></returns> private EdgeRing FindEdgeRing(PolygonizeDirectedEdge startDE) { var er = new EdgeRing(_factory); er.Build(startDE); return er; }
private static void AssignHoleToShell(EdgeRing holeEdgeRing, IList<EdgeRing> shellList) { var shell = EdgeRing.FindEdgeRingContaining(holeEdgeRing, shellList); if (shell != null) { shell.AddHole(holeEdgeRing); } }
/// <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; }