edu.uci.ics.jung.visualization.spatial.rtree.RStarSplitter Maven / Gradle / Ivy
package edu.uci.ics.jung.visualization.spatial.rtree;
import static edu.uci.ics.jung.visualization.spatial.rtree.Node.M;
import static edu.uci.ics.jung.visualization.spatial.rtree.Node.m;
import static edu.uci.ics.jung.visualization.spatial.rtree.Node.nodeArea;
import static edu.uci.ics.jung.visualization.spatial.rtree.Node.nodeMargin;
import static edu.uci.ics.jung.visualization.spatial.rtree.Node.nodeOverlap;
import com.google.common.collect.Lists;
import java.awt.geom.Rectangle2D;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RStarSplitter extends AbstractSplitter implements Splitter {
private static Logger log = LoggerFactory.getLogger(RStarSplitter.class);
private Comparator> horizontalEdgeComparator = new HorizontalEdgeNodeComparator();
private Comparator verticalEdgeComparator = new VerticalEdgeNodeComparator();
public Pair> split(List> children, Node newEntry) {
return chooseSplitNodes(children, newEntry);
}
private Pair> chooseSplitNodes(Collection> entries, Node newEntry) {
Pair>> pair = chooseSplit(entries, newEntry);
InnerNode innerNodeLeft = InnerNode.create(pair.left);
InnerNode innerNodeRight = InnerNode.create(pair.right);
return Pair.of(innerNodeLeft, innerNodeRight);
}
private Pair>> chooseSplit(Collection> entries, Node newEntry) {
// make 2 lists to sort
List> xAxisList = Lists.newArrayList(entries);
xAxisList.add(newEntry);
List> yAxisList = Lists.newArrayList(entries);
yAxisList.add(newEntry);
xAxisList.sort(horizontalEdgeComparator);
yAxisList.sort(verticalEdgeComparator);
List>>> horizontalGroup = Lists.newArrayList();
List>>> verticalGroup = Lists.newArrayList();
for (int k = 0; k < M - 2 * m + 2; k++) {
horizontalGroup.add(
Pair.of(xAxisList.subList(0, m - 1 + k), xAxisList.subList(m - 1 + k, xAxisList.size())));
verticalGroup.add(
Pair.of(yAxisList.subList(0, m - 1 + k), yAxisList.subList(m - 1 + k, yAxisList.size())));
}
int sumXMarginValue = 0;
for (Pair>> pair : horizontalGroup) {
sumXMarginValue += nodeMargin(pair.left, pair.right);
}
int sumYMarginValue = 0;
for (Pair>> pair : verticalGroup) {
sumYMarginValue += nodeMargin(pair.left, pair.right);
}
// Axis split = null;
if (sumXMarginValue < sumYMarginValue) {
// split = Axis.X;
return chooseSplitIndex(horizontalGroup);
} else {
// split = Axis.Y;
return chooseSplitIndex(verticalGroup);
}
}
private Pair>> chooseSplitIndex(List>>> group) {
double minOverlap = 0;
double minArea = 0;
Optional>>> winner = Optional.empty();
// find the Pair of lists with the mim overlap or min area
for (Pair>> pair : group) {
double nodeOverlap = nodeOverlap(pair.left, pair.right);
double nodeArea = nodeArea(pair.left, pair.right);
if (!winner.isPresent()) {
minOverlap = nodeOverlap;
minArea = nodeArea;
winner = Optional.of(pair);
} else if (nodeOverlap == minOverlap) {
// try area
if (nodeArea < minArea) {
minOverlap = nodeOverlap;
minArea = nodeArea;
winner = Optional.of(pair);
}
} else if (nodeOverlap < minOverlap) {
minOverlap = nodeOverlap;
minArea = nodeArea;
winner = Optional.of(pair);
}
}
return winner.orElse(null);
}
@Override
public Optional> chooseSubtree(InnerNode nodeToSplit, T element, Rectangle2D bounds) {
if (nodeToSplit.isLeafChildren()) {
return leastOverlapThenEnlargementThenAreaThenKids(nodeToSplit, bounds); // R*-Tree
} else {
return leastEnlargementThenAreaThenKids(nodeToSplit, bounds);
}
}
// leaf methods
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy