Ejemplo n.º 1
0
        /// <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;
            }
        }
Ejemplo n.º 2
0
        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();
                }
            }
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
        /// <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;
        }