/// <summary>
        /// Creates stub edges for all the intersections in this
        /// Edge (if any) and inserts them into the graph.
        /// </summary>
        /// <param name="edge"></param>
        /// <param name="l"></param>
        public virtual void ComputeEdgeEnds(Edge edge, IList l)
        {
            EdgeIntersectionList eiList = edge.EdgeIntersectionList;
            // ensure that the list has entries for the first and last point of the edge
            eiList.AddEndpoints();

            IEnumerator it = eiList.GetEnumerator();
            EdgeIntersection eiCurr = null;
            // no intersections, so there is nothing to do
            if (!it.MoveNext()) return;
            EdgeIntersection eiNext = (EdgeIntersection)it.Current;
            do
            {
                EdgeIntersection eiPrev = eiCurr;
                eiCurr = eiNext;
                eiNext = null;

                if (it.MoveNext())
                    eiNext = (EdgeIntersection)it.Current;

                if (eiCurr != null)
                {
                    CreateEdgeEndForPrev(edge, l, eiCurr, eiPrev);
                    CreateEdgeEndForNext(edge, l, eiCurr, eiNext);
                }
            }
            while (eiCurr != null);
        }
Beispiel #2
0
        private DirectedEdge _sym; // the symmetric edge

        #endregion

        #region Constructors

        /// <summary>
        /// Creates a new instance of a directed edge
        /// </summary>
        /// <param name="inEdge">The edge to use in order to create a directed edge</param>
        /// <param name="inIsForward">A boolean that forces whether or not this edge is counted as forward</param>
        public DirectedEdge(Edge inEdge, bool inIsForward)
            : base(inEdge)
        {
            _isForward = inIsForward;
            if (_isForward)
                base.Init(inEdge.GetCoordinate(0), inEdge.GetCoordinate(1));
            else
            {
                int n = inEdge.NumPoints - 1;
                base.Init(inEdge.GetCoordinate(n), inEdge.GetCoordinate(n - 1));
            }
            ComputeDirectedLabel();
        }
Beispiel #3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="edge"></param>
 /// <param name="isForward"></param>
 /// <param name="isFirstEdge"></param>
 protected virtual void AddPoints(Edge edge, bool isForward, bool isFirstEdge)
 {
     IList<Coordinate> edgePts = edge.Coordinates;
     if (isForward)
     {
         int startIndex = 1;
         if (isFirstEdge)
             startIndex = 0;
         for (int i = startIndex; i < edgePts.Count; i++)
             _pts.Add(edgePts[i]);
     }
     else
     {
         // is backward
         int startIndex = edgePts.Count - 2;
         if (isFirstEdge)
             startIndex = edgePts.Count - 1;
         for (int i = startIndex; i >= 0; i--)
             _pts.Add(edgePts[i]);
     }
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="edge"></param>
 public EdgeIntersectionList(Edge edge)
 {
     _edge = edge;
 }
Beispiel #5
0
 /// <summary>
 /// Adds a new EdgeEnd to the planar graph
 /// </summary>
 /// <param name="e"></param>
 protected virtual void InsertEdge(Edge e)
 {
     _edges.Add(e);
 }
Beispiel #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;
 }
Beispiel #7
0
 /// <summary>
 /// Add an Edge computed externally.  The label on the Edge is assumed
 /// to be correct.
 /// </summary>
 /// <param name="e"></param>
 public virtual void AddEdge(Edge e)
 {
     InsertEdge(e);
     IList<Coordinate> coord = e.Coordinates;
     // insert the endpoint as a node, to mark that it is on the boundary
     InsertPoint(_argIndex, coord[0], LocationType.Boundary);
     InsertPoint(_argIndex, coord[coord.Count - 1], LocationType.Boundary);
 }
Beispiel #8
0
 /// <summary>
 /// Label an isolated node with its relationship to the target point.
 /// </summary>
 /// <param name="e"></param>
 /// <param name="targetIndex"></param>
 private void LabelIsolatedLine(Edge e, int targetIndex)
 {
     LocationType loc = _ptLocator.Locate(e.Coordinate, _op.GetArgGeometry(targetIndex));
     e.Label.SetLocation(targetIndex, loc);
 }
Beispiel #9
0
 /// <summary>
 /// Insert an edge unless it is already in the list.
 /// </summary>
 /// <param name="e"></param>
 public virtual void Add(Edge e)
 {
     _edges.Add(e);
     _index.Insert(e.Envelope, e);
 }
Beispiel #10
0
 /// <summary>
 /// Remove the selected Edge element from the list if present.
 /// </summary>
 /// <param name="e">Edge element to remove from list</param>
 public virtual void Remove(Edge e)
 {
     _edges.Remove(e);
 }
Beispiel #11
0
 /// <summary>
 /// If the edge e is already in the list, return its index.
 /// </summary>
 /// <param name="e"></param>
 /// <returns>
 /// Index, if e is already in the list,
 /// -1 otherwise.
 /// </returns>
 public virtual int FindEdgeIndex(Edge e)
 {
     for (int i = 0; i < _edges.Count; i++)
         if (_edges[i].Equals(e))
             return i;
     return -1;
 }
Beispiel #12
0
 // <FIX> fast lookup for edges
 /// <summary>
 /// If there is an edge equal to e already in the list, return it.
 /// Otherwise return null.
 /// </summary>
 /// <param name="e"></param>
 /// <returns>
 /// equal edge, if there is one already in the list,
 /// null otherwise.
 /// </returns>
 public virtual Edge FindEqualEdge(Edge e)
 {
     ICollection testEdges = _index.Query(e.Envelope);
     for (IEnumerator i = testEdges.GetEnumerator(); i.MoveNext(); )
     {
         Edge testEdge = (Edge)i.Current;
         if (testEdge.Equals(e))
             return testEdge;
     }
     return null;
 }
