Exemple #1
0
        private EdgeRing _shell; // if non-null, the ring is a hole and this EdgeRing is its containing shell

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the EdgeRing class.
        /// </summary>
        public EdgeRing( DirectedEdge start, GeometryFactory geometryFactory, CGAlgorithms cga )
        {
            _geometryFactory = geometryFactory;
            _cga = cga;
            ComputePoints(start);
            ComputeRing();
        }
Exemple #2
0
        public void ComputeDepths(DirectedEdge de)
        {
            int edgeIndex = FindIndex(de);
            Label label = de.Label;
            int startDepth = de.GetDepth( Position.Left );

            // compute the depths from this edge up to the end of the edge array
            int nextDepth = ComputeDepths( edgeIndex + 1, _edgeList.Count - 1, startDepth );

            // compute the depths for the initial part of the array
            int lastDepth = ComputeDepths( 0, edgeIndex, nextDepth );

            //Trace.WriteLine( ToString() );
            Trace.Assert( lastDepth == startDepth, "depth mismatch at " + de.Coordinate.ToString() );
        }
		public override DirectedEdge GetNext( DirectedEdge de )
		{
			return de.Next;
		}
		/// <summary>
		/// Initializes a new instance of the MaximalEdgeRing class.
		/// A MaximalEdgeRing is a ring of edges which may contain nodes of degree > 2.
		/// A MaximalEdgeRing may represent two different spatial entities:
		/// &lt;ul&gt;
		/// &lt;li&gt;a single polygon possibly containing inversions (if the ring is oriented CW)
		/// &lt;li&gt;a single hole possibly containing exversions (if the ring is oriented CCW)
		/// &lt;/ul&gt;
		/// If the MaximalEdgeRing represents a polygon,
		/// the interior of the polygon is strongly connected.
		/// These are the form of rings used to define polygons under some spatial data models.
		/// However, under the OGC SFS model, {@link MinimalEdgeRings} are required.
		/// A MaximalEdgeRing can be converted to a list of MinimalEdgeRings using the
		/// { BuildMinimalRings() } method.
		/// </summary>
		public MaximalEdgeRing( DirectedEdge start, GeometryFactory geometryFactory, CGAlgorithms cga ) : base( start, geometryFactory, cga )
		{
		}
Exemple #5
0
        /// <summary>
        /// Collect all the points from the DirectedEdges of this ring into a contiguous list.
        /// </summary>
        /// <param name="start"></param>
        protected void ComputePoints(DirectedEdge start)
        {
            _startDe = start;
            DirectedEdge de = start;
            bool isFirstEdge = true;
            do
            {
                if ( de == null )
                {
                    throw new InvalidOperationException("Found null Directed Edge.");
                }
                _edges.Add( de );

                Label label = de.Label;

                // Java used an assert here...
                if ( !label.IsArea() )
                {
                    throw new InvalidOperationException("Label IsArea() is false when true is expected.");
                }

                MergeLabel( label );
                AddPoints( de.Edge, de.IsForward, isFirstEdge );
                isFirstEdge = false;
                SetEdgeRing( de, this );
                de = GetNext( de );			// GetNext will be implemented in the inherited class...this class is abstract.
            } while ( de != _startDe );
        }
Exemple #6
0
 public abstract void SetEdgeRing( DirectedEdge de, EdgeRing er );
