/// <summary>
        /// Updates each map item in the set, setting whether it's in the view specified by the given
        /// location rect and zoom level.
        /// </summary>
        /// <param name="locationRect">The location rect component of the view.</param>
        /// <param name="zoomLevel">The zoom level component of the view.</param>
        public override void UpdateVisibilty(LocationRect locationRect, int zoomLevel)
        {
            // If the location rect has no area...
            if (locationRect.Width <= 0 || locationRect.Height <= 0)
            {
                // ...then clear the visibility on each map item.
                foreach (MapItem item in _Items)
                {
                    item.InView = false;
                }
            }
            else
            {
                // ...otherwise, do the normal visibility update.
                NormalizedMercatorRect queryRect = new NormalizedMercatorRect(locationRect);

                foreach (MapItem item in _Items)
                {
                    bool inView = false;

                    if (zoomLevel <= item.MaxZoomLevel && zoomLevel >= item.MinZoomLevel)
                    {
                        NormalizedMercatorRect itemRect = item.BoundingRectAtZoomLevel(zoomLevel);

                        if (queryRect.Intersects(itemRect))
                        {
                            inView = true;
                        }
                    }

                    item.InView = inView;
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Returns all of the items that intersect the given rect at the given zoom level. This list
        /// may contain duplicate items.
        /// </summary>
        /// <param name="rect">The rect.</param>
        /// <param name="zoomLevel">The zoom level.</param>
        /// <returns></returns>
        public IEnumerable<MapItem> IntersectingItems(NormalizedMercatorRect rect, int zoomLevel)
        {
            if (zoomLevel < 0)
            {
                throw new ArgumentException("zoom level must be non-negative");
            }

            if (!rect.Intersects(_RootNode.Rect))
            {
                throw new ArgumentException("rect out of range");
            }

            int nodesVisited = 0;

            Debug.Assert(_NodesToVisit.Count == 0);
            _NodesToVisit.Push(_RootNode);

            for (; _NodesToVisit.Count > 0; nodesVisited++)
            {
                MapItemQuadTreeNode node = _NodesToVisit.Pop();
                Debug.Assert(node.ZoomLevel <= zoomLevel);
                Debug.Assert(rect.Intersects(node.Rect));

                if (zoomLevel == node.ZoomLevel)
                {
                    foreach (MapItem item in node.Items)
                    {
                        if (item.BoundingRectAtZoomLevel(node.ZoomLevel).Intersects(rect))
                        {
                            yield return item;
                        }
                    }
                }
                else
                {
                    for (int childIdx = 0; childIdx < 4; childIdx++)
                    {
                        MapItemQuadTreeNode child = node.GetChild(childIdx);

                        if (child != null && rect.Intersects(child.Rect))
                        {
                            _NodesToVisit.Push(child);
                        }
                    }
                }
            }
        }