Esempio n. 1
0
        private RTreeNode <TItem> doSplit(RTreeNode <TItem> node, DynamicRTreeBalanceHeuristic heuristic)
        {
            Boolean isLeaf = node.IsLeaf;

            IEnumerable <IBoundable <IExtents> > boundables;
            Int32 boundablesCount;

            if (isLeaf)
            {
                boundables      = Caster.Upcast <IBoundable <IExtents>, TItem>(node.Items);
                boundablesCount = node.ItemCount;
            }
            else
            {
                boundables      = Caster.Upcast <IBoundable <IExtents>, ISpatialIndexNode <IExtents, TItem> >(node.SubNodes);
                boundablesCount = node.SubNodeCount;
            }

            List <IBoundable <IExtents> > entries = new List <IBoundable <IExtents> >(boundablesCount);

            entries.AddRange(boundables);

            IBoundable <IExtents>[] group1 = new IBoundable <IExtents> [heuristic.NodeItemMaximumCount];
            IBoundable <IExtents>[] group2 = new IBoundable <IExtents> [heuristic.NodeItemMaximumCount];

            pickSeeds(entries, group1, group2);

            Int32 group1Count = 1, group2Count = 1;

            distribute(entries, group1, group2, heuristic, ref group1Count, ref group2Count);

            if (entries.Count > 0)
            {
                if (group1Count < group2Count)
                {
                    fillShortGroup(entries, group1, ref group1Count);
                }
                else // group2Count < heuristic.NodeItemMinimumCount
                {
                    fillShortGroup(entries, group2, ref group2Count);
                }
            }

            node.Clear();

            RTreeNode <TItem> sibling = (node.Index as RTree <TItem>).CreateNode(node.Level);

            IEnumerable <IBoundable <IExtents> > g1Sized = Enumerable.Take(group1, group1Count);
            IEnumerable <IBoundable <IExtents> > g2Sized = Enumerable.Take(group2, group2Count);

            if (isLeaf)
            {
                IEnumerable <TItem> g1Cast = Caster.Downcast <TItem, IBoundable <IExtents> >(g1Sized);
                node.InsertRange(g1Cast);

                //IEnumerable<TItem> g2Cast = Caster.Downcast<TItem, IBoundable<IExtents>>(g2Sized);
                sibling.AddRange(g2Sized);
            }
            else
            {
                //IEnumerable<ISpatialIndexNode<IExtents, TItem>> g1Cast
                //    = Caster.Downcast<ISpatialIndexNode<IExtents, TItem>, IBoundable<IExtents>>(g1Sized);
                node.AddRange(g1Sized);

                //IEnumerable<ISpatialIndexNode<IExtents, TItem>> g2Cast
                //    = Caster.Downcast<ISpatialIndexNode<IExtents, TItem>, IBoundable<IExtents>>(g2Sized);
                sibling.AddRange(g2Sized);
            }

            return(sibling);
        }