Ejemplo n.º 1
0
        /// <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 IList <ILineString> DeleteCutEdges()
        {
            ComputeNextCWEdges();
            // label the current set of edgerings
            FindLabeledEdgeRings(dirEdges);

            /*
             * Cut Edges are edges where both dirEdges have the same label.
             * Delete them, and record them
             */
            IList <ILineString> cutLines = new List <ILineString>();

            foreach (PolygonizeDirectedEdge de in dirEdges)
            {
                if (de.IsMarked)
                {
                    continue;
                }

                PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge)de.Sym;
                if (de.Label == sym.Label)
                {
                    de.Marked  = true;
                    sym.Marked = true;

                    // save the line as a cut edge
                    PolygonizeEdge e = (PolygonizeEdge)de.Edge;
                    cutLines.Add(e.Line);
                }
            }
            return(cutLines);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Add a <c>LineString</c> forming an edge of the polygon graph.
        /// </summary>
        /// <param name="line">The line to add.</param>
        public void AddEdge(ILineString line)
        {
            if (line.IsEmpty)
            {
                return;
            }

            Coordinate[] linePts = CoordinateArrays.RemoveRepeatedPoints(line.Coordinates);
            if (linePts.Length < 2)
            {
                return;
            }

            Coordinate startPt = linePts[0];
            Coordinate endPt   = linePts[linePts.Length - 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.Length - 2], false);
            Edge         edge = new PolygonizeEdge(line);

            edge.SetDirectedEdges(de0, de1);
            Add(edge);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="startDE"></param>
        /// <returns></returns>
        private EdgeRing FindEdgeRing(PolygonizeDirectedEdge startDE)
        {
            var er = new EdgeRing(_factory);

            er.Build(startDE);
            return(er);
        }
Ejemplo n.º 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="node"></param>
        private static void ComputeNextCWEdges(Node node)
        {
            DirectedEdgeStar       deStar  = node.OutEdges;
            PolygonizeDirectedEdge startDE = null;
            PolygonizeDirectedEdge prevDE  = null;

            // the edges are stored in CCW order around the star
            foreach (PolygonizeDirectedEdge outDE in deStar.Edges)
            {
                if (outDE.IsMarked)
                {
                    continue;
                }

                if (startDE == null)
                {
                    startDE = outDE;
                }

                if (prevDE != null)
                {
                    PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge)prevDE.Sym;
                    sym.Next = outDE;
                }
                prevDE = outDE;
            }
            if (prevDE != null)
            {
                PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge)prevDE.Sym;
                sym.Next = startDE;
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Computes the next edge pointers going CCW around the given node, for the
        /// given edgering label.
        /// This algorithm has the effect of converting maximal edgerings into minimal edgerings
        /// </summary>
        /// <param name="node"></param>
        /// <param name="label"></param>
        private static void ComputeNextCCWEdges(Node node, long label)
        {
            DirectedEdgeStar deStar = node.OutEdges;
            //PolyDirectedEdge lastInDE = null;
            PolygonizeDirectedEdge firstOutDE = null;
            PolygonizeDirectedEdge prevInDE   = null;

            // the edges are stored in CCW order around the star
            IList <DirectedEdge> edges = deStar.Edges;

            //for (IEnumerator i = deStar.Edges.GetEnumerator(); i.MoveNext(); ) {
            for (int i = edges.Count - 1; i >= 0; i--)
            {
                PolygonizeDirectedEdge de  = (PolygonizeDirectedEdge)edges[i];
                PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge)de.Sym;

                PolygonizeDirectedEdge outDE = null;
                if (de.Label == label)
                {
                    outDE = de;
                }

                PolygonizeDirectedEdge inDE = null;
                if (sym.Label == label)
                {
                    inDE = sym;
                }

                if (outDE == null && inDE == null)
                {
                    continue;                                 // this edge is not in edgering
                }
                if (inDE != null)
                {
                    prevInDE = inDE;
                }

                if (outDE != null)
                {
                    if (prevInDE != null)
                    {
                        prevInDE.Next = outDE;
                        prevInDE      = null;
                    }
                    if (firstOutDE == null)
                    {
                        firstOutDE = outDE;
                    }
                }
            }
            if (prevInDE != null)
            {
                Assert.IsTrue(firstOutDE != null);
                prevInDE.Next = firstOutDE;
            }
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Traverses the polygonized edge rings in the graph
 /// and computes the depth parity (odd or even)
 /// relative to the exterior of the graph.
 ///
 /// If the client has requested that the output
 /// be polygonally valid, only odd polygons will be constructed.
 /// </summary>
 public void ComputeDepthParity()
 {
     while (true)
     {
         PolygonizeDirectedEdge de = null; //findLowestDirEdge();
         if (de == null)
         {
             return;
         }
         ComputeDepthParity(de);
     }
 }
