示例#1
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="outstream"></param>
 public virtual void Write(StreamWriter outstream)
 {
     for (IEnumerator it = GetEnumerator(); it.MoveNext();)
     {
         EdgeEnd e = (EdgeEnd)it.Current;
         e.Write(outstream);
     }
 }
示例#2
0
 /// <summary>
 ///
 /// </summary>
 private void ComputeEdgeEndLabels()
 {
     // Compute edge label for each EdgeEnd
     for (IEnumerator it = GetEnumerator(); it.MoveNext();)
     {
         EdgeEnd ee = (EdgeEnd)it.Current;
         ee.ComputeLabel();
     }
 }
示例#3
0
 /// <summary>
 /// Insert an EdgeEnd into the map, and clear the edgeList cache,
 /// since the list of edges has now changed.
 /// </summary>
 /// <param name="e"></param>
 /// <param name="obj"></param>
 protected void InsertEdgeEnd(EdgeEnd e, object obj)
 {
     // Diego Guidi says: i have inserted this line because if i try to add an object already present
     // in the list, a System.ArgumentException was thrown.
     if (_edgeMap.Contains(e))
     {
         return;
     }
     _edgeMap.Add(e, obj);
     _edgeList = null;    // edge list has changed - clear the cache
 }
 /// <summary>
 /// Insert a EdgeEnd in order in the list.
 /// If there is an existing EdgeStubBundle which is parallel, the EdgeEnd is
 /// added to the bundle.  Otherwise, a new EdgeEndBundle is created
 /// to contain the EdgeEnd.
 /// </summary>
 /// <param name="e"></param>
 public override void Insert(EdgeEnd e)
 {
     EdgeEndBundle eb = (EdgeEndBundle)EdgeMap[e];
     if (eb == null)
     {
         eb = new EdgeEndBundle(e);
         InsertEdgeEnd(e, eb);
     }
     else
         eb.Insert(e);
 }
示例#5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ee"></param>
        /// <returns></returns>
        public virtual EdgeEnd GetNextCw(EdgeEnd ee)
        {
            InitializeEdges();
            int i       = _edgeList.IndexOf(ee);
            int iNextCw = i - 1;

            if (i == 0)
            {
                iNextCw = _edgeList.Count - 1;
            }
            return((EdgeEnd)_edgeList[iNextCw]);
        }
示例#6
0
 /// <summary>
 /// Returns the EdgeEnd which has edge e as its base edge
 /// (MD 18 Feb 2002 - this should return a pair of edges).
 /// </summary>
 /// <param name="e"></param>
 /// <returns> The edge, if found <c>null</c> if the edge was not found.</returns>
 public virtual EdgeEnd FindEdgeEnd(Edge e)
 {
     for (IEnumerator i = EdgeEnds.GetEnumerator(); i.MoveNext();)
     {
         EdgeEnd ee = (EdgeEnd)i.Current;
         if (ee.Edge == e)
         {
             return(ee);
         }
     }
     return(null);
 }
示例#7
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="eSearch"></param>
 /// <returns></returns>
 public virtual int FindIndex(EdgeEnd eSearch)
 {
     GetEnumerator();   // force edgelist to be computed
     for (int i = 0; i < _edgeList.Count; i++)
     {
         EdgeEnd e = (EdgeEnd)_edgeList[i];
         if (e == eSearch)
         {
             return(i);
         }
     }
     return(-1);
 }
示例#8
0
 /// <summary>
 /// Implements the total order relation:
 /// a has a greater angle with the positive x-axis than b.
 /// Using the obvious algorithm of simply computing the angle is not robust,
 /// since the angle calculation is obviously susceptible to roundoff.
 /// A robust algorithm is:
 /// - first compare the quadrant.  If the quadrants
 /// are different, it it trivial to determine which vector is "greater".
 /// - if the vectors lie in the same quadrant, the computeOrientation function
 /// can be used to decide the relative orientation of the vectors.
 /// </summary>
 /// <param name="e"></param>
 public virtual int CompareDirection(EdgeEnd e)
 {
     if (_dx == e._dx && _dy == e._dy)
     {
         return(0);
     }
     // if the rays are in different quadrants, determining the ordering is trivial
     if (_quadrant > e._quadrant)
     {
         return(1);
     }
     if (_quadrant < e._quadrant)
     {
         return(-1);
     }
     // vectors are in the same quadrant - check relative orientation of direction vectors
     // this is > e if it is CCW of e
     return(CgAlgorithms.ComputeOrientation(e._p0, e._p1, _p1));
 }
