content: package org.oscim.utils;
  
  import org.oscim.core.Box;
  import org.oscim.utils.pool.Pool;
  import org.oscim.utils.quadtree.BoxTree;
  import org.oscim.utils.quadtree.BoxTree.BoxItem;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.util.List;
  
  /**
   * Quad-tree with fixed extents.
   * This implementation uses int bounding-boxes internally,
   * so items extents should be greater than 1. FIXME tests this case
   */
  public class QuadTree<T> extends BoxTree<BoxItem<T>, T> implements SpatialIndex<T> {
  
      static final Logger log = LoggerFactory.getLogger(QuadTree.class);
  
      public QuadTree(int extents, int maxDepth) {
          super(extents, maxDepth);
      }
  
      final Pool<BoxItem<T>> boxPool = new Pool<BoxItem<T>>() {
          @Override
          protected BoxItem<T> createItem() {
              return new BoxItem<T>();
          }
      };
  
      private BoxItem<T> getBox(Box box) {
          BoxItem<T> it = boxPool.get();
          it.x1 = (int) box.xmin;
          it.y1 = (int) box.ymin;
          it.x2 = (int) box.xmax;
          it.y2 = (int) box.ymax;
          return it;
      }
  
      @Override
      public void insert(Box box, T item) {
          insert(new BoxItem<T>(box, item));
      }
  
      @Override
      public boolean remove(Box box, T item) {
          BoxItem<T> bbox = getBox(box);
          boolean ok = remove(bbox, item);
          boxPool.release(bbox);
          return ok;
      }
  
      static class CollectCb<T> implements SearchCb<T> {
          @SuppressWarnings("unchecked")
          @Override
          public boolean call(T item, Object context) {
              List<T> l = (List<T>) context;
              l.add(item);
              return true;
          }
      }
  
      final CollectCb<T> collectCb = new CollectCb<T>();
  
      @Override
      public List<T> search(Box bbox, List<T> results) {
          BoxItem<T> box = getBox(bbox);
          search(box, collectCb, results);
          boxPool.release(box);
          return results;
      }
  
      @Override
      public boolean search(Box bbox, SearchCb<T> cb, Object context) {
          BoxItem<T> box = getBox(bbox);
          boolean finished = search(box, cb, context);
          boxPool.release(box);
          return finished;
      }
  }
  