Exemple #1
0
 internal override double Nearest(Point p, RTree rTree, double furthestDistanceSq, PriorityQueueRTree nearestRectangles)
 {
     for (int i = 0; i < entryCount; i++)
     {
         double tempDistanceSq = entries[i].Value.distanceSq(p.x, p.y);
         if (tempDistanceSq < furthestDistanceSq)
         {
             furthestDistanceSq = tempDistanceSq;
             nearestRectangles.Clear();
         }
         if (tempDistanceSq <= furthestDistanceSq)
         {
             nearestRectangles.Insert(entries[i].Value, tempDistanceSq);
         }
     }
     return(furthestDistanceSq);
 }
Exemple #2
0
        private PriorityQueueRTree createNearestNDistanceQueue(Point p, UInt32 count, double furthestDistance)
        {
            PriorityQueueRTree distanceQueue = new PriorityQueueRTree();

            //  return immediately if given an invalid "count" parameter
            if (count == 0)
            {
                return(distanceQueue);
            }

            parents.Clear();
            parents.Push(rootNode);

            parentsEntry.Clear();
            parentsEntry.Push(-1);

            // TODO: possible shortcut here - could test for intersection with the MBR of the root node. If no intersection, return immediately.
            double furthestDistanceSq = furthestDistance * furthestDistance;

            while (parents.Count > 0)
            {
                NodeBase n          = parents.Peek();
                int      startIndex = parentsEntry.Peek() + 1;

                if (!n.IsLeaf)
                {
                    // go through every entry in the index node to check if it could contain an entry closer than the farthest entry currently stored.
                    bool         near         = false;
                    NodeInternal nodeInternal = n as NodeInternal;
                    for (int i = startIndex; i < n.entryCount; i++)
                    {
                        if (n.entries[i].Value.distanceSq(p.x, p.y) <= furthestDistanceSq)
                        {
                            parents.Push(nodeInternal.childNodes[i]);
                            parentsEntry.Pop();
                            parentsEntry.Push(i); // this becomes the start index when the child has been searched
                            parentsEntry.Push(-1);
                            near = true;
                            break; // ie go to next iteration of while()
                        }
                    }
                    if (near)
                    {
                        continue;
                    }
                }
                else
                {
                    // go through every entry in the leaf to check if it is currently one of the nearest N entries.
                    for (int i = 0; i < n.entryCount; i++)
                    {
                        double entryDistanceSq = n.entries[i].Value.distanceSq(p.x, p.y);

                        if (entryDistanceSq <= furthestDistanceSq)
                        {
                            distanceQueue.Insert(n.entries[i].Value, entryDistanceSq);

                            while (distanceQueue.Count > count)
                            {
                                // normal case - we can simply remove the lowest priority (highest distance) entry
                                Rectangle value      = distanceQueue.ValuePeek;
                                double    distanceSq = distanceQueue.PriorityPeek;
                                distanceQueue.Pop();

                                // rare case - multiple items of the same priority (distance)
                                if (distanceSq == distanceQueue.PriorityPeek)
                                {
                                    savedValues.Add(value);
                                    savedPriority = distanceSq;
                                }
                                else
                                {
                                    savedValues.Clear();
                                }
                            }

                            // if the saved values have the same distance as the next one in the tree, add them back in.
                            if (savedValues.Count > 0 && savedPriority == distanceQueue.PriorityPeek)
                            {
                                for (int svi = 0; svi < savedValues.Count; svi++)
                                {
                                    distanceQueue.Insert(savedValues[svi], savedPriority);
                                }
                                savedValues.Clear();
                            }

                            // narrow the search, if we have already found N items
                            if (distanceQueue.PriorityPeek < furthestDistanceSq && distanceQueue.Count >= count)
                            {
                                furthestDistanceSq = distanceQueue.PriorityPeek;
                            }
                        }
                    }
                }
                parents.Pop();
                parentsEntry.Pop();
            }
            return(distanceQueue);
        }