示例#9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="geomIndex"></param>
        /// <returns></returns>
        private bool CheckAreaLabelsConsistent(int geomIndex)
        {
            // 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
            IList edges = Edges;

            // if no edges, trivially consistent
            if (edges.Count <= 0)
            {
                return(true);
            }
            // initialize startLoc to location of last Curve side (if any)
            int          lastEdgeIndex = edges.Count - 1;
            Label        startLabel    = ((EdgeEnd)edges[lastEdgeIndex]).Label;
            LocationType startLoc      = startLabel.GetLocation(geomIndex, PositionType.Left);

            Assert.IsTrue(startLoc != LocationType.Null, "Found unlabelled area edge");

            LocationType currLoc = startLoc;

            for (IEnumerator it = GetEnumerator(); it.MoveNext();)
            {
                EdgeEnd e     = (EdgeEnd)it.Current;
                Label   label = e.Label;
                // we assume that we are only checking a area
                Assert.IsTrue(label.IsArea(geomIndex), "Found non-area edge");
                LocationType leftLoc  = label.GetLocation(geomIndex, PositionType.Left);
                LocationType rightLoc = label.GetLocation(geomIndex, PositionType.Right);
                // check that edge is really a boundary between inside and outside!
                if (leftLoc == rightLoc)
                {
                    return(false);
                }
                // check side location conflict
                if (rightLoc != currLoc)
                {
                    return(false);
                }
                currLoc = leftLoc;
            }
            return(true);
        }
示例#10
0
        /// <summary>
        /// Compute the labelling for all dirEdges in this star, as well
        /// as the overall labelling.
        /// </summary>
        /// <param name="geom"></param>
        public override void ComputeLabelling(GeometryGraph[] geom)
        {
            base.ComputeLabelling(geom);

            // determine the overall labelling for this DirectedEdgeStar
            // (i.e. for the node it is based at)
            _label = new Label(LocationType.Null);
            IEnumerator it = GetEnumerator();

            while (it.MoveNext())
            {
                EdgeEnd ee     = (EdgeEnd)it.Current;
                Edge    e      = ee.Edge;
                Label   eLabel = e.Label;
                for (int i = 0; i < 2; i++)
                {
                    LocationType eLoc = eLabel.GetLocation(i);
                    if (eLoc == LocationType.Interior || eLoc == LocationType.Boundary)
                    {
                        _label.SetLocation(i, LocationType.Interior);
                    }
                }
            }
        }
示例#11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public virtual int CompareTo(object obj)
        {
            EdgeEnd e = (EdgeEnd)obj;

            return(CompareDirection(e));
        }
