コード例 #1
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <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
            for (IEnumerator i = deStar.Edges.GetEnumerator(); i.MoveNext();)
            {
                PolygonizeDirectedEdge outDe = (PolygonizeDirectedEdge)i.Current;
                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;
            }
        }
コード例 #2
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <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);
        }
コード例 #3
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <summary>
        ///
        /// </summary>
        /// <param name="dirEdges">A List of the DirectedEdges in the graph.</param>
        /// <returns>A List of DirectedEdges, one for each edge ring found.</returns>
        private static IList FindLabeledEdgeRings(IEnumerable dirEdges)
        {
            IList edgeRingStarts = new ArrayList();
            // label the edge rings formed
            long currLabel = 1;

            for (IEnumerator i = dirEdges.GetEnumerator(); i.MoveNext();)
            {
                PolygonizeDirectedEdge de = (PolygonizeDirectedEdge)i.Current;
                if (de.IsMarked)
                {
                    continue;
                }
                if (de.Label >= 0)
                {
                    continue;
                }

                edgeRingStarts.Add(de);
                IList edges = FindDirEdgesInRing(de);

                Label(edges, currLabel);
                currLabel++;
            }
            return(edgeRingStarts);
        }
コード例 #4
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <summary>
        /// Computes the EdgeRings formed by the edges in this graph.
        /// </summary>
        /// <returns>A list of the{EdgeRings found by the polygonization process.</returns>
        public virtual IList GetEdgeRings()
        {
            // maybe could optimize this, since most of these pointers should be set correctly already by deleteCutEdges()
            ComputeNextCwEdges();
            // clear labels of all edges in graph
            Label(DirectedEdges, -1);
            IList maximalRings = FindLabeledEdgeRings(DirectedEdges);

            ConvertMaximalToMinimalEdgeRings(maximalRings);

            // find all edgerings
            IList edgeRingList = new ArrayList();

            for (IEnumerator i = DirectedEdges.GetEnumerator(); i.MoveNext();)
            {
                PolygonizeDirectedEdge de = (PolygonizeDirectedEdge)i.Current;
                if (de.IsMarked)
                {
                    continue;
                }
                if (de.IsInRing)
                {
                    continue;
                }

                EdgeRing er = FindEdgeRing(de);
                edgeRingList.Add(er);
            }
            return(edgeRingList);
        }
コード例 #5
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <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 IList FindIntersectionNodes(PolygonizeDirectedEdge startDe, long label)
        {
            PolygonizeDirectedEdge de = startDe;
            IList intNodes            = null;

            do
            {
                if (de == null)
                {
                    continue;
                }
                Node node = de.FromNode;
                if (GetDegree(node, label) > 1)
                {
                    if (intNodes == null)
                    {
                        intNodes = new ArrayList();
                    }
                    intNodes.Add(node);
                }
                de = de.Next;
                if (de == null)
                {
                    throw new NullEdgeException();
                }
                if (de != startDe && de.IsInRing)
                {
                    throw new DuplicateEdgeException();
                }
            }while (de != startDe);
            return(intNodes);
        }
コード例 #6
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
 /// <summary>
 ///
 /// </summary>
 /// <param name="dirEdges"></param>
 /// <param name="label"></param>
 private static void Label(IEnumerable dirEdges, long label)
 {
     for (IEnumerator i = dirEdges.GetEnumerator(); i.MoveNext();)
     {
         PolygonizeDirectedEdge de = (PolygonizeDirectedEdge)i.Current;
         de.Label = label;
     }
 }
コード例 #7
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <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 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;
            }
        }
コード例 #8
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <summary>
        ///
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private static int GetDegreeNonDeleted(Node node)
        {
            IList edges  = node.OutEdges.Edges;
            int   degree = 0;

            for (IEnumerator i = edges.GetEnumerator(); i.MoveNext();)
            {
                PolygonizeDirectedEdge de = (PolygonizeDirectedEdge)i.Current;
                if (!de.IsMarked)
                {
                    degree++;
                }
            }
            return(degree);
        }
