Пример #1
0
        /// <summary>
        /// Chooses which node should we enlarge with the new envelope to minimalize the overlap between the nodes
        /// </summary>
        /// <param name="entries">The nodes from we want to choose.</param>
        /// <param name="newEnvelope">The new envelope.</param>
        /// <returns></returns>
        private RTreeNode ChooseNode(List <RTreeNode> entries, Envelope newEnvelope)
        {
            RTreeNode minimalEntry     = entries[0];
            Envelope  enlargedEnvelope = Envelope.FromEnvelopes(minimalEntry.Envelope, newEnvelope);
            Double    minimalOverlap   = entries.Sum(x => x != entries[0] ? ComputeOverlap(enlargedEnvelope, x.Envelope) : 0);

            for (Int32 i = 1; i < entries.Count; i++)
            {
                enlargedEnvelope = Envelope.FromEnvelopes(entries[i].Envelope, newEnvelope);
                Double overlap = entries.Sum(x => x != entries[i] ? ComputeOverlap(enlargedEnvelope, x.Envelope) : 0);

                if (overlap < minimalOverlap)
                {
                    minimalOverlap = overlap;
                    minimalEntry   = entries[i];
                }
                else if (overlap == minimalOverlap)
                {
                    if (entries[i].ComputeEnlargement(newEnvelope) < minimalEntry.ComputeEnlargement(newEnvelope))
                    {
                        minimalEntry = entries[i];
                    }
                }
            }
            return(minimalEntry);
        }
Пример #2
0
        /// <summary>
        /// Splits a node into two nodes.
        /// </summary>
        /// <param name="overflownNode">The overflown node.</param>
        /// <param name="firstNode">The first produced node.</param>
        /// <param name="secondNode">The second produced node.</param>
        protected virtual void SplitNode(RTreeNode overflownNode, out RTreeNode firstNode, out RTreeNode secondNode)
        {
            RTreeNode firstSeed, secondSeed;

            PickSeeds(overflownNode.Children, out firstSeed, out secondSeed);

            firstNode  = (overflownNode.Parent != null) ? new RTreeNode(overflownNode.Parent) : new RTreeNode(overflownNode.MaxChildren);
            secondNode = (overflownNode.Parent != null) ? new RTreeNode(overflownNode.Parent) : new RTreeNode(overflownNode.MaxChildren);

            firstNode.AddChild(firstSeed);
            secondNode.AddChild(secondSeed);

            overflownNode.Children.Remove(firstSeed);
            overflownNode.Children.Remove(secondSeed);

            while (overflownNode.ChildrenCount > 0)
            {
                RTreeNode node = PickNext(overflownNode.Children);

                if (firstNode.ChildrenCount + overflownNode.ChildrenCount <= MinChildren)
                {
                    firstNode.AddChild(node);
                }
                else if (secondNode.ChildrenCount + overflownNode.ChildrenCount <= MinChildren)
                {
                    secondNode.AddChild(node);
                }
                else
                {
                    Double firstEnlargement  = firstNode.ComputeEnlargement(node.Envelope);
                    Double secondEnlargement = secondNode.ComputeEnlargement(node.Envelope);

                    if (firstEnlargement < secondEnlargement)
                    {
                        firstNode.AddChild(node);
                    }
                    else if (firstEnlargement > secondEnlargement)
                    {
                        secondNode.AddChild(node);
                    }
                    else
                    {
                        if (firstNode.Envelope.Surface < secondNode.Envelope.Surface)
                        {
                            firstNode.AddChild(node);
                        }
                        else
                        {
                            secondNode.AddChild(node);
                        }
                    }
                }
            }
        }