Class RenderingData
java.lang.Object
org.apache.sis.internal.map.coverage.RenderingData
- All Implemented Interfaces:
Cloneable
The
RenderedImage to draw in a PlanarCanvas together with transforms from pixel coordinates
to display coordinates. This is a helper class for implementations of stateful renderer.
All grid geometries and transforms managed by this class are two-dimensional.
If the source data have more dimensions, a two-dimensional slice will be taken.
Note on Java2D optimizations
Graphics2D.drawRenderedImage(RenderedImage, AffineTransform) implementation
has the following optimizations:
- If the image is an instance of
BufferedImage, then theAffineTransformcan be anything. Java2D applies interpolations efficiently. - Otherwise if the
AffineTransformscale factors are 1 and the translations are integers, then Java2D invokesRenderedImage.getTile(int, int). It makes possible for us to create a very large image covering the whole data but with tiles computed only when first requested. - Otherwise Java2D invokes
RenderedImage.getData(Rectangle), which is more costly. We try to avoid that situation.
resampledToDisplay transform should stay integers.
Current version of this class does not perform a special case for BufferedImage.
It may not be desirable because interpolations would not be applied in the same way, except
when SIS ImageProcessor would have interpolated RGB color values anyway like Java2D.
We wait to see if this class works well in the general case before doing special cases.
- Since:
- 1.1
- Version:
- 1.3
- Author:
- Martin Desruisseaux (Geomatys)
-
Field Summary
FieldsModifier and TypeFieldDescriptionLoader for reading and caching coverages at various resolutions.final ImageProcessorThe processor that we use for resampling image and recoloring the image. -
Constructor Summary
ConstructorsConstructorDescriptionRenderingData(ErrorHandler errorHandler) Creates a new instance initialized to no image. -
Method Summary
Modifier and TypeMethodDescriptionfinal voidclear()Clears this renderer.clone()Creates new rendering data initialized to a copy of this instance.final GridCoverageensureCoverageLoaded(LinearTransform objectiveToDisplay, org.opengis.geometry.DirectPosition objectivePOI) Loads a new grid coverage if data is null or if the pyramid level changed.final booleanensureImageLoaded(GridCoverage coverage, GridExtent sliceExtent, boolean force) Fetches the rendered image if data is null or is for a different slice.final floatgetDataPixelSize(org.opengis.geometry.DirectPosition objectivePOI) Returns an estimation of the size of data pixels, in objective CRS.final org.opengis.referencing.operation.MathTransformgetDataToObjective(org.opengis.referencing.datum.PixelInCell anchor) Returns the conversion fromdatapixel coordinates to objective CRS.final RenderedImageReturns the image which will be used as the source for rendering operations.final AffineTransformgetTransform(LinearTransform objectiveToDisplay) Gets the transform to use for painting the resampled image.final booleanhasChanged(RenderingData previous) Returns whetherdataGeometryorobjectiveToCenterchanged since a previous rendering.final RectangleobjectiveToData(Rectangle2D bounds) Converts the given bounds from objective coordinates to pixel coordinates in the source coverage.final RenderedImageprefetch(RenderedImage resampledImage, AffineTransform resampledToDisplay, Envelope2D displayBounds) Computes immediately, possibly using many threads, the tiles that are going to be displayed.final RenderedImageresampleAndConvert(RenderedImage recoloredImage, LinearTransform objectiveToDisplay, org.opengis.geometry.DirectPosition objectivePOI) Creates the resampled image, then optionally applies an index color model.final voidsetImageSpace(GridGeometry domain, List<SampleDimension> ranges, int[] xyDims) Sets the input space (domain) and output space (ranges) of the image to be rendered.final voidsetObjectiveCRS(org.opengis.referencing.crs.CoordinateReferenceSystem objectiveCRS) Sets the coordinate reference system of the display.Returns statistics on the source image (computed when first requested, then cached).toString()Returns a string representation for debugging purposes.final booleanvalidateCRS(org.opengis.referencing.crs.CoordinateReferenceSystem objectiveCRS) Verifies if thisRenderingDatacontains an image for the given objective CRS.
-
Field Details
-
coverageLoader
Loader for reading and caching coverages at various resolutions. Required if no image has been explicitly assigned todata. The same instance may be shared by manyRenderingDataobjects. -
processor
The processor that we use for resampling image and recoloring the image.
-
-
Constructor Details
-
RenderingData
Creates a new instance initialized to no image.- Parameters:
errorHandler- where to report errors during tile computations.
-
-
Method Details
-
clear
public final void clear()Clears this renderer. This method should be invoked when the source of data (resource or coverage) changed. ThedisplayToObjectivetransform will be recomputed from scratch when first needed. -
validateCRS
public final boolean validateCRS(org.opengis.referencing.crs.CoordinateReferenceSystem objectiveCRS) Verifies if thisRenderingDatacontains an image for the given objective CRS. If this is not the case, the cached resampled images will need to be discarded.- Parameters:
objectiveCRS- the coordinate reference system to use for rendering.- Returns:
- whether the data are valid for the given objective CRS.
-
setImageSpace
Sets the input space (domain) and output space (ranges) of the image to be rendered. Those values can be initially provided byGridCoverageResourceand replaced later by the actualGridCoveragevalues after coverage loading is completed. It is caller's responsibility to reduce n-dimensional domain to two dimensions.- Parameters:
domain- the two-dimensional grid geometry, ornullif there is no data.ranges- descriptions of bands, ornullif there is no data.xyDims- the dimensions to select in the grid coverage for producing an image. This is an array of length 2 almost always equal to {0,1}.
-
ensureCoverageLoaded
public final GridCoverage ensureCoverageLoaded(LinearTransform objectiveToDisplay, org.opengis.geometry.DirectPosition objectivePOI) throws org.opengis.referencing.operation.TransformException, DataStoreException Loads a new grid coverage if data is null or if the pyramid level changed. It is caller's responsibility to ensure thatcoverageLoaderhas a non-null value and is using the right resource before to invoke this method.Caller should invoke
ensureImageLoaded(GridCoverage, GridExtent, boolean)after this method (this is not done automatically).- Parameters:
objectiveToDisplay- transform used for rendering the coverage on screen.objectivePOI- point where to compute resolution, in coordinates of objective CRS.- Returns:
- the loaded grid coverage, or
nullif no loading has been done (which means that the coverage is unchanged, not that it does not exist). - Throws:
org.opengis.referencing.operation.TransformException- if an error occurred while computing resolution from given transforms.DataStoreException- if an error occurred while loading the coverage.- See Also:
-
ensureImageLoaded
public final boolean ensureImageLoaded(GridCoverage coverage, GridExtent sliceExtent, boolean force) throws org.opengis.util.FactoryException, org.opengis.referencing.operation.TransformException Fetches the rendered image if data is null or is for a different slice. This method needs to be invoked at least once aftersetImageSpace(GridGeometry, List, int[]). Thecoveragegiven in argument should be the value returned by a previous call toensureCoverageLoaded(LinearTransform, DirectPosition), except that it shall not be null.- Parameters:
coverage- the coverage from which to read data. Shall not be null.sliceExtent- a subspace of the grid coverage extent where all dimensions except two have a size of 1 cell. May benullif this grid coverage has only two dimensions with a size greater than 1 cell.force- whether to force data loading. Should betrueifcoveragechanged since last call.- Returns:
- whether the changed.
- Throws:
org.opengis.util.FactoryException- if the CRS changed but the transform from old to new CRS cannot be determined.org.opengis.referencing.operation.TransformException- if an error occurred while transforming coordinates from old to new CRS.
-
getSourceImage
Returns the image which will be used as the source for rendering operations.- Returns:
- the image loaded be
ensureImageLoaded(GridCoverage, GridExtent, boolean).
-
statistics
Returns statistics on the source image (computed when first requested, then cached). There is oneStatisticsinstance per band. This is an information for dynamic stretching of image color ramp. Such recoloring operation should use statistics on the source image instead of statistics on the shown image in order to have stable colors during pans or zooms.The returned map is suitable for use with
ImageProcessor.stretchColorRamp(RenderedImage, Map). The map content is:"statistics": the statistics as aStatistics[]array."sampleDimensions": band descriptions as aList<SampleDimension>.
coverageLoaderis non-null, statistics will be computed on the image with coarsest resolution.- Returns:
- statistics on sample values for each band, in a modifiable map.
- Throws:
DataStoreException- if an error occurred while reading the image at coarsest resolution.
-
setObjectiveCRS
public final void setObjectiveCRS(org.opengis.referencing.crs.CoordinateReferenceSystem objectiveCRS) throws org.opengis.referencing.operation.TransformException Sets the coordinate reference system of the display. This method does nothing if the CRS was already set. It does not verify if CRS is the same, it is caller responsibility to clearchangeOfCRSbefore to invoke this method for forcing a change of CRS.This method updates the following fields only:
changeOfCRSprocessorpositional accuracy hint
- Parameters:
objectiveCRS- value ofCanvas.getObjectiveCRS().- Throws:
org.opengis.referencing.operation.TransformException- if an error occurred while transforming coordinates from grid to new CRS.
-
resampleAndConvert
public final RenderedImage resampleAndConvert(RenderedImage recoloredImage, LinearTransform objectiveToDisplay, org.opengis.geometry.DirectPosition objectivePOI) throws org.opengis.referencing.operation.TransformException Creates the resampled image, then optionally applies an index color model. This method will compute theMathTransformsteps from image coordinate system to display coordinate system if those steps have not already been computed.- Parameters:
recoloredImage-dataor a derived (typically recolored) image.objectiveToDisplay- value ofCanvas.getObjectiveToDisplay().objectivePOI- value ofCanvas.getPointOfInterest(boolean)in objective CRS.- Returns:
- image with operation applied and color ramp stretched.
- Throws:
org.opengis.referencing.operation.TransformException- if an error occurred in the use of "grid to CRS" transforms.
-
prefetch
public final RenderedImage prefetch(RenderedImage resampledImage, AffineTransform resampledToDisplay, Envelope2D displayBounds) Computes immediately, possibly using many threads, the tiles that are going to be displayed. The returned instance should be used only for current rendering event; it should not be cached.- Parameters:
resampledImage- the image computed byresampleAndConvert(…).resampledToDisplay- the transform computed bygetTransform(LinearTransform).displayBounds- size and location of the display device (plus margin), in pixel units.- Returns:
- a temporary image with tiles intersecting the display region already computed.
-
getTransform
Gets the transform to use for painting the resampled image. If the image to draw is an instance ofBufferedImage, then it is okay to have any transform. However for other kinds of image, it is important that the transform has scale factors of 1 and integer translations because Java2D has an optimization which avoid to copy the whole data only for that case.- Parameters:
objectiveToDisplay- the transform from objective CRS to canvas coordinates.- Returns:
- transform from resampled image to canvas (display) coordinates.
-
getDataPixelSize
public final float getDataPixelSize(org.opengis.geometry.DirectPosition objectivePOI) Returns an estimation of the size of data pixels, in objective CRS.- Parameters:
objectivePOI- point of interest in objective CRS.- Returns:
- an estimation of the source pixel size at the given location.
-
getDataToObjective
public final org.opengis.referencing.operation.MathTransform getDataToObjective(org.opengis.referencing.datum.PixelInCell anchor) Returns the conversion fromdatapixel coordinates to objective CRS.- Parameters:
anchor- whether the conversion should start from pixel corner or pixel center.- Returns:
- conversion from data pixel coordinates to objective CRS.
-
objectiveToData
public final Rectangle objectiveToData(Rectangle2D bounds) throws org.opengis.referencing.operation.TransformException Converts the given bounds from objective coordinates to pixel coordinates in the source coverage.- Parameters:
bounds- objective coordinates.- Returns:
- data coverage cell coordinates (in pixels), or
nullif unknown. - Throws:
org.opengis.referencing.operation.TransformException- if the bounds cannot be transformed.
-
hasChanged
Returns whetherdataGeometryorobjectiveToCenterchanged since a previous rendering. This is used for information purposes only.- Parameters:
previous- previous instance ofRenderingData.- Returns:
- whether this
RenderingDatadoes a different rendering than previousRenderingData.
-
clone
Creates new rendering data initialized to a copy of this instance. -
toString
Returns a string representation for debugging purposes. The string content may change in any future version.
-