/// <summary> /// /// </summary> /// <returns></returns> public bool MoveNext() { if (currNode == null) { currNode = nextNode; currSegIndex = currNode.SegmentIndex; ReadNextNode(); return(true); } // check for trying to read too far if (nextNode == null) { return(false); } if (nextNode.SegmentIndex == currNode.SegmentIndex) { currNode = nextNode; currSegIndex = currNode.SegmentIndex; ReadNextNode(); return(true); } if (nextNode.SegmentIndex > currNode.SegmentIndex) { } return(false); }
/// <summary> /// Create a new "split edge" with the section of points between /// (and including) the two intersections. /// The label for the new edge is the same as the label for the parent edge. /// </summary> /// <param name="ei0"></param> /// <param name="ei1"></param> /// <returns></returns> SegmentString CreateSplitEdge(SegmentNode ei0, SegmentNode ei1) { int npts = ei1.SegmentIndex - ei0.SegmentIndex + 2; ICoordinate lastSegStartPt = edge.GetCoordinate(ei1.SegmentIndex); // if the last intersection point is not equal to the its segment start pt, add it to the points list as well. // (This check is needed because the distance metric is not totally reliable!) // The check for point equality is 2D only - Z values are ignored bool useIntPt1 = ei1.IsInterior || !ei1.Coordinate.Equals2D(lastSegStartPt); if (!useIntPt1) { npts--; } ICoordinate[] pts = new ICoordinate[npts]; int ipt = 0; pts[ipt++] = new Coordinate(ei0.Coordinate); for (int i = ei0.SegmentIndex + 1; i <= ei1.SegmentIndex; i++) { pts[ipt++] = edge.GetCoordinate(i); } if (useIntPt1) { pts[ipt] = ei1.Coordinate; } return(new SegmentString(pts, edge.Data)); }
/// <summary> /// /// </summary> /// <param name="outstream"></param> public void Write(StreamWriter outstream) { outstream.Write("Intersections:"); foreach (object obj in this) { SegmentNode ei = (SegmentNode)obj; ei.Write(outstream); } }
/// <summary> /// /// </summary> private void ReadNextNode() { if (nodeIt.MoveNext()) { nextNode = (SegmentNode)nodeIt.Current; } else { nextNode = null; } }
/// <summary> /// Adds an intersection into the list, if it isn't already there. /// The input segmentIndex and dist are expected to be normalized. /// </summary> /// <param name="intPt"></param> /// <param name="segmentIndex"></param> /// <returns>The SegmentIntersection found or added.</returns> public SegmentNode Add(ICoordinate intPt, int segmentIndex) { SegmentNode eiNew = new SegmentNode(edge, intPt, segmentIndex, edge.GetSegmentOctant(segmentIndex)); SegmentNode ei = (SegmentNode) nodeMap[eiNew]; if(ei != null) { // debugging sanity check Assert.IsTrue(ei.Coordinate.Equals2D(intPt), "Found equal nodes with different coordinates"); return ei; } // node does not exist, so create it nodeMap.Add(eiNew, eiNew); return eiNew; }
/// <summary> /// Adds an intersection into the list, if it isn't already there. /// The input segmentIndex and dist are expected to be normalized. /// </summary> /// <param name="intPt"></param> /// <param name="segmentIndex"></param> /// <returns>The SegmentIntersection found or added.</returns> public SegmentNode Add(ICoordinate intPt, int segmentIndex) { SegmentNode eiNew = new SegmentNode(edge, intPt, segmentIndex, edge.GetSegmentOctant(segmentIndex)); SegmentNode ei = (SegmentNode)nodeMap[eiNew]; if (ei != null) { // debugging sanity check Assert.IsTrue(ei.Coordinate.Equals2D(intPt), "Found equal nodes with different coordinates"); return(ei); } // node does not exist, so create it nodeMap.Add(eiNew, eiNew); return(eiNew); }
/// <summary> /// </summary> /// <param name="obj"></param> /// <returns> /// -1 this SegmentNode is located before the argument location, or /// 0 this SegmentNode is at the argument location, or /// 1 this SegmentNode is located after the argument location. /// </returns> public int CompareTo(object obj) { SegmentNode other = (SegmentNode)obj; if (SegmentIndex < other.SegmentIndex) { return(-1); } if (SegmentIndex > other.SegmentIndex) { return(1); } if (Coordinate.Equals2D(other.Coordinate)) { return(0); } return(SegmentPointComparator.Compare(segmentOctant, Coordinate, other.Coordinate)); }
/// <summary> /// Creates new edges for all the edges that the intersections in this /// list split the parent edge into. /// Adds the edges to the provided argument list /// (this is so a single list can be used to accumulate all split edges /// for a set of <see cref="SegmentString" />s). /// </summary> /// <param name="edgeList"></param> public void AddSplitEdges(IList edgeList) { // ensure that the list has entries for the first and last point of the edge AddEndPoints(); AddCollapsedNodes(); IEnumerator ie = GetEnumerator(); ie.MoveNext(); // there should always be at least two entries in the list, since the endpoints are nodes SegmentNode eiPrev = (SegmentNode)ie.Current; while (ie.MoveNext()) { SegmentNode ei = (SegmentNode)ie.Current; SegmentString newEdge = CreateSplitEdge(eiPrev, ei); edgeList.Add(newEdge); eiPrev = ei; } }
/// <summary> /// /// </summary> /// <param name="ei0"></param> /// <param name="ei1"></param> /// <param name="collapsedVertexIndex"></param> /// <returns></returns> private bool FindCollapseIndex(SegmentNode ei0, SegmentNode ei1, int[] collapsedVertexIndex) { // only looking for equal nodes if (!ei0.Coordinate.Equals2D(ei1.Coordinate)) { return(false); } int numVerticesBetween = ei1.SegmentIndex - ei0.SegmentIndex; if (!ei1.IsInterior) { numVerticesBetween--; } // if there is a single vertex between the two equal nodes, this is a collapse if (numVerticesBetween == 1) { collapsedVertexIndex[0] = ei0.SegmentIndex + 1; return(true); } return(false); }
/// <summary> /// /// </summary> /// <param name="intPt"></param> /// <param name="segmentIndex"></param> public void AddIntersection(ICoordinate intPt, int segmentIndex) { int normalizedSegmentIndex = segmentIndex; // normalize the intersection point location int nextSegIndex = normalizedSegmentIndex + 1; if (nextSegIndex < pts.Length) { ICoordinate nextPt = pts[nextSegIndex]; // Normalize segment index if intPt falls on vertex // The check for point equality is 2D only - Z values are ignored if (intPt.Equals2D(nextPt)) { normalizedSegmentIndex = nextSegIndex; } } // Add the intersection point to edge intersection list. SegmentNode ei = nodeList.Add(intPt, normalizedSegmentIndex); }
/// <summary> /// Adds nodes for any collapsed edge pairs caused by inserted nodes /// Collapsed edge pairs occur when the same coordinate is inserted as a node /// both before and after an existing edge vertex. /// To provide the correct fully noded semantics, /// the vertex must be added as a node as well. /// </summary> /// <param name="collapsedVertexIndexes"></param> private void FindCollapsesFromInsertedNodes(IList collapsedVertexIndexes) { int[] collapsedVertexIndex = new int[1]; IEnumerator ie = GetEnumerator(); ie.MoveNext(); // there should always be at least two entries in the list, since the endpoints are nodes SegmentNode eiPrev = (SegmentNode)ie.Current; while (ie.MoveNext()) { SegmentNode ei = (SegmentNode)ie.Current; bool isCollapsed = FindCollapseIndex(eiPrev, ei, collapsedVertexIndex); if (isCollapsed) { collapsedVertexIndexes.Add(collapsedVertexIndex[0]); } eiPrev = ei; } }
/// <summary> /// /// </summary> /// <returns></returns> public bool MoveNext() { if (currNode == null) { currNode = nextNode; currSegIndex = currNode.SegmentIndex; ReadNextNode(); return true; } // check for trying to read too far if (nextNode == null) return false; if (nextNode.SegmentIndex == currNode.SegmentIndex) { currNode = nextNode; currSegIndex = currNode.SegmentIndex; ReadNextNode(); return true; } if (nextNode.SegmentIndex > currNode.SegmentIndex) { } return false; }
/// <summary> /// /// </summary> private void ReadNextNode() { if (nodeIt.MoveNext()) nextNode = (SegmentNode) nodeIt.Current; else nextNode = null; }
/// <summary> /// Create a new "split edge" with the section of points between /// (and including) the two intersections. /// The label for the new edge is the same as the label for the parent edge. /// </summary> /// <param name="ei0"></param> /// <param name="ei1"></param> /// <returns></returns> SegmentString CreateSplitEdge(SegmentNode ei0, SegmentNode ei1) { int npts = ei1.SegmentIndex - ei0.SegmentIndex + 2; ICoordinate lastSegStartPt = edge.GetCoordinate(ei1.SegmentIndex); // if the last intersection point is not equal to the its segment start pt, add it to the points list as well. // (This check is needed because the distance metric is not totally reliable!) // The check for point equality is 2D only - Z values are ignored bool useIntPt1 = ei1.IsInterior || !ei1.Coordinate.Equals2D(lastSegStartPt); if(!useIntPt1) npts--; ICoordinate[] pts = new ICoordinate[npts]; int ipt = 0; pts[ipt++] = new Coordinate(ei0.Coordinate); for (int i = ei0.SegmentIndex + 1; i <= ei1.SegmentIndex; i++) pts[ipt++] = edge.GetCoordinate(i); if (useIntPt1) pts[ipt] = ei1.Coordinate; return new SegmentString(pts, edge.Data); }
/// <summary> /// /// </summary> /// <param name="ei0"></param> /// <param name="ei1"></param> /// <param name="collapsedVertexIndex"></param> /// <returns></returns> private bool FindCollapseIndex(SegmentNode ei0, SegmentNode ei1, int[] collapsedVertexIndex) { // only looking for equal nodes if (!ei0.Coordinate.Equals2D(ei1.Coordinate)) return false; int numVerticesBetween = ei1.SegmentIndex - ei0.SegmentIndex; if (!ei1.IsInterior) numVerticesBetween--; // if there is a single vertex between the two equal nodes, this is a collapse if (numVerticesBetween == 1) { collapsedVertexIndex[0] = ei0.SegmentIndex + 1; return true; } return false; }