/// <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 { Assert.IsTrue(de != null, "found null Directed Edge"); if (de == null) { continue; } 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> /// Updates an IM from the label for an edge. /// Handles edges from both L and A geometries. /// </summary> /// <param name="label"></param> /// <param name="im"></param> public static void UpdateIm(Label label, IntersectionMatrix im) { im.SetAtLeastIfValid(label.GetLocation(0, PositionType.On), label.GetLocation(1, PositionType.On), DimensionType.Curve); if (!label.IsArea()) { return; } im.SetAtLeastIfValid(label.GetLocation(0, PositionType.Left), label.GetLocation(1, PositionType.Left), DimensionType.Surface); im.SetAtLeastIfValid(label.GetLocation(0, PositionType.Right), label.GetLocation(1, PositionType.Right), DimensionType.Surface); }
/// <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 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 = ((EdgeEnd)edges[lastEdgeIndex]).Label; LocationType startLoc = startLabel.GetLocation(geomIndex, PositionType.Left); Assert.IsTrue(startLoc != LocationType.Null, "Found unlabelled area edge"); LocationType currLoc = startLoc; for (IEnumerator it = GetEnumerator(); it.MoveNext();) { EdgeEnd e = (EdgeEnd)it.Current; Label label = e.Label; // we assume that we are only checking a area Assert.IsTrue(label.IsArea(geomIndex), "Found non-area edge"); LocationType leftLoc = label.GetLocation(geomIndex, PositionType.Left); LocationType rightLoc = label.GetLocation(geomIndex, PositionType.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="label"></param> /// <param name="im"></param> public static void UpdateIm(Label label, IntersectionMatrix im) { im.SetAtLeastIfValid(label.GetLocation(0, PositionType.On), label.GetLocation(1, PositionType.On), DimensionType.Curve); if (!label.IsArea()) return; im.SetAtLeastIfValid(label.GetLocation(0, PositionType.Left), label.GetLocation(1, PositionType.Left), DimensionType.Surface); im.SetAtLeastIfValid(label.GetLocation(0, PositionType.Right), label.GetLocation(1, PositionType.Right), DimensionType.Surface); }
/// <summary> /// /// </summary> /// <param name="geomIndex"></param> public virtual 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 LocationType startLoc = LocationType.Null; // initialize loc to location of last Curve side (if any) for (IEnumerator it = GetEnumerator(); it.MoveNext();) { EdgeEnd e = (EdgeEnd)it.Current; Label label = e.Label; if (label.IsArea(geomIndex) && label.GetLocation(geomIndex, PositionType.Left) != LocationType.Null) { startLoc = label.GetLocation(geomIndex, PositionType.Left); } } // no labelled sides found, so no labels to propagate if (startLoc == LocationType.Null) { return; } LocationType currLoc = startLoc; for (IEnumerator it = GetEnumerator(); it.MoveNext();) { EdgeEnd e = (EdgeEnd)it.Current; Label label = e.Label; // set null On values to be in current location if (label.GetLocation(geomIndex, PositionType.On) == LocationType.Null) { label.SetLocation(geomIndex, PositionType.On, currLoc); } // set side labels (if any) // if (label.IsArea()) //ORIGINAL if (label.IsArea(geomIndex)) { LocationType leftLoc = label.GetLocation(geomIndex, PositionType.Left); LocationType rightLoc = label.GetLocation(geomIndex, PositionType.Right); // if there is a right location, that is the next location to propagate if (rightLoc != LocationType.Null) { if (rightLoc != currLoc) { throw new TopologyException(TopologyText.SideLocationConflict, e.Coordinate); } if (leftLoc == LocationType.Null) { throw new TopologyException(TopologyText.SingleNullSide, 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, PositionType.Left) == LocationType.Null, "found single null side"); label.SetLocation(geomIndex, PositionType.Right, currLoc); label.SetLocation(geomIndex, PositionType.Left, currLoc); } } } }