/// <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<EdgeEnd> l) { EdgeIntersectionList eiList = edge.EdgeIntersectionList; // ensure that the list has entries for the first and last point of the edge eiList.AddEndpoints(); IEnumerator<EdgeIntersection> it = eiList.GetEnumerator(); EdgeIntersection eiPrev; EdgeIntersection eiCurr = null; // no intersections, so there is nothing to do if (! it.MoveNext()) return; EdgeIntersection eiNext = it.Current; do { eiPrev = eiCurr; eiCurr = eiNext; eiNext = null; if (it.MoveNext()) eiNext = it.Current; if (eiCurr != null) { CreateEdgeEndForPrev(edge, l, eiCurr, eiPrev); CreateEdgeEndForNext(edge, l, eiCurr, eiNext); } } while (eiCurr != null); }
/// <summary> /// Insert an edge unless it is already in the list. /// </summary> /// <param name="e"></param> public void Add(Edge e) { _edges.Add(e); var oca = new OrientedCoordinateArray(e.Coordinates); _ocaMap.Add(oca, e); //_index.Insert(e.Envelope, 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<EdgeEnd> 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); }
/// <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<EdgeEnd> 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); }
/// <summary> /// /// </summary> /// <param name="edge"></param> /// <param name="isForward"></param> /// <param name="isFirstEdge"></param> protected void AddPoints(Edge edge, bool isForward, bool isFirstEdge) { Coordinate[] 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 Location loc = _ptLocator.Locate(e.Coordinate, target); e.Label.SetAllLocations(targetIndex, loc); } else e.Label.SetAllLocations(targetIndex, Location.Exterior); }
/// <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) { Location loc = _ptLocator.Locate(e.Coordinate, _op.GetArgGeometry(targetIndex)); e.Label.SetLocation(targetIndex, loc); }
private readonly Edge edge; // the parent edge /// <summary> /// /// </summary> /// <param name="edge"></param> public EdgeIntersectionList(Edge edge) { this.edge = edge; }
/// <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) { foreach (EdgeEnd ee in edgeEndList ) if (ee.Edge == e) return ee; return null; }
/// <summary> /// /// </summary> /// <param name="e"></param> protected void InsertEdge(Edge e) { _edges.Add(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> /// 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) { var oca = new OrientedCoordinateArray(e.Coordinates); // will return null if no edge matches Edge matchEdge; _ocaMap.TryGetValue(oca, out matchEdge); return matchEdge; }
private void ComputeNodedEdges(IList<ISegmentString> bufferSegStrList, IPrecisionModel precisionModel) { var noder = GetNoder(precisionModel); noder.ComputeNodes(bufferSegStrList); var nodedSegStrings = noder.GetNodedSubstrings(); // DEBUGGING ONLY //BufferDebug.saveEdges(nodedEdges, "run" + BufferDebug.runCount + "_nodedEdges"); foreach (var segStr in nodedSegStrings) { /** * Discard edges which have zero length, * since they carry no information and cause problems with topology building */ var pts = segStr.Coordinates; if (pts.Length == 2 && pts[0].Equals2D(pts[1])) continue; var oldLabel = (Label)segStr.Context; var edge = new Edge(segStr.Coordinates, new Label(oldLabel)); InsertUniqueEdge(edge); } //saveEdges(edgeList.getEdges(), "run" + runCount + "_collapsedEdges"); }
/// <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> protected void InsertUniqueEdge(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); } }