/**
   * Creates resource URL.
   *
   * @param wmsEntity
   * @param wmsCapabilities
   * @param layers
   * @param centerB
   * @param centerL
   * @param zoomInt
   * @param width
   * @param length
   * @param format
   * @return String with URL.
   * @throws WmsException
   */
  public String getUrl(
      boolean encode,
      WmsEntity wmsEntity,
      WmsCapabilities wmsCapabilities,
      String layers,
      double centerB,
      double centerL,
      int zoomInt,
      int width,
      int length,
      String format)
      throws WmsException {
    try {
      Assert.notNull(wmsEntity, "wmsEntity is null");
      GeoConversion geoConversion = GeoconversionFactory.create(wmsEntity.getSrs());
      Assert.notNull(geoConversion, "geoConversion is null");
      Assert.notNull(centerB, "centerB is null");
      Assert.notNull(centerL, "centerL is null");
      Assert.notNull(zoomInt, "zoomInt is null");
      Assert.notNull(zoomInt, "width is null");
      Assert.notNull(length, "length is null");
      geoConversion.setUrlGivenParams(centerB, centerL, zoomInt, width, length);

      Assert.notNull(wmsCapabilities, "wmsCapabilities is null");
      Assert.notNull(wmsCapabilities.getCapability(), "wmsCapabilities.getCapability() is null");
      Assert.notNull(
          wmsCapabilities.getCapability().getRequest(),
          "wmsCapabilities.getCapability().getRequest() is null");
      Assert.notNull(
          wmsCapabilities.getCapability().getRequest().getGetMap(),
          "wmsCapabilities.getCapability().getRequest().getGetMap() is null");
      Assert.notNull(
          wmsCapabilities.getCapability().getRequest().getGetMap().getDcpType(),
          "wmsCapabilities.getCapability().getRequest().getGetMap().getDcpType() is null");
      Assert.notNull(
          wmsCapabilities.getCapability().getRequest().getGetMap().getDcpType().getHttp(),
          "wmsCapabilities.getCapability().getRequest().getGetMap().getDcpType().getHttp() is null");
      Assert.notNull(
          wmsCapabilities.getCapability().getRequest().getGetMap().getDcpType().getHttp().getGet(),
          "wmsCapabilities.getCapability().getRequest().getGetMap().getDcpType().getHttp().getGet() is null");
      Assert.notNull(
          wmsCapabilities
              .getCapability()
              .getRequest()
              .getGetMap()
              .getDcpType()
              .getHttp()
              .getGet()
              .getOnlineResource(),
          "wmsCapabilities.getCapability().getRequest().getGetMap().getDcpType().getHttp().getGet().getOnlineResource() is null");
      Assert.notNull(
          wmsCapabilities
              .getCapability()
              .getRequest()
              .getGetMap()
              .getDcpType()
              .getHttp()
              .getGet()
              .getOnlineResource()
              .getHref(),
          "wmsCapabilities.getCapability().getRequest().getGetMap().getDcpType().getHttp().getGet().getOnlineResource().getHref() is null");

      Assert.notNull(wmsCapabilities.getService(), "wmsCapabilities.getService() is null");

      String url;
      try {
        if (encode) layers = URLEncoder.encode(layers, "UTF-8");
        url =
            wmsCapabilities
                    .getCapability()
                    .getRequest()
                    .getGetMap()
                    .getDcpType()
                    .getHttp()
                    .getGet()
                    .getOnlineResource()
                    .getHref()
                + "?REQUEST=GetMap"
                + "&SERVICE="
                + wmsCapabilities.getService().getName()
                + "&VERSION="
                + wmsCapabilities.getVersion()
                + "&LAYERS="
                + layers
                + "&STYLES=&FORMAT=image/"
                + format
                + "&BGCOLOR=0xFFFFFF&TRANSPARENT=TRUE"
                + "&"
                + geoConversion.getSrsPart()
                + "&"
                + geoConversion.getConvertedBboxUrlPart()
                + "&"
                + geoConversion.getConvertedWidth()
                + "&"
                + geoConversion.getConvertedHeight();
      } catch (UnsupportedEncodingException e) {
        LOGGER.error("Unsupported Encoding", e);
        throw new WmsException(e.getMessage());
      }

      LOGGER.info("TRANSLATED URL=" + url);
      return url.replace("??", "?");
    } catch (IllegalArgumentException e) {
      LOGGER.error(e);
      if (LOGGER.isDebugEnabled()) LOGGER.debug("WMS: IllegalArgumentException", e);
      throw new WmsException(e.getMessage());
    }
  }
  /**
   * Forwards requests to resource.
   *
   * @param name
   * @param response
   * @param request
   * @param layers
   * @param center
   * @param zoom
   * @param size
   * @param format
   * @throws WmsException
   */
  @RequestMapping(
      value = "/{name}/redirect",
      method = RequestMethod.GET,
      produces = "application/json; charset=utf-8")
  public void forwardWmsMap(
      @PathVariable String name,
      HttpServletResponse response,
      HttpServletRequest request,
      @RequestParam String layers,
      @RequestParam(required = false) String center,
      @RequestParam(required = false) String zoom,
      @RequestParam(required = false) String size,
      @RequestParam(required = false) String format)
      throws WmsException {

    if (LOGGER.isDebugEnabled())
      LOGGER.debug(
          "Received params: \nlayers="
              + layers
              + "\ncenter="
              + center
              + "\nzoom="
              + zoom
              + "\nsize="
              + size
              + "\nformat="
              + format);

    WmsEntity wmsEntity = wmsRepository.findByName(name);
    if (wmsEntity == null) {
      // no WMS entity for given ID
      throw new HttpClientErrorException(
          HttpStatus.BAD_REQUEST, "No WMS entity for name given in URL; name=" + name);
    }

    WmsCapabilities capabilities = wmsService.getCapabilities(wmsEntity.getUrl());
    if (capabilities == null) {
      // no WMS entity for given ID
      throw new HttpClientErrorException(
          HttpStatus.FAILED_DEPENDENCY, "Incorrect answer from WMS resource");
    }
    LayerWrap availableLayers = capabilities.getCapability().getLayerWrap();

    try {
      center =
          center != null
              ? center
              : configService.getStringValueForConfigVariable("wms.params.center");
      zoom = zoom != null ? zoom : configService.getStringValueForConfigVariable("wms.params.zoom");
      size = size != null ? size : configService.getStringValueForConfigVariable("wms.params.size");
      format =
          format != null
              ? format
              : configService.getStringValueForConfigVariable("wms.params.format");

      validate(request, layers, center, zoom, size, format, availableLayers);

      String[] centerParts = center.split(",");
      String[] sizeParts = size.split("x");
      String url =
          getUrl(
              false,
              wmsEntity,
              capabilities,
              layers,
              Double.parseDouble(centerParts[0]),
              Double.parseDouble(centerParts[1]),
              Integer.parseInt(zoom),
              Integer.parseInt(sizeParts[0]),
              Integer.parseInt(sizeParts[1]),
              format);
      response.sendRedirect(url);
    } catch (IOException e) {
      LOGGER.error(e);
      if (LOGGER.isDebugEnabled()) LOGGER.debug("WMS: IOException", e);
      throw new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
    } catch (ConfigException e) {
      LOGGER.error(e);
      if (LOGGER.isDebugEnabled()) LOGGER.debug("WMS: ConfigException", e);
      throw new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
    }
  }