* get a decent test coverage on it first as to avoid regressions as much as
* possible
*/
@SuppressWarnings("unchecked")
public void execute(Request req) throws ServiceException {
final GetMapRequest request = (GetMapRequest) req;
assertMandatory(request);
final String outputFormat = request.getFormat();
this.delegate = getDelegate(outputFormat);
// JD:make instance variable in order to release resources later
// final WMSMapContext map = new WMSMapContext();
map = new WMSMapContext(request);
this.delegate.setMapContext(map);
final Envelope env = request.getBbox();
// enable on the fly meta tiling if request looks like a tiled one
if (MetatileMapProducer.isRequestTiled(request, delegate)) {
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.finer("Tiled request detected, activating on the fly meta tiler");
}
this.delegate = new MetatileMapProducer(request, (RasterMapProducer) delegate);
this.delegate.setMapContext(map);
}
final MapLayerInfo[] layers = request.getLayers();
final Style[] styles = request.getStyles().toArray(new Style[] {});
final Filter[] filters = buildLayersFilters(request.getFilter(), layers);
// DJB DONE: replace by setAreaOfInterest(Envelope,
// CoordinateReferenceSystem)
// with the user supplied SRS parameter
// if there's a crs in the request, use that. If not, assume its 4326
final CoordinateReferenceSystem mapcrs = request.getCrs();
// DJB: added this to be nicer about the "NONE" srs.
if (mapcrs != null) {
map.setAreaOfInterest(env, mapcrs);
} else {
map.setAreaOfInterest(env, DefaultGeographicCRS.WGS84);
}
map.setMapWidth(request.getWidth());
map.setMapHeight(request.getHeight());
map.setAngle(request.getAngle());
map.setBgColor(request.getBgColor());
map.setTransparent(request.isTransparent());
map.setBuffer(request.getBuffer());
map.setPaletteInverter(request.getPalette());
// //
//
// Check to see if we really have something to display. Sometimes width
// or height or both are non positivie or the requested area is null.
//
// ///
if ((request.getWidth() <= 0) || (request.getHeight() <= 0)
|| (map.getAreaOfInterest().getLength(0) <= 0)
|| (map.getAreaOfInterest().getLength(1) <= 0)) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER
.fine("We are not going to render anything because either the area is null or the dimensions are not positive.");
}
return;
}
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("setting up map");
}
try { // mapcontext can leak memory -- we make sure we done (see
// finally block)
// track the external caching strategy for any map layers
boolean cachingPossible = "GET".equals(request.getHttpServletRequest().getMethod());
final String featureVersion = request.getFeatureVersion();
int maxAge = Integer.MAX_VALUE;
for (int i = 0; i < layers.length; i++) {
final Style layerStyle = styles[i];
final Filter layerFilter = filters[i];
final MapLayer layer;
if (layers[i].getType() == MapLayerInfo.TYPE_REMOTE_VECTOR) {
cachingPossible = false;
final FeatureSource<SimpleFeatureType, SimpleFeature> source = layers[i]
.getRemoteFeatureSource();
layer = new DefaultMapLayer(source, layerStyle);
layer.setTitle(layers[i].getRemoteFeatureSource().getSchema().getTypeName());
final DefaultQuery definitionQuery = new DefaultQuery(source.getSchema()
.getTypeName());
definitionQuery.setFilter(layerFilter);
definitionQuery.setVersion(featureVersion);
int maxFeatures = request.getMaxFeatures() != null ? request.getMaxFeatures()
: Integer.MAX_VALUE;
definitionQuery.setMaxFeatures(maxFeatures);
layer.setQuery(definitionQuery);
map.addLayer(layer);
} else if (layers[i].getType() == MapLayerInfo.TYPE_VECTOR) {
if (cachingPossible) {
if (layers[i].isCachingEnabled()) {
int nma = layers[i].getCacheMaxAge();
// suppose the map contains multiple cachable
// layers...we can only cache the combined map for
// the
// time specified by the shortest-cached layer.
if (nma < maxAge) {
maxAge = nma;
}
} else {
// if one layer isn't cachable, then we can't cache
// any of them. Disable caching.
cachingPossible = false;
}
}
FeatureSource<? extends FeatureType, ? extends Feature> source;
// /////////////////////////////////////////////////////////
//
// Adding a feature layer
//
// /////////////////////////////////////////////////////////
try {
source = layers[i].getFeatureSource(true);
// NOTE for the feature. Here there was some code that
// sounded like:
// * get the bounding box from feature source
// * eventually reproject it to the actual CRS used for
// map
// * if no intersection, don't bother adding the feature
// source to the map
// This is not an optimization, on the contrary,
// computing the bbox may be
// very expensive depending on the data size. Using
// sigma.openplans.org data
// and a tiled client like OpenLayers, it dragged the
// server to his knees
// and the client simply timed out
} catch (IOException exp) {
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE, new StringBuffer("Getting feature source: ")
.append(exp.getMessage()).toString(), exp);
}
throw new WmsException("Internal error", "", exp);
}
layer = new FeatureSourceMapLayer(source, layerStyle);
layer.setTitle(layers[i].getFeature().getName());
final DefaultQuery definitionQuery = new DefaultQuery(source.getSchema()
.getName().getLocalPart());
definitionQuery.setVersion(featureVersion);
definitionQuery.setFilter(layerFilter);
// check for startIndex + offset
final Integer startIndex = request.getStartIndex();
if (startIndex != null) {
QueryCapabilities queryCapabilities = source.getQueryCapabilities();
if (queryCapabilities.isOffsetSupported()) {
// fsource is required to support
// SortBy.NATURAL_ORDER so we don't bother checking
definitionQuery.setStartIndex(startIndex);
} else {
// source = new PagingFeatureSource(source,
// request.getStartIndex(), limit);
throw new WmsException("startIndex is not supported for the "
+ layers[i].getName() + " layer");
}
}
int maxFeatures = request.getMaxFeatures() != null ? request.getMaxFeatures()
: Integer.MAX_VALUE;
definitionQuery.setMaxFeatures(maxFeatures);
layer.setQuery(definitionQuery);
map.addLayer(layer);
} else if (layers[i].getType() == MapLayerInfo.TYPE_RASTER) {
// /////////////////////////////////////////////////////////
//
// Adding a coverage layer
//
// /////////////////////////////////////////////////////////
AbstractGridCoverage2DReader reader;
reader = (AbstractGridCoverage2DReader) layers[i].getCoverageReader();
if (reader != null) {
// /////////////////////////////////////////////////////////
//
// Setting coverage reading params.
//
// /////////////////////////////////////////////////////////
/*
* 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.
*/
try {
ParameterValue time = reader.getFormat().getReadParameters().parameter(
"TIME");
if (time != null && request.getTime() != null) {
time.setValue(request.getTime());
}
} catch (ParameterNotFoundException p) {
}
// uncomment when the DIM_RANGE vendor parameter will be
// enabled
// try {
// ParameterValue dimRange =
// reader.getFormat().getReadParameters()
// .parameter("DIM_RANGE");
// if (dimRange != null && request.getDimRange() !=
// null) {
// dimRange.setValue(request.getDimRange());
// }
// } catch (ParameterNotFoundException p) {
// }
try {
ParameterValue elevation = reader.getFormat().getReadParameters()
.parameter("ELEVATION");
if (elevation != null && request.getElevation() != null) {
elevation.setValue(request.getElevation().intValue());
}
} catch (ParameterNotFoundException p) {
//ignore?
}
try {
final ParameterValueGroup params = reader.getFormat()
.getReadParameters();
layer = new DefaultMapLayer(FeatureUtilities.wrapGridCoverageReader(
reader, CoverageUtils.getParameters(params, layers[i]
.getCoverage().getParameters())), layerStyle);
layer.setTitle(layers[i].getCoverage().getName());
layer.setQuery(Query.ALL);
map.addLayer(layer);
} catch (IllegalArgumentException e) {
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE, new StringBuffer(
"Wrapping GC in feature source: ").append(
e.getLocalizedMessage()).toString(), e);
}
throw new WmsException(
null,
new StringBuffer(
"Internal error : unable to get reader for this coverage layer ")
.append(layers[i].toString()).toString());
}
} else {
throw new WmsException(null, new StringBuffer(
"Internal error : unable to get reader for this coverage layer ")
.append(layers[i].toString()).toString());
}
}
}
// setup the SLD variable substitution environment
EnvFunction.setLocalValues(request.getEnv());
// /////////////////////////////////////////////////////////
//
// Producing the map in the requested format.
//