use of org.locationtech.geowave.core.store.util.IteratorWrapper in project geowave by locationtech.
the class RasterDataAdapter method convertToIndex.
@Override
public Iterator<GridCoverage> convertToIndex(final Index index, final GridCoverage gridCoverage) {
final HierarchicalNumericIndexStrategy indexStrategy = CompoundHierarchicalIndexStrategyWrapper.findHierarchicalStrategy(index.getIndexStrategy());
if (indexStrategy != null) {
final CoordinateReferenceSystem sourceCrs = gridCoverage.getCoordinateReferenceSystem();
final Envelope sampleEnvelope = gridCoverage.getEnvelope();
final ReferencedEnvelope sampleReferencedEnvelope = new ReferencedEnvelope(new org.locationtech.jts.geom.Envelope(sampleEnvelope.getMinimum(0), sampleEnvelope.getMaximum(0), sampleEnvelope.getMinimum(1), sampleEnvelope.getMaximum(1)), gridCoverage.getCoordinateReferenceSystem());
ReferencedEnvelope projectedReferenceEnvelope = sampleReferencedEnvelope;
final CoordinateReferenceSystem indexCrs = GeometryUtils.getIndexCrs(index);
if (!indexCrs.equals(sourceCrs)) {
try {
projectedReferenceEnvelope = sampleReferencedEnvelope.transform(indexCrs, true);
} catch (TransformException | FactoryException e) {
LOGGER.warn("Unable to transform envelope of grid coverage to Index CRS", e);
}
}
final MultiDimensionalNumericData bounds;
if (indexCrs.equals(GeometryUtils.getDefaultCRS())) {
bounds = IndexUtils.clampAtIndexBounds(GeometryUtils.basicConstraintSetFromEnvelope(projectedReferenceEnvelope).getIndexConstraints(indexStrategy), indexStrategy);
} else {
bounds = IndexUtils.clampAtIndexBounds(GeometryUtils.getBoundsFromEnvelope(projectedReferenceEnvelope), indexStrategy);
}
final GridEnvelope gridEnvelope = gridCoverage.getGridGeometry().getGridRange();
// only one set of constraints..hence reference '0' element
final double[] tileRangePerDimension = new double[bounds.getDimensionCount()];
final Double[] maxValuesPerDimension = bounds.getMaxValuesPerDimension();
final Double[] minValuesPerDimension = bounds.getMinValuesPerDimension();
for (int d = 0; d < tileRangePerDimension.length; d++) {
tileRangePerDimension[d] = ((maxValuesPerDimension[d] - minValuesPerDimension[d]) * tileSize) / gridEnvelope.getSpan(d);
}
final TreeMap<Double, SubStrategy> substrategyMap = new TreeMap<>();
for (final SubStrategy pyramidLevel : indexStrategy.getSubStrategies()) {
final double[] idRangePerDimension = pyramidLevel.getIndexStrategy().getHighestPrecisionIdRangePerDimension();
// to create a pyramid, ingest into each substrategy that is
// lower resolution than the sample set in at least one
// dimension and the one substrategy that is at least the same
// resolution or higher resolution to retain the original
// resolution as well as possible
double maxSubstrategyResToSampleSetRes = -Double.MAX_VALUE;
for (int d = 0; d < tileRangePerDimension.length; d++) {
final double substrategyResToSampleSetRes = idRangePerDimension[d] / tileRangePerDimension[d];
maxSubstrategyResToSampleSetRes = Math.max(maxSubstrategyResToSampleSetRes, substrategyResToSampleSetRes);
}
substrategyMap.put(maxSubstrategyResToSampleSetRes, pyramidLevel);
}
// all entries will be greater than 1 (lower resolution pyramid
// levels)
// also try to find the one entry that is closest to 1.0 without
// going over (this will be the full resolution level)
// add an epsilon to try to catch any roundoff error
final double fullRes = 1.0 + MathUtils.EPSILON;
final Entry<Double, SubStrategy> fullResEntry = substrategyMap.floorEntry(fullRes);
final List<SubStrategy> pyramidLevels = new ArrayList<>();
if (fullResEntry != null) {
pyramidLevels.add(fullResEntry.getValue());
}
if (buildPyramid) {
final NavigableMap<Double, SubStrategy> map = substrategyMap.tailMap(fullRes, false);
pyramidLevels.addAll(map.values());
}
if (pyramidLevels.isEmpty()) {
// this case shouldn't occur theoretically, but just in case,
// make sure the substrategy closest to 1.0 is used
final Entry<Double, SubStrategy> bestEntry = substrategyMap.higherEntry(1.0);
pyramidLevels.add(bestEntry.getValue());
}
return new IteratorWrapper<>(pyramidLevels.iterator(), new MosaicPerPyramidLevelBuilder(bounds, gridCoverage, tileSize, backgroundValuesPerBand, RasterUtils.getFootprint(projectedReferenceEnvelope, gridCoverage), interpolation, projectedReferenceEnvelope.getCoordinateReferenceSystem()));
}
LOGGER.warn("Strategy is not an instance of HierarchicalNumericIndexStrategy : " + index.getIndexStrategy().getClass().getName());
return Collections.<GridCoverage>emptyIterator();
}
Aggregations