public MapItemQuadTreeNode(MapItemQuadTreeNode parent, int childIdx)
        {
            Parent = parent;

            if (Parent == null)
            {
                Rect = new Rect(0, 0, 1, 1);
                ZoomLevel = 0;
                X = Y = 0L;
            }
            else
            {
                Rect = parent.GetChildRect(childIdx);
                ZoomLevel = parent.ZoomLevel + 1;

                X = (Parent.X << 1) + (childIdx % 2);
                Y = (Parent.Y << 1) + (childIdx / 2);
            }

            _Children = new MapItemQuadTreeNode[4];
            _Items = new HashSet<MapItem>();
        }
Exemple #2
0
 public MapItemQuadTree()
 {
     _RootNode = new MapItemQuadTreeNode(null, 0);
     _NodesToVisit = new Stack<MapItemQuadTreeNode>();
 }
Exemple #3
0
        /// <summary>
        /// Clusters the map items contained in the node. Clustered items are modified and new items are added
        /// to the tree to represent the clusters.
        /// </summary>
        private static void ClusterNodeItems(MapItemQuadTree tree, MapItemQuadTreeNode node)
        {
            var clumps = new List<List<MapItem>>();
            var clusters = new List<Tuple<List<MapItem>, Point>>();
            HashSet<MapItem> visitedNodes = new HashSet<MapItem>();

            // Create the set of clusters of intersecting items.
            foreach (var item in node.Items)
            {
                List<MapItem> clump = new List<MapItem>();

                GrowClump(tree, item, node.ZoomLevel, visitedNodes, clump);

                if (clump.Count > 1)
                {
                    foreach (var cluster in ClusterClump(clump, node.ZoomLevel))
                    {
                        if (cluster.Item1.Count > 1)
                        {
                            clusters.Add(cluster);
                        }
                    }
                }
            }

            // For each cluster, modify the existing items in the cluster such that they don't appear at the same
            // LOD as the cluster and add new item(s) to the tree that represent the cluster.
            foreach (var cluster in clusters)
            {
                Debug.Assert(cluster.Item1.Count > 1);

                Point clusterLocation = cluster.Item2;

                var clusterItem = new FixedSizeInScreenSpaceMapItem(
                    clusterLocation.ToLocation(),
                    PositionOrigin.Center,
                    new Size(20, 20),
                    0,
                    node.ZoomLevel);

                tree.Add(clusterItem);

                foreach (var item in cluster.Item1)
                {
                    tree.Remove(item);

                    // If this item isn't present at a finer LOD than this, then it's been totally
                    // subsumed by the cluster; otherwise, re-add it to the tree with adjusted
                    // min zoom level.
                    if (item.MaxZoomLevel > node.ZoomLevel)
                    {
                        var adjustedItem = new FixedSizeInScreenSpaceMapItem(
                            item.Location,
                            PositionOrigin.Center,
                            new Size(20, 20),
                            node.ZoomLevel + 1,
                            item.MaxZoomLevel)
                        {
                            Parent = clusterItem
                        };

                        // We're removing the item, so re-assign the children's parent to the cluster that's
                        // standing in for it.
                        foreach (var child in item.Children)
                        {
                            child.Parent = adjustedItem;
                            adjustedItem.AddChild(child);
                        }

                        clusterItem.AddChild(adjustedItem);

                        tree.Add(adjustedItem);
                    }
                }
            }
        }
        public MapItemQuadTreeNode EnsureChild(int childIdx)
        {
            MapItemQuadTreeNode child = _Children[childIdx];

            if (child == null)
            {
                child = _Children[childIdx] = new MapItemQuadTreeNode(this, childIdx);
            }

            return child;
        }