/// <summary> /// Process items with a covering rectangle that overlaps a query window. /// </summary> /// <param name="extent">The extent of the query window</param> /// <param name="types">The type(s) of object to look for</param> /// <param name="itemHandler">The method that should be called for each query hit. A hit /// is defined as anything with a covering rectangle that overlaps the query window (this /// does not mean the hit actually intersects the window).</param> public void QueryWindow(IWindow extent, SpatialType types, ProcessItem itemHandler) { Extent w = (extent == null || extent.IsEmpty ? new Extent() : new Extent(extent)); if ((types & SpatialType.Point) != 0) { m_Points.Query(w, itemHandler); } if ((types & SpatialType.Line) != 0) { m_Lines.Query(w, itemHandler); } if ((types & SpatialType.Text) != 0) { m_Text.Query(w, itemHandler); } if ((types & SpatialType.Polygon) != 0) { m_Polygons.Query(w, itemHandler); } }
/** * Look for groups of vertices that are separated by at most merge_distance() * and merge them into a single vertex. */ private void MergeVertices() { // The overall strategy is to start from each vertex and grow a maximal // cluster of mergable vertices. In graph theoretic terms, we find the // connected components of the undirected graph whose edges connect pairs of // vertices that are separated by at most merge_distance. // // We then choose a single representative vertex for each cluster, and // update all the edges appropriately. We choose an arbitrary existing // vertex rather than computing the centroid of all the vertices to avoid // creating new vertex pairs that need to be merged. (We guarantee that all // vertex pairs are separated by at least merge_distance in the output.) var index = new PointIndex(_options.MergeDistance.Radians); foreach (var edge in _edges) { index.Add(edge.Key); var vset = edge.Value; foreach (var v in vset) { index.Add(v); } } // Next, we loop through all the vertices and attempt to grow a maximial // mergeable group starting from each vertex. var mergeMap = new Dictionary <S2Point, S2Point>(); var frontier = new Stack <S2Point>(); var mergeable = new List <S2Point>(); foreach (var entry in index) { var point = entry.Value; if (point.IsMarked) { continue; // Already processed. } point.Mark(); // Grow a maximal mergeable component starting from "vstart", the // canonical representative of the mergeable group. var vstart = point.Point; frontier.Push(vstart); while (frontier.Any()) { var v0 = frontier.Pop(); index.Query(v0, mergeable); foreach (var v1 in mergeable) { frontier.Push(v1); mergeMap.Add(v1, vstart); } } } // Finally, we need to replace vertices according to the merge_map. MoveVertices(mergeMap); }