Example #1
0
        /// <summary>
        /// Check if any shell ring has an unvisited edge.
        /// A shell ring is a ring which is not a hole and which has the interior
        /// of the parent area on the RHS.
        /// (Notice that there may be non-hole rings with the interior on the LHS,
        /// since the interior of holes will also be polygonized into CW rings
        /// by the <c>LinkAllDirectedEdges()</c> step).
        /// </summary>
        /// <param name="edgeRings"></param>
        /// <returns><c>true</c> if there is an unvisited edge in a non-hole ring.</returns>
        private bool HasUnvisitedShellEdge(IList edgeRings)
        {
            for (int i = 0; i < edgeRings.Count; i++)
            {
                EdgeRing er = (EdgeRing)edgeRings[i];
                if (er.IsHole)
                {
                    continue;
                }
                IList        edges = er.Edges;
                DirectedEdge de    = (DirectedEdge)edges[0];
                // don't check CW rings which are holes
                if (de.Label.GetLocation(0, PositionType.Right) != LocationType.Interior)
                {
                    continue;
                }

                // must have a CW ring which surrounds the INT of the area, so check all
                // edges have been visited
                for (int j = 0; j < edges.Count; j++)
                {
                    de = (DirectedEdge)edges[j];
                    if (!de.IsVisited)
                    {
                        _disconnectedRingcoord = de.Coordinate;
                        return(true);
                    }
                }
            }
            return(false);
        }
Example #2
0
        /// <summary>
        /// This method will cause the ring to be computed.
        /// It will also check any holes, if they have been assigned.
        /// </summary>
        /// <param name="p"></param>
        public virtual bool ContainsPoint(Coordinate p)
        {
            ILinearRing shell = LinearRing;
            IEnvelope   env   = shell.EnvelopeInternal;

            if (!env.Contains(p))
            {
                return(false);
            }
            if (!CgAlgorithms.IsPointInRing(p, shell.Coordinates))
            {
                return(false);
            }
            for (IEnumerator i = _holes.GetEnumerator(); i.MoveNext();)
            {
                EdgeRing hole = (EdgeRing)i.Current;
                if (hole.ContainsPoint(p))
                {
                    return(false);
                }
            }
            return(true);
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="er"></param>
 /// <returns></returns>
 public virtual int GetOutgoingDegree(EdgeRing er)
 {
     int degree = 0;
     for (IEnumerator it = GetEnumerator(); it.MoveNext(); )
     {
         DirectedEdge de = (DirectedEdge)it.Current;
         if (de.EdgeRing == er)
             degree++;
     }
     return degree;
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="er"></param>
        public virtual void LinkMinimalDirectedEdges(EdgeRing er)
        {
            // find first area edge (if any) to start linking at
            DirectedEdge firstOut = null;
            DirectedEdge incoming = null;
            int state = SCANNING_FOR_INCOMING;
            // link edges in CW order
            for (int i = _resultAreaEdgeList.Count - 1; i >= 0; i--)
            {
                DirectedEdge nextOut = (DirectedEdge)_resultAreaEdgeList[i];
                DirectedEdge nextIn = nextOut.Sym;

                // record first outgoing edge, in order to link the last incoming edge
                if (firstOut == null && nextOut.EdgeRing == er)
                    firstOut = nextOut;

                switch (state)
                {
                    case SCANNING_FOR_INCOMING:
                        if (nextIn.EdgeRing != er)
                            continue;
                        incoming = nextIn;
                        state = LINKING_TO_OUTGOING;
                        break;
                    case LINKING_TO_OUTGOING:
                        if (nextOut.EdgeRing != er)
                            continue;
                        if (incoming != null) incoming.NextMin = nextOut;
                        state = SCANNING_FOR_INCOMING;
                        break;
                    default:
                        break;
                }
            }
            if (state == LINKING_TO_OUTGOING)
            {
                Assert.IsTrue(firstOut != null, "found null for first outgoing dirEdge");
                if (firstOut != null)
                {
                    Assert.IsTrue(firstOut.EdgeRing == er, "unable to link last incoming dirEdge");
                    if (incoming != null) incoming.NextMin = firstOut;
                }
            }
        }
Example #5
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="de"></param>
 /// <param name="er"></param>
 public abstract void SetEdgeRing(DirectedEdge de, EdgeRing er);
Example #6
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ring"></param>
 public virtual void AddHole(EdgeRing ring)
 {
     _holes.Add(ring);
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="de"></param>
 /// <param name="er"></param>
 public override void SetEdgeRing(DirectedEdge de, EdgeRing er)
 {
     de.EdgeRing = er;
 }
Example #8
0
        /// <summary>
        /// Find the innermost enclosing shell EdgeRing containing the argument EdgeRing, if any.
        /// The innermost enclosing ring is the <i>smallest</i> enclosing ring.
        /// The algorithm used depends on the fact that:
        /// ring A contains ring B iff envelope(ring A) contains envelope(ring B).
        /// This routine is only safe to use if the chosen point of the hole
        /// is known to be properly contained in a shell
        /// (which is guaranteed to be the case if the hole does not touch its shell).
        /// </summary>
        /// <param name="testEr"></param>
        /// <param name="shellList"></param>
        /// <returns>Containing EdgeRing, if there is one, OR
        /// null if no containing EdgeRing is found.</returns>
        private static EdgeRing FindEdgeRingContaining(EdgeRing testEr, IEnumerable shellList)
        {
            ILinearRing teString = testEr.LinearRing;
            IEnvelope testEnv = teString.EnvelopeInternal;
            Coordinate testPt = teString.Coordinates[0];

            EdgeRing minShell = null;
            IEnvelope minEnv = null;
            for (IEnumerator it = shellList.GetEnumerator(); it.MoveNext(); )
            {
                EdgeRing tryShell = (EdgeRing)it.Current;
                ILinearRing tryRing = tryShell.LinearRing;
                IEnvelope tryEnv = tryRing.EnvelopeInternal;
                if (minShell != null)
                    minEnv = minShell.LinearRing.EnvelopeInternal;
                bool isContained = false;
                if (tryEnv.Contains(testEnv) && CgAlgorithms.IsPointInRing(testPt, tryRing.Coordinates))
                    isContained = true;
                // check if this new containing ring is smaller than the current minimum ring
                if (isContained)
                {
                    if (minShell == null || minEnv.Contains(tryEnv))
                        minShell = tryShell;
                }
            }
            return minShell;
        }
Example #9
0
 /// <summary>
 /// This method assigns the holes for a Polygon (formed from a list of
 /// MinimalEdgeRings) to its shell.
 /// Determining the holes for a MinimalEdgeRing polygon serves two purposes:
 /// it is faster than using a point-in-polygon check later on.
 /// it ensures correctness, since if the PIP test was used the point
 /// chosen might lie on the shell, which might return an incorrect result from the
 /// PIP test.
 /// </summary>
 /// <param name="shell"></param>
 /// <param name="minEdgeRings"></param>
 private static void PlacePolygonHoles(EdgeRing shell, IEnumerable minEdgeRings)
 {
     for (IEnumerator it = minEdgeRings.GetEnumerator(); it.MoveNext(); )
     {
         MinimalEdgeRing er = (MinimalEdgeRing)it.Current;
         if (er.IsHole)
             er.Shell = shell;
     }
 }
Example #10
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="de"></param>
 /// <param name="er"></param>
 public abstract void SetEdgeRing(DirectedEdge de, EdgeRing er);
Example #11
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ring"></param>
 public virtual void AddHole(EdgeRing ring)
 {
     _holes.Add(ring);
 }