/// <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); }
/// <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); }
/// <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); }