/// <summary> /// Creates a new <c>FindOverlapsQuery</c> (and executes it). The result of the query /// can then be obtained through the <c>Result</c> property. /// </summary> /// <param name="index">The spatial index to search</param> /// <param name="closedShape">The closed shape defining the search area.</param> /// <param name="spatialType">The type of objects to look for.</param> internal FindOverlapsQuery(ISpatialIndex index, IPosition[] closedShape, SpatialType spatialType) { m_ClosedShape = new ClosedShape(closedShape); m_Points = new List <PointFeature>(100); m_Result = new List <ISpatialObject>(100); // If we are looking for points or lines, locate points that overlap. Note that // if the user does not actually want points in the result, we still do a point // search, since it helps with the selection of lines. if ((spatialType & SpatialType.Point) != 0 || (spatialType & SpatialType.Line) != 0) { index.QueryWindow(m_ClosedShape.Extent, SpatialType.Point, OnPointFound); // Remember the points in the result if the caller wants them if ((spatialType & SpatialType.Point) != 0) { m_Result.AddRange(m_Points.ToArray()); } } // Find lines (this automatically includes lines connected to the points we just found) if ((spatialType & SpatialType.Line) != 0) { index.QueryWindow(m_ClosedShape.Extent, SpatialType.Line, OnLineFound); } // Find any overlapping text if ((spatialType & SpatialType.Text) != 0) { index.QueryWindow(m_ClosedShape.Extent, SpatialType.Text, OnTextFound); } m_Result.TrimExcess(); m_Points = null; }
/// <summary> /// Creates a new <c>FindOverlapsQuery</c> (and executes it). The result of the query /// can then be obtained through the <c>Result</c> property. /// </summary> /// <param name="index">The spatial index to search</param> /// <param name="closedShape">The closed shape defining the search area.</param> /// <param name="spatialType">The type of objects to look for.</param> internal FindOverlapsQuery(ISpatialIndex index, IPosition[] closedShape, SpatialType spatialType) { m_ClosedShape = new ClosedShape(closedShape); m_Points = new List<PointFeature>(100); m_Result = new List<ISpatialObject>(100); // If we are looking for points or lines, locate points that overlap. Note that // if the user does not actually want points in the result, we still do a point // search, since it helps with the selection of lines. if ((spatialType & SpatialType.Point)!=0 || (spatialType & SpatialType.Line)!=0) { index.QueryWindow(m_ClosedShape.Extent, SpatialType.Point, OnPointFound); // Remember the points in the result if the caller wants them if ((spatialType & SpatialType.Point)!=0) m_Result.AddRange(m_Points.ToArray()); } // Find lines (this automatically includes lines connected to the points we just found) if ((spatialType & SpatialType.Line)!=0) index.QueryWindow(m_ClosedShape.Extent, SpatialType.Line, OnLineFound); // Find any overlapping text if ((spatialType & SpatialType.Text)!=0) index.QueryWindow(m_ClosedShape.Extent, SpatialType.Text, OnTextFound); m_Result.TrimExcess(); m_Points = null; }
/// <summary> /// Does any edge of this closed shape intersect the edge of another shape. /// This assumes that a window-window overlap has already been checked for. /// </summary> /// <param name="that">The closed shape to compare with (preferably the one /// with the smaller spatial extent). /// </param> /// <returns>True if the edges of the shapes intersect</returns> bool IsIntersect(ClosedShape that) { IPointGeometry[] data = this.Data; for (int i = 1; i < data.Length; i++) { if (that.IsOverlap(data[i - 1], data[i])) { return(true); } } return(false); }
/// <summary> /// Delegate that's called whenever the index finds text with a window that overlaps the query window /// </summary> /// <param name="item">The item to process (expected to be some sort of <c>TextFeature</c>)</param> /// <returns>True (always), indicating that the query should continue.</returns> private bool OnTextFound(ISpatialObject item) { TextFeature text = (TextFeature)item; // Get the outline for the text IPosition[] outline = text.TextGeometry.Outline; // If any corner of the text outline is inside the closed shape (or any edge of // the outline intersects), remember the text in the results ClosedShape cs = new ClosedShape(outline); if (cs.IsOverlap(m_ClosedShape)) { m_Result.Add(text); } return(true); }
/// <summary> /// Does this closed shape overlap another closed shape? /// </summary> /// <param name="that">The closed shape to compare with</param> /// <returns>True if the shapes overlap</returns> /// <remarks>It should be more efficient to make <c>this</c> closed shape the /// smaller one.</remarks> internal bool IsOverlap(ClosedShape that) { // The window of this shape must overlap the window of the other shape if (!m_Extent.IsOverlap(that.Extent)) { return(false); } // If any position in this shape falls inside the other one, we've got overlap. foreach (IPointGeometry p in this.Data) { if (that.IsOverlap(p)) { return(true); } } // NONE of the positions in this shape fall inside the // other shape. So check if any segment intersects the other shape. // To try to maximize efficiency, compare the shape that // has the larger spatial extent. That way, we should be // able to eliminate the max number of segments with a // simple segment-window test. double areaThis = this.Extent.Width * this.Extent.Height; double areaThat = that.Extent.Width * that.Extent.Height; if (areaThis > areaThat) { return(this.IsIntersect(that)); } else { return(that.IsIntersect(this)); } }
/// <summary> /// Does any edge of this closed shape intersect the edge of another shape. /// This assumes that a window-window overlap has already been checked for. /// </summary> /// <param name="that">The closed shape to compare with (preferably the one /// with the smaller spatial extent). /// </param> /// <returns>True if the edges of the shapes intersect</returns> bool IsIntersect(ClosedShape that) { IPointGeometry[] data = this.Data; for (int i=1; i<data.Length; i++) { if (that.IsOverlap(data[i-1], data[i])) return true; } return false; }
/// <summary> /// Does this closed shape overlap another closed shape? /// </summary> /// <param name="that">The closed shape to compare with</param> /// <returns>True if the shapes overlap</returns> /// <remarks>It should be more efficient to make <c>this</c> closed shape the /// smaller one.</remarks> internal bool IsOverlap(ClosedShape that) { // The window of this shape must overlap the window of the other shape if (!m_Extent.IsOverlap(that.Extent)) return false; // If any position in this shape falls inside the other one, we've got overlap. foreach (IPointGeometry p in this.Data) { if (that.IsOverlap(p)) return true; } // NONE of the positions in this shape fall inside the // other shape. So check if any segment intersects the other shape. // To try to maximize efficiency, compare the shape that // has the larger spatial extent. That way, we should be // able to eliminate the max number of segments with a // simple segment-window test. double areaThis = this.Extent.Width * this.Extent.Height; double areaThat = that.Extent.Width * that.Extent.Height; if (areaThis > areaThat) return this.IsIntersect(that); else return that.IsIntersect(this); }
/// <summary> /// Delegate that's called whenever the index finds text with a window that overlaps the query window /// </summary> /// <param name="item">The item to process (expected to be some sort of <c>TextFeature</c>)</param> /// <returns>True (always), indicating that the query should continue.</returns> private bool OnTextFound(ISpatialObject item) { TextFeature text = (TextFeature)item; // Get the outline for the text IPosition[] outline = text.TextGeometry.Outline; // If any corner of the text outline is inside the closed shape (or any edge of // the outline intersects), remember the text in the results ClosedShape cs = new ClosedShape(outline); if (cs.IsOverlap(m_ClosedShape)) m_Result.Add(text); return true; }