Exemple #7
0
 public abstract DirectedEdge GetNext( DirectedEdge de );
        }         // public void LinkAllDirectedEdges()

        /// <summary>
        /// Traverse the star edges, maintaing the current location in the result area
        /// at this node (if any).  If any L edges are found in the interior of the result,
        /// mark them as covered.
        /// </summary>
        public void FindCoveredLineEdges()
        {
            //Trace.WriteLine("findCoveredLineEdges");
            //Trace.WriteLine( ToString() );
            // Since edges are stored in CCW order around the node,
            // as we move around the ring we move from the right to the left side of the edge


            // Find first DirectedEdge of result area (if any).
            // The interior of the result is on the RHS of the edge,
            // so the start location will be:
            // - INTERIOR if the edge is outgoing
            // - EXTERIOR if the edge is incoming
            int startLoc = Location.Null;

            foreach (DirectedEdge de in Edges())
            {
                DirectedEdge nextOut = de;
                DirectedEdge nextIn  = nextOut.Sym;

                if (!nextOut.IsLineEdge)
                {
                    if (nextOut.InResult)
                    {
                        startLoc = Location.Interior;
                        break;
                    }
                    if (nextIn.InResult)
                    {
                        startLoc = Location.Exterior;
                        break;
                    }
                }
            }             // foreach ( object obj in edges )

            // no A edges found, so can't determine if L edges are covered or not
            if (startLoc == Location.Null)
            {
                return;
            }


            // move around ring, keeping track of the current location
            // (Interior or Exterior) for the result area.
            // If L edges are found, mark them as covered if they are in the interior
            int currLoc = startLoc;

            foreach (DirectedEdge de in Edges())
            {
                DirectedEdge nextOut = de;
                DirectedEdge nextIn  = nextOut.Sym;
                if (nextOut.IsLineEdge)
                {
                    nextOut.Edge.SetCovered = (currLoc == Location.Interior);
                    //Trace.WriteLine( nextOut.ToString() );
                }
                else
                {                  // edge is an Area edge
                    if (nextOut.InResult)
                    {
                        currLoc = Location.Exterior;
                    }
                    if (nextIn.InResult)
                    {
                        currLoc = Location.Interior;
                    }
                }
            }     // foreach ( object obj in edges )
        }         // public void FindCoveredLineEdges()
		} // private void CollectLines( int opCode )

		/// <summary>
		/// 
		/// </summary>
		/// <param name="de"></param>
		/// <param name="opCode"></param>
		/// <param name="edges"></param>
		public void CollectLineEdge( DirectedEdge de, int opCode, ArrayList edges )
		{
			Label label = de.Label;
			Edge e = de.Edge;
			// include L edges which are in the result
			if ( de.IsLineEdge ) 
			{
				if ( !de.Visited && OverlayOp.IsResultOfOp( label, opCode ) && !e.IsCovered ) 
				{
					//Trace.WriteLine("de: " + de.Label.ToString() );
					//Trace.WriteLine("edge: " + e.Label.ToString() );

					edges.Add( e );
					de.SetVisitedEdge( true );
				} // if ( !de.Visited && OverlayOp.IsResultOfOp( label, opCode ) && !e.IsCovered )
			} // if ( de.IsLineEdge )
		} // public void CollectLineEdge( DirectedEdge de, int opCode, ArrayList edges )
		protected void VisitLinkedDirectedEdges(DirectedEdge start)
		{
			
			DirectedEdge startDe = start;
			DirectedEdge de = start;
			//Debug.println(de);
			do 
			{
				de.Visited=true;
				de = de.Next;
				//Debug.println(de);
			} while (de != startDe);
		}
Exemple #11
0
 abstract public void SetEdgeRing(DirectedEdge de, EdgeRing er);
Exemple #12
0
        }         // public void ComputeRing()

        abstract public DirectedEdge GetNext(DirectedEdge de);
        /// <summary>
        ///  Insert a directed edge in the list.
        /// </summary>
        /// <param name="ee">The EdgeEnd to be inserted into the list.  Must be of type DirectedEdge.</param>
        public override void Insert(EdgeEnd ee)
        {
            DirectedEdge de = (DirectedEdge)ee;

            InsertEdgeEnd(de, de);
        }
		public override void SetEdgeRing( DirectedEdge de, EdgeRing er )
		{
			de.EdgeRing = er;
		}
		} // public void CollectLineEdge( DirectedEdge de, int opCode, ArrayList edges )

		/// <summary>
		/// Collect edges from Area input which should be in the result by which have not been included
		/// in a result area.  This happens ONLY:
		/// &lt;ul&gt;
		///		&lt;li&gt;during an intersection when the boundaries of two areas touch in a line segment.
		///		&lt;li&gt;OR as a result of a dimensional collapse.
		///	&lt;/ul&gt;
		/// </summary>
		/// <param name="de"></param>
		/// <param name="opCode"></param>
		/// <param name="edges"></param>
		public void CollectBoundaryTouchEdge( DirectedEdge de, int opCode, ArrayList edges )
		{
			Label label = de.Label;
			// this smells like a bit of a hack, but it seems to work...
			if (   !de.IsLineEdge
				&& !de.IsInteriorAreaEdge  // added to handle dimensional collapses
				&& !de.Edge.IsInResult
				&& !de.Visited
				&& OverlayOp.IsResultOfOp( label, opCode )
				&& opCode == OverlayOp.Intersection )
			{
				edges.Add( de.Edge );
				de.SetVisitedEdge( true );
			}
		} // public void CollectBoundaryTouchEdge( DirectedEdge de, int opCode, ArrayList edges )