Beispiel #13
0
        /// <summary>
        /// Inserted edges are checked to see if an identical edge already exists.
        /// If so, the edge is not inserted, but its label is merged
        /// with the existing edge.
        /// </summary>
        /// <param name="e"></param>
        protected void InsertEdge(Edge e)
        {
            //<FIX> MD 8 Oct 03  speed up identical edge lookup
            // fast lookup
            Edge existingEdge = _edgeList.FindEqualEdge(e);

            // If an identical edge already exists, simply update its label
            if (existingEdge != null)
            {
                Label existingLabel = existingEdge.Label;

                Label labelToMerge = e.Label;
                // check if new edge is in reverse direction to existing edge
                // if so, must flip the label before merging it
                if (!existingEdge.IsPointwiseEqual(e))
                {
                    labelToMerge = new Label(e.Label);
                    labelToMerge.Flip();
                }
                existingLabel.Merge(labelToMerge);

                // compute new depth delta of sum of edges
                int mergeDelta = DepthDelta(labelToMerge);
                int existingDelta = existingEdge.DepthDelta;
                int newDelta = existingDelta + mergeDelta;
                existingEdge.DepthDelta = newDelta;
            }
            else
            {   // no matching existing edge was found
                // add this new edge to the list of edges in this graph
                //e.setName(name + edges.size());
                _edgeList.Add(e);
                e.DepthDelta = DepthDelta(e.Label);
            }
        }
Beispiel #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="bufferSegStrList"></param>
        /// <param name="precisionModel"></param>
        private void ComputeNodedEdges(IList bufferSegStrList, PrecisionModel precisionModel)
        {
            INoder noder = GetNoder(precisionModel);
            noder.ComputeNodes(bufferSegStrList);
            IList nodedSegStrings = noder.GetNodedSubstrings();

            foreach (object obj in nodedSegStrings)
            {
                SegmentString segStr = (SegmentString)obj;
                Label oldLabel = (Label)segStr.Data;
                Edge edge = new Edge(segStr.Coordinates, new Label(oldLabel));
                InsertEdge(edge);
            }
        }
Beispiel #15
0
 /// <summary>
 /// The left and right topological location arguments assume that the ring is oriented CW.
 /// If the ring is in the opposite orientation,
 /// the left and right locations must be interchanged.
 /// </summary>
 /// <param name="lr"></param>
 /// <param name="cwLeft"></param>
 /// <param name="cwRight"></param>
 private void AddPolygonRing(IBasicGeometry lr, LocationType cwLeft, LocationType cwRight)
 {
     IList<Coordinate> coord = CoordinateArrays.RemoveRepeatedPoints(lr.Coordinates);
     if (coord.Count < 4)
     {
         _hasTooFewPoints = true;
         _invalidPoint = coord[0];
         return;
     }
     LocationType left = cwLeft;
     LocationType right = cwRight;
     if (CgAlgorithms.IsCounterClockwise(coord))
     {
         left = cwRight;
         right = cwLeft;
     }
     Edge e = new Edge(coord, new Label(_argIndex, LocationType.Boundary, left, right));
     _lineEdgeMap.Add(lr, e);
     InsertEdge(e);
     // insert the endpoint as a node, to mark that it is on the boundary
     InsertPoint(_argIndex, coord[0], LocationType.Boundary);
 }
        /// <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);
        }
Beispiel #17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="line"></param>
        private void AddLineString(IBasicGeometry line)
        {
            IList<Coordinate> coord = CoordinateArrays.RemoveRepeatedPoints(line.Coordinates);

            if (coord.Count < 2)
            {
                _hasTooFewPoints = true;
                _invalidPoint = coord[0];
                return;
            }

            // add the edge for the LineString
            // line edges do not have locations for their left and right sides
            Edge e = new Edge(coord, new Label(_argIndex, LocationType.Interior));
            _lineEdgeMap.Add(line, e);
            InsertEdge(e);

            /*
            * Add the boundary points of the LineString, if any.
            * Even if the LineString is closed, add both points as if they were endpoints.
            * This allows for the case that the node already exists and is a boundary point.
            */
            Assert.IsTrue(coord.Count >= 2, "found LineString with single point");
            InsertBoundaryPoint(_argIndex, coord[0]);
            InsertBoundaryPoint(_argIndex, coord[coord.Count - 1]);
        }
        /// <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);
        }
Beispiel #19
0
        /// <summary>
        /// Insert an edge from one of the noded input graphs.
        /// Checks edges that are inserted to see if an
        /// identical edge already exists.
        /// If so, the edge is not inserted, but its label is merged
        /// with the existing edge.
        /// </summary>
        /// <param name="e"></param>
        protected virtual void InsertUniqueEdge(Edge e)
        {
            int foundIndex = _edgeList.FindEdgeIndex(e);
            // If an identical edge already exists, simply update its label
            if (foundIndex >= 0)
            {
                Edge existingEdge = _edgeList[foundIndex];
                Label existingLabel = existingEdge.Label;

                Label labelToMerge = e.Label;
                // check if new edge is in reverse direction to existing edge
                // if so, must flip the label before merging it
                if (!existingEdge.IsPointwiseEqual(e))
                {
                    labelToMerge = new Label(e.Label);
                    labelToMerge.Flip();
                }
                Depth depth = existingEdge.Depth;
                // if this is the first duplicate found for this edge, initialize the depths
                if (depth.IsNull())
                    depth.Add(existingLabel);
                depth.Add(labelToMerge);
                existingLabel.Merge(labelToMerge);
            }
            else
            {
                // no matching existing edge was found
                // add this new edge to the list of edges in this graph
                _edgeList.Add(e);
            }
        }