/// <summary> /// Collect all the points from the DirectedEdges of this ring into a contiguous list. /// </summary> /// <param name="start"></param> protected void ComputePoints(DirectedEdge start) { startDe = start; DirectedEdge de = start; bool isFirstEdge = true; do { if (de == null) { throw new TopologyException("found null Directed Edge"); } if (de.EdgeRing == this) { throw new TopologyException("Directed Edge visited twice during ring-building at " + de.Coordinate); } _edges.Add(de); Label label = de.Label; Assert.IsTrue(label.IsArea()); MergeLabel(label); AddPoints(de.Edge, de.IsForward, isFirstEdge); isFirstEdge = false; SetEdgeRing(de, this); de = GetNext(de); }while (de != startDe); }
/// <summary> /// /// </summary> /// <param name="geomIndex"></param> /// <returns></returns> private bool CheckAreaLabelsConsistent(int geomIndex) { // Since edges are stored in CCW order around the node, // As we move around the ring we move from the right to the left side of the edge IList<EdgeEnd> edges = Edges; // if no edges, trivially consistent if (edges.Count <= 0) return true; // initialize startLoc to location of last Curve side (if any) int lastEdgeIndex = edges.Count - 1; Label startLabel = edges[lastEdgeIndex].Label; Location startLoc = startLabel.GetLocation(geomIndex, Positions.Left); Assert.IsTrue(startLoc != Location.Null, "Found unlabelled area edge"); Location currLoc = startLoc; foreach (EdgeEnd e in Edges) { Label label = e.Label; // we assume that we are only checking a area Assert.IsTrue(label.IsArea(geomIndex), "Found non-area edge"); Location leftLoc = label.GetLocation(geomIndex, Positions.Left); Location rightLoc = label.GetLocation(geomIndex, Positions.Right); // check that edge is really a boundary between inside and outside! if (leftLoc == rightLoc) return false; // check side location conflict if (rightLoc != currLoc) return false; currLoc = leftLoc; } return true; }
/// <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, Geometries.Position.On), label.GetLocation(1, Geometries.Position.On), Dimension.Curve); if (label.IsArea()) { im.SetAtLeastIfValid(label.GetLocation(0, Geometries.Position.Left), label.GetLocation(1, Geometries.Position.Left), Dimension.Surface); im.SetAtLeastIfValid(label.GetLocation(0, Geometries.Position.Right), label.GetLocation(1, Geometries.Position.Right), Dimension.Surface); } }
/// <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), Dimension.Curve); if (label.IsArea()) { im.SetAtLeastIfValid(label.GetLocation(0, Positions.Left), label.GetLocation(1, Positions.Left), Dimension.Surface); im.SetAtLeastIfValid(label.GetLocation(0, Positions.Right), label.GetLocation(1, Positions.Right), Dimension.Surface); } }
/// <summary> /// /// </summary> /// <param name="geomIndex"></param> public void PropagateSideLabels(int geomIndex) { // Since edges are stored in CCW order around the node, // As we move around the ring we move from the right to the left side of the edge Location startLoc = Location.Null; // initialize loc to location of last Curve side (if any) foreach (EdgeEnd e in Edges) { Label label = e.Label; if (label.IsArea(geomIndex) && label.GetLocation(geomIndex, Positions.Left) != Location.Null) startLoc = label.GetLocation(geomIndex, Positions.Left); } // no labelled sides found, so no labels to propagate if (startLoc == Location.Null) return; Location currLoc = startLoc; foreach (EdgeEnd e in Edges) { Label label = e.Label; // set null On values to be in current location if (label.GetLocation(geomIndex, Positions.On) == Location.Null) label.SetLocation(geomIndex, Positions.On, currLoc); // set side labels (if any) if (label.IsArea(geomIndex)) { Location leftLoc = label.GetLocation(geomIndex, Positions.Left); Location rightLoc = label.GetLocation(geomIndex, Positions.Right); // if there is a right location, that is the next location to propagate if (rightLoc != Location.Null) { if (rightLoc != currLoc) throw new TopologyException("side location conflict", e.Coordinate); if (leftLoc == Location.Null) Assert.ShouldNeverReachHere("found single null side (at " + e.Coordinate + ")"); currLoc = leftLoc; } else { /* RHS is null - LHS must be null too. * This must be an edge from the other point, which has no location * labelling for this point. This edge must lie wholly inside or outside * the other point (which is determined by the current location). * Assign both sides to be the current location. */ Assert.IsTrue(label.GetLocation(geomIndex, Positions.Left) == Location.Null, "found single null side"); label.SetLocation(geomIndex, Positions.Right, currLoc); label.SetLocation(geomIndex, Positions.Left, currLoc); } } } }