/// <summary> /// Tests if an edge of the maximal edge ring is already linked into /// a minimal <see cref="OverlayEdgeRing"/>. If so, this node has already been processed /// earlier in the maximal edgering linking scan. /// </summary> /// <param name="edge">An edge of a maximal edgering</param> /// <param name="maxRing">The maximal edgering</param> /// <returns><c>true</c> if the edge has already been linked into a minimal edgering.</returns> private static bool IsAlreadyLinked(OverlayEdge edge, MaximalEdgeRing maxRing) { bool isLinked = edge.MaxEdgeRing == maxRing && edge.IsResultLinked; return(isLinked); }
private void LinkResultAreaEdgesMax(IEnumerable <OverlayEdge> resultEdges) { foreach (var edge in resultEdges) { //Assert.isTrue(edge.isInResult()); // TODO: find some way to skip nodes which are already linked MaximalEdgeRing.LinkResultAreaMaxRingAtNode(edge); } }
private static OverlayEdge SelectMaxOutEdge(OverlayEdge currOut, MaximalEdgeRing maxEdgeRing) { // select if currOut edge is part of this max ring if (currOut.MaxEdgeRing == maxEdgeRing) { return(currOut); } // otherwise skip this edge return(null); }
/// <summary> /// For all OverlayEdges in result, form them into MaximalEdgeRings /// </summary> private static List <MaximalEdgeRing> BuildMaximalRings(IEnumerable <OverlayEdge> edges) { var edgeRings = new List <MaximalEdgeRing>(); foreach (var e in edges) { if (e.IsInResultArea && e.Label.IsBoundaryEither) { // if this edge has not yet been processed if (e.MaxEdgeRing == null) { var er = new MaximalEdgeRing(e); edgeRings.Add(er); } } } return(edgeRings); }
private static OverlayEdge LinkMaxInEdge(OverlayEdge currOut, OverlayEdge currMaxRingOut, MaximalEdgeRing maxEdgeRing) { var currIn = currOut.SymOE; // currIn is not in this max-edgering, so keep looking if (currIn.MaxEdgeRing != maxEdgeRing) { return(currMaxRingOut); } //Debug.println("Found result in-edge: " + currIn); currIn.NextResult = currMaxRingOut; //Debug.println("Linked Min Edge: " + currIn + " -> " + currMaxRingOut); // return null to indicate to scan for the next max-ring out-edge return(null); }
/// <summary> /// Links the edges of a <see cref="MaximalEdgeRing"/> around this node /// into minimal edge rings (<see cref="OverlayEdgeRing"/>s). /// Minimal ring edges are linked in the opposite orientation (CW) /// to the maximal ring. /// This changes self-touching rings into a two or more separate rings, /// as per the OGC SFS polygon topology semantics. /// This relinking must be done to each max ring separately, /// rather than all the node result edges, since there may be /// more than one max ring incident at the node. /// </summary> /// <param name="maxRing">The maximal ring to link</param> /// <param name="nodeEdge">An edge originating at this node</param> private static void LinkMinRingEdgesAtNode(OverlayEdge nodeEdge, MaximalEdgeRing maxRing) { //Assert.isTrue(nodeEdge.isInResult(), "Attempt to link non-result edge"); /* * The node edge is an out-edge, * so it is the first edge linked * with the next CCW in-edge */ var endOut = nodeEdge; var currMaxRingOut = endOut; var currOut = endOut.ONextOE; //Debug.println("\n------ Linking node MIN ring edges"); //Debug.println("BEFORE: " + toString(nodeEdge)); do { if (IsAlreadyLinked(currOut.SymOE, maxRing)) { return; } if (currMaxRingOut == null) { currMaxRingOut = SelectMaxOutEdge(currOut, maxRing); } else { currMaxRingOut = LinkMaxInEdge(currOut, currMaxRingOut, maxRing); } currOut = currOut.ONextOE; } while (currOut != endOut); //Debug.println("AFTER: " + toString(nodeEdge)); if (currMaxRingOut != null) { throw new TopologyException("Unmatched edge found during min-ring linking", nodeEdge.Coordinate); } }