/// <summary>
        /// This method is called by clients
        /// of the <see cref="ISegmentIntersector" /> class to process
        /// intersections for two segments of the <see cref="SegmentString" />s being intersected.
        /// Notice that some clients (such as <see cref="MonotoneChain" />s) may optimize away
        /// this call for segment pairs which they have determined do not intersect
        /// (e.g. by an disjoint envelope test).
        /// </summary>
        /// <param name="e0"></param>
        /// <param name="segIndex0"></param>
        /// <param name="e1"></param>
        /// <param name="segIndex1"></param>
        public void ProcessIntersections(SegmentString e0, int segIndex0, SegmentString e1, int segIndex1 )
        {
            // don't bother intersecting a segment with itself
            if (e0 == e1 && segIndex0 == segIndex1) 
                return;

            Coordinate p00 = e0.Coordinates[segIndex0];
            Coordinate p01 = e0.Coordinates[segIndex0 + 1];
            Coordinate p10 = e1.Coordinates[segIndex1];
            Coordinate p11 = e1.Coordinates[segIndex1 + 1];

            _li.ComputeIntersection(p00, p01, p10, p11);            

            if (_li.HasIntersection)
            {
                if (_li.IsInteriorIntersection())
                {
                    for(int intIndex = 0; intIndex < _li.IntersectionNum; intIndex++)
                        _interiorIntersections.Add(_li.GetIntersection(intIndex));
                    
                    e0.AddIntersections(_li, segIndex0);
                    e1.AddIntersections(_li, segIndex1);
                }
            }
        }
Пример #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SegmentNode"/> class.
 /// </summary>
 /// <param name="segString"></param>
 /// <param name="coord"></param>
 /// <param name="segmentIndex"></param>
 /// <param name="segmentOctant"></param>
 public SegmentNode(SegmentString segString, Coordinate coord, int segmentIndex, Octants segmentOctant) 
 {
     this.segString = segString;
     this.Coordinate = new Coordinate(coord);
     this.SegmentIndex = segmentIndex;
     this.segmentOctant = segmentOctant;
     isInterior = !coord.Equals2D(segString.GetCoordinate(segmentIndex));
 }
 /// <summary>
 /// Creates a {SegmentString} for a coordinate list which is a raw offset curve,
 /// and adds it to the list of buffer curves.
 /// The SegmentString is tagged with a Label giving the topology of the curve.
 /// The curve may be oriented in either direction.
 /// If the curve is oriented CW, the locations will be:
 /// Left: Location.Exterior.
 /// Right: Location.Interior.
 /// </summary>
 private void AddCurve(IList<Coordinate> coord, Locations leftLoc, Locations rightLoc)
 {
     // don't add null curves!
     if (coord.Count < 2) return;
     // add the edge for a coordinate list which is a raw offset curve
     SegmentString e = new SegmentString(coord, new Label(0, Locations.Boundary, leftLoc, rightLoc));
     _curveList.Add(e);
 }
        /// <summary>
        /// This method is called by clients
        /// of the <see cref="ISegmentIntersector" /> class to process
        /// intersections for two segments of the <see cref="SegmentString" /> being intersected.
        /// Notice that some clients (such as <see cref="MonotoneChain" />s) may optimize away
        /// this call for segment pairs which they have determined do not intersect
        /// (e.g. by an disjoint envelope test).
        /// </summary>
        /// <param name="e0"></param>
        /// <param name="segIndex0"></param>
        /// <param name="e1"></param>
        /// <param name="segIndex1"></param>
        public void ProcessIntersections(SegmentString e0, int segIndex0, SegmentString e1, int segIndex1)
        {
            if (e0 == e1 && segIndex0 == segIndex1)
                return;

            _numTests++;
            Coordinate p00 = e0.Coordinates[segIndex0];
            Coordinate p01 = e0.Coordinates[segIndex0 + 1];
            Coordinate p10 = e1.Coordinates[segIndex1];
            Coordinate p11 = e1.Coordinates[segIndex1 + 1];

            _li.ComputeIntersection(p00, p01, p10, p11);
            if (!_li.HasIntersection) return;
            _numIntersections++;
            if (_li.IsInteriorIntersection())
            {
                NumInteriorIntersections++;
                _hasInterior = true;                    
            }
            // if the segments are adjacent they have at least one trivial intersection,
            // the shared endpoint.  Don't bother adding it if it is the
            // only intersection.
            if (IsTrivialIntersection(e0, segIndex0, e1, segIndex1)) return;
            _hasIntersection = true;
            e0.AddIntersections(_li, segIndex0);
            e1.AddIntersections(_li, segIndex1);
            if (!_li.IsProper) return;
            _numProperIntersections++;
            _hasProper = true;
            _hasProperInterior = true;
        }
 /// <summary>
 /// A trivial intersection is an apparent self-intersection which in fact
 /// is simply the point shared by adjacent line segments.
 /// Notice that closed edges require a special check for the point shared by the beginning and end segments.
 /// </summary>
 /// <param name="e0"></param>
 /// <param name="segIndex0"></param>
 /// <param name="e1"></param>
 /// <param name="segIndex1"></param>
 /// <returns></returns>
 private bool IsTrivialIntersection(SegmentString e0, int segIndex0, SegmentString e1, int segIndex1)
 {
     if(e0 == e1)
     {
         if(_li.IntersectionNum == 1)
         {
             if(IsAdjacentSegments(segIndex0, segIndex1))
                 return true;
             if (e0.IsClosed)
             {
                 int maxSegIndex = e0.Count - 1;
                 if ( (segIndex0 == 0 && segIndex1 == maxSegIndex) || 
                      (segIndex1 == 0 && segIndex0 == maxSegIndex) )                        
                         return true;                        
             }
         }
     }
     return false;
 }
