예제 #1
0
        /// <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);
        }