Ejemplo n.º 1
0
        private void runDeleteAllEntries(int minNodeEntries, int maxNodeEntries, int numRects)
        {
            RTree rtree = new RTree(minNodeEntries, maxNodeEntries);

            for (int i = 0; i <= numRects; i += 100)
            {
                // add some entries
                for (int j = 0; j < i; j++)
                {
                    rtree.Add(rects[j]);
                }
                Assert.True(rtree.checkConsistency());

                // now delete them all
                for (int j = 0; j < i; j++)
                {
                    rtree.Remove(rects[j]);
                }
                Assert.True(rtree.Count == 0);
                Assert.True(rtree.checkConsistency());

                // check that we can make queries on an empty rtree without error.
                Rectangle testRect  = new Rectangle(1, 2, 3, 4);
                Point     testPoint = new Point(1, 2);

                Counter counter = new Counter();
                rtree.Intersects(testRect, counter.execute);
                Assert.True(counter.count == 0);

                PriorityQueueRTree priorityQue = rtree.Nearest(testPoint, float.MaxValue);
                Assert.True(priorityQue.Count == 0);

                priorityQue = rtree.NearestN(testPoint, 10, float.MaxValue);
                Assert.True(priorityQue.Count == 0);

                rtree.Contains(testRect, counter.execute);
                Assert.True(counter.count == 0);
            }
        }
Ejemplo n.º 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;
    }
Ejemplo n.º 3
0
    /// <summary>
    /// Finds the nearest rectangles to the passed point. If multiple rectangles are equally near, they will all be returned.
    /// </summary>
    /// <param name="p">the point we are looking for</param>
    /// <param name="furthestDistance">The furthest distance away from the rectangle to search. Rectangles further than this will not be found.</param>
    /// <returns>a PriorityQue containing the found recatngles and their priorities (distances from point)</returns>
    public PriorityQueueRTree Nearest(Point p, double furthestDistance)
    {
      PriorityQueueRTree distanceQueue = new PriorityQueueRTree(); 

      double furthestDistanceSq = furthestDistance * furthestDistance;
      rootNode.Nearest(p, this, furthestDistanceSq, distanceQueue);
      return distanceQueue;
    }
Ejemplo n.º 4
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;
 }
Ejemplo n.º 5
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);
     // a rectangle nearer than actualNearest
     if (tempDistanceSq <= furthestDistanceSq)
     {
       NodeBase node = childNodes[i]; // search the child node
       furthestDistanceSq = node.Nearest(p, rTree, furthestDistanceSq, nearestRectangles);
     }
   }
   return furthestDistanceSq;
 }
Ejemplo n.º 6
0
 internal abstract double Nearest(Point p, RTree rTree, double furthestDistanceSq, PriorityQueueRTree nearestRectangles);