Exemplo n.º 1
0
        /// <summary>
        /// Checks if this ring encloses a specific position.
        /// </summary>
        /// <param name="p">The position to check</param>
        /// <returns>True is this ring encloses the position. False if the position
        /// is outside, or ON the edge.</returns>
        /// <remarks>Do not override. Any island polygons are intentionally ignored.</remarks>
        internal bool IsRingEnclosing(IPosition p)
        {
            // Return if the position doesn't fall within the window of this polygon
            if (!this.Extent.IsOverlap(p))
            {
                return(false);
            }

            // Set up a search line from the test position to the edge of this
            // polygon's window.
            IPosition east = new Position(this.Extent.Max.X, p.Y);

            // Round off to the nearest micron on the ground
            PointGeometry vs = new PointGeometry(p);
            PointGeometry ve = new PointGeometry(east);

            IDivider closest = null;

            // For each divider we have in the list, locate the closest
            // point of intersection with the search line.
            foreach (IDivider d in m_Edge)
            {
                uint error;
                if (d.LineGeometry.GetCloser(vs, ref ve, out error))
                {
                    closest = d;
                }

                // Return if the vertex coincides with the closest point
                // on the divider (point exactly on the edge of this polygon).
                if (error != 0 || vs.IsCoincident(ve))
                {
                    return(false);
                }
            }

            // We SHOULD have got something.
            if (closest == null)
            {
                return(false);
            }

            // The point can't be inside if we're dealing with an island, and the
            // divider we've found is either a bridge, or a dangle that radiates outwards
            // from the island (this assumes that points exactly coincident with the edge
            // can be treated as "outside").
            if (this is Island && closest.Left == closest.Right)
            {
                return(false);
            }

            // Which side of the divider does the directed line hit?
            IDivider sideDivider;
            Side     side = Topology.GetSide(closest, vs, ve, out sideDivider);

            // Check if we're hitting the divider from the inside. If this
            // ring is an island, things are backwards.
            if (this is Island)
            {
                if (side == Side.Right && sideDivider.Left == this)
                {
                    return(true);
                }
                if (side == Side.Left && sideDivider.Right == this)
                {
                    return(true);
                }
            }
            else
            {
                if (side == Side.Left && sideDivider.Left == this)
                {
                    return(true);
                }
                if (side == Side.Right && sideDivider.Right == this)
                {
                    return(true);
                }
            }

            return(false);
        }