Ejemplo n.º 7
0
        public void Build(PolygonizeDirectedEdge startDE)
        {
            PolygonizeDirectedEdge de = startDE;

            do
            {
                Add(de);
                de.Ring = this;
                de      = de.Next;
                Utilities.Assert.IsTrue(de != null, "found null DE in ring");
                Utilities.Assert.IsTrue(de == startDE || !de.IsInRing, "found DE already in ring");
            } while (de != startDE);
        }
        /// <summary>
        /// Traverses a ring of DirectedEdges, accumulating them into a list.
        /// This assumes that all dangling directed edges have been removed
        /// from the graph, so that there is always a next dirEdge.
        /// </summary>
        /// <param name="startDE">The DirectedEdge to start traversing at.</param>
        /// <returns>A List of DirectedEdges that form a ring.</returns>
        private static IEnumerable <DirectedEdge> FindDirEdgesInRing(PolygonizeDirectedEdge startDE)
        {
            PolygonizeDirectedEdge de    = startDE;
            IList <DirectedEdge>   edges = new List <DirectedEdge>();

            do
            {
                edges.Add(de);
                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(edges);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Deletes all edges at a node.
        /// </summary>
        /// <param name="node"></param>
        public static void DeleteAllEdges(Node node)
        {
            IList <DirectedEdge> edges = node.OutEdges.Edges;

            foreach (PolygonizeDirectedEdge de in edges)
            {
                de.Marked = true;
                PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge)de.Sym;
                if (sym != null)
                {
                    sym.Marked = true;
                }
            }
        }
Ejemplo n.º 10
0
        /**
         * Traverses a ring of DirectedEdges, accumulating them into a list.
         * This assumes that all dangling directed edges have been removed
         * from the graph, so that there is always a next dirEdge.
         *
         * @param startDE the DirectedEdge to start traversing at
         * @return a List of DirectedEdges that form a ring
         */

        public static List <DirectedEdge> FindDirEdgesInRing(PolygonizeDirectedEdge startDE)
        {
            var de    = startDE;
            var edges = new List <DirectedEdge>();

            do
            {
                edges.Add(de);
                de = de.Next;
                Utilities.Assert.IsTrue(de != null, "found null DE in ring");
                Utilities.Assert.IsTrue(de == startDE || !de.IsInRing, "found DE already in ring");
            } while (de != startDE);
            return(edges);
        }
        /// <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);
        }
