/**
   * reads a deegree WCS configuration file and performs a GetCoverage request Steps:
   *
   * <ul>
   *   <li>read configuration file
   *   <li>read a GetCoverage request object
   *   <li>perform the request
   * </ul>
   */
  public void _testGetCoverage3() {
    try {
      WCSConfiguration configuration =
          WCSConfiguration.create(Configuration.getWCSConfigurationURL());
      WCService service = new WCService(configuration);

      Map<String, String> map = new HashMap<String, String>();
      map.put("SERVICE", "WCS");
      map.put("REQUEST", "GetCoverage");
      map.put("VERSION", "1.0.0");
      map.put("COVERAGE", "europe");
      map.put("CRS", "EPSG:4326");
      map.put("BBOX", "-5,40,20,60");
      map.put("WIDTH", "800");
      map.put("HEIGHT", "800");
      map.put("FORMAT", "jpeg");

      // StringBuffer sb = new StringBuffer();
      // sb.append(Configuration.PROTOCOL + "://" + Configuration.HOST)
      // .append(':').append(Configuration.PORT).append('/')
      // .append(Configuration.WCS_WEB_CONTEXT).append('/')
      // .append(Configuration.WCS_SERVLET).append("?service=WCS&")
      // .append("request=GetCoverage&version=1.0.0&coverage=europe&")
      // .append( "crs=EPSG:4326&BBOX=-5,40,20,60&Width=800&height=800&")
      // .append("format=jpeg");
      GetCoverage desc = GetCoverage.create(map);
      ResultCoverage o = (ResultCoverage) service.doService(desc);
      BufferedImage bi = ((AbstractGridCoverage) o.getCoverage()).getAsImage(800, 800);

      FileOutputStream fos =
          new FileOutputStream(Configuration.getWCSBaseDir().getPath() + "/kannweg3.tif");
      ImageUtils.saveImage(bi, fos, "tif", 1);
      fos.close();
    } catch (Exception e) {
      fail(StringTools.stackTraceToString(e));
    }
  }
  /**
   * reads a deegree WCS configuration file and performs a GetCoverage request. same as
   * testGetCoverage1() but uses nameIndexed data source Steps:
   *
   * <ul>
   *   <li>read configuration file
   *   <li>read a GetCoverage request object
   *   <li>perform the request
   * </ul>
   */
  public void _testGetCoverage2() {
    try {
      WCSConfiguration configuration =
          WCSConfiguration.create(Configuration.getWCSConfigurationURL());
      WCService service = new WCService(configuration);

      Map<String, String> map = new HashMap<String, String>();
      map.put("SERVICE", "WCS");
      map.put("REQUEST", "GetCoverage");
      map.put("VERSION", "1.0.0");
      map.put("COVERAGE", "dem");
      map.put("CRS", "EPSG:4326");
      map.put("BBOX", "-122.6261,37.4531,-122.0777,38.0");
      map.put("WIDTH", "828");
      map.put("HEIGHT", "823");
      map.put("FORMAT", "GeoTiff");

      // StringBuffer sb = new StringBuffer();
      // sb.append(Configuration.PROTOCOL + "://" + Configuration.HOST).append(':').append(
      // Configuration.PORT).append('/').append(Configuration.WCS_WEB_CONTEXT).append(
      // '/').append(Configuration.WCS_SERVLET).append("?service=WCS&").append(
      // "request=GetCoverage&version=1.0.0&coverage=dem&").append(
      // "crs=EPSG:4326&BBOX=-122.6261,37.4531,-122.0777,38.0&Width=828&height=823&")
      // .append("format=GeoTiff");
      GetCoverage desc = GetCoverage.create(map);
      ResultCoverage o = (ResultCoverage) service.doService(desc);
      BufferedImage bi = ((AbstractGridCoverage) o.getCoverage()).getAsImage(828, 823);
      LOG.logInfo(o.toString());
      FileOutputStream fos =
          new FileOutputStream(new URL(Configuration.getWCSBaseDir(), "/kannweg2.tif").getFile());
      ImageUtils.saveImage(bi, fos, "tif", 1);
      fos.close();
    } catch (Exception e) {
      fail(StringTools.stackTraceToString(e));
    }
  }
  /**
   * validates the passed <tt>GetCoverage</tt> against the passed <tt>WCSCapabilities</tt>
   *
   * @param capabilities
   * @param request
   * @throws InvalidParameterValueException
   */
  private static void validate(WCSCapabilities capabilities, GetCoverage request)
      throws InvalidParameterValueException {
    String coverage = request.getSourceCoverage();
    ContentMetadata cm = capabilities.getContentMetadata();
    // is coverage known by the WCS?
    CoverageOfferingBrief cob = cm.getCoverageOfferingBrief(coverage);
    if (cob == null) {
      throw new InvalidParameterValueException(
          "Coverage: " + coverage + " is not known by the WCS");
    }

    URL url = cob.getConfiguration();
    CoverageDescription cd = null;
    try {
      cd = CoverageDescription.createCoverageDescription(url);
    } catch (Exception e) {
      LOG.logError(e.getMessage(), e);
      throw new InvalidParameterValueException(e.getMessage());
    }
    CoverageOffering co = cd.getCoverageOffering(coverage);
    if (co == null) {
      throw new InvalidParameterValueException(
          "no coverage descrition " + "available for requested coverage: " + coverage);
    }
    // validate requested format
    String format = request.getOutput().getFormat().getCode();
    SupportedFormats sf = co.getSupportedFormats();
    CodeList[] codeList = sf.getFormats();
    if (!validate(codeList, null, format)) {
      throw new InvalidParameterValueException(
          "requested format: " + format + " is not known by the WCS for coverage:" + coverage);
    }
    // validate requested response CRS
    String crs = request.getOutput().getCrs().getCode();
    URI codeSpace = request.getOutput().getCrs().getCodeSpace();
    String space = null;
    if (codeSpace != null) {
      space = codeSpace.toString();
    }

    CodeList[] rrcrs = co.getSupportedCRSs().getRequestResponseSRSs();
    CodeList[] rescrs = co.getSupportedCRSs().getResponseSRSs();
    if (!validate(rrcrs, space, crs) && !validate(rescrs, space, crs)) {
      throw new InvalidParameterValueException(
          "requested response CRS: "
              + crs
              + " is not known by the WCS "
              + "for coverage:"
              + coverage);
    }
    // validate requested CRS
    crs = request.getDomainSubset().getRequestSRS().getCode();
    codeSpace = request.getDomainSubset().getRequestSRS().getCodeSpace();
    if (codeSpace != null) {
      space = codeSpace.toString();
    }
    CodeList[] reqcrs = co.getSupportedCRSs().getRequestSRSs();

    if (!validate(rrcrs, space, crs) && !validate(reqcrs, space, crs)) {
      throw new InvalidParameterValueException(
          "requested request CRS: " + crs + " is not known by the WCS for coverage:" + coverage);
    }
    // validate requested envelope
    Envelope envelope = request.getDomainSubset().getSpatialSubset().getEnvelope();
    LonLatEnvelope llEnv = cob.getLonLatEnvelope();
    Envelope[] domEnvs = co.getDomainSet().getSpatialDomain().getEnvelops();

    try {
      if (!intersects(envelope, request.getDomainSubset().getRequestSRS(), domEnvs, llEnv)) {
        throw new InvalidParameterValueException(
            "requested BBOX: doesn't intersect "
                + " the area of the requested coverage: "
                + coverage);
      }
    } catch (UnknownCRSException e) {
      throw new InvalidParameterValueException(e);
    }
  }