示例#12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="geom"></param>
        public virtual void ComputeLabelling(GeometryGraph[] geom)
        {
            ComputeEdgeEndLabels();
            // Propagate side labels  around the edges in the star
            // for each parent Geometry
            PropagateSideLabels(0);
            PropagateSideLabels(1);

            /*
             * If there are edges that still have null labels for a point
             * this must be because there are no area edges for that point incident on this node.
             * In this case, to label the edge for that point we must test whether the
             * edge is in the interior of the point.
             * To do this it suffices to determine whether the node for the edge is in the interior of an area.
             * If so, the edge has location Interior for the point.
             * In all other cases (e.g. the node is on a line, on a point, or not on the point at all) the edge
             * has the location Exterior for the point.
             *
             * Notice that the edge cannot be on the Boundary of the point, since then
             * there would have been a parallel edge from the Geometry at this node also labelled Boundary
             * and this edge would have been labelled in the previous step.
             *
             * This code causes a problem when dimensional collapses are present, since it may try and
             * determine the location of a node where a dimensional collapse has occurred.
             * The point should be considered to be on the Exterior
             * of the polygon, but locate() will return Interior, since it is passed
             * the original Geometry, not the collapsed version.
             *
             * If there are incident edges which are Line edges labelled Boundary,
             * then they must be edges resulting from dimensional collapses.
             * In this case the other edges can be labelled Exterior for this Geometry.
             *
             * MD 8/11/01 - NOT True!  The collapsed edges may in fact be in the interior of the Geometry,
             * which means the other edges should be labelled Interior for this Geometry.
             * Not sure how solve this...  Possibly labelling needs to be split into several phases:
             * area label propagation, symLabel merging, then finally null label resolution.
             */
            bool[] hasDimensionalCollapseEdge = { false, false };
            for (IEnumerator it = GetEnumerator(); it.MoveNext();)
            {
                EdgeEnd e     = (EdgeEnd)it.Current;
                Label   label = e.Label;
                for (int geomi = 0; geomi < 2; geomi++)
                {
                    if (label.IsLine(geomi) && label.GetLocation(geomi) == LocationType.Boundary)
                    {
                        hasDimensionalCollapseEdge[geomi] = true;
                    }
                }
            }
            for (IEnumerator it = GetEnumerator(); it.MoveNext();)
            {
                EdgeEnd e     = (EdgeEnd)it.Current;
                Label   label = e.Label;
                for (int geomi = 0; geomi < 2; geomi++)
                {
                    if (label.IsAnyNull(geomi))
                    {
                        LocationType loc;
                        if (hasDimensionalCollapseEdge[geomi])
                        {
                            loc = LocationType.Exterior;
                        }
                        else
                        {
                            Coordinate p = e.Coordinate;
                            loc = GetLocation(geomi, p, geom);
                        }
                        label.SetAllLocationsIfNull(geomi, loc);
                    }
                }
            }
        }
示例#13
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ee"></param>
 /// <returns></returns>
 public virtual EdgeEnd GetNextCw(EdgeEnd ee)
 {
     InitializeEdges();
     int i = _edgeList.IndexOf(ee);
     int iNextCw = i - 1;
     if (i == 0)
         iNextCw = _edgeList.Count - 1;
     return (EdgeEnd)_edgeList[iNextCw];
 }
示例#14
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="eSearch"></param>
 /// <returns></returns>
 public virtual int FindIndex(EdgeEnd eSearch)
 {
     GetEnumerator();   // force edgelist to be computed
     for (int i = 0; i < _edgeList.Count; i++)
     {
         EdgeEnd e = (EdgeEnd)_edgeList[i];
         if (e == eSearch)
             return i;
     }
     return -1;
 }
示例#15
0
 /// <summary>
 /// Insert a EdgeEnd into this EdgeEndStar.
 /// </summary>
 /// <param name="e"></param>
 public abstract void Insert(EdgeEnd e);
示例#16
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="e"></param>
 public EdgeEndBundle(EdgeEnd e)
     : base(e.Edge, e.Coordinate, e.DirectedCoordinate, new Label(e.Label))
 {
     Insert(e);
 }
示例#17
0
 /// <summary>
 /// Add the edge to the list of edges at this node.
 /// </summary>
 /// <param name="e"></param>
 public virtual void Add(EdgeEnd e)
 {
     // Assert: start pt of e is equal to node point
     _edges.Insert(e);
     e.Node = this;
 }
示例#18
0
 /// <summary>
 /// Add the edge to the list of edges at this node.
 /// </summary>
 /// <param name="e"></param>
 public virtual void Add(EdgeEnd e)
 {
     // Assert: start pt of e is equal to node point
     _edges.Insert(e);
     e.Node = this;
 }
示例#19
0
        /// <summary>
        /// Insert a directed edge in the list.
        /// </summary>
        /// <param name="ee"></param>
        public override void Insert(EdgeEnd ee)
        {
            DirectedEdge de = (DirectedEdge)ee;

            InsertEdgeEnd(de, de);
        }
示例#20
0
 /// <summary>
 /// Adds a new EdgeEnd to the planar graph
 /// </summary>
 /// <param name="e">The EdgeEnd to add</param>
 public virtual void Add(EdgeEnd e)
 {
     _nodes.Add(e);
     _edgeEndList.Add(e);
 }
示例#21
0
 /// <summary>
 /// Adds a new EdgeEnd to the planar graph
 /// </summary>
 /// <param name="e">The EdgeEnd to add</param>
 public virtual void Add(EdgeEnd e)
 {
     _nodes.Add(e);
     _edgeEndList.Add(e);
 }
