@Override
 public <A> int choose(
     A options,
     ArrayAdapter<? extends SpatialComparable, A> getter,
     SpatialComparable obj,
     int height,
     int depth) {
   final int size = getter.size(options);
   assert (size > 0) : "Choose from empty set?";
   // R*-Tree: overlap increase for leaves.
   int best = -1;
   double least_overlap = Double.POSITIVE_INFINITY;
   double least_areainc = Double.POSITIVE_INFINITY;
   double least_area = Double.POSITIVE_INFINITY;
   // least overlap increase, on reduced candidate set:
   for (int i = 0; i < size; i++) {
     // Existing object and extended rectangle:
     SpatialComparable entry = getter.get(options, i);
     HyperBoundingBox mbr = SpatialUtil.union(entry, obj);
     // Compute relative overlap increase.
     double overlap_wout = 0.0;
     double overlap_with = 0.0;
     for (int k = 0; k < size; k++) {
       if (i != k) {
         SpatialComparable other = getter.get(options, k);
         overlap_wout += SpatialUtil.relativeOverlap(entry, other);
         overlap_with += SpatialUtil.relativeOverlap(mbr, other);
       }
     }
     double inc_overlap = overlap_with - overlap_wout;
     if (inc_overlap < least_overlap) {
       final double area = SpatialUtil.volume(entry);
       final double inc_area = SpatialUtil.volume(mbr) - area;
       // Volume increase and overlap increase:
       least_overlap = inc_overlap;
       least_areainc = inc_area;
       least_area = area;
       best = i;
     } else if (inc_overlap == least_overlap) {
       final double area = SpatialUtil.volume(entry);
       final double inc_area = SpatialUtil.volume(mbr) - area;
       if (inc_area < least_areainc || (inc_area == least_areainc && area < least_area)) {
         least_overlap = inc_overlap;
         least_areainc = inc_area;
         least_area = area;
         best = i;
       }
     }
   }
   assert (best > -1) : "No split found? Volume outside of double precision?";
   return best;
 }
示例#2
0
 /**
  * Compute the union of a number of objects as a flat MBR (low-level, for index structures).
  *
  * @param data Object
  * @param getter Array adapter
  * @param <E> object type
  * @param <A> data value type
  * @return Flat MBR
  */
 public static <E extends SpatialComparable, A> double[] unionFlatMBR(
     A data, ArrayAdapter<E, ? super A> getter) {
   final int num = getter.size(data);
   assert (num > 0) : "Cannot compute MBR of empty set.";
   final int dim;
   final double[] mbr;
   { // First entry
     final E first = getter.get(data, 0);
     dim = first.getDimensionality();
     mbr = new double[2 * dim];
     for (int d = 0; d < dim; d++) {
       mbr[d] = first.getMin(d);
       mbr[dim + d] = first.getMax(d);
     }
   } // Remaining entries
   for (int i = 1; i < num; i++) {
     E next = getter.get(data, i);
     for (int d = 0; d < dim; d++) {
       mbr[d] = Math.min(mbr[d], next.getMin(d));
       mbr[dim + d] = Math.max(mbr[dim + d], next.getMax(d));
     }
   }
   return mbr;
 }