Пример #6
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ss"></param>
 private static void CheckCollapses(SegmentString ss)
 {
     IList<Coordinate> pts = ss.Coordinates;
     for (int i = 0; i < pts.Count - 2; i++)
         CheckCollapse(pts[i], pts[i + 1], pts[i + 2]);            
 }
Пример #7
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e0"></param>
        /// <param name="segIndex0"></param>
        /// <param name="e1"></param>
        /// <param name="segIndex1"></param>
        private void CheckInteriorIntersections(SegmentString e0, int segIndex0, SegmentString e1, int segIndex1)
        {
            if (e0 == e1 && segIndex0 == segIndex1) 
                return;
            
            Coordinate p00 = e0.Coordinates[segIndex0];
            Coordinate p01 = e0.Coordinates[segIndex0 + 1];
            Coordinate p10 = e1.Coordinates[segIndex1];
            Coordinate p11 = e1.Coordinates[segIndex1 + 1];

            _li.ComputeIntersection(p00, p01, p10, p11);
            if (_li.HasIntersection)  
                if (_li.IsProper || HasInteriorIntersection(_li, p00, p01) || HasInteriorIntersection(_li, p10, p11))
                    throw new Exception("found non-noded intersection at " + p00 + "-" + p01
                                               + " and " + p10 + "-" + p11);                            
        }
Пример #8
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ss0"></param>
 /// <param name="ss1"></param>
 private void CheckInteriorIntersections(SegmentString ss0, SegmentString ss1)
 {
     IList<Coordinate> pts0 = ss0.Coordinates;
     IList<Coordinate> pts1 = ss1.Coordinates;
     for (int i0 = 0; i0 < pts0.Count - 1; i0++)
         for (int i1 = 0; i1 < pts1.Count - 1; i1++)
             CheckInteriorIntersections(ss0, i0, ss1, i1);            
 }
Пример #9
0
        private readonly SegmentString _edge;  // the parent edge

        /// <summary>
        /// Initializes a new instance of the <see cref="SegmentNodeList"/> class.
        /// </summary>
        /// <param name="edge">The edge.</param>
        public SegmentNodeList(SegmentString edge)
        {
            _edge = edge;
        }
Пример #10
0
 NodeVertexIterator(SegmentNodeList nodeList)
 {
     _nodeList = nodeList;
     _edge = nodeList.Edge;
     _nodeIt = nodeList.GetEnumerator();            
 }
Пример #11
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="segStr"></param>
 private void Add(SegmentString segStr)
 {
     IList segChains = MonotoneChainBuilder.GetChains(segStr.Coordinates, segStr);
     foreach(object obj in segChains) 
     {
         MonotoneChain mc = (MonotoneChain)obj;
         mc.Id = idCounter++;
         index.Insert(mc.Envelope, mc);
         monoChains.Add(mc);
     }
 }
Пример #12
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="e0"></param>
 /// <param name="e1"></param>
 private void ComputeIntersects(SegmentString e0, SegmentString e1)
 {
     IList<Coordinate> pts0 = e0.Coordinates;
     IList<Coordinate> pts1 = e1.Coordinates;
     for (int i0 = 0; i0 < pts0.Count - 1; i0++)
         for (int i1 = 0; i1 < pts1.Count - 1; i1++)
             SegmentIntersector.ProcessIntersections(e0, i0, e1, i1);
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="oca"></param>
 /// <param name="segString"></param>
 private void Add(OrientedCoordinateArray oca, SegmentString segString)
 {
     ocaMap.Add(oca, segString);
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="oca"></param>
 /// <param name="segString"></param>
 /// <returns></returns>
 private SegmentString FindMatching(OrientedCoordinateArray oca, SegmentString segString)
 {
     return (SegmentString)ocaMap[oca];            
 }        
 /// <summary>
 /// Dissolve the given <see cref="SegmentString" />.
 /// </summary>
 /// <param name="segString"></param>
 public void Dissolve(SegmentString segString)
 {
     OrientedCoordinateArray oca = new OrientedCoordinateArray(segString.Coordinates);
     SegmentString existing = FindMatching(oca, segString);
     if (existing == null)
         Add(oca, segString);            
     else
     {
         if (merger != null)
         {
             bool isSameOrientation = CoordinateArrays.Equals(existing.Coordinates, segString.Coordinates);
             merger.Merge(existing, segString, isSameOrientation);
         }
     }
 }