//
// GRAB A READER
//
// grab the reader using the default params
final AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) 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);
//
// ELEVATION SUPPORT VIA A SPECIFIC AXIS ELEVATION
//
double[] elevations = null;
// 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) {
elevations = new double[axis.getSingleValue().size()];
for (int s = 0; s < axis.getSingleValue().size(); s++) {
elevations[s] = 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);
elevations = new double[(int) (Math.floor(max - min) / res + 1)];
for (int b = 0; b < elevations.length; b++)
elevations[b] = (min + b * res);
}
}
}
}
}
// if(dimension==3&&elevationLevels>0)
// {
// // compute the elevation levels, we have elevationLevels values
// elevations=new double[elevationLevels];
//
// elevations[0]=requestedEnvelope.getLowerCorner().getOrdinate(2); // TODO put the
// extrema
// elevations[elevationLevels-1]=requestedEnvelope.getUpperCorner().getOrdinate(2);
// if(elevationLevels>2){
// final int adjustedLevelsNum=elevationLevels-1;
// double step = (elevations[elevationLevels-1]-elevations[0])/adjustedLevelsNum;
// for(int i=1;i<adjustedLevelsNum;i++)
// elevations[i]=elevations[i-1]+step;
// }
// }
//
// TIME
//
final List<Date> timeValues = new LinkedList<Date>();
// sequence of timepositions
if (temporalSubset != null && temporalSubset.getTimePosition() != null
&& temporalSubset.getTimePosition().size() > 0) {
final EList timePositionLists = temporalSubset.getTimePosition();
for (Iterator it = timePositionLists.iterator(); it.hasNext();) {
TimePositionTypeImpl tp = (TimePositionTypeImpl) it.next();
timeValues.add((Date) tp.getValue());
}
}
// else if (temporalSubset!=null&&temporalSubset.getTimePeriod() != null
// &&temporalSubset.getTimePeriod().size() > 0) {
// final EList timePeriodLists =temporalSubset.getTimePeriod();
// for (Iterator it =domainSubset.getTemporalSubset().getTimePeriod().iterator();
// it.hasNext(); ) {
// TimePeriodType tp = (TimePeriodType) it.next();
// Date beginning = (Date)tp.getBeginPosition().getValue();
// Date ending = (Date)tp.getEndPosition().getValue();
//
// timeValues.add(beginning);
// timeValues.add(ending);
// }
// }
//
// 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 se 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();
/*
* 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 = readParametersDescriptor
.getDescriptor().descriptors();
ParameterValue time = null;
boolean hasTime = timeValues.size() > 0;
ParameterValue elevation = null;
boolean hasElevation = elevations != null && !Double.isNaN(elevations[0]);
if (hasElevation || hasTime) {
for (GeneralParameterDescriptor pd : parameterDescriptors) {
final String code = pd.getName().getCode();
//
// TIME
//
if (code.equalsIgnoreCase("TIME")) {
time = (ParameterValue) pd.createValue();
time.setValue(timeValues);
}
//
// ELEVATION
//
if (code.equalsIgnoreCase(WCSUtils.ELEVATION)) {
elevation = (ParameterValue) pd.createValue();
elevation.setValue(elevations[0]);
}
// leave?
if ((hasElevation && elevation != null && hasTime && time != null)
|| !hasElevation && hasTime && time != null || hasElevation
&& elevation != null && !hasTime)
break;
}
}
//
// add read parameters
//
int addedParams = 1 + (hasTime ? 1 : 0) + (hasElevation ? 1 : 0);
// add to the list
GeneralParameterValue[] readParametersClone = new GeneralParameterValue[readParameters.length
+ addedParams--];
System.arraycopy(readParameters, 0, readParametersClone, 0, readParameters.length);
readParametersClone[readParameters.length + addedParams--] = requestedGridGeometryParam;
if (hasTime)
readParametersClone[readParameters.length + addedParams--] = time;
if (hasElevation)
readParametersClone[readParameters.length + addedParams--] = elevation;
readParameters = readParametersClone;
// Check we're not going to read too much data
WCSUtils.checkInputLimits(wcs, meta, reader, requestedGridGeometry);
//
// perform read
//
coverage = (GridCoverage2D) reader.read(readParameters);
if ((coverage == null) || !(coverage instanceof GridCoverage2D)) {
throw new IOException("The requested coverage could not be found.");
}
// double check what we have loaded