public ImageFormatter serviceRequest(IMapRequest req) throws IOException, WMSServiceException {
      ImageFormatter formatter = null;
      try {
        Sector reqExtent =
            (SingleFileLayer.this.isElevation)
                ? req.getExtentForElevationRequest()
                : req.getExtent();

        if (null == this.intersects(reqExtent, SingleFileLayer.this.getBBox())) {
          String msg =
              Logging.getMessage(
                  "WMS.Layer.OutOfCoverage",
                  reqExtent.toString(),
                  SingleFileLayer.this.getBBox().toString());
          Logging.logger().severe(msg);
          throw new WMSServiceException(msg);
        }

        if (req.getHeight() <= 0 || req.getWidth() <= 0) {
          String msg =
              Logging.getMessage("generic.InvalidImageSize", req.getWidth(), req.getHeight());
          Logging.logger().severe(msg);
          throw new WMSServiceException(msg);
        }

        DataRaster[] rasters = SingleFileLayer.this.rasters;
        if (null == rasters || 0 == rasters.length) {
          String msg = Logging.getMessage("nullValue.RasterIsNull");
          Logging.logger().severe(msg);
          throw new WMSServiceException(msg);
        }

        double missingDataReplacement = (double) SingleFileLayer.this.nodataReplacement;
        try {
          String s = req.getBGColor();
          if (null != s) {
            missingDataReplacement = Double.parseDouble(s);
          }
        } catch (Exception e) {
          missingDataReplacement = (double) SingleFileLayer.this.nodataReplacement;
        }

        DataRaster raster = rasters[0];
        if (raster instanceof BufferedImageRaster) {
          BufferedImageRaster reqRaster =
              new BufferedImageRaster(
                  req.getWidth(), req.getHeight(), Transparency.TRANSLUCENT, reqExtent);

          raster.drawOnTo(reqRaster);

          BufferedImage img = reqRaster.getBufferedImage();
          this.makeNoDataTransparent(
              img, SingleFileLayer.this.nodataSignal, (short) missingDataReplacement);

          formatter = new BufferedImageFormatter(img);
        } else if (raster instanceof ByteBufferRaster) {
          AVList reqParams = new AVListImpl();

          reqParams.setValue(AVKey.WIDTH, req.getWidth());
          reqParams.setValue(AVKey.HEIGHT, req.getHeight());
          reqParams.setValue(AVKey.SECTOR, reqExtent);
          reqParams.setValue(
              AVKey.BYTE_ORDER, AVKey.LITTLE_ENDIAN); // by default BIL is LITTLE ENDIAN
          reqParams.setValue(AVKey.PIXEL_FORMAT, AVKey.ELEVATION);

          String reqFormat = req.getFormat();
          if (null != reqFormat && reqFormat.endsWith("32")) {
            reqParams.setValue(AVKey.DATA_TYPE, AVKey.FLOAT32);
          } else {
            reqParams.setValue(AVKey.DATA_TYPE, AVKey.INT16);
          }
          reqParams.setValue(AVKey.MISSING_DATA_REPLACEMENT, missingDataReplacement);

          ByteBufferRaster reqRaster =
              new ByteBufferRaster(req.getWidth(), req.getHeight(), reqExtent, reqParams);

          raster.drawOnTo(reqRaster);

          if (SingleFileLayer.this.convertFeetToMeters) {
            this.convertFeetToMeters(reqRaster);
          }

          formatter = new DataRasterFormatter(reqRaster);
        } else {
          String msg =
              Logging.getMessage(
                  "generic.UnrecognizedImageSourceType", raster.getClass().getName());
          Logging.logger().severe(msg);
          throw new WMSServiceException(msg);
        }
      } catch (WMSServiceException wmsse) {
        throw wmsse;
      } catch (Exception ex) {
        Logging.logger()
            .log(
                java.util.logging.Level.SEVERE,
                SingleFileLayer.this.getThreadId() + ex.getMessage(),
                ex);
        // throw new WMSServiceException( s );
      } finally {
      }

      return formatter;
    }
    public ImageFormatter serviceRequest(IMapRequest req) throws IOException, WMSServiceException {
      int reqWidth = 512;
      int reqHeight = 512;

      this.threadId = Thread.currentThread().getId();

      MapSource myMapSource = CompoundImageryGenerator.this.mapSource;
      Logging.logger()
          .info("START CompoundServiceInstance :: serviceRequest( " + myMapSource.getName() + ")");
      try {
        Integer bgColor = CompoundImageryGenerator.DEFAULT_MISSING_DATA_COLOR;
        String bgColorStr = req.getBGColor();
        if (bgColorStr != null && 0 < bgColorStr.length()) {
          try {
            bgColor = Integer.parseInt(bgColorStr, 16);
          } catch (NumberFormatException ex) {
            Logging.logger()
                .severe("Unable to parse BGCOLOR in get imagery request: " + ex.getMessage());
            bgColor = CompoundImageryGenerator.DEFAULT_MISSING_DATA_COLOR;
          }
        } else
          Logging.logger()
              .severe(
                  "BGCOLOR was not specified in the getImagery request: using default " + bgColor);

        req.setBGColor(bgColor.toString());

        reqWidth = (req.getWidth() > 0) ? req.getWidth() : 512;
        req.setWidth(reqWidth);

        reqHeight = (req.getHeight() > 0) ? req.getHeight() : 512;
        req.setHeight(reqHeight);

        Sector reqSector =
            Sector.fromDegrees(
                req.getBBoxYMin(), req.getBBoxYMax(), req.getBBoxXMin(), req.getBBoxXMax());

        double reqPixelSize = reqSector.getDeltaLatDegrees() / reqHeight;
        MapSource reqMapSource = null;

        for (Iterator<MapSource> iterator = myMapSource.getChildren(); iterator.hasNext(); ) {
          MapSource ms = iterator.next();
          MapGenerator gen = (null != ms) ? ms.getMapGenerator() : null;
          if (null == gen) {
            Logging.logger()
                .severe("child mapSource `" + ms.getName() + "` has no associated map generator!");
            continue;
          }
          Sector bbox = gen.getBBox();
          Logging.logger()
              .info(
                  "found child mapSource `" + ms.getName() + "` with generator: " + gen.toString());
          if (!reqSector.intersects(bbox)) {
            Logging.logger()
                .info(
                    "child mapSource`"
                        + ms.getName()
                        + "`: out of coverage, skipping"
                        + bbox.toString());
            continue;
          }

          double genPixelSize = gen.getPixelSize();
          reqMapSource =
              ms; // assumes layers are configured in order according to resolutions from low to
          // high
          Logging.logger()
              .info(
                  "Comparing texel sizes: req = "
                      + reqPixelSize
                      + " , layer's = "
                      + gen.getPixelSize());
          if (reqPixelSize >= genPixelSize) {
            // satisfactory generator found
            break;
          }
        }

        ImageFormatter fmt = null;
        if (null != reqMapSource) {
          try {
            MapGenerator gen = reqMapSource.getMapGenerator();
            Logging.logger()
                .info(
                    "`"
                        + reqMapSource.getName()
                        + "` is executing request; req texel size = "
                        + reqPixelSize
                        + " where layer's texel size = "
                        + gen.getPixelSize());
            fmt = gen.getServiceInstance().serviceRequest(req);
          } catch (Exception ex) {
            Logging.logger().severe("Error while accessing a child mapSource: " + ex.getMessage());
          }
        }

        if (null == fmt) {
          Logging.logger().info("CompoundImageryGenerator will return an empty transparent image");
          fmt = createEmptyImage(req.getWidth(), req.getHeight(), new Color(bgColor));
        }
        return fmt;
      } catch (Exception ex) {
        String msg = Logging.getMessage("WMS.RequestFailed", ex.getMessage());
        Logging.logger().log(java.util.logging.Level.SEVERE, msg, ex);
        throw new WMSServiceException(msg);
      }
    }