示例#22
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="de"></param>
        /// <param name="i"></param>
        /// <returns></returns>
        private static PositionType GetRightmostSideOfSegment(EdgeEnd de, int i)
        {
            Edge e = de.Edge;
            IList<Coordinate> coord = e.Coordinates;

            if (i < 0 || i + 1 >= coord.Count)
                return PositionType.Parallel;
            if (coord[i].Y == coord[i + 1].Y)
                return PositionType.Parallel;

            PositionType pos = PositionType.Left;
            if (coord[i].Y < coord[i + 1].Y)
                pos = PositionType.Right;

            return pos;
        }
示例#23
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="e"></param>
 public void Insert(EdgeEnd e)
 {
     // Assert: start point is the same
     // Assert: direction is the same
     _edgeEnds.Add(e);
 }
示例#24
0
        /// <summary>
        /// Create a StubEdge for the edge after the intersection eiCurr.
        /// The next intersection is provided
        /// in case it is the endpoint for the stub edge.
        /// Otherwise, the next point from the parent edge will be the endpoint.
        /// eiCurr will always be an EdgeIntersection, but eiNext may be null.
        /// </summary>
        /// <param name="edge"></param>
        /// <param name="l"></param>
        /// <param name="eiCurr"></param>
        /// <param name="eiNext"></param>
        public virtual void CreateEdgeEndForNext(Edge edge, IList l, EdgeIntersection eiCurr, EdgeIntersection eiNext)
        {
            int iNext = eiCurr.SegmentIndex + 1;
            // if there is no next edge there is nothing to do
            if (iNext >= edge.NumPoints && eiNext == null)
                return;

            Coordinate pNext = edge.GetCoordinate(iNext);
            // if the next intersection is in the same segment as the current, use it as the endpoint
            if (eiNext != null && eiNext.SegmentIndex == eiCurr.SegmentIndex)
                pNext = eiNext.Coordinate;

            EdgeEnd e = new EdgeEnd(edge, eiCurr.Coordinate, pNext, new Label(edge.Label));
            l.Add(e);
        }
示例#25
0
 /// <summary>
 /// Adds a node for the start point of this EdgeEnd
 /// (if one does not already exist in this map).
 /// Adds the EdgeEnd to the (possibly new) node.
 /// </summary>
 /// <param name="e"></param>
 public virtual void Add(EdgeEnd e)
 {
     Coordinate p = e.Coordinate;
     Node n = AddNode(p);
     n.Add(e);
 }
示例#26
0
        /// <summary>
        /// Create a EdgeStub for the edge before the intersection eiCurr.
        /// The previous intersection is provided
        /// in case it is the endpoint for the stub edge.
        /// Otherwise, the previous point from the parent edge will be the endpoint.
        /// eiCurr will always be an EdgeIntersection, but eiPrev may be null.
        /// </summary>
        /// <param name="edge"></param>
        /// <param name="l"></param>
        /// <param name="eiCurr"></param>
        /// <param name="eiPrev"></param>
        public virtual void CreateEdgeEndForPrev(Edge edge, IList l, EdgeIntersection eiCurr, EdgeIntersection eiPrev)
        {
            int iPrev = eiCurr.SegmentIndex;
            if (eiCurr.Distance == 0.0)
            {
                // if at the start of the edge there is no previous edge
                if (iPrev == 0)
                    return;
                iPrev--;
            }
            Coordinate pPrev = edge.GetCoordinate(iPrev);
            // if prev intersection is past the previous vertex, use it instead
            if (eiPrev != null && eiPrev.SegmentIndex >= iPrev)
                pPrev = eiPrev.Coordinate;

            Label label = new Label(edge.Label);
            // since edgeStub is oriented opposite to it's parent edge, have to flip sides for edge label
            label.Flip();
            EdgeEnd e = new EdgeEnd(edge, eiCurr.Coordinate, pPrev, label);
            l.Add(e);
        }
示例#27
0
 /// <summary>
 /// Insert a EdgeEnd into this EdgeEndStar.
 /// </summary>
 /// <param name="e"></param>
 public abstract void Insert(EdgeEnd e);
示例#28
0
 /// <summary>
 /// Insert a directed edge in the list.
 /// </summary>
 /// <param name="ee"></param>
 public override void Insert(EdgeEnd ee)
 {
     DirectedEdge de = (DirectedEdge)ee;
     InsertEdgeEnd(de, de);
 }
