use of org.apache.sis.internal.coverage.j2d.TiledImage in project sis by apache.
the class TiledGridCoverage method render.
/**
* Returns a two-dimensional slice of grid data as a rendered image.
*
* @param sliceExtent a subspace of this grid coverage extent, or {@code null} for the whole image.
* @return the grid slice as a rendered image. Image location is relative to {@code sliceExtent}.
*/
@Override
public RenderedImage render(GridExtent sliceExtent) {
final GridExtent available = getGridGeometry().getExtent();
final int dimension = available.getDimension();
if (sliceExtent == null) {
sliceExtent = available;
} else {
final int sd = sliceExtent.getDimension();
if (sd != dimension) {
throw new MismatchedDimensionException(Errors.format(Errors.Keys.MismatchedDimension_3, "sliceExtent", dimension, sd));
}
}
final int[] selectedDimensions = sliceExtent.getSubspaceDimensions(BIDIMENSIONAL);
if (selectedDimensions[1] != 1) {
// TODO
throw new UnsupportedOperationException("Non-horizontal slices not yet implemented.");
}
final RenderedImage image;
try {
// Indices of first tile to read, inclusive.
final int[] tileLower = new int[dimension];
// Indices of last tile to read, exclusive.
final int[] tileUpper = new int[dimension];
// Pixel offset compared to Area Of Interest.
final int[] offsetAOI = new int[dimension];
// Subsampled image size.
final int[] imageSize = new int[dimension];
for (int i = 0; i < dimension; i++) {
// Lowest valid coordinate in subsampled image.
final long min = available.getLow(i);
// Highest valid coordinate, inclusive.
final long max = available.getHigh(i);
// Requested coordinate in subsampled image.
final long aoiMin = sliceExtent.getLow(i);
final long aoiMax = sliceExtent.getHigh(i);
final long tileUp = incrementExact(toTileMatrixCoordinate(Math.min(aoiMax, max), i));
final long tileLo = toTileMatrixCoordinate(Math.max(aoiMin, min), i);
if (tileUp <= tileLo) {
final String message = Errors.getResources(getLocale()).getString(Errors.Keys.IllegalRange_2, aoiMin, aoiMax);
if (aoiMin > aoiMax) {
throw new IllegalArgumentException(message);
} else {
throw new DisjointExtentException(message);
}
}
// Lower and upper coordinates in subsampled image, rounded to integer number of tiles and clipped to available data.
final long lower = /* inclusive */
Math.max(toSubsampledPixel(/* inclusive */
multiplyExact(tileLo, tileSize[i]), i), min);
final long upper = incrementExact(Math.min(toSubsampledPixel(decrementExact(multiplyExact(tileUp, tileSize[i])), i), max));
imageSize[i] = toIntExact(subtractExact(upper, lower));
offsetAOI[i] = toIntExact(subtractExact(lower, aoiMin));
tileLower[i] = toIntExact(subtractExact(tileLo, tmcOfFirstTile[i]));
tileUpper[i] = toIntExact(subtractExact(tileUp, tmcOfFirstTile[i]));
}
/*
* Prepare an iterator over all tiles to read, together with the following properties:
* - Two-dimensional conversion from pixel coordinates to "real world" coordinates.
*/
final AOI iterator = new AOI(tileLower, tileUpper, offsetAOI, dimension);
final Map<String, Object> properties = DeferredProperty.forGridGeometry(getGridGeometry(), selectedDimensions);
if (deferredTileReading) {
image = new TiledDeferredImage(imageSize, tileLower, properties, iterator);
} else {
/*
* If the loading strategy is not `RasterLoadingStrategy.AT_GET_TILE_TIME`, get all tiles
* in the area of interest now. I/O operations, if needed, happen in `readTiles(…)` call.
*/
final Raster[] result = readTiles(iterator);
image = new TiledImage(properties, colors, imageSize[X_DIMENSION], imageSize[Y_DIMENSION], tileLower[X_DIMENSION], tileLower[Y_DIMENSION], result);
}
} catch (Exception e) {
// Too many exception types for listing them all.
throw new CannotEvaluateException(Resources.forLocale(getLocale()).getString(Resources.Keys.CanNotRenderImage_1, getDisplayName()), e);
}
return image;
}
Aggregations