Exemple #16
0
        /// <summary>
        /// Add a set of edges to the graph.  For each edge two DirectedEdges
        /// will be created.  DirectedEdges are NOT linked by this method.
        /// </summary>
        /// <param name="edgesToAdd"></param>
        public void AddEdges( ArrayList edgesToAdd )
        {
            // create all the nodes for the edges
            foreach( object objectEdge in edgesToAdd )
            {
                Edge e = (Edge) objectEdge;
                _edges.Add( e );

                DirectedEdge de1 = new DirectedEdge( e, true );
                DirectedEdge de2 = new DirectedEdge( e, false );

                de1.Sym = de2;
                de2.Sym = de1;

                Add( de1 );
                Add( de2 );
            } // foreach( object objectEdge in edgesToAdd )
        }
        }         // private ArrayList GetResultAreaEdges()

        /// <summary>
        /// Traverse the star of DirectedEdges, linking the included edge together.
        /// To link two dirEdges, the next pointer for an incoming dirEdge is set to the next outgoing edge.
        ///
        /// DirEdges are only  linked. If:
        /// &lt;ul&gt;
        /// &lt;li&gt;They belong to an area (i.e. they have sides)
        /// &lt;li&gt;They are marked as being in the result.
        /// &lt;/ul&gt;
        /// Edges are linked in CCW order (the order they are stored.) This means that rings have
        /// their face on the Right ( in other words, the topological location of the face is given
        /// by the RHS label of the DirectedEdge)
        ///
        /// PRECONDITION: No pair of dirEdges are both marked as being in the result.
        /// </summary>
        public void LinkResultDirectedEdges()
        {
            // make sure edges are copied to resultAreaEdges list
            GetResultAreaEdges();

            // find first area edge (if any) to start linking at
            DirectedEdge firstOut = null;
            DirectedEdge incoming = null;
            int          state    = ScanningForIncoming;

            // link edges in CCW order
            for (int i = 0; i < _resultAreaEdgeList.Count; i++)
            {
                DirectedEdge nextOut = (DirectedEdge)_resultAreaEdgeList[i];
                DirectedEdge nextIn  = nextOut.Sym;

                // skip de's that we're not interested in
                if (nextOut.Label.IsArea())
                {
                    // record first outgoing edge, in order to link the last incoming edge
                    if (firstOut == null && nextOut.InResult)
                    {
                        firstOut = nextOut;
                    }

                    // assert: sym.isInResult() == false, since pairs of dirEdges should have been removed already

                    switch (state)
                    {
                    case ScanningForIncoming:
                        if (!nextIn.InResult)
                        {
                            continue;
                        }
                        incoming = nextIn;
                        state    = LinkingToOutGoing;
                        break;

                    case LinkingToOutGoing:
                        if (!nextOut.InResult)
                        {
                            continue;
                        }
                        incoming.Next = nextOut;
                        state         = ScanningForIncoming;
                        break;
                    }     // switch ( state )
                }         // if ( nextOut.Label.IsArea() )
            }             // for (int i = 0; i < _resultAreaEdgeList.Count; i++)

            //Trace.WriteLine( ToString() );

            if (state == LinkingToOutGoing)
            {
                if (firstOut == null)
                {
                    throw new TopologyException("No outgoing dirEdge found.");
                }
                if (!firstOut.InResult)
                {
                    throw new TopologyException("Unable to link last incoming dirEdge.");
                }
                incoming.Next = firstOut;
            }
        }         // public void LinkResultDirectedEdges()