use of org.opengis.coverage.grid.GridCoverage in project geowave by locationtech.
the class RasterDataAdapter method createWritableSerializer.
@Override
public HadoopWritableSerializer<GridCoverage, GridCoverageWritable> createWritableSerializer() {
return new HadoopWritableSerializer<GridCoverage, GridCoverageWritable>() {
@Override
public GridCoverageWritable toWritable(final GridCoverage entry) {
final Envelope env = entry.getEnvelope();
final DataBuffer dataBuffer = entry.getRenderedImage().copyData(new InternalWritableRaster(sampleModel.createCompatibleSampleModel(tileSize, tileSize), new Point())).getDataBuffer();
Persistable metadata = null;
if (entry instanceof GridCoverage2D) {
final Object metadataObj = ((GridCoverage2D) entry).getProperty(TILE_METADATA_PROPERTY_KEY);
if ((metadataObj != null) && (metadataObj instanceof Persistable)) {
metadata = (Persistable) metadataObj;
}
}
return new GridCoverageWritable(new RasterTile(dataBuffer, metadata), env.getMinimum(0), env.getMaximum(0), env.getMinimum(1), env.getMaximum(1), env.getCoordinateReferenceSystem());
}
@Override
public GridCoverage fromWritable(final GridCoverageWritable writable) {
final ReferencedEnvelope mapExtent = new ReferencedEnvelope(writable.getMinX(), writable.getMaxX(), writable.getMinY(), writable.getMaxY(), writable.getCrs());
try {
return prepareCoverage(writable.getRasterTile(), tileSize, mapExtent);
} catch (final IOException e) {
LOGGER.error("Unable to read raster data", e);
}
return null;
}
};
}
use of org.opengis.coverage.grid.GridCoverage 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();
}
use of org.opengis.coverage.grid.GridCoverage in project geowave by locationtech.
the class GeoWaveRasterReader method loadTiles.
/**
* @param backgroundColor the background color
* @param outputTransparentColor the transparent color
* @param pixelDimension
* @return the gridcoverage as the final result
* @throws IOException
*/
private GridCoverage2D loadTiles(final String coverageName, final Color backgroundColor, final Color outputTransparentColor, Interpolation interpolation, final Rectangle pixelDimension, final GeoWaveRasterReaderState state, final CoordinateReferenceSystem crs, final GeneralEnvelope originalEnvelope) throws IOException {
transformRequestEnvelope(state, crs);
// /////////////////////////////////////////////////////////////////////
if (!state.getRequestEnvelopeXformed().intersects(originalEnvelope, true)) {
LOGGER.warn("The requested envelope does not intersect the envelope of this mosaic");
LOGGER.warn(state.getRequestEnvelopeXformed().toString());
LOGGER.warn(originalEnvelope.toString());
return null;
}
final ImageReadParam readP = new ImageReadParam();
final Integer imageChoice;
final RasterDataAdapter adapter = (RasterDataAdapter) geowaveAdapterStore.getAdapter(getAdapterId(coverageName)).getAdapter();
if (pixelDimension != null) {
try {
synchronized (this) {
if (!setupResolutions(coverageName)) {
LOGGER.warn("Cannot find the overview statistics for the requested coverage name");
return coverageFactory.create(coverageName, RasterUtils.getEmptyImage((int) pixelDimension.getWidth(), (int) pixelDimension.getHeight(), backgroundColor, outputTransparentColor, adapter.getColorModel()), state.getRequestedEnvelope());
}
imageChoice = setReadParams(state.getCoverageName(), OverviewPolicy.getDefaultPolicy(), readP, state.getRequestEnvelopeXformed(), pixelDimension);
}
readP.setSourceSubsampling(1, 1, 0, 0);
} catch (final TransformException e) {
LOGGER.error(e.getLocalizedMessage(), e);
return coverageFactory.create(coverageName, RasterUtils.getEmptyImage((int) pixelDimension.getWidth(), (int) pixelDimension.getHeight(), backgroundColor, outputTransparentColor, adapter.getColorModel()), state.getRequestedEnvelope());
}
} else {
imageChoice = Integer.valueOf(0);
}
final double[][] resolutionLevels = getResolutionLevels(coverageName);
final Histogram histogram;
boolean equalizeHistogram;
if (config.isEqualizeHistogramOverrideSet()) {
equalizeHistogram = config.isEqualizeHistogramOverride();
} else {
equalizeHistogram = adapter.isEqualizeHistogram();
}
if (equalizeHistogram) {
histogram = getHistogram(coverageName, resolutionLevels[imageChoice.intValue()][0], resolutionLevels[imageChoice.intValue()][1]);
} else {
histogram = null;
}
// default to always scale to 8-bit
boolean scaleTo8Bit = true;
final boolean scaleTo8BitSet = config.isScaleTo8BitSet();
if (scaleTo8BitSet) {
scaleTo8Bit = config.isScaleTo8Bit();
}
try (final CloseableIterator<GridCoverage> gridCoverageIt = queryForTiles(pixelDimension, state.getRequestEnvelopeXformed(), resolutionLevels[imageChoice.intValue()][0], resolutionLevels[imageChoice.intValue()][1], adapter)) {
// allow the config to override the WMS request
if (config.isInterpolationOverrideSet()) {
interpolation = config.getInterpolationOverride();
} else // WMS request
if (interpolation == null) {
interpolation = adapter.getInterpolation();
}
final GridCoverage2D result = RasterUtils.mosaicGridCoverages(gridCoverageIt, backgroundColor, outputTransparentColor, pixelDimension, state.getRequestEnvelopeXformed(), resolutionLevels[imageChoice.intValue()][0], resolutionLevels[imageChoice.intValue()][1], adapter.getNoDataValuesPerBand(), state.isAxisSwapped(), coverageFactory, state.getCoverageName(), interpolation, histogram, scaleTo8BitSet, scaleTo8Bit, adapter.getColorModel());
return transformResult(result, pixelDimension, state);
}
}
use of org.opengis.coverage.grid.GridCoverage in project geowave by locationtech.
the class WebMercatorRasterTest method testStoreRetrieve.
@Test
public void testStoreRetrieve() throws IOException, MismatchedDimensionException, NoSuchAuthorityCodeException, FactoryException {
GeoWaveStoreFinder.getRegisteredStoreFactoryFamilies().put("memory", new MemoryStoreFactoryFamily());
final DataStore dataStore = GeoWaveStoreFinder.createDataStore(Collections.EMPTY_MAP);
final int xTiles = 8;
final int yTiles = 8;
final double[] minsPerBand = new double[] { 0, 0, 0 };
final double[] maxesPerBand = new double[] { (xTiles * 3) + (yTiles * 24), (xTiles * 3) + (yTiles * 24), (xTiles * 3) + (yTiles * 24) };
final String[] namesPerBand = new String[] { "b1", "b2", "b3" };
final RasterDataAdapter adapter = RasterUtils.createDataAdapterTypeDouble("test", 3, 64, minsPerBand, maxesPerBand, namesPerBand, new NoDataMergeStrategy());
final Index index = // 3857
new SpatialIndexBuilder().setCrs(CRS_STR).createIndex();
double bounds = CRS.decode(CRS_STR).getCoordinateSystem().getAxis(0).getMaximumValue();
if (!Double.isFinite(bounds)) {
bounds = SpatialDimensionalityTypeProvider.DEFAULT_UNBOUNDED_CRS_INTERVAL;
}
bounds /= 32.0;
dataStore.addType(adapter, index);
for (double xTile = 0; xTile < xTiles; xTile++) {
for (double yTile = 0; yTile < yTiles; yTile++) {
try (Writer<GridCoverage> writer = dataStore.createWriter(adapter.getTypeName())) {
final WritableRaster raster = RasterUtils.createRasterTypeDouble(3, 64);
RasterUtils.fillWithNoDataValues(raster, new double[][] { { (xTile * 3) + (yTile * 24) }, { (xTile * 3) + (yTile * 24) + 1 }, { (xTile * 3) + (yTile * 24) + 2 } });
writer.write(RasterUtils.createCoverageTypeDouble("test", xTile * bounds, (xTile + 1) * bounds, yTile * bounds, (yTile + 1) * bounds, minsPerBand, maxesPerBand, namesPerBand, raster, CRS_STR));
}
}
}
final int[][] grid = new int[8][8];
final GeoWaveRasterReader reader = new GeoWaveRasterReader(GeoWaveRasterConfig.createConfig(Collections.EMPTY_MAP, ""));
for (int xTile = 1; xTile < xTiles; xTile++) {
for (int yTile = 1; yTile < yTiles; yTile++) {
final GeneralEnvelope queryEnvelope = new GeneralEnvelope(new double[] { (xTile - (15 / 64.0)) * bounds, (yTile - (15 / 64.0)) * bounds }, new double[] { // scaling
(xTile + (15 / 64.0)) * bounds, (yTile + (15 / 64.0)) * bounds });
queryEnvelope.setCoordinateReferenceSystem(CRS.decode(CRS_STR));
final GridCoverage gridCoverage = reader.renderGridCoverage("test", new Rectangle(32, 32), queryEnvelope, null, null, null);
final Raster img = gridCoverage.getRenderedImage().getData();
grid[xTile - 1][yTile - 1] = img.getSample(0, 16, 0);
grid[xTile - 1][yTile] = img.getSample(0, 0, 0);
grid[xTile][yTile - 1] = img.getSample(16, 16, 0);
grid[xTile][yTile] = img.getSample(16, 0, 0);
final double expectedMinXMinYValue = ((xTile - 1) * 3) + ((yTile - 1) * 24);
final double expectedMinXMaxYValue = ((xTile - 1) * 3) + (yTile * 24);
final double expectedMaxXMinYValue = (xTile * 3) + ((yTile - 1) * 24);
final double expectedMaxXMaxYValue = (xTile * 3) + (yTile * 24);
for (int x = 0; x < 32; x++) {
for (int y = 0; y < 32; y++) {
for (int b = 0; b < 3; b++) {
double expectedValue;
if (x > 15) {
if (y <= 15) {
expectedValue = expectedMaxXMaxYValue;
} else {
expectedValue = expectedMaxXMinYValue;
}
} else if (y <= 15) {
expectedValue = expectedMinXMaxYValue;
} else {
expectedValue = expectedMinXMinYValue;
}
expectedValue += b;
Assert.assertEquals(String.format("Value didn't match expected at x=%d;y=%d;b=%d", x, y, b), expectedValue, img.getSample(x, y, b), FloatCompareUtils.COMP_EPSILON);
}
}
}
}
}
}
use of org.opengis.coverage.grid.GridCoverage in project geowave by locationtech.
the class RDDUtils method writeRasterToGeoWave.
public static void writeRasterToGeoWave(final SparkContext sc, final Index index, final DataStorePluginOptions outputStoreOptions, final RasterDataAdapter adapter, final JavaRDD<GridCoverage> inputRDD) throws IOException {
// setup the configuration and the output format
final Configuration conf = new org.apache.hadoop.conf.Configuration(sc.hadoopConfiguration());
GeoWaveOutputFormat.setStoreOptions(conf, outputStoreOptions);
GeoWaveOutputFormat.addIndex(conf, index);
GeoWaveOutputFormat.addDataAdapter(conf, adapter);
// create the job
final Job job = new Job(conf);
job.setOutputKeyClass(GeoWaveOutputKey.class);
job.setOutputValueClass(GridCoverage.class);
job.setOutputFormatClass(GeoWaveOutputFormat.class);
// broadcast string names
final ClassTag<String> stringTag = scala.reflect.ClassTag$.MODULE$.apply(String.class);
final Broadcast<String> typeName = sc.broadcast(adapter.getTypeName(), stringTag);
final Broadcast<String> indexName = sc.broadcast(index.getName(), stringTag);
// map to a pair containing the output key and the output value
inputRDD.mapToPair(gridCoverage -> new Tuple2<>(new GeoWaveOutputKey(typeName.value(), indexName.value()), gridCoverage)).saveAsNewAPIHadoopDataset(job.getConfiguration());
}
Aggregations