/// <summary> /// Updates the tracked ringStartEdge /// if the given edge has a lower origin /// (using the standard <see cref="Coordinate"/> ordering). /// </summary> /// <remarks> /// Identifying the lowest starting node meets two goals: /// * It ensures that isolated input rings are created using the original node and orientation. /// * For isolated rings formed from multiple input linestrings, /// it provides a canonical node and orientation for the output /// (rather than essentially random, and thus hard to test). /// </remarks> /// <param name="e"></param> private void UpdateRingStartEdge(DissolveHalfEdge e) { if (!e.IsStart) { e = (DissolveHalfEdge)e.Sym; if (!e.IsStart) { return; } } // here e is known to be a start edge if (_ringStartEdge == null) { _ringStartEdge = e; return; } Coordinate eOrig = e.Orig; Coordinate rseOrig = _ringStartEdge.Orig; int compareTo = eOrig.CompareTo(rseOrig); if (compareTo < 0) { _ringStartEdge = e; } }
private void Add(ILineString lineString) { if (_factory == null) { _factory = lineString.Factory; } ICoordinateSequence seq = lineString.CoordinateSequence; for (int i = 1; i < seq.Count; i++) { Coordinate prev = seq.GetCoordinate(i - 1); Coordinate curr = seq.GetCoordinate(i); DissolveHalfEdge e = (DissolveHalfEdge)_graph.AddEdge(prev, curr); // Record source initial segments, so that they can be reflected in output when needed // (i.e. during formation of isolated rings) if (i == 1) { e.SetStart(); } } }
/// <summary> /// Builds a line starting from the given edge. /// The start edge origin is a node (valence = 1 or >= 3), /// unless it is part of a pure ring. /// </summary> /// <remarks> /// A pure ring has no other incident lines. /// In this case the start edge may occur anywhere on the ring. /// </remarks> /// <remarks> /// The line is built up to the next node encountered, /// or until the start edge is re-encountered /// (which happens if the edges form a ring). /// </remarks> /// <param name="eStart"></param> private void BuildLine(HalfEdge eStart) { CoordinateList line = new CoordinateList(); DissolveHalfEdge e = (DissolveHalfEdge)eStart; _ringStartEdge = null; MarkHalfEdge.MarkBoth(e); Coordinate orig = e.Orig; line.Add(orig.Clone(), false); // scan along the path until a node is found (if one exists) while (e.Sym.Degree() == 2) { UpdateRingStartEdge(e); DissolveHalfEdge eNext = (DissolveHalfEdge)e.Next; // check if edges form a ring - if so, we're done if (eNext == eStart) { BuildRing(_ringStartEdge); return; } // add point to line, and move to next edge orig = eNext.Orig; line.Add(orig.Clone(), false); e = eNext; MarkHalfEdge.MarkBoth(e); } // add final node Coordinate dest = e.Dest; line.Add(dest.Clone(), false); // queue up the final node edges StackEdges(e.Sym); // store the scanned line AddLine(line); }
/// <summary> /// Updates the tracked ringStartEdge /// if the given edge has a lower origin /// (using the standard <see cref="Coordinate"/> ordering). /// </summary> /// <remarks> /// Identifying the lowest starting node meets two goals: /// * It ensures that isolated input rings are created using the original node and orientation. /// * For isolated rings formed from multiple input linestrings, /// it provides a canonical node and orientation for the output /// (rather than essentially random, and thus hard to test). /// </remarks> /// <param name="e"></param> private void UpdateRingStartEdge(DissolveHalfEdge e) { if (!e.IsStart) { e = (DissolveHalfEdge)e.Sym; if (!e.IsStart) return; } // here e is known to be a start edge if (_ringStartEdge == null) { _ringStartEdge = e; return; } Coordinate eOrig = e.Orig; Coordinate rseOrig = _ringStartEdge.Orig; int compareTo = eOrig.CompareTo(rseOrig); if (compareTo < 0) _ringStartEdge = e; }