private int depthDelta = 0; // the change in area depth from the R to Curve side of this edge /// <summary> /// /// </summary> /// <param name="pts"></param> /// <param name="label"></param> public Edge(ICoordinate[] pts, Label label) { eiList = new EdgeIntersectionList(this); this.pts = pts; this.label = label; }
/// <summary> /// Converts a Label to a Line label (that is, one with no side Locations). /// </summary> /// <param name="label">Label to convert.</param> /// <returns>Label as Line label.</returns> public static Label ToLineLabel(Label label) { Label lineLabel = new Label(Locations.Null); for (int i = 0; i < 2; i++) lineLabel.SetLocation(i, label.GetLocation(i)); return lineLabel; }
/// <summary> /// Updates an IM from the label for an edge. /// Handles edges from both L and A geometries. /// </summary> /// <param name="im"></param> /// <param name="label"></param> public static void UpdateIM(Label label, IntersectionMatrix im) { im.SetAtLeastIfValid(label.GetLocation(0, Positions.On), label.GetLocation(1, Positions.On), Dimensions.Curve); if (label.IsArea()) { im.SetAtLeastIfValid(label.GetLocation(0, Positions.Left), label.GetLocation(1, Positions.Left), Dimensions.Surface); im.SetAtLeastIfValid(label.GetLocation(0, Positions.Right), label.GetLocation(1, Positions.Right), Dimensions.Surface); } }
/// <summary> /// Compute the change in depth as an edge is crossed from R to L. /// </summary> /// <param name="label"></param> private static int DepthDelta(Label label) { Locations lLoc = label.GetLocation(0, Positions.Left); Locations rLoc = label.GetLocation(0, Positions.Right); if (lLoc == Locations.Interior && rLoc == Locations.Exterior) return 1; else if (lLoc == Locations.Exterior && rLoc == Locations.Interior) return -1; return 0; }
/// <summary> /// This computes the overall edge label for the set of /// edges in this EdgeStubBundle. It essentially merges /// the ON and side labels for each edge. /// These labels must be compatible /// </summary> public override void ComputeLabel() { // create the label. If any of the edges belong to areas, // the label must be an area label bool isArea = false; for (IEnumerator it = GetEnumerator(); it.MoveNext(); ) { EdgeEnd e = (EdgeEnd) it.Current; if (e.Label.IsArea()) isArea = true; } if (isArea) label = new Label(Locations.Null, Locations.Null, Locations.Null); else label = new Label(Locations.Null); // compute the On label, and the side labels if present for (int i = 0; i < 2; i++) { ComputeLabelOn(i); if (isArea) ComputeLabelSides(i); } }
/// <summary> /// Compute the labelling for all dirEdges in this star, as well /// as the overall labelling. /// </summary> /// <param name="geom"></param> public override void ComputeLabelling(GeometryGraph[] geom) { base.ComputeLabelling(geom); // determine the overall labelling for this DirectedEdgeStar // (i.e. for the node it is based at) label = new Label(Locations.Null); IEnumerator it = GetEnumerator(); while(it.MoveNext()) { EdgeEnd ee = (EdgeEnd)it.Current; Edge e = ee.Edge; Label eLabel = e.Label; for (int i = 0; i < 2; i++) { Locations eLoc = eLabel.GetLocation(i); if (eLoc == Locations.Interior || eLoc == Locations.Boundary) label.SetLocation(i, Locations.Interior); } } }
/// <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> /// 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); } }
/// <summary> /// /// </summary> /// <param name="lbl"></param> /// <param name="side"></param> /// <returns></returns> public bool IsEqualOnSide(Label lbl, int side) { return this.elt[0].IsEqualOnSide(lbl.elt[0], side) && this.elt[1].IsEqualOnSide(lbl.elt[1], side); }
/// <summary> /// Merge this label with another one. /// Merging updates any null attributes of this label with the attributes from lbl. /// </summary> /// <param name="lbl"></param> public void Merge(Label lbl) { for (int i = 0; i < 2; i++) { if (elt[i] == null && lbl.elt[i] != null) elt[i] = new TopologyLocation(lbl.elt[i]); else elt[i].Merge(lbl.elt[i]); } }
/// <summary> /// Construct a Label with the same values as the argument Label. /// </summary> /// <param name="lbl"></param> public Label(Label lbl) { elt[0] = new TopologyLocation(lbl.elt[0]); elt[1] = new TopologyLocation(lbl.elt[1]); }
/// <summary> /// /// </summary> /// <param name="label"></param> /// <param name="opCode"></param> /// <returns></returns> public static bool IsResultOfOp(Label label, SpatialFunctions opCode) { Locations loc0 = label.GetLocation(0); Locations loc1 = label.GetLocation(1); return IsResultOfOp(loc0, loc1, opCode); }
/// <summary> /// /// </summary> /// <param name="edge"></param> /// <param name="p0"></param> /// <param name="p1"></param> /// <param name="label"></param> public EdgeEnd(Edge edge, ICoordinate p0, ICoordinate p1, Label label) : this(edge) { Init(p0, p1); this.label = label; }
/// <summary> /// /// </summary> /// <param name="coord"></param> /// <param name="edges"></param> public Node(ICoordinate coord, EdgeEndStar edges) { this.coord = coord; this.edges = edges; label = new Label(0, Locations.Null); }
/// <summary> /// /// </summary> /// <param name="label"></param> public GraphComponent(Label label) { this.label = label; }
/// <summary> /// The location for a given eltIndex for a node will be one /// of { Null, Interior, Boundary }. /// A node may be on both the boundary and the interior of a point; /// in this case, the rule is that the node is considered to be in the boundary. /// The merged location is the maximum of the two input values. /// </summary> /// <param name="label2"></param> /// <param name="eltIndex"></param> public Locations ComputeMergedLocation(Label label2, int eltIndex) { Locations loc = Locations.Null; loc = label.GetLocation(eltIndex); if (!label2.IsNull(eltIndex)) { Locations nLoc = label2.GetLocation(eltIndex); if (loc != Locations.Boundary) loc = nLoc; } return loc; }
/// <summary> /// /// </summary> /// <param name="argIndex"></param> /// <param name="onLocation"></param> public void SetLabel(int argIndex, Locations onLocation) { if (label == null) label = new Label(argIndex, onLocation); else label.SetLocation(argIndex, onLocation); }
/// <summary> /// To merge labels for two nodes, /// the merged location for each LabelElement is computed. /// The location for the corresponding node LabelElement is set to the result, /// as long as the location is non-null. /// </summary> /// <param name="label2"></param> public void MergeLabel(Label label2) { for (int i = 0; i < 2; i++) { Locations loc = ComputeMergedLocation(label2, i); Locations thisLoc = label.GetLocation(i); if (thisLoc == Locations.Null) label.SetLocation(i, loc); } }
/// <summary> /// Merge the RHS label from a DirectedEdge into the label for this EdgeRing. /// The DirectedEdge label may be null. This is acceptable - it results /// from a node which is NOT an intersection node between the Geometries /// (e.g. the end node of a LinearRing). In this case the DirectedEdge label /// does not contribute any information to the overall labelling, and is simply skipped. /// </summary> /// <param name="deLabel"></param> /// <param name="geomIndex"></param> protected void MergeLabel(Label deLabel, int geomIndex) { Locations loc = deLabel.GetLocation(geomIndex, Positions.Right); // no information to be had from this label if (loc == Locations.Null) return; // if there is no current RHS value, set it if (label.GetLocation(geomIndex) == Locations.Null) { label.SetLocation(geomIndex, loc); return; } }
/// <summary> /// /// </summary> /// <param name="deLabel"></param> protected void MergeLabel(Label deLabel) { MergeLabel(deLabel, 0); MergeLabel(deLabel, 1); }
/// <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> /// Update incomplete dirEdge labels from the labelling for the node. /// </summary> /// <param name="nodeLabel"></param> public void UpdateLabelling(Label nodeLabel) { for (IEnumerator it = GetEnumerator(); it.MoveNext(); ) { DirectedEdge de = (DirectedEdge)it.Current; Label label = de.Label; label.SetAllLocationsIfNull(0, nodeLabel.GetLocation(0)); label.SetAllLocationsIfNull(1, nodeLabel.GetLocation(1)); } }
/// <summary> /// /// </summary> /// <param name="lbl"></param> public void Add(Label lbl) { for (int i = 0; i < 2; i++) { for (int j = 1; j < 3; j++) { Locations loc = lbl.GetLocation(i, (Positions)j); if (loc == Locations.Exterior || loc == Locations.Interior) { // initialize depth if it is null, otherwise add this location value if (IsNull(i, (Positions)j)) depth[i,j] = DepthAtLocation(loc); else depth[i,j] += DepthAtLocation(loc); } } } }
/// <summary> /// Compute the label in the appropriate orientation for this DirEdge. /// </summary> private void ComputeDirectedLabel() { label = new Label(edge.Label); if (!isForward) label.Flip(); }