use of com.google.uzaygezen.core.ranges.BigIntegerRange in project geowave by locationtech.
the class UnboundedHilbertSFCOperations method decomposeRange.
@Override
public RangeDecomposition decomposeRange(final NumericData[] rangePerDimension, final CompactHilbertCurve compactHilbertCurve, final SFCDimensionDefinition[] dimensionDefinitions, final int totalPrecision, final int maxFilteredIndexedRanges, final boolean removeVacuum, final boolean overInclusiveOnEdge) {
// List of query range minimum
// and
// maximum
// values
final List<BigInteger> minRangeList = new ArrayList<>();
final List<BigInteger> maxRangeList = new ArrayList<>();
final BigIntegerContent zero = new BigIntegerContent(BigInteger.valueOf(0L));
final List<BigIntegerRange> region = new ArrayList<>(dimensionDefinitions.length);
for (int d = 0; d < dimensionDefinitions.length; d++) {
final BigInteger normalizedMin = normalizeDimension(dimensionDefinitions[d], rangePerDimension[d].getMin(), binsPerDimension[d], true, overInclusiveOnEdge);
BigInteger normalizedMax = normalizeDimension(dimensionDefinitions[d], rangePerDimension[d].getMax(), binsPerDimension[d], false, overInclusiveOnEdge);
if (normalizedMin.compareTo(normalizedMax) > 0) {
// if they're both equal, which is possible because we treat max
// as exclusive, set bin max to bin min (ie. treat it as
// inclusive in this case)
normalizedMax = normalizedMin;
}
minRangeList.add(normalizedMin);
maxRangeList.add(normalizedMax);
region.add(BigIntegerRange.of(normalizedMin, normalizedMax.add(BigInteger.ONE)));
}
final BigInteger minQuadSize = getMinimumQuadSize(minRangeList, maxRangeList);
final RegionInspector<BigIntegerRange, BigIntegerContent> regionInspector = SimpleRegionInspector.create(ImmutableList.of(region), new BigIntegerContent(minQuadSize), Functions.<BigIntegerRange>identity(), BigIntegerRangeHome.INSTANCE, zero);
final PlainFilterCombiner<BigIntegerRange, BigInteger, BigIntegerContent, BigIntegerRange> intervalCombiner = new PlainFilterCombiner<>(BigIntegerRange.of(0, 1));
final QueryBuilder<BigIntegerRange, BigIntegerRange> queryBuilder = BacktrackingQueryBuilder.create(regionInspector, intervalCombiner, maxFilteredIndexedRanges, removeVacuum, BigIntegerRangeHome.INSTANCE, zero);
synchronized (compactHilbertCurve) {
compactHilbertCurve.accept(new ZoomingSpaceVisitorAdapter(compactHilbertCurve, queryBuilder));
}
// com.google.uzaygezen.core.Query<LongRange, LongRange> hilbertQuery =
// queryBuilder.get();
final List<FilteredIndexRange<BigIntegerRange, BigIntegerRange>> hilbertRanges = queryBuilder.get().getFilteredIndexRanges();
final ByteArrayRange[] sfcRanges = new ByteArrayRange[hilbertRanges.size()];
final int expectedByteCount = (int) Math.ceil(totalPrecision / 8.0);
if (expectedByteCount <= 0) {
// special case for no precision
return new RangeDecomposition(new ByteArrayRange[] { new ByteArrayRange(new byte[0], new byte[0]) });
}
for (int i = 0; i < hilbertRanges.size(); i++) {
final FilteredIndexRange<BigIntegerRange, BigIntegerRange> range = hilbertRanges.get(i);
// sanity check that values fit within the expected range
// it seems that uzaygezen can produce a value at 2^totalPrecision
// rather than 2^totalPrecision - 1
final BigInteger startValue = clamp(minHilbertValue, maxHilbertValue, range.getIndexRange().getStart());
final BigInteger endValue = clamp(minHilbertValue, maxHilbertValue, range.getIndexRange().getEnd().subtract(BigInteger.ONE));
// make sure its padded if necessary
final byte[] start = HilbertSFC.fitExpectedByteCount(expectedByteCount, startValue.toByteArray());
// make sure its padded if necessary
final byte[] end = HilbertSFC.fitExpectedByteCount(expectedByteCount, endValue.toByteArray());
sfcRanges[i] = new ByteArrayRange(start, end);
}
final RangeDecomposition rangeDecomposition = new RangeDecomposition(sfcRanges);
return rangeDecomposition;
}
Aggregations