示例#29
0
 /// <summary>
 /// Insert an EdgeEnd into the map, and clear the edgeList cache,
 /// since the list of edges has now changed.
 /// </summary>
 /// <param name="e"></param>
 /// <param name="obj"></param>
 protected void InsertEdgeEnd(EdgeEnd e, object obj)
 {
     // Diego Guidi says: i have inserted this line because if i try to add an object already present
     // in the list, a System.ArgumentException was thrown.
     if (_edgeMap.Contains(e))
         return;
     _edgeMap.Add(e, obj);
     _edgeList = null;    // edge list has changed - clear the cache
 }
示例#30
0
 /// <summary>
 /// Implements the total order relation:
 /// a has a greater angle with the positive x-axis than b.
 /// Using the obvious algorithm of simply computing the angle is not robust,
 /// since the angle calculation is obviously susceptible to roundoff.
 /// A robust algorithm is:
 /// - first compare the quadrant.  If the quadrants
 /// are different, it it trivial to determine which vector is "greater".
 /// - if the vectors lie in the same quadrant, the computeOrientation function
 /// can be used to decide the relative orientation of the vectors.
 /// </summary>
 /// <param name="e"></param>
 public virtual int CompareDirection(EdgeEnd e)
 {
     if (_dx == e._dx && _dy == e._dy)
         return 0;
     // if the rays are in different quadrants, determining the ordering is trivial
     if (_quadrant > e._quadrant)
         return 1;
     if (_quadrant < e._quadrant)
         return -1;
     // vectors are in the same quadrant - check relative orientation of direction vectors
     // this is > e if it is CCW of e
     return CgAlgorithms.ComputeOrientation(e._p0, e._p1, _p1);
 }
示例#31
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="geomIndex"></param>
        public virtual void PropagateSideLabels(int geomIndex)
        {
            // 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
            LocationType startLoc = LocationType.Null;

            // initialize loc to location of last Curve side (if any)
            for (IEnumerator it = GetEnumerator(); it.MoveNext();)
            {
                EdgeEnd e     = (EdgeEnd)it.Current;
                Label   label = e.Label;
                if (label.IsArea(geomIndex) && label.GetLocation(geomIndex, PositionType.Left) != LocationType.Null)
                {
                    startLoc = label.GetLocation(geomIndex, PositionType.Left);
                }
            }
            // no labelled sides found, so no labels to propagate
            if (startLoc == LocationType.Null)
            {
                return;
            }

            LocationType currLoc = startLoc;

            for (IEnumerator it = GetEnumerator(); it.MoveNext();)
            {
                EdgeEnd e     = (EdgeEnd)it.Current;
                Label   label = e.Label;
                // set null On values to be in current location
                if (label.GetLocation(geomIndex, PositionType.On) == LocationType.Null)
                {
                    label.SetLocation(geomIndex, PositionType.On, currLoc);
                }
                // set side labels (if any)
                // if (label.IsArea())    //ORIGINAL
                if (label.IsArea(geomIndex))
                {
                    LocationType leftLoc  = label.GetLocation(geomIndex, PositionType.Left);
                    LocationType rightLoc = label.GetLocation(geomIndex, PositionType.Right);
                    // if there is a right location, that is the next location to propagate
                    if (rightLoc != LocationType.Null)
                    {
                        if (rightLoc != currLoc)
                        {
                            throw new TopologyException(TopologyText.SideLocationConflict, e.Coordinate);
                        }
                        if (leftLoc == LocationType.Null)
                        {
                            throw new TopologyException(TopologyText.SingleNullSide, e.Coordinate);
                        }
                        currLoc = leftLoc;
                    }
                    else
                    {
                        /* RHS is null - LHS must be null too.
                         *  This must be an edge from the other point, which has no location
                         *  labelling for this point.  This edge must lie wholly inside or outside
                         *  the other point (which is determined by the current location).
                         *  Assign both sides to be the current location.
                         */
                        Assert.IsTrue(label.GetLocation(geomIndex, PositionType.Left) == LocationType.Null, "found single null side");
                        label.SetLocation(geomIndex, PositionType.Right, currLoc);
                        label.SetLocation(geomIndex, PositionType.Left, currLoc);
                    }
                }
            }
        }