public double getPixelSize() {
   // default is 0 after initialization,
   // so if it is not 0, that means it was already calculated
   if (0d == this.pixelSize && null != this.mapSource && null != this.mapSource.getChildren()) {
     try {
       for (Iterator<MapSource> iterator = this.mapSource.getChildren(); iterator.hasNext(); ) {
         MapGenerator gen = null;
         MapSource ms = iterator.next();
         if (null != ms && null != (gen = ms.getMapGenerator())) {
           double d = gen.getPixelSize();
           if (0d == this.pixelSize || d < this.pixelSize) this.pixelSize = d;
         }
       }
     } catch (Exception e) {
       Logging.logger().fine(e.getMessage());
     }
   }
   return this.pixelSize;
 }
  public Sector getBBox() {
    if (null != this.coverage) return this.coverage;

    this.coverage = Sector.EMPTY_SECTOR;
    MapSource myMapSource = this.mapSource;
    for (Iterator<MapSource> iterator = myMapSource.getChildren(); iterator.hasNext(); ) {
      MapSource ms = iterator.next();
      try {
        MapGenerator gen = (null != ms) ? ms.getMapGenerator() : null;
        if (null != gen) {
          Sector bbox = gen.getBBox();
          if (null != bbox) this.coverage = Sector.union(this.coverage, bbox);
        }
      } catch (Exception e) {
        Logging.logger()
            .severe(
                "CompoundImageryGenerator:getBBox: undefined coverage of child map source"
                    + ms.getName());
      }
    }
    return this.coverage;
  }
  public boolean initialize(MapSource mapSource) throws IOException, WMSServiceException {
    boolean success = true; // Assume the best...

    Logging.logger().info("CompoundImageryGenerator:initialize(): started... ");
    try {
      if (null == mapSource) {
        String msg = Logging.getMessage("nullValue.SourceIsNull");
        Logging.logger().severe(msg);
        throw new IllegalArgumentException(msg);
      }
      this.mapSource = mapSource;

      success = true;
      Logging.logger()
          .info("CompoundImageryGenerator:initialize( " + mapSource.getName() + "): status=Done!");
    } catch (Exception ex) {
      success = false;
      Logging.logger().severe("CompoundImageryGenerator:initialize(): Error! " + ex.getMessage());
    }
    return success;
  }
  public boolean initialize(MapSource mapSource) throws IOException, WMSServiceException {
    if (null == mapSource) {
      String msg = Logging.getMessage("nullValue.MapSourceIsNull");
      Logging.logger().severe(msg);
      throw new WMSServiceException(msg);
    }

    this.mapSource = mapSource;

    this.params = mapSource.getParameters();
    if (null == params) {
      String msg = Logging.getMessage("nullValue.AVListIsNull");
      Logging.logger().severe(msg);
      throw new WMSServiceException(msg);
    }

    if (!params.hasKey(AVKey.FILE_NAME)) {
      String msg = Logging.getMessage("nullValue.ParamsIsNull");
      Logging.logger().severe(msg);
      throw new WMSServiceException(msg);
    }

    this.sourceFile = new File(params.getStringValue(AVKey.FILE_NAME));
    if (!this.sourceFile.exists()) {
      String msg = Logging.getMessage("generic.FileNotFound", this.sourceFile.getAbsolutePath());
      Logging.logger().severe(msg);
      throw new FileNotFoundException(msg);
    }

    AVList fileParams = this.params.copy();

    try {
      this.readerFactory =
          (DataRasterReaderFactory)
              WorldWind.createConfigurationComponent(AVKey.DATA_RASTER_READER_FACTORY_CLASS_NAME);
    } catch (Exception e) {
      this.readerFactory = new BasicDataRasterReaderFactory();
    }
    DataRasterReader reader =
        this.readerFactory.findReaderFor(this.sourceFile, fileParams, readers);
    if (reader == null) {
      String msg = Logging.getMessage("nullValue.ReaderIsNull", this.sourceFile);
      Logging.logger().severe(msg);
      throw new WMSServiceException(msg);
    }

    reader.readMetadata(this.sourceFile, fileParams);

    this.params.setValues(fileParams);

    if (!this.params.hasKey(AVKey.SECTOR)) {
      String msg = Logging.getMessage("nullValue.SectorIsNull");
      Logging.logger().severe(msg);
      throw new WMSServiceException(msg);
    }
    this.BBOX = (Sector) this.params.getValue(AVKey.SECTOR);

    if (0d == this.BBOX.getDeltaLatDegrees() || 0d == this.BBOX.getDeltaLonDegrees()) {
      String msg = Logging.getMessage("generic.SectorSizeInvalid");
      Logging.logger().severe(msg);
      throw new WMSServiceException(msg);
    }

    int height = 0;
    if (!this.params.hasKey(AVKey.HEIGHT)) {
      String msg = Logging.getMessage("generic.InvalidHeight", 0);
      Logging.logger().severe(msg);
      throw new WMSServiceException(msg);
    } else {
      Object o = this.params.getValue(AVKey.HEIGHT);
      double d = Double.parseDouble("" + o);
      height = (int) d;
    }

    if (!this.params.hasKey(AVKey.WIDTH)) {
      String msg = Logging.getMessage("generic.InvalidWidth", 0);
      Logging.logger().severe(msg);
      throw new WMSServiceException(msg);
    }

    this.isElevation =
        (this.params.hasKey(AVKey.PIXEL_FORMAT)
            && AVKey.ELEVATION.equals(this.params.getValue(AVKey.PIXEL_FORMAT)));

    if (this.params.hasKey(AVKey.MISSING_DATA_SIGNAL)) {
      try {
        Object o = this.params.getValue(AVKey.MISSING_DATA_SIGNAL);
        double d = Double.parseDouble("" + o);
        this.nodataSignal = (short) d;
      } catch (Exception e) {
        this.nodataSignal = (this.isElevation) ? Short.MIN_VALUE : 0;
      }
    } else {
      this.nodataSignal = (this.isElevation) ? Short.MIN_VALUE : 0;
    }

    if (this.params.hasKey(AVKey.MISSING_DATA_REPLACEMENT)) {
      try {
        Object o = this.params.getValue(AVKey.MISSING_DATA_REPLACEMENT);
        double d = Double.parseDouble("" + o);
        this.nodataReplacement = (short) d;
      } catch (Exception e) {
        Logging.logger().finest(e.getMessage());
        this.nodataReplacement = (this.isElevation) ? Short.MIN_VALUE : 0;
      }
    } else {
      this.nodataReplacement = (this.isElevation) ? Short.MIN_VALUE : 0;
    }

    if (this.isElevation) {
      if (this.params.hasKey(AVKey.ELEVATION_UNIT)) {
        try {
          String unit = this.params.getStringValue(AVKey.ELEVATION_UNIT);
          this.convertFeetToMeters = "feet".equalsIgnoreCase(unit);
        } catch (Exception e) {
          Logging.logger().finest(e.getMessage());
        }
      }
    }

    // if PIXEL_HEIGHT is specified, we are not overriding it
    // because UTM images will have different pixel size
    if (!this.params.hasKey(AVKey.PIXEL_HEIGHT)) {
      this.pixelHeight = this.BBOX.getDeltaLatDegrees() / (double) height;
    } else {
      try {
        Object o = this.params.getValue(AVKey.PIXEL_HEIGHT);
        this.pixelHeight = Double.parseDouble("" + o);
      } catch (Exception e) {
        Logging.logger().finest(e.getMessage());
      }
    }

    this.rasters = reader.read(this.sourceFile, this.params);

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

    return true;
  }
    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);
      }
    }