//
// PREPARE DOMAIN SUBSET ELEMENT
//
final DomainSubsetType domainSubset = request.getDomainSubset();
// time
final TimeSequenceType temporalSubset = domainSubset.getTemporalSubset();
// spatial
final SpatialSubsetType spatialSubset = domainSubset.getSpatialSubset();
final EList grids = spatialSubset.getGrid();
if (grids.size() == 0)
throw new IllegalArgumentException(
"Invalid number of Grid for spatial subsetting was set:" + grids.size());
final RectifiedGridType grid = (RectifiedGridType) grids.get(0);
final List envelopes = spatialSubset.getEnvelope();
if (envelopes.size() == 0)
throw new IllegalArgumentException(
"Invalid number of Envelope for spatial subsetting was set:"
+ envelopes.size());
final GeneralEnvelope requestedEnvelope = (GeneralEnvelope) envelopes.get(0);
final OutputType output = request.getOutput();
if (output == null)
throw new IllegalArgumentException("Output type was null");
final CodeType outputCRS = output.getCrs();
final int dimension = grid.getDimension().intValue();
// WE SUPPORT 3D DIMENSION ONLY VIA A BAND
if (dimension == 3)
throw new WcsException(
"We support a third dimension only via a specifica Axis in Range",
InvalidParameterValue, null);
//
// 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));