//
// GRAB A READER
//
// grab the reader using the default params
final GridCoverage2DReader reader = (GridCoverage2DReader) meta
.getGridCoverageReader(null, WCSUtils.getReaderHints(wcs));
if (reader == null) {
// cannot instantiate a reader, we should return an empty array
return coverageResults.toArray(new GridCoverage2D[] {});
}
// get native elements and then play with the the requested ones
final GeneralEnvelope nativeEnvelope = reader.getOriginalEnvelope();
final CoordinateReferenceSystem nativeCRS = nativeEnvelope
.getCoordinateReferenceSystem();
// get requested crs
String requestedCRS = null;
if (outputCRS != null) {
requestedCRS = outputCRS.getValue();
}
// Compute the target crs, the crs that the final coverage will be served into
final CoordinateReferenceSystem targetCRS;
if (requestedCRS == null) {
targetCRS = reader.getOriginalEnvelope().getCoordinateReferenceSystem();
requestedCRS = CRS.lookupIdentifier(targetCRS, true);
} else {
// FORCE LON,LAT!!!!
targetCRS = CRS.decode(requestedCRS, true);
}
//
// PREPARE DESTINATION DIMENSIONS
//
final Rectangle destinationSize;
final AffineTransform2D destinationG2W;
final GridEnvelope limits = grid.getLimits();
if (limits != null) {
//
// we have imposed limits from the request, we just use them as they are
//
final int[] lowers = limits.getLow().getCoordinateValues();
destinationG2W = null;
destinationSize = new Rectangle(lowers[0], lowers[1], limits.getSpan(0), limits
.getSpan(1));
} else if (grid.getOffsetVector() != null && grid.getOffsetVector().size() > 0) {
//
// we have NO imposed limits from the request, we need to create a proper G2W with
// the RESOLUTION we where given.
// Notice that this is specific to WCS 1.0.0 since the request just allow us to
// specify ResX and ResY
//
final VectorType offsetVector = (VectorType) grid.getOffsetVector().get(0);
final List offsetValues = offsetVector.getValue();
final double resX = (Double) offsetValues.get(0);
final double resY = (Double) offsetValues.get(1);
final DirectPositionType origin_ = grid.getOrigin().getPos();
destinationSize = null;
destinationG2W = new AffineTransform2D(resX, 0d, 0d, resY, (Double) origin_
.getValue().get(0), (Double) origin_.getValue().get(1));
} else {
throw new WcsException("Invalid Grid value:" + grid.toString(),
InvalidParameterValue, null);
}
//
// SETTING COVERAGE READING PARAMS
//
// get the group of parameters tha this reader supports
final ParameterValueGroup readParametersDescriptor = reader.getFormat()
.getReadParameters();
GeneralParameterValue[] readParameters = CoverageUtils.getParameters(
readParametersDescriptor, meta.getParameters());
readParameters = (readParameters != null ? readParameters
: new GeneralParameterValue[0]);
// read grid geometry
final GridGeometry2D requestedGridGeometry;
if (destinationSize != null)
// we have been asked to support a specific raster size, we will set the grid2world
// accordingly
requestedGridGeometry = new GridGeometry2D(new GridEnvelope2D(destinationSize),
getHorizontalEnvelope(requestedEnvelope));
else
// we have been asked to support a specific g2w, we will set the raster size
// accordingly
requestedGridGeometry = new GridGeometry2D(PixelInCell.CELL_CENTER, destinationG2W,
getHorizontalEnvelope(requestedEnvelope), null);
// NOTICE that we always have to respect the provided envelope
final ParameterValue<GeneralGridGeometry> requestedGridGeometryParam = new DefaultParameterDescriptor<GeneralGridGeometry>(
AbstractGridFormat.READ_GRIDGEOMETRY2D.getName().toString(),
GeneralGridGeometry.class, null, requestedGridGeometry).createValue();
GeneralParameterValue[] tmpArray = new GeneralParameterValue[readParameters.length+1];
System.arraycopy(readParameters, 0, tmpArray, 0, readParameters.length);
tmpArray[tmpArray.length-1]=requestedGridGeometryParam;
readParameters=tmpArray;
/*
* Test if the parameter "TIME" is present in the WMS request, and by the way in the
* reading parameters. If it is the case, one can adds it to the request. If an
* exception is thrown, we have nothing to do.
*/
final List<GeneralParameterDescriptor> parameterDescriptors = new ArrayList<GeneralParameterDescriptor>(
readParametersDescriptor.getDescriptor().descriptors());
Set<ParameterDescriptor<List>> dynamicParameters = reader.getDynamicParameters();
parameterDescriptors.addAll(dynamicParameters);
//
// TIME
//
ReaderDimensionsAccessor dimensions = new ReaderDimensionsAccessor(reader);
DimensionInfo timeDimension = meta.getMetadata().get(ResourceInfo.TIME, DimensionInfo.class);
if(timeDimension != null && timeDimension.isEnabled() && dimensions.hasTime()) {
final List<Object> timeValues = new ArrayList<Object>();
if (temporalSubset != null && temporalSubset.getTimePosition() != null) {
// grab the time positions
final EList timePosition = temporalSubset.getTimePosition();
for (Iterator it = timePosition.iterator(); it.hasNext();) {
TimePositionType tp = (TimePositionType) it.next();
Date date = (Date) tp.getValue();
if(date == null) {
date = dimensions.getMaxTime();
}
timeValues.add(date);
}
// grab the time intervals
final EList timePeriods = temporalSubset.getTimePeriod();
for (Iterator it = timePeriods.iterator(); it.hasNext();) {
TimePeriodType tp = (TimePeriodType) it.next();
Date begin = (Date) tp.getBeginPosition().getValue();
Date end = (Date) tp.getEndPosition().getValue();
timeValues.add(new DateRange(begin, end));
}
}
if(timeValues.isEmpty()) {
Date date = dimensions.getMaxTime();
timeValues.add(date);
}
readParameters = CoverageUtils.mergeParameter(parameterDescriptors,
readParameters, timeValues, "TIME", "Time");
}
//
// ELEVATION SUPPORT VIA A SPECIFIC AXIS ELEVATION
//
DimensionInfo elevationDimension = meta.getMetadata().get(ResourceInfo.ELEVATION, DimensionInfo.class);
if(elevationDimension != null && elevationDimension.isEnabled() && dimensions.hasElevation()) {
List<Double> elevations = new ArrayList<Double>();
// extract elevation values
List axisSubset = null;
if (request.getRangeSubset() != null) {
axisSubset = request.getRangeSubset().getAxisSubset();
if (axisSubset.size() > 0) {
for (int a = 0; a < axisSubset.size(); a++) {
AxisSubsetType axis = (AxisSubsetType) axisSubset.get(a);
String axisName = axis.getName();
if (axisName.equalsIgnoreCase(WCSUtils.ELEVATION)) {
if (axis.getSingleValue().size() > 0) {
for (int s = 0; s < axis.getSingleValue().size(); s++) {
elevations.add(Double.parseDouble(((TypedLiteralType) axis
.getSingleValue().get(s)).getValue()));
}
} else if (axis.getInterval().size() > 0) {
IntervalType interval = (IntervalType) axis.getInterval().get(0);
int min = Integer.parseInt(interval.getMin().getValue());
int max = Integer.parseInt(interval.getMax().getValue());
int res = (interval.getRes() != null ? Integer.parseInt(interval
.getRes().getValue()) : 1);
int count = (int) (Math.floor(max - min) / res + 1);
for (int b = 0; b < count; b++) {
elevations.add(new Double(min + b * res));
}
}
}
}
}
}
if(elevations.isEmpty()) {
elevations.add(dimensions.getMinElevation());
}
readParameters = CoverageUtils.mergeParameter(parameterDescriptors,
readParameters, elevations, "ELEVATION", "Elevation");
}
//
// CUSTOM DIMENSION SUPPORT
//
if (request.getRangeSubset() != null) {
EList<?> axisSubset = request.getRangeSubset().getAxisSubset();
final int asCount = axisSubset == null ? 0 : axisSubset.size();
for (int i = 0; i < asCount; i++) {
AxisSubsetType axis = (AxisSubsetType)axisSubset.get(i);
String axisName = axis.getName();
if (!axisName.equalsIgnoreCase(WCSUtils.ELEVATION)) {
Object dimInfo = meta.getMetadata().get(ResourceInfo.CUSTOM_DIMENSION_PREFIX + axisName);
axisName = axisName.toUpperCase(); // using uppercase with imagemosaic
if (dimInfo instanceof DimensionInfo && dimensions.hasDomain(axisName)) {
int valueCount = axis.getSingleValue().size();
if (valueCount > 0) {
List<String> dimValues = new ArrayList<String>(valueCount);
for (int s = 0; s < valueCount; s++) {
dimValues.add(((TypedLiteralType) axis
.getSingleValue().get(s)).getValue());
}
readParameters = CoverageUtils.mergeParameter(parameterDescriptors,
readParameters, dimValues, axisName);
}
}
}
}
}
//
// Check if we have a filter among the params
//
Filter filter = WCSUtils.getRequestFilter();
if(filter != null) {
readParameters = CoverageUtils.mergeParameter(parameterDescriptors,
readParameters, filter, "FILTER", "Filter");
}
// Check we're not going to read too much data
WCSUtils.checkInputLimits(wcs, meta, reader, requestedGridGeometry);
//
// Checking for supported Interpolation Methods
//
Interpolation interpolation = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
String interpolationType = null;
if(request.getInterpolationMethod()!=null){
interpolationType = request.getInterpolationMethod().getLiteral();
if (interpolationType != null) {
if (interpolationType.equalsIgnoreCase("bilinear")) {
interpolation = Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
} else if (interpolationType.equalsIgnoreCase("bicubic")) {
interpolation = Interpolation.getInstance(Interpolation.INTERP_BICUBIC);
} else if (interpolationType.equalsIgnoreCase("nearest neighbor")) {
interpolation = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
}
readParameters = CoverageUtils.mergeParameter(parameterDescriptors,readParameters, interpolation, "interpolation");
if(meta.getStore().getFormat() instanceof ImageMosaicFormat){
GeneralParameterValue[] temp = new GeneralParameterValue[readParameters.length+1];
System.arraycopy(readParameters, 0, temp, 0, readParameters.length);
temp[temp.length-1]=ImageMosaicFormat.INTERPOLATION.createValue();
((ParameterValue)temp[temp.length-1]).setValue(interpolation);
readParameters=temp;
}
}
}
//
// make sure we work in streaming mode
//
// work in streaming fashion when JAI is involved
readParameters = WCSUtils.replaceParameter(readParameters, Boolean.FALSE,
AbstractGridFormat.USE_JAI_IMAGEREAD);
//
// perform read
//
coverage = (GridCoverage2D) reader.read(readParameters);
if ((coverage == null) || !(coverage instanceof GridCoverage2D)) {
throw new IOException("No raster data found in the request (it may be that " +
"the request bbox is outside of the coverage area, or that the filters used " +
"match no portions of it.");
}