use of org.apache.sis.coverage.grid.GridCoverage in project sis by apache.
the class ValuesUnderCursor method create.
/**
* Creates a new instance for the given canvas and registers as a listener by weak reference.
* Caller must retain the returned reference somewhere, e.g. in {@link StatusBar#sampleValuesProvider}.
*
* @param canvas the canvas for which to create a {@link ValuesUnderCursor}, or {@code null}.
* @return the sample values provider, or {@code null} if none.
*/
static ValuesUnderCursor create(final MapCanvas canvas) {
if (canvas instanceof CoverageCanvas) {
final FromCoverage listener = new FromCoverage();
final ObjectProperty<GridCoverage> coverageProperty = ((CoverageCanvas) canvas).coverageProperty;
coverageProperty.addListener(new WeakChangeListener<>(listener));
final GridCoverage coverage = coverageProperty.get();
if (coverage != null) {
listener.changed(null, null, coverage);
}
return listener;
} else {
// More cases may be added in the future.
}
return null;
}
use of org.apache.sis.coverage.grid.GridCoverage in project sis by apache.
the class CoverageExplorer method getViewAndControls.
/**
* Returns the view-control pair for the given view type.
* The view-control pair is created when first needed.
* Invoking this method may cause data to be loaded in a background thread.
*
* @param type type of view to obtain.
* @param load whether to force loading of data in the new type.
*/
private ViewAndControls getViewAndControls(final View type, boolean load) {
ViewAndControls c = views.get(type);
if (c == null) {
switch(type) {
case TABLE:
c = new GridControls(this);
break;
case IMAGE:
c = new CoverageControls(this);
break;
default:
throw new AssertionError(type);
}
SplitPane.setResizableWithParent(c.view(), Boolean.TRUE);
views.put(type, c);
load = true;
}
/*
* If this explorer is showing a coverage, load data in the newly created view.
* Data may also be loaded because the view was previously unselected (hidden)
* and became selected (visible).
*/
if (load) {
final GridCoverageResource resource = getResource();
final GridCoverage coverage = getCoverage();
if (resource != null || coverage != null) {
c.load(new ImageRequest(resource, coverage));
}
}
return c;
}
use of org.apache.sis.coverage.grid.GridCoverage in project sis by apache.
the class ImageRequest method load.
/**
* Loads the image. If the coverage has more than {@value #BIDIMENSIONAL} dimensions,
* only two of them are taken for the image; for all other dimensions, only the values
* at lowest index will be read.
*
* <p>If the {@link #coverage} field was null, it will be initialized as a side-effect.
* No other fields will be modified.</p>
*
* <h4>Thread safety</h4>
* This class does not need to be thread-safe because it should be used only once in a well-defined life cycle.
* We nevertheless synchronize as a safety (e.g. user could give the same {@code ImageRequest} to two different
* {@link CoverageExplorer} instances). In such case the {@link GridCoverage} will be loaded only once,
* but no caching is done for the {@link RenderedImage} (because usually not needed).
*
* @param task the task invoking this method (for checking for cancellation).
* @return the image loaded from the source given at construction time, or {@code null}
* if the task has been cancelled.
* @throws DataStoreException if an error occurred while loading the grid coverage.
*/
final synchronized RenderedImage load(final FutureTask<?> task) throws DataStoreException {
GridCoverage cv = coverage;
final Long id = LogHandler.loadingStart(resource);
try {
if (cv == null) {
cv = MultiResolutionImageLoader.getInstance(resource, null).getOrLoad(domain, range);
}
coverage = cv = cv.forConvertedValues(true);
if (task.isCancelled()) {
return null;
}
GridExtent ex = sliceExtent;
if (ex == null) {
final GridGeometry gg = cv.getGridGeometry();
if (gg.getDimension() > MultiResolutionImageLoader.BIDIMENSIONAL) {
ex = MultiResolutionImageLoader.slice(gg.derive(), gg.getExtent()).getIntersection();
}
}
return cv.render(ex);
} finally {
LogHandler.loadingStop(id);
}
}
use of org.apache.sis.coverage.grid.GridCoverage in project sis by apache.
the class MultiResolutionCoverageLoader method getOrLoad.
/**
* Returns the coverage at the given level if it is present in the cache, or loads and caches it otherwise.
*
* @param level pyramid level of the desired coverage.
* @return the coverage at the specified level (never null).
* @throws DataStoreException if an error occurred while loading the coverage.
*/
public final GridCoverage getOrLoad(final int level) throws DataStoreException {
synchronized (coverages) {
final Reference<GridCoverage> ref = coverages[level];
if (ref != null) {
final GridCoverage coverage = ref.get();
if (coverage != null)
return coverage;
coverages[level] = null;
}
}
GridGeometry domain = null;
if (resolutionSquared.length != 0) {
final double[] resolutions = resolutionSquared[level].clone();
for (int i = 0; i < resolutions.length; i++) {
resolutions[i] = Math.sqrt(resolutions[i]);
}
final MathTransform gridToCRS = MathTransforms.scale(resolutions);
domain = new GridGeometry(PixelInCell.CELL_CORNER, gridToCRS, areaOfInterest, GridRoundingMode.ENCLOSING);
}
final GridCoverage coverage = resource.read(getReadDomain(domain), readRanges);
/*
* Cache and return the coverage. The returned coverage may be a different instance
* if another coverage has been cached concurrently for the same level.
*/
synchronized (coverages) {
final Reference<GridCoverage> ref = coverages[level];
if (ref != null) {
final GridCoverage c = ref.get();
if (c != null)
return c;
}
coverages[level] = new SoftReference<>(coverage);
}
return coverage;
}
use of org.apache.sis.coverage.grid.GridCoverage in project sis by apache.
the class MultiResolutionCoverageLoader method toString.
/**
* Returns a string representation of this loader for debugging purpose.
* Default implementation formats the resolution thresholds in a table
* with "cached" word after the level having a cached coverage.
*
* @return a string representation of this loader.
*/
@Override
public String toString() {
final int count = getLastLevel();
double delta = magnitude(0);
if (count != 0) {
delta = (magnitude(count) - delta) / count;
}
final int n = Math.max(Math.min(DecimalFunctions.fractionDigitsForDelta(delta, false), 6), 0);
final NumberFormat f = NumberFormat.getInstance();
f.setMinimumFractionDigits(n);
f.setMaximumFractionDigits(n);
final TableAppender table = new TableAppender(" ");
table.setCellAlignment(TableAppender.ALIGN_RIGHT);
for (int level = 0; level <= count; level++) {
final double[] rs = resolutionSquared[level];
for (final double r : rs) {
table.append(f.format(Math.sqrt(r)));
table.nextColumn();
}
final Reference<GridCoverage> ref = coverages[level];
if (ref != null && ref.get() != null) {
// TODO: use !refersTo(null) in JDK16.
table.append("cached");
}
table.nextLine();
}
return table.toString();
}
Aggregations