package visad.data;

import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

import visad.VisADException;
import edu.wisc.ssec.mcidas.AreaFile;
import edu.wisc.ssec.mcidas.AreaFileException;
import edu.wisc.ssec.mcidas.AreaFileFactory;
import edu.wisc.ssec.mcidas.adde.AddeImageURL;
import edu.wisc.ssec.mcidas.adde.AddeURLException;

/**
 * Knows how to read local satellite data to be used by a cache adaptor.
 * 
 * TODO: Add capability to work in conjunciton with ADDE data sources 
 * including the IDV ucar.visad.data.CachedFlatField.
 */
public class AreaImageAccessor implements FlatFieldCacheAccessor, 
    Comparable {

  private static Logger log = Logger.getLogger(AreaImageAccessor.class.getName());
  
  private final int band;
  private final String source;
  private int startLine;
  private int numLines;
  private int lineMag;
  private int startElem;
  private int numElems;
  private int elemMag;
  private Date nominalTime;
  private int[][][] readCache;
  
  private boolean isAddeSource;
  
  /**
   * Create an instance. No data is read at this time.
   * 
   * @param source As described in {@link AreaFileFactory#getAreaFileInstance(String)}.
   * @param band The band number of the image.
   * @param readCache Array to use as a cache for reading AREA data into. If null data will
   *  not be read by-reference. See {@link AreaFile#getData(int[][][])}.
   * @throws VisADException
   */
  public AreaImageAccessor(String source, int band, int[][][] readCache) throws VisADException {
    super();
    this.band = band;
    this.source = source;
    this.readCache = readCache;
    if (this.readCache == null) {
      log.fine("readCache is null, by-reference data reading is disabled");
    }
    try {
      new AddeImageURL(source, AddeImageURL.REQ_IMAGEDATA, "", "");
      isAddeSource = true;
      throw new IllegalArgumentException("adde sources are not currently supported");
    } catch (Exception e) {
      isAddeSource = false;
    }
  }

  /**
   * Set AREA file subsetting parameters.
   * 
   * @param startLine
   * @param numLines
   * @param lineMag
   * @param startElem
   * @param numElems
   * @param elemMag
   */
  public void setAreaParams(int startLine, int numLines, int lineMag, int startElem, int numElems, 
        int elemMag) {
    this.startLine = startLine;
    this.numLines = numLines;
    this.lineMag = lineMag;
    this.startElem = startElem;
    this.numElems = numElems;
    this.elemMag = elemMag;
  }
  
  public boolean isAddeSource() {
    return isAddeSource;
  }

  protected int[][][] getAreaData() throws AreaFileException, AddeURLException {
    
    AreaFile af = null;
    if (!isAddeSource) {
      af = AreaFileFactory.getAreaFileInstance(source.toString(), startLine, numLines, lineMag,
          startElem, numElems, elemMag, band);
    } else {
      // expect sub-setting to be done in URL
      af = AreaFileFactory.getAreaFileInstance(source.toString());
    }
    
    if (nominalTime == null) {
      nominalTime = af.getAreaDirectory().getNominalTime();
    } else if (nominalTime.equals(af.getAreaDirectory())) {
      throw new FlatFieldCacheError("nominal time mismatch on subsequent reads", null);
    }
    
    // use by-reference if possible
    int[][][] raw = null;
    if (readCache != null) {
      raw = af.getData(readCache);
    } else {
      raw = af.getData();
    }
    return raw; 
  }
  
  public String getSource() {
    return source;
  }
  
  public double[][] readFlatField() {
    double[][] range = null;
    try {
      
      int[][][] raw = getAreaData();
      
      range = new double[1][numLines * numElems];
      int idx = 0;
      for (int line = 0; line < raw[0].length; line++) {
        for (int elem = 0; elem < raw[0][0].length; elem++) {
          range[0][idx++] = (double) raw[0][line][elem];
        }
      }
    } catch (Exception e) {
      log.log(Level.SEVERE, "Could not read image data: " + source.toString(), e);
    }
    return range;
  }
  
  public float[][] readFlatFieldFloats() {
    float[][] range = null;
    try {
      
      int[][][] raw = getAreaData();
      
      range = new float[1][numLines * numElems];
      int idx = 0;
      for (int line = 0; line < raw[0].length; line++) {
        for (int elem = 0; elem < raw[0][0].length; elem++) {
          range[0][idx++] = (float) raw[0][line][elem];
        }
      }
    } catch (Exception e) {
      log.log(Level.SEVERE, "Could not read AREA file: " + source.toString(), e);
    }
    return range;
  }

  public Date getNominalTime() {
    if (nominalTime == null) {
      AreaFile af;
      try {
        af = AreaFileFactory.getAreaFileInstance(source.toString());
      } catch (Exception e) {
        throw new FlatFieldCacheError("Error getting nominal time from AREA file", e);
      }
      nominalTime = af.getAreaDirectory().getNominalTime();
    }
    return nominalTime;
  }
  
  public int compareTo(AreaImageAccessor that) {
    long myTime = getNominalTime().getTime();
    long yourTime = that.getNominalTime().getTime();
    if (myTime > yourTime) {
      return 1;
    } else if (myTime < yourTime) {
      return -1;
    }
    return 0;
  }
  
  
}

 

Ads help maintain this website.