Ejemplo n.º 12
0
        /// <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 <see cref="ILineString"/>s that formed dangles.</returns>
        public ICollection <ILineString> DeleteDangles()
        {
            var nodesToRemove = FindNodesOfDegree(1);
            HashSet <ILineString> dangleLines = new HashSet <ILineString>();
            Stack <Node>          nodeStack   = new Stack <Node>();

            foreach (Node node in nodesToRemove)
            {
                nodeStack.Push(node);
            }

            while (nodeStack.Count != 0)
            {
                Node node = nodeStack.Pop();

                DeleteAllEdges(node);
                IList <DirectedEdge> nodeOutEdges = node.OutEdges.Edges;
                foreach (PolygonizeDirectedEdge de in nodeOutEdges)
                {
                    // delete this edge and its sym
                    de.Marked = true;
                    PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge)de.Sym;
                    if (sym != null)
                    {
                        sym.Marked = 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);
                    }
                }
            }

            var dangleArray = new ILineString[dangleLines.Count];

            dangleLines.CopyTo(dangleArray, 0);
            return(new ReadOnlyCollection <ILineString>(dangleArray));
            //new ArrayList(dangleLines.CastPlatform());
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Add a <c>LineString</c> forming an edge of the polygon graph.
        /// </summary>
        /// <param name="line">The line to add.</param>
        public void AddEdge(ILineString line)
        {
            if (line.IsEmpty)
                return;

            Coordinate[] linePts = CoordinateArrays.RemoveRepeatedPoints(line.Coordinates);
            Coordinate startPt = linePts[0];
            Coordinate endPt = linePts[linePts.Length - 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.Length - 2], false);
            Edge edge = new PolygonizeEdge(line);
            edge.SetDirectedEdges(de0, de1);
            Add(edge);
        }
Ejemplo n.º 14
0
        /// <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;
                }
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Finds all nodes in a maximal edgering which are self-intersection nodes
        /// </summary>
        /// <param name="startDE"></param>
        /// <param name="label"></param>
        /// <returns>
        /// The list of intersection nodes found,
        /// or null if no intersection nodes were found.
        /// </returns>
        private static IEnumerable <Node> FindIntersectionNodes(PolygonizeDirectedEdge startDE, long label)
        {
            PolygonizeDirectedEdge de       = startDE;
            IList <Node>           intNodes = null;

            do
            {
                Node node = de.FromNode;
                if (GetDegree(node, label) > 1)
                {
                    if (intNodes == null)
                    {
                        intNodes = new List <Node>();
                    }
                    intNodes.Add(node);
                }

                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(intNodes);
        }
Ejemplo n.º 16
0
 /// <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;
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Finds all nodes in a maximal edgering which are self-intersection nodes
        /// </summary>
        /// <param name="startDE"></param>
        /// <param name="label"></param>
        /// <returns> 
        /// The list of intersection nodes found,
        /// or null if no intersection nodes were found.       
        /// </returns>
        private static IEnumerable<Node> FindIntersectionNodes(PolygonizeDirectedEdge startDE, long label)
        {
            PolygonizeDirectedEdge de = startDE;
            IList<Node> intNodes = null;
            do 
            {
                Node node = de.FromNode;
                if (GetDegree(node, label) > 1) 
                {
                    if (intNodes == null)
                        intNodes = new List<Node>();
                    intNodes.Add(node);
                }

                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 intNodes;
        }
Ejemplo n.º 18
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="startDE"></param>
 /// <returns></returns>
 private EdgeRing FindEdgeRing(PolygonizeDirectedEdge startDE)
 {
     var er = new EdgeRing(_factory);
     er.Build(startDE);
     return er;
 }
Ejemplo n.º 19
0
        ///<summary>
        /// Traverses all connected edges, computing the depth parity of the associated polygons.
        ///</summary>
        /// <param name="de"></param>
        private void ComputeDepthParity(PolygonizeDirectedEdge de)
        {

        }
Ejemplo n.º 20
0
 ///<summary>
 /// Traverses all connected edges, computing the depth parity of the associated polygons.
 ///</summary>
 /// <param name="de"></param>
 private void ComputeDepthParity(PolygonizeDirectedEdge de)
 {
 }
Ejemplo n.º 21
0
 /// <summary>
 /// Traverses a ring of DirectedEdges, accumulating them into a list.
 /// This assumes that all dangling directed edges have been removed
 /// from the graph, so that there is always a next dirEdge.
 /// </summary>
 /// <param name="startDE">The DirectedEdge to start traversing at.</param>
 /// <returns>A List of DirectedEdges that form a ring.</returns>
 private static IEnumerable<DirectedEdge> FindDirEdgesInRing(PolygonizeDirectedEdge startDE)
 {
     PolygonizeDirectedEdge de = startDE;
     IList<DirectedEdge> edges = new List<DirectedEdge>();
     do 
     {
         edges.Add(de);
         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 edges;
 }