/// <summary> /// A trivial intersection is an apparent self-intersection which in fact /// is simply the point shared by adjacent line segments. /// Note that closed edges require a special check for the point shared by the beginning /// and end segments. /// </summary> 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.Closed) { int maxSegIndex = e0.Count - 1; if ((segIndex0 == 0 && segIndex1 == maxSegIndex) || (segIndex1 == 0 && segIndex0 == maxSegIndex)) { return(true); } } } } return(false); }
private SegmentString FindMatching(OrientedCoordinateArray oca, SegmentString segString) { SegmentString matchSS = (SegmentString)ocaMap[oca]; return(matchSS); }
/// <summary> This method is called by clients /// of the <see cref="ISegmentIntersector"/> class to process /// intersections for two segments of the {@link SegmentStrings} being intersected. /// Note that some clients (such as {@link 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> 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, 0); e1.AddIntersections(li, segIndex1, 1); } } }
public object Execute(object obj) { SegmentString ss = (SegmentString)obj; return(new SegmentString(m_objNoder.Scale(ss.Coordinates), ss.Data)); }
public override void Overlap(MonotoneChain mc1, int start1, MonotoneChain mc2, int start2) { SegmentString ss1 = (SegmentString)mc1.Context; SegmentString ss2 = (SegmentString)mc2.Context; si.ProcessIntersections(ss1, start1, ss2, start2); }
public object Execute(object obj) { SegmentString ss = (SegmentString)obj; m_objNoder.Rescale(ss.Coordinates); return(null); }
/// <summary> Checks if a segment string contains a segment pattern a-b-a (which implies a self-intersection)</summary> private void CheckCollapses() { for (IEnumerator i = segStrings.GetEnumerator(); i.MoveNext();) { SegmentString ss = (SegmentString)i.Current; CheckCollapses(ss); } }
public static void GetNodedSubstrings(IList segStrings, IList resultEdgelist) { for (IEnumerator i = segStrings.GetEnumerator(); i.MoveNext();) { SegmentString ss = (SegmentString)i.Current; ss.NodeList.AddSplitEdges(resultEdgelist); } }
public SegmentNode(SegmentString segString, Coordinate coord, int segmentIndex, int segmentOctant) { this.segString = segString; this.coord = new Coordinate(coord); this.segmentIndex = segmentIndex; this.segmentOctant = segmentOctant; isInterior = !coord.Equals( segString.GetCoordinate(segmentIndex)); }
/// <summary> /// Checks for intersections between an endpoint of a segment string /// and an interior vertex of another segment string /// </summary> private void CheckEndPtVertexIntersections() { for (IEnumerator i = segStrings.GetEnumerator(); i.MoveNext();) { SegmentString ss = (SegmentString)i.Current; ICoordinateList pts = ss.Coordinates; CheckEndPtVertexIntersections(pts[0], segStrings); CheckEndPtVertexIntersections(pts[pts.Count - 1], segStrings); } }
private void CheckCollapses(SegmentString ss) { ICoordinateList pts = ss.Coordinates; int nCount = pts.Count; for (int i = 0; i < nCount - 2; i++) { CheckCollapse(pts[i], pts[i + 1], pts[i + 2]); } }
private void Add(SegmentString segStr) { IList segChains = MonotoneChainBuilder.GetChains( segStr.Coordinates, segStr); for (IEnumerator i = segChains.GetEnumerator(); i.MoveNext();) { MonotoneChain mc = (MonotoneChain)i.Current; mc.Id = idCounter++; index.Insert(mc.Envelope, mc); monoChains.Add(mc); } }
private void ComputeIntersects(SegmentString e0, SegmentString e1) { ICoordinateList pts0 = e0.Coordinates; ICoordinateList pts1 = e1.Coordinates; for (int i0 = 0; i0 < pts0.Count - 1; i0++) { for (int i1 = 0; i1 < pts1.Count - 1; i1++) { segInt.ProcessIntersections(e0, i0, e1, i1); } } }
private void CheckInteriorIntersections(SegmentString ss0, SegmentString ss1) { ICoordinateList pts0 = ss0.Coordinates; ICoordinateList 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); } } }
private void CheckInteriorIntersections() { for (IEnumerator i = segStrings.GetEnumerator(); i.MoveNext();) { SegmentString ss0 = (SegmentString)i.Current; for (IEnumerator j = segStrings.GetEnumerator(); j.MoveNext();) { SegmentString ss1 = (SegmentString)j.Current; CheckInteriorIntersections(ss0, ss1); } } }
public override void ComputeNodes(IList inputSegStrings) { this.nodedSegStrings = inputSegStrings; for (IEnumerator i0 = inputSegStrings.GetEnumerator(); i0.MoveNext();) { SegmentString edge0 = (SegmentString)i0.Current; for (IEnumerator i1 = inputSegStrings.GetEnumerator(); i1.MoveNext();) { SegmentString edge1 = (SegmentString)i1.Current; ComputeIntersects(edge0, edge1); } } }
/// <summary> /// This method is called by clients of the <see cref="ISegmentIntersector"/> class to process /// intersections for two segments of the {@link SegmentStrings} being intersected. /// Note that some clients (such as {@link 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> public void ProcessIntersections(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) { //intersectionFound = true; numIntersections++; if (li.IsInteriorIntersection()) { numInteriorIntersections++; this.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)) { this.hasIntersection = true; e0.AddIntersections(li, segIndex0, 0); e1.AddIntersections(li, segIndex1, 1); if (li.Proper) { numProperIntersections++; this.hasProper = true; this.hasProperInterior = true; } } } }
private void CheckEndPtVertexIntersections(Coordinate testPt, IList segStrings) { for (IEnumerator i = segStrings.GetEnumerator(); i.MoveNext();) { SegmentString ss = (SegmentString)i.Current; ICoordinateList pts = ss.Coordinates; int nCount = pts.Count; for (int j = 1; j < nCount - 1; j++) { if (pts[j].Equals(testPt)) { throw new GeometryException("Found endpt/interior pt intersection at index " + j + " :pt " + testPt); } } } }
/// <summary> Dissolve the given <see cref="SegmentString"/>. /// /// </summary> /// <param name="segString">the string to dissolve /// </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 = Equals(existing.Coordinates, segString.Coordinates); merger.Merge(existing, segString, isSameOrientation); } } }
/// <summary> /// Creates new edges for all the edges that the intersections in /// this list split the parent edge into. /// Adds the edges to the input list (this is so a single list /// can be used to accumulate all split edges for a Geometry). /// </summary> public void AddSplitEdges(IList edgeList) { // ensure that the list has entries for the first and last point of the edge AddEndpoints(); AddCollapsedNodes(); IEnumerator it = Iterator(); // there should always be at least two entries in the list, // since t he endpoints are nodes it.MoveNext(); //PAUL SegmentNode eiPrev = (SegmentNode)it.Current; while (it.MoveNext()) { SegmentNode ei = (SegmentNode)it.Current; SegmentString newEdge = CreateSplitEdge(eiPrev, ei); edgeList.Add(newEdge); eiPrev = ei; } }
/// <summary> /// Checks the correctness of the set of split edges corresponding /// to this edge. /// </summary> /// <param name="splitEdges"> /// The split edges for this edge (in order). /// </param> private void CheckSplitEdgesCorrectness(IList splitEdges) { ICoordinateList edgePts = edge.Coordinates; // check that first and last points of split edges are same //as endpoints of edge SegmentString split0 = (SegmentString)splitEdges[0]; Coordinate pt0 = split0.GetCoordinate(0); if (!pt0.Equals(edgePts[0])) { throw new GeometryException("bad split edge start point at " + pt0); } SegmentString splitn = (SegmentString)splitEdges[splitEdges.Count - 1]; ICoordinateList splitnPts = splitn.Coordinates; Coordinate ptn = splitnPts[splitnPts.Count - 1]; if (!ptn.Equals(edgePts[edgePts.Count - 1])) { throw new GeometryException("bad split edge end point at " + ptn); } }
private void CheckInteriorIntersections(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) { if (li.Proper || HasInteriorIntersection(li, p00, p01) || HasInteriorIntersection(li, p10, p11)) { throw new GeometryException("found non-node based intersection at " + p00 + "-" + p01 + " and " + p10 + "-" + p11); } } }
private SegmentString edge; // the parent edge #endregion #region Constructors and Destructor public SegmentNodeList(SegmentString edge) { this.nodeMap = new SortedList(); this.edge = edge; }
private void Add(OrientedCoordinateArray oca, SegmentString segString) { ocaMap[oca] = segString; }