/// <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 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 eiPrev = null; EdgeIntersection eiCurr = null; // no intersections, so there is nothing to do if (! it.MoveNext()) return; EdgeIntersection eiNext = (EdgeIntersection) it.Current; do { 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); }
// <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 Edge FindEqualEdge(Edge e) { ICollection testEdges = index.Query(e.Envelope); for (var i = testEdges.GetEnumerator(); i.MoveNext(); ) { var testEdge = (Edge) i.Current; if (testEdge.Equals(e)) return testEdge; } return null; }
/// <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 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--; } ICoordinate 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); }
/// <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 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; ICoordinate 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); }
/// <summary> /// Insert an edge unless it is already in the list. /// </summary> /// <param name="e"></param> public void Add(Edge e) { edges.Add(e); index.Insert(e.Envelope, e); }
/// <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 int FindEdgeIndex(Edge e) { for (var i = 0; i < edges.Count; i++) if ((edges[i]).Equals(e)) return i; return -1; }
/// <summary> /// Remove the selected Edge element from the list if present. /// </summary> /// <param name="e">Edge element to remove from list</param> public void Remove(Edge e) { edges.Remove(e); }
/// <summary> /// /// </summary> /// <param name="bufferSegStrList"></param> /// <param name="precisionModel"></param> private void ComputeNodedEdges(IList bufferSegStrList, IPrecisionModel 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); } }
/// <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); } }
/// <summary> /// /// </summary> /// <param name="e"></param> protected void InsertEdge(Edge e) { edges.Add(e); }
/// <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 EdgeEnd FindEdgeEnd(Edge e) { for (IEnumerator i = EdgeEnds.GetEnumerator(); i.MoveNext(); ) { EdgeEnd ee = (EdgeEnd) i.Current; if (ee.Edge == e) return ee; } return null; }
/// <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) { Locations loc = ptLocator.Locate(e.Coordinate, op.GetArgGeometry(targetIndex)); e.Label.SetLocation(targetIndex, loc); }
/// <summary> /// /// </summary> /// <param name="edge"></param> /// <param name="isForward"></param> /// <param name="isFirstEdge"></param> protected void AddPoints(Edge edge, bool isForward, bool isFirstEdge) { ICoordinate[] edgePts = edge.Coordinates; if (isForward) { int startIndex = 1; if (isFirstEdge) startIndex = 0; for (int i = startIndex; i < edgePts.Length; i++) pts.Add(edgePts[i]); } else { // is backward int startIndex = edgePts.Length - 2; if (isFirstEdge) startIndex = edgePts.Length - 1; for (int i = startIndex; i >= 0; i--) pts.Add(edgePts[i]); } }
/// <summary> /// Label an isolated edge of a graph with its relationship to the target point. /// If the target has dim 2 or 1, the edge can either be in the interior or the exterior. /// If the target has dim 0, the edge must be in the exterior. /// </summary> /// <param name="e"></param> /// <param name="targetIndex"></param> /// <param name="target"></param> private void LabelIsolatedEdge(Edge e, int targetIndex, IGeometry target) { // this won't work for GeometryCollections with both dim 2 and 1 geoms if (target.Dimension > 0) { // since edge is not in boundary, may not need the full generality of PointLocator? // Possibly should use ptInArea locator instead? We probably know here // that the edge does not touch the bdy of the target Geometry Locations loc = ptLocator.Locate(e.Coordinate, target); e.Label.SetAllLocations(targetIndex, loc); } else e.Label.SetAllLocations(targetIndex, Locations.Exterior); }
private Edge edge; // the parent edge /// <summary> /// /// </summary> /// <param name="edge"></param> public EdgeIntersectionList(Edge edge) { this.edge = edge; }
/// <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 void InsertUniqueEdge(Edge e) { int foundIndex = edgeList.FindEdgeIndex(e); // If an identical edge already exists, simply update its label if (foundIndex >= 0) { Edge existingEdge = (Edge) 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); } }