class TmsController {

	@RequestMapping(value = MAPPING + "{layerId}@{crs}/{styleKey}/{tileLevel}/{xIndex}/{yIndex}.{imageFormat}",
			method = RequestMethod.GET)
	public void getVectorTile(@PathVariable String layerId, @PathVariable String styleKey, @PathVariable String crs,
			@PathVariable Integer tileLevel, @PathVariable Integer xIndex, @PathVariable Integer yIndex,
			@RequestParam(required = false) Double resolution, @RequestParam(required = false) String tileOrigin,
			@RequestParam(required = false, defaultValue = "256") int tileWidth,
			@RequestParam(required = false, defaultValue = "256") int tileHeight,
			@RequestParam(required = false, defaultValue = "true") boolean showGeometries,
			@RequestParam(required = false, defaultValue = "false") boolean showLabels,
			@RequestParam(required = false) String filter, HttpServletResponse response) throws Exception {
		try {
			Crs tileCrs = geoService.getCrs2(crs);
			TmsTileMetadata tileMetadata = new TmsTileMetadata();
			tileMetadata.setCode(new TileCode(tileLevel, xIndex, yIndex));
			tileMetadata.setCrs(geoService.getCodeFromCrs(tileCrs));
			tileMetadata.setLayerId(layerId);
			tileMetadata.setPaintGeometries(showGeometries);
			tileMetadata.setPaintLabels(showLabels);
			tileMetadata.setRenderer(TMS_TILE_RENDERER);
			tileMetadata.setTileWidth(tileWidth);
			tileMetadata.setTileHeight(tileHeight);
			// TmsTileMetadata specific
			tileMetadata.setStyleInfo(styleService.retrieveStyle(layerId, styleKey));
			tileMetadata.setFilter(filter);
			// if no origin or resolution, try one of the preconfigured profiles or fall back to
			// the layer bounds
			if (resolution == null || tileOrigin == null) {
				getProfileForLayer(layerId, crs).prepareMetadata(tileMetadata);
			} else {
				tileMetadata.setResolution(resolution);
				tileMetadata.setTileOrigin(parseOrigin(tileOrigin));
			}

			RebuildCacheContainer rcc = new RebuildCacheContainer();
			rcc.setMetadata(tileMetadata);
			PipelineContext context = pipelineService.createContext();
			context.put(PipelineCode.TILE_METADATA_KEY, tileMetadata);
			context.put(PipelineCode.LAYER_ID_KEY, layerId);
			// store container to recover the key
			cachingSupportService.putContainer(context, securityContextAdder, CacheCategory.REBUILD, KEYS,
					RasterizingPipelineCode.IMAGE_ID_KEY, RasterizingPipelineCode.IMAGE_ID_CONTEXT, rcc, null);
			String key = context.get(RasterizingPipelineCode.IMAGE_ID_KEY, String.class);
			renderImage(layerId, key, response);
		} catch (Throwable e) { // NOSONAR need to log all problems
			log.error("Could not rasterize tile " + layerId + "/" + styleKey + "/" + tileLevel + "-" + xIndex + "-"
					+ yIndex + ".png", e);
			response.sendError(HttpServletResponse.SC_NO_CONTENT);
		}
	}

	public  TmsController();

}