コード例 #9
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <summary>
        /// Deletes all edges at a node.
        /// </summary>
        /// <param name="node"></param>
        public static void DeleteAllEdges(Node node)
        {
            IList edges = node.OutEdges.Edges;

            for (IEnumerator i = edges.GetEnumerator(); i.MoveNext();)
            {
                PolygonizeDirectedEdge de = (PolygonizeDirectedEdge)i.Current;
                de.IsMarked = true;
                PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge)de.Sym;
                if (sym != null)
                {
                    sym.IsMarked = true;
                }
            }
        }
コード例 #10
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <summary>
        ///
        /// </summary>
        /// <param name="node"></param>
        /// <param name="label"></param>
        /// <returns></returns>
        private static int GetDegree(Node node, long label)
        {
            IList edges  = node.OutEdges.Edges;
            int   degree = 0;

            for (IEnumerator i = edges.GetEnumerator(); i.MoveNext();)
            {
                PolygonizeDirectedEdge de = (PolygonizeDirectedEdge)i.Current;
                if (de.Label == label)
                {
                    degree++;
                }
            }
            return(degree);
        }
コード例 #11
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <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));
        }
コード例 #12
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <summary>
        /// Convert the maximal edge rings found by the initial graph traversal
        /// into the minimal edge rings required by NTS polygon topology rules.
        /// </summary>
        /// <param name="ringEdges">The list of start edges for the edgeRings to convert.</param>
        private static void ConvertMaximalToMinimalEdgeRings(IEnumerable ringEdges)
        {
            for (IEnumerator i = ringEdges.GetEnumerator(); i.MoveNext();)
            {
                PolygonizeDirectedEdge de = (PolygonizeDirectedEdge)i.Current;
                long  label    = de.Label;
                IList intNodes = FindIntersectionNodes(de, label);

                if (intNodes == null)
                {
                    continue;
                }
                // flip the next pointers on the intersection nodes to create minimal edge rings
                for (IEnumerator iNode = intNodes.GetEnumerator(); iNode.MoveNext();)
                {
                    Node node = (Node)iNode.Current;
                    ComputeNextCcwEdges(node, label);
                }
            }
        }
コード例 #13
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <summary>
        /// Traverse 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 IList FindDirEdgesInRing(PolygonizeDirectedEdge startDe)
        {
            PolygonizeDirectedEdge de = startDe;
            IList edges = new ArrayList();

            do
            {
                edges.Add(de);
                de = de.Next;
                if (de == null)
                {
                    throw new NullEdgeException();
                }
                if (de != startDe && de.IsInRing)
                {
                    throw new DuplicateEdgeException();
                }
            }while (de != startDe);
            return(edges);
        }
コード例 #14
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <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);
        }
コード例 #15
0
ファイル: PolygonizeGraph.cs プロジェクト: AlvaIce/GFJT-2020
        /// <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;
                if (de == null)
                {
                    throw new NullEdgeException();
                }
                if (de != startDe && de.IsInRing)
                {
                    throw new DuplicateEdgeException();
                }
            }while (de != startDe);
            return(er);
        }
コード例 #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;
         if (de == null) throw new NullEdgeException();
         if (de != startDe && de.IsInRing) throw new DuplicateEdgeException();
     }
     while (de != startDe);
     return er;
 }
コード例 #17
0
 /// <summary>
 /// Traverse 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 IList FindDirEdgesInRing(PolygonizeDirectedEdge startDe)
 {
     PolygonizeDirectedEdge de = startDe;
     IList edges = new ArrayList();
     do
     {
         edges.Add(de);
         de = de.Next;
         if (de == null) throw new NullEdgeException();
         if (de != startDe && de.IsInRing) throw new DuplicateEdgeException();
     }
     while (de != startDe);
     return edges;
 }
コード例 #18
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 IList FindIntersectionNodes(PolygonizeDirectedEdge startDe, long label)
 {
     PolygonizeDirectedEdge de = startDe;
     IList intNodes = null;
     do
     {
         if (de == null) continue;
         Node node = de.FromNode;
         if (GetDegree(node, label) > 1)
         {
             if (intNodes == null)
                 intNodes = new ArrayList();
             intNodes.Add(node);
         }
         de = de.Next;
         if (de == null) throw new NullEdgeException();
         if (de != startDe && de.IsInRing) throw new DuplicateEdgeException();
     }
     while (de != startDe);
     return intNodes;
 }
コード例 #19
0
        /// <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);
        }