use of org.apache.sis.coverage.grid.ImageRenderer in project sis by apache.
the class RenderingData method ensureImageLoaded.
/**
* Fetches the rendered image if {@linkplain #data} is null. This method needs to be invoked at least
* once after {@link #setCoverageSpace(GridGeometry, List)}. The {@code coverage} given in argument
* may be the value returned by {@link #ensureCoverageLoaded(LinearTransform, DirectPosition)}.
*
* @param coverage the coverage from which to read data, or {@code null} if the coverage did not changed.
* @param sliceExtent a subspace of the grid coverage extent where all dimensions except two have a size of 1 cell.
* May be {@code null} if this grid coverage has only two dimensions with a size greater than 1 cell.
* @return whether the {@linkpalin #data} changed.
* @throws FactoryException if the CRS changed but the transform from old to new CRS can not be determined.
* @throws TransformException if an error occurred while transforming coordinates from old to new CRS.
*/
public final boolean ensureImageLoaded(GridCoverage coverage, final GridExtent sliceExtent) throws FactoryException, TransformException {
if (data != null || coverage == null) {
return false;
}
coverage = coverage.forConvertedValues(true);
final GridGeometry old = dataGeometry;
final List<SampleDimension> ranges = coverage.getSampleDimensions();
final RenderedImage image = coverage.render(sliceExtent);
final Object value = image.getProperty(PlanarImage.GRID_GEOMETRY_KEY);
final GridGeometry domain = (value instanceof GridGeometry) ? (GridGeometry) value : new ImageRenderer(coverage, sliceExtent).getImageGeometry(BIDIMENSIONAL);
setCoverageSpace(domain, ranges);
data = image;
/*
* Update the transforms in a way that preserve the current zoom level, translation, etc.
* We compute the change in the "data grid to objective CRS" transforms caused by the change
* in data grid geometry, then we concatenate that change to the existing transforms.
* That way, the objective CRS is kept unchanged.
*/
if (old != null && cornerToObjective != null && objectiveToCenter != null) {
MathTransform toNew = null, toOld = null;
if (old.isDefined(GridGeometry.CRS) && domain.isDefined(GridGeometry.CRS)) {
final CoordinateReferenceSystem oldCRS = old.getCoordinateReferenceSystem();
final CoordinateReferenceSystem newCRS = dataGeometry.getCoordinateReferenceSystem();
if (newCRS != oldCRS) {
// Quick check for the vast majority of cases.
/*
* Transform computed below should always be the identity transform,
* but we check anyway as a safety. A non-identity transform would be
* a pyramid where the CRS changes according the pyramid level.
*/
final GeographicBoundingBox areaOfInterest = Extents.union(dataGeometry.getGeographicExtent().orElse(null), old.getGeographicExtent().orElse(null));
toNew = CRS.findOperation(oldCRS, newCRS, areaOfInterest).getMathTransform();
toOld = toNew.inverse();
}
}
final MathTransform forward = concatenate(PixelInCell.CELL_CORNER, dataGeometry, old, toOld);
final MathTransform inverse = concatenate(PixelInCell.CELL_CENTER, old, dataGeometry, toNew);
cornerToObjective = MathTransforms.concatenate(forward, cornerToObjective);
objectiveToCenter = MathTransforms.concatenate(objectiveToCenter, inverse);
}
return true;
}
use of org.apache.sis.coverage.grid.ImageRenderer in project sis by apache.
the class Raster method render.
/**
* Returns a two-dimensional slice of grid data as a rendered image.
* This returns a view as much as possible; sample values are not copied.
*/
@Override
public RenderedImage render(final GridExtent target) {
final ImageRenderer renderer = new ImageRenderer(this, target);
try {
renderer.setData(data);
if (bandOffsets != null) {
renderer.setInterleavedPixelOffsets(pixelStride, bandOffsets);
}
if (colors != null) {
renderer.setCategoryColors(colors);
}
renderer.setVisibleBand(visibleBand);
return renderer.createImage();
} catch (IllegalArgumentException | ArithmeticException | RasterFormatException e) {
throw new RuntimeException(Resources.format(Resources.Keys.CanNotRender_2, label, e), e);
}
}
Aggregations