/// <summary> /// Finds and removes all cut edges from the graph. /// </summary> /// <returns>A list of the <c>LineString</c>s forming the removed cut edges.</returns> public virtual IList DeleteCutEdges() { ComputeNextCwEdges(); // label the current set of edgerings FindLabeledEdgeRings(DirectedEdges); /* * Cut Edges are edges where both dirEdges have the same label. * Delete them, and record them */ IList cutLines = new ArrayList(); for (IEnumerator i = DirectedEdges.GetEnumerator(); i.MoveNext();) { PolygonizeDirectedEdge de = (PolygonizeDirectedEdge)i.Current; if (de.IsMarked) { continue; } PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge)de.Sym; if (de.Label == sym.Label) { de.IsMarked = true; sym.IsMarked = true; // save the line as a cut edge PolygonizeEdge e = (PolygonizeEdge)de.Edge; cutLines.Add(e.Line); } } return(cutLines); }
private void EnsureCoordinates() { if (_ringPts != null) { return; } CoordinateList coordList = new CoordinateList(); for (IEnumerator i = _deList.GetEnumerator(); i.MoveNext();) { DirectedEdge de = (DirectedEdge)i.Current; PolygonizeEdge edge = (PolygonizeEdge)de.Edge; AddEdge(edge.Line.Coordinates, de.EdgeDirection, coordList); } _ringPts = coordList; }
/// <summary> /// Marks all edges from the graph which are "dangles". /// Dangles are which are incident on a node with degree 1. /// This process is recursive, since removing a dangling edge /// may result in another edge becoming a dangle. /// In order to handle large recursion depths efficiently, /// an explicit recursion stack is used. /// </summary> /// <returns>A List containing the LineStrings that formed dangles.</returns> public virtual IList DeleteDangles() { IList nodesToRemove = FindNodesOfDegree(1); ISet dangleLines = new HashedSet(); Stack nodeStack = new Stack(); for (IEnumerator i = nodesToRemove.GetEnumerator(); i.MoveNext();) { nodeStack.Push(i.Current); } while (nodeStack.Count != 0) { Node node = (Node)nodeStack.Pop(); DeleteAllEdges(node); IList nodeOutEdges = node.OutEdges.Edges; for (IEnumerator i = nodeOutEdges.GetEnumerator(); i.MoveNext();) { PolygonizeDirectedEdge de = (PolygonizeDirectedEdge)i.Current; // delete this edge and its sym de.IsMarked = true; PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge)de.Sym; if (sym != null) { sym.IsMarked = true; } // save the line as a dangle PolygonizeEdge e = (PolygonizeEdge)de.Edge; dangleLines.Add(e.Line); Node toNode = de.ToNode; // add the toNode to the list to be processed, if it is now a dangle if (GetDegreeNonDeleted(toNode) == 1) { nodeStack.Push(toNode); } } } return(new ArrayList(dangleLines)); }
/// <summary> /// Add a <c>LineString</c> forming an edge of the polygon graph. /// </summary> /// <param name="line">The line to add.</param> public virtual void AddEdge(LineString line) { if (line.IsEmpty) { return; } IList <Coordinate> linePts = CoordinateArrays.RemoveRepeatedPoints(line.Coordinates); Coordinate startPt = linePts[0]; Coordinate endPt = linePts[linePts.Count - 1]; Node nStart = GetNode(startPt); Node nEnd = GetNode(endPt); DirectedEdge de0 = new PolygonizeDirectedEdge(nStart, nEnd, linePts[1], true); DirectedEdge de1 = new PolygonizeDirectedEdge(nEnd, nStart, linePts[linePts.Count - 2], false); Edge edge = new PolygonizeEdge(line); edge.SetDirectedEdges(de0, de1); Add(edge); }
/// <summary> /// Add a <c>LineString</c> forming an edge of the polygon graph. /// </summary> /// <param name="line">The line to add.</param> public virtual void AddEdge(LineString line) { if (line.IsEmpty) return; IList<Coordinate> linePts = CoordinateArrays.RemoveRepeatedPoints(line.Coordinates); Coordinate startPt = linePts[0]; Coordinate endPt = linePts[linePts.Count - 1]; Node nStart = GetNode(startPt); Node nEnd = GetNode(endPt); DirectedEdge de0 = new PolygonizeDirectedEdge(nStart, nEnd, linePts[1], true); DirectedEdge de1 = new PolygonizeDirectedEdge(nEnd, nStart, linePts[linePts.Count - 2], false); Edge edge = new PolygonizeEdge(line); edge.SetDirectedEdges(de0, de1); Add(edge); }