uk.ac.ceh.dynamo.GridMapController Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dynamo-mapping Show documentation
Show all versions of dynamo-mapping Show documentation
A Spring MVC plugin for creating dynamic MapServer maps with freemarker templates
package uk.ac.ceh.dynamo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.InvocableHandlerMethod;
import org.springframework.web.method.support.ModelAndViewContainer;
/**
*
* @author Chris Johnson
*/
public class GridMapController {
private final GridMap annotation;
private final Map> providers;
private final ServletContext context;
private final GridMapRequestFactory gridMapHelper;
/**
* Constructor for the grid mapping controller.
* @param annotation The annotation which is present on the request mapped method
* which this controller will use as its mapping endpoint
* @param providers A map of method types to the providers for that type
* @param gridMapHelper The grid map helper to use for grid mapping
* @param context The context this controller is running in
* @see GridMapRequestMappingHandlerMapping
*/
public GridMapController(GridMap annotation,
Map> providers,
GridMapRequestFactory gridMapHelper,
ServletContext context) {
this.annotation = annotation;
this.providers = providers;
this.gridMapHelper = gridMapHelper;
this.context = context;
}
@RequestMapping({"map", "legend"})
public void map(NativeWebRequest request, ModelAndViewContainer mavContainer, HttpServletResponse response) throws NoSuchMethodException, Exception {
String uri = request.getNativeRequest(HttpServletRequest.class).getRequestURI();
//Obtain the end part of the requested path until the last '/'. Lookup this
//in the GridMapMethod enum
GridMapMethod gridMapMethod = GridMapMethod.valueOf(uri.substring(uri.lastIndexOf('/') + 1).toUpperCase());
InterceptedHttpServletRequest newRequest = provideForRequest(gridMapMethod, request, mavContainer);
//Strip the map method part of the url and the servlet context, this is the address
//to proxy with the wrapped HttpServletRequest
String host = uri.substring(context.getContextPath().length(), uri.lastIndexOf('/'));
RequestDispatcher requestDispatcher = context.getRequestDispatcher(host);
requestDispatcher.forward(newRequest, response);
}
/*
* The following resource will handle resolution requests and produce a
* map whose keys are the zoom levels for the grid map and values are arrays of
* the valid resolutions for the respective zoom level
*/
@RequestMapping("resolutions")
@ResponseBody
public Map> resolutions(HttpServletRequest request,
@RequestParam(value = "feature", required = false) String featureId,
@RequestParam(value = "nationalextent", required = false) String nationalExtent) {
Map> toReturn = new HashMap<>();
BoundingBox featureToFocusOn = gridMapHelper.getFeatureToFocusOn(featureId, nationalExtent, annotation);
for(int i=1; i<=GridMapRequestFactory.ZOOM_LEVELS; i++) {
toReturn.put(Integer.toString(i), getAvailableResolutionListForImagesSize(
annotation.layers(), featureToFocusOn, i
));
}
return toReturn;
}
private InterceptedHttpServletRequest provideForRequest(GridMapMethod type, NativeWebRequest request, ModelAndViewContainer mavContainer) throws Exception {
return new InterceptedHttpServletRequest(
request.getNativeRequest(HttpServletRequest.class),
provideFor(type, request, mavContainer));
}
private Map provideFor(GridMapMethod type, NativeWebRequest request, ModelAndViewContainer mavContainer) throws Exception {
Map toReturn = new HashMap<>();
GridMap.GridLayer resolution = getResolution(annotation, request.getParameter("resolution"));
for(InvocableHandlerMethod handler: providers.get(type)) {
Map providersResponse = (Map)handler.invokeForRequest(request, mavContainer, annotation, resolution, gridMapHelper);
toReturn.putAll(providersResponse);
}
return toReturn;
}
private List getAvailableResolutionListForImagesSize(GridMap.GridLayer[] layers, BoundingBox featureToFocusOn, int imageSize){
List toReturn = new ArrayList<>();
for(GridMap.GridLayer currLayer : layers) {
if(gridMapHelper.getGridMapRequest(featureToFocusOn, currLayer.resolution(), imageSize).isValidRequest()) {
toReturn.add(currLayer.name());
}
}
return toReturn;
}
/**
* Obtain the selected GridLayer from an instance of GridMap and a requested
* resolution
* @param annotation The configuration for the gridmap service
* @param resolution The requested resolution which should be defined in the
* layers section of the grid map annotation. If null, return the default
* GridMap.GridLayer as defined in the annotation
* @return The requested GridLayer
*/
public static GridMap.GridLayer getResolution(GridMap annotation, String resolution) {
//Work out which layer to use. Either one requested or this Grid maps default
String resolutionToUse = (resolution != null) ? resolution : annotation.defaultLayer();
//Find the layer which corresponds to this resolution
for(GridMap.GridLayer currLayer : annotation.layers()) {
if(resolutionToUse.equals(currLayer.name())) {
return currLayer;
}
}
throw new IllegalArgumentException("This map service does not support the resolution " + resolutionToUse);
}
}