edu.uci.ics.jung.visualization.spatial.rtree.RStarLeafSplitter 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 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.Map;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* splits a Collection of Map.Entries according to R*-Tree semantics
*
* @param
*/
public class RStarLeafSplitter implements LeafSplitter {
private static final Logger log = LoggerFactory.getLogger(RStarLeafSplitter.class);
private final Comparator> horizontalEdgeComparator =
new HorizontalEdgeMapEntryComparator();
private final Comparator> verticalEdgeComparator =
new VerticalEdgeMapEntryComparator();
public Pair> split(
Collection> entries, Map.Entry newEntry) {
return chooseSplitNodes(entries, newEntry);
}
private Pair> chooseSplitNodes(
Collection> entries, Map.Entry newEntry) {
Pair>> pair = chooseSplit(entries, newEntry);
LeafNode leafNodeLeft = LeafNode.create(pair.left);
LeafNode leafNodeRight = LeafNode.create(pair.right);
return Pair.of(leafNodeLeft, leafNodeRight);
}
/**
* R*-Tree method
*
* @param entries
* @param newEntry
* @return
*/
private Pair>> chooseSplit(
Collection> entries, Map.Entry newEntry) {
// make 2 lists to sort
List> xAxisList = Lists.newArrayList(entries);
xAxisList.add(newEntry);
List> yAxisList = Lists.newArrayList(entries);
yAxisList.add(newEntry);
// sort them by min value then max value
xAxisList.sort(horizontalEdgeComparator);
yAxisList.sort(verticalEdgeComparator);
// create containers for the 2 lists to split
List>>> horizontalGroup = Lists.newArrayList();
List>>> verticalGroup = Lists.newArrayList();
// iterate over the lists to create collections with different midpoints
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())));
}
if (log.isTraceEnabled()) {
log.trace("horizontalGroup size is {}", horizontalGroup.size());
for (Pair>> pair : horizontalGroup) {
log.trace("size of pair lists are {} and {}", pair.left.size(), pair.right.size());
}
log.trace("verticalGroup size is {}", verticalGroup.size());
for (Pair>> pair : verticalGroup) {
log.trace("size of pair lists are {} and {}", pair.left.size(), pair.right.size());
}
}
// sum up the margin values from each group
int sumXMarginValue = 0;
for (Pair>> pair : horizontalGroup) {
sumXMarginValue += Node.entryMargin(pair.left, pair.right);
}
int sumYMarginValue = 0;
for (Pair>> pair : verticalGroup) {
sumYMarginValue += Node.entryMargin(pair.left, pair.right);
}
// use the group (horizontal or vertical) that has the smallest margin value su
if (sumXMarginValue < sumYMarginValue) {
// split on x axis
return chooseSplitIndex(horizontalGroup);
} else {
// split on y axis
return chooseSplitIndex(verticalGroup);
}
}
/**
* R*-Tree method
*
* @param group
* @return
*/
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 = Node.entryOverlap(pair.left, pair.right);
double nodeArea = Node.entryArea(pair.left, pair.right);
// no winner yet. first node wins by default
if (!winner.isPresent()) {
minOverlap = nodeOverlap;
minArea = nodeArea;
winner = Optional.of(pair);
} else if (nodeOverlap == minOverlap) {
// tie for overlap, try area
if (nodeArea < minArea) {
minOverlap = nodeOverlap;
minArea = nodeArea;
winner = Optional.of(pair);
}
} else if (nodeOverlap < minOverlap) {
// winner has the smallest overlap
minOverlap = nodeOverlap;
minArea = nodeArea;
winner = Optional.of(pair);
}
}
return winner.orElse(null);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy