
com.jamieswhiteshirt.rtree3i.RStarSplitter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rtree-3i-lite Show documentation
Show all versions of rtree-3i-lite Show documentation
Immutable map applying a spatial index to keys based on R-Trees
The newest version!
package com.jamieswhiteshirt.rtree3i;
import java.util.*;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import com.google.common.base.Preconditions;
/**
* An R*-tree splitter.
*/
public final class RStarSplitter implements Splitter {
private final Comparator> groupsComparator;
/**
* Constructs an R*-tree splitter.
*/
public RStarSplitter() {
this.groupsComparator = com.jamieswhiteshirt.rtree3i.Comparators.groupsVolumeComparator.thenComparing(com.jamieswhiteshirt.rtree3i.Comparators.groupsIntersectionVolumeComparator);
}
@Override
public Groups split(List items, int minSize, Function boxMapper) {
Preconditions.checkArgument(!items.isEmpty());
// sort nodes into increasing x, calculate min overlap where both groups
// have more than minChildren
Map>> map = new EnumMap<>(SortType.class);
for (SortType sortType : SortType.values()) {
ToIntFunction accessor = item -> sortType.keyAccessor.applyAsInt(boxMapper.apply(item));
Comparator comparator = Comparator.comparingInt(accessor);
map.put(sortType, createPairs(minSize, sort(items, comparator), boxMapper));
}
// compute S the sum of all margin-values of the lists above
// the list with the least S is then used to find minimum overlap
SortType leastMarginSumSortType = Collections.min(sortTypes, marginSumComparator(map));
List> pairs = map.get(leastMarginSumSortType);
return Collections.min(pairs, groupsComparator);
}
private enum SortType {
X1(Box::x1),
X2(Box::x2),
Y1(Box::y1),
Y2(Box::y2),
Z1(Box::z1),
Z2(Box::z2);
final ToIntFunction keyAccessor;
SortType(ToIntFunction keyAccessor) {
this.keyAccessor = keyAccessor;
}
}
private static final List sortTypes = Collections
.unmodifiableList(Arrays.asList(SortType.values()));
private static Comparator marginSumComparator(final Map>> map) {
return Comparator.comparing(sortType -> marginValueSum(map.get(sortType)));
}
private static int marginValueSum(List> list) {
int sum = 0;
for (Groups p : list)
sum += p.getMarginSum();
return sum;
}
static List> createPairs(int minSize, List list, Function key) {
List> pairs = new ArrayList>(list.size() - 2 * minSize + 1);
for (int i = minSize; i < list.size() - minSize + 1; i++) {
List list1 = list.subList(0, i);
List list2 = list.subList(i, list.size());
Groups pair = new Groups<>(Group.of(list1, key), Group.of(list2, key));
pairs.add(pair);
}
return pairs;
}
private static List sort(List items, Comparator comparator) {
ArrayList list = new ArrayList<>(items);
list.sort(comparator);
return list;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy