public void write(DataRaster raster) throws IOException, IllegalArgumentException {
    if (null == raster) {
      String msg = Logging.getMessage("nullValue.RasterIsNull");
      Logging.logger().finest(msg);
      throw new IllegalArgumentException(msg);
    }

    if (!(raster.getWidth() > 0)) {
      String msg = Logging.getMessage("generic.InvalidWidth", raster.getWidth());
      Logging.logger().finest(msg);
      throw new IllegalArgumentException(msg);
    }

    if (!(raster.getHeight() > 0)) {
      String msg = Logging.getMessage("generic.InvalidHeight", raster.getHeight());
      Logging.logger().finest(msg);
      throw new IllegalArgumentException(msg);
    }

    if (raster instanceof BufferedImageRaster) {
      this.write(((BufferedImageRaster) raster).getBufferedImage(), raster);
    } else if (raster instanceof BufferWrapperRaster) {
      this.writeRaster((BufferWrapperRaster) raster);
    }
  }
    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;
    }
    protected void importImagery() {
      try {
        // Read the data and save it in a temp file.
        File sourceFile = ExampleUtil.saveResourceToTempFile(IMAGE_PATH, ".tif");

        // Create a raster reader to read this type of file. The reader is created from the
        // currently
        // configured factory. The factory class is specified in the Configuration, and a different
        // one can be
        // specified there.
        DataRasterReaderFactory readerFactory =
            (DataRasterReaderFactory)
                WorldWind.createConfigurationComponent(AVKey.DATA_RASTER_READER_FACTORY_CLASS_NAME);
        DataRasterReader reader = readerFactory.findReaderFor(sourceFile, null);

        // Before reading the raster, verify that the file contains imagery.
        AVList metadata = reader.readMetadata(sourceFile, null);
        if (metadata == null || !AVKey.IMAGE.equals(metadata.getStringValue(AVKey.PIXEL_FORMAT)))
          throw new Exception("Not an image file.");

        // Read the file into the raster. read() returns potentially several rasters if there are
        // multiple
        // files, but in this case there is only one so just use the first element of the returned
        // array.
        DataRaster[] rasters = reader.read(sourceFile, null);
        if (rasters == null || rasters.length == 0)
          throw new Exception("Can't read the image file.");

        DataRaster raster = rasters[0];

        // Determine the sector covered by the image. This information is in the GeoTIFF file or
        // auxiliary
        // files associated with the image file.
        final Sector sector = (Sector) raster.getValue(AVKey.SECTOR);
        if (sector == null) throw new Exception("No location specified with image.");

        // Request a sub-raster that contains the whole image. This step is necessary because only
        // sub-rasters
        // are reprojected (if necessary); primary rasters are not.
        int width = raster.getWidth();
        int height = raster.getHeight();

        // getSubRaster() returns a sub-raster of the size specified by width and height for the
        // area indicated
        // by a sector. The width, height and sector need not be the full width, height and sector
        // of the data,
        // but we use the full values of those here because we know the full size isn't huge. If it
        // were huge
        // it would be best to get only sub-regions as needed or install it as a tiled image layer
        // rather than
        // merely import it.
        DataRaster subRaster = raster.getSubRaster(width, height, sector, null);

        // Tne primary raster can be disposed now that we have a sub-raster. Disposal won't affect
        // the
        // sub-raster.
        raster.dispose();

        // Verify that the sub-raster can create a BufferedImage, then create one.
        if (!(subRaster instanceof BufferedImageRaster))
          throw new Exception("Cannot get BufferedImage.");
        BufferedImage image = ((BufferedImageRaster) subRaster).getBufferedImage();

        // The sub-raster can now be disposed. Disposal won't affect the BufferedImage.
        subRaster.dispose();

        // Create a SurfaceImage to display the image over the specified sector.
        final SurfaceImage si1 = new SurfaceImage(image, sector);

        // On the event-dispatch thread, add the imported data as an SurfaceImageLayer.
        SwingUtilities.invokeLater(
            new Runnable() {
              public void run() {
                // Add the SurfaceImage to a layer.
                SurfaceImageLayer layer = new SurfaceImageLayer();
                layer.setName("Imported Surface Image");
                layer.setPickEnabled(false);
                layer.addRenderable(si1);

                // Add the layer to the model and update the application's layer panel.
                insertBeforeCompass(AppFrame.this.getWwd(), layer);
                AppFrame.this.getLayerPanel().update(AppFrame.this.getWwd());

                // Set the view to look at the imported image.
                ExampleUtil.goTo(getWwd(), sector);
              }
            });
      } catch (Exception e) {
        e.printStackTrace();
      }
    }