//
// get the coverage info from the catalog or throw an exception if we don't find it
//
final LayerInfo linfo = NCNameResourceCodec.getCoverage(catalog, request.getCoverageId());
if(linfo == null) {
throw new WCS20Exception("Could not locate coverage " + request.getCoverageId(),
WCS20Exception.WCS20ExceptionCode.NoSuchCoverage, "coverageId");
}
final CoverageInfo cinfo = (CoverageInfo) linfo.getResource();
if(LOGGER.isLoggable(Level.FINE)){
LOGGER.fine("Executing GetCoverage request on coverage :"+linfo.toString());
}
// === k, now start the execution
GridCoverage coverage = null;
try {
// === extract all extensions for later usage
Map<String, ExtensionItemType> extensions = extractExtensions(request);
// === prepare the hints to use
// here I find if I can use overviews and do subsampling
final Hints hints = GeoTools.getDefaultHints();
hints.add(WCSUtils.getReaderHints(wcs));
hints.add(new RenderingHints(JAI.KEY_BORDER_EXTENDER,BorderExtender.createInstance(BorderExtender.BORDER_COPY)));
// hints.add(new RenderingHints(JAI.KEY_REPLACE_INDEX_COLOR_MODEL,Boolean.FALSE));// TODO check interpolation
// get a reader for this coverage
final GridCoverage2DReader reader = (GridCoverage2DReader) cinfo.getGridCoverageReader(
new DefaultProgressListener(),
hints);
WCSDimensionsSubsetHelper helper = parseGridCoverageRequest(cinfo, reader, request, extensions);
GridCoverageRequest gcr = helper.getGridCoverageRequest();
//TODO consider dealing with the Format instance instead of a String parsing or check against WCSUtils.isSupportedMDOutputFormat(String).
final GridCoverageFactory coverageFactory = CoverageFactoryFinder.getGridCoverageFactory(hints);
if (reader instanceof StructuredGridCoverage2DReader && formatSupportMDOutput(request.getFormat())) {
// Split the main request into a List of requests in order to read more coverages to be stacked
final Set<GridCoverageRequest> requests = helper.splitRequestToSet();
if (requests == null || requests.isEmpty()) {
throw new IllegalArgumentException("Splitting requests returned nothing");
} else {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("Splitting request generated " + requests.size() + " sub requests");
}
}
final List<DimensionBean> dimensions = helper.setupDimensions();
final String nativeName = cinfo.getNativeCoverageName();
final String coverageName = nativeName != null ? nativeName : reader.getGridCoverageNames()[0];
final GranuleStackImpl stack = new GranuleStackImpl(coverageName, reader.getCoordinateReferenceSystem(), dimensions);
// Geoserver max memory limit definition
long outputLimit = wcs.getMaxOutputMemory() * 1024;
long inputLimit = wcs.getMaxInputMemory() * 1024;
// Object value used for storing the sum of the output size of each internal coverage
ImageSizeRecorder incrementalOutputSize=new ImageSizeRecorder(outputLimit,false);
// Object used for storing the sum of the output size of each internal coverage
ImageSizeRecorder incrementalInputSize=new ImageSizeRecorder(inputLimit,true);
// Image size estimation
final int numRequests = requests.size();
final Iterator<GridCoverageRequest> requestsIterator = requests.iterator();
GridCoverageRequest firstRequest = requestsIterator.next();
GridCoverage2D firstCoverage = setupCoverage(helper, firstRequest, request, reader, hints, extensions, dimensions,
incrementalOutputSize, incrementalInputSize, coverageFactory);
// check the first coverage memory usage
long actual = incrementalInputSize.finalSize();
// Estimated size
long estimatedSize = actual*numRequests;
//Check if the estimated size is greater than that of the maximum output memory
// Limit check is performed only when the limit is defined
if(outputLimit > 0 && estimatedSize > outputLimit){
throw new WcsException("This request is trying to generate too much data, " +
"the limit is " + formatBytes(outputLimit) + " but the estimated amount of bytes to be " +
"written in the output is " + formatBytes(estimatedSize));
}
// If the estimated size does not exceed the limit, the first coverage is added to the GranuleStack
stack.addCoverage(firstCoverage);
// Get a coverage for each subrequest
while (requestsIterator.hasNext()) {
GridCoverageRequest subRequest = requestsIterator.next();
GridCoverage2D singleCoverage = setupCoverage(helper, subRequest, request, reader, hints, extensions, dimensions,
incrementalOutputSize, incrementalInputSize, coverageFactory);
stack.addCoverage(singleCoverage);
}
coverage = stack;
} else {
// IncrementalSize not used
coverage = setupCoverage(helper, gcr, request, reader, hints, extensions, null, null, null, coverageFactory);
}
} catch(ServiceException e) {
throw e;
} catch(Exception e) {
throw new WCS20Exception("Failed to read the coverage " + request.getCoverageId(), e);
} finally {
// make sure the coverage will get cleaned at the end of the processing
if (coverage != null) {
CoverageCleanerCallback.addCoverages(coverage);
}