Example #1
0
        /// <summary>
        /// Confirms that a potential link is valid. For a link to be valid, the
        /// midpoint of the link must fall inside the specified polygon, and the
        /// line connecting the 2 points cannot intersect anything.
        /// </summary>
        /// <param name="other">The end of the proposed point to link to.</param>
        /// <param name="pol">The polygon the link must fall completely inside.</param>
        /// <returns>True if link is valid.</returns>
        internal bool IsLinkValid(PolygonLink other, Polygon pol)
        {
            // 22-MAR-00 There may be no point at a corner.
            if (m_Point == null || other.Point == null)
            {
                return(false);
            }

            // Get the midpoint of the link.
            IPosition mid = Geom.MidPoint(m_Point, other.Point);

            // Confirm the midpoint falls inside the right polygon.
            if (!pol.IsRingEnclosing(mid))
            {
                return(false);
            }

            // Locate any intersections formed by the proposed link (considering
            // only the currently active theme).
            LineGeometry       seg   = new SegmentGeometry(m_Point, other.m_Point);
            IntersectionFinder xsect = new IntersectionFinder(seg, true);

            // The proposed link is not valid if it intersects anything
            // along the length of the segment, or has any grazes.
            if (xsect.IsGrazing || xsect.IsSplitNeeded)
            {
                return(false);
            }

            return(true);
        }
Example #2
0
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>Ring</c>)</param>
        /// <returns>True if the query should continue. False if the enclosing polygon has been found.</returns>
        private bool OnQueryHit(ISpatialObject item)
        {
            // We're only interested in real polygons (not islands)
            if (!(item is Polygon))
            {
                return(true);
            }

            // The area of the polygon MUST be bigger than the area of the island.
            Polygon p = (Polygon)item;

            if (p.Area < m_Island.Area)
            {
                return(true);
            }

            // Skip if the window does not actually overlap the search point.
            if (!p.Extent.IsOverlap(m_EastPoint))
            {
                return(true);
            }

            // The window of the island must be ENTIRELY within the window
            // of the candidate polygon.
            if (!m_Island.Extent.IsEnclosedBy(p.Extent))
            {
                return(true);
            }

            // Skip if the polygon doesn't enclose the east point.
            if (!p.IsRingEnclosing(m_EastPoint))
            {
                return(true);
            }

            // Skip if we previously found something, and the area of the candidate
            // polygon is bigger. Take care here - the polygons may not yet know about
            // all their islands (which might lead to an incorrect enclosing polygon),
            // so this test should EXCLUDE the area of any islands that they already
            // know about).
            if (m_Result != null && p.AreaExcludingIslands > m_Result.AreaExcludingIslands)
            {
                return(true);
            }

            m_Result = p;

            // Keep going after finding a result, since a different (smaller) polygon
            // may be found further on in the search.
            return(true);
        }
Example #3
0
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>Ring</c>)</param>
        /// <returns>True if the query should continue. False if the enclosing polygon has been found.</returns>
        private bool OnQueryHit(ISpatialObject item)
        {
            // We're only interested in real polygons (not islands)
            if (!(item is Polygon))
            {
                return(true);
            }

            // The window of the polygon has to overlap.
            Polygon p = (Polygon)item;

            if (!p.Extent.IsOverlap(m_Point))
            {
                return(true);
            }

            // Skip if it doesn't enclose the search position
            if (!p.IsRingEnclosing(m_Point))
            {
                return(true);
            }

            // If the polygon contains any islands, remember the polygon
            // for a further look. Things like an unclosed street network
            // can have MANY islands, so checking whether the position falls
            // inside any of them is a bit laborious. We'll comes back to
            // this polygon if we can't find an easy match.

            if (p.HasAnyIslands)
            {
                if (m_Candidates == null)
                {
                    m_Candidates = new List <Polygon>(1);
                }

                m_Candidates.Add(p);
                return(true);
            }

            m_Result = p;
            return(false);
        }