All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ucar.nc2.ft.point.remote.RemoteStationCollection Maven / Gradle / Ivy

Go to download

The NetCDF-Java Library is a Java interface to NetCDF files, as well as to many other types of scientific data formats.

The newest version!
package ucar.nc2.ft.point.remote;

import ucar.ma2.StructureData;
import ucar.nc2.ft.point.*;
import ucar.nc2.ft.*;
import ucar.nc2.stream.CdmRemote;
import ucar.nc2.stream.NcStream;
import ucar.nc2.time.CalendarDateRange;
import ucar.nc2.units.DateUnit;
import ucar.unidata.geoloc.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * Connect to remote Station Collection using cdmremote
 *
 * @author caron
 */
public class RemoteStationCollection extends StationTimeSeriesCollectionImpl {
  private String uri;
  protected LatLonRect boundingBoxSubset;
  protected CalendarDateRange dateRangeSubset;
  private boolean restrictedList = false;

  /**
   * Constructor. defer metadata
   *
   * @param uri cdmremote endpoint
   */
  public RemoteStationCollection(String uri, DateUnit timeUnit, String altUnits) {
    super(uri, timeUnit, altUnits);
    this.uri = uri;
  }

  /**
   * initialize the stationHelper.
   */
  @Override
  protected StationHelper createStationHelper() throws IOException {
    // read in all the stations with the "stations" query
    StationHelper stationHelper = new StationHelper();

    try (InputStream in = CdmRemote.sendQuery(uri, "req=stations")) {
      PointStream.MessageType mtype = PointStream.readMagic(in);
      if (mtype != PointStream.MessageType.StationList) {
        throw new RuntimeException("Station Request: bad response");
      }

      int len = NcStream.readVInt(in);
      byte[] b = new byte[len];
      NcStream.readFully(in, b);
      PointStreamProto.StationList stationsp = PointStreamProto.StationList.parseFrom(b);
      for (ucar.nc2.ft.point.remote.PointStreamProto.Station sp : stationsp.getStationsList()) {
//        Station s = new StationImpl(sp.getId(), sp.getDesc(), sp.getWmoId(), sp.getLat(), sp.getLon(), sp.getAlt());
        stationHelper.addStation(new RemoteStationFeatureImpl(null, null));    // LOOK WRONG
      }
      return stationHelper;
    }
  }

  // note this assumes that a PointFeature is-a StationPointFeature
  @Override
  public Station getStation(PointFeature feature) throws IOException {
    StationPointFeature stationFeature = (StationPointFeature) feature; // LOOK probably will fail here
    return stationFeature.getStation();
  }


  // Must override default subsetting implementation for efficiency: eg to make a single call to server

  // StationTimeSeriesFeatureCollection

  @Override
  public StationTimeSeriesFeatureCollection subset(List stations) throws IOException {
    if (stations == null) return this;
//    List subset = getStationHelper().getStationFeatures(stations);
    return new RemoteStationCollectionSubset(this, null, null); // LOOK WRONG
  }

  @Override
  public StationTimeSeriesFeatureCollection subset(ucar.unidata.geoloc.LatLonRect boundingBox) throws IOException {
    if (boundingBox == null) return this;
    return new RemoteStationCollectionSubset(this, boundingBox, null);
  }

  // NestedPointFeatureCollection
  @Override
  public PointFeatureCollection flatten(LatLonRect boundingBox, CalendarDateRange dateRange) throws IOException {
    QueryMaker queryMaker = restrictedList ? new QueryByStationList() : null;
    RemotePointCollection pfc = new RemotePointCollection(uri, getTimeUnit(), getAltUnits(), queryMaker);
    return pfc.subset(boundingBox, dateRange);
  }

  private class QueryByStationList implements QueryMaker {
    @Override
    public String makeQuery() {
      StringBuilder query = new StringBuilder("stns=");
      for (Station s : getStationHelper().getStations()) {
        query.append(s.getName());
        query.append(",");
      }
      return PointDatasetRemote.makeQuery(query.toString(), boundingBoxSubset, dateRangeSubset);
    }
  }

  //////////////////////////////////////////////////////////////////////////////


  private static class RemoteStationCollectionSubset extends RemoteStationCollection {
    RemoteStationCollection from;

    RemoteStationCollectionSubset(RemoteStationCollection from, LatLonRect filter_bb,
            CalendarDateRange filter_date) throws IOException {
      super(from.uri, from.getTimeUnit(), from.getAltUnits());
      this.from = from;

      if (filter_bb == null)
        this.boundingBoxSubset = from.getBoundingBox();
      else
        this.boundingBoxSubset = (from.getBoundingBox() == null) ? filter_bb : from.getBoundingBox().intersect(filter_bb);

      if (filter_date == null) {
        this.dateRangeSubset = from.dateRangeSubset;
      } else {
        this.dateRangeSubset = (from.dateRangeSubset == null) ? filter_date : from.dateRangeSubset.intersect(filter_date);
      }
    }

    @Override
    protected StationHelper createStationHelper() throws IOException {
      List stations = from.getStationHelper().getStationFeatures(boundingBoxSubset);
      StationHelper stationHelper = new StationHelper();
      stationHelper.setStations(stations);
      return stationHelper;
    }

    @Override
    public Station getStation(PointFeature feature) throws IOException {
      return from.getStation(feature);
    }
  }

  ///////////////////////////////////////////////////////////////////////////////

  private class RemoteStationFeatureImpl extends StationTimeSeriesFeatureImpl {
    StationTimeSeriesFeature stnFeature;
    RemotePointFeatureIterator riter;

    RemoteStationFeatureImpl(StationTimeSeriesFeature s, CalendarDateRange dateRange) {
      super(s, RemoteStationCollection.this.getTimeUnit(), RemoteStationCollection.this.getAltUnits(), -1);
      this.stnFeature = s;
      this.dateRange = dateRange;
    }

    // Must override default subsetting implementation to make a single call to server

    // StationTimeSeriesFeature

    @Override
    public StationTimeSeriesFeature subset(CalendarDateRange dateRange) throws IOException {
      if (dateRange == null) return this;
      return new RemoteStationFeatureImpl(stnFeature, dateRange);
    }

    @Override
    public StructureData getFeatureData() throws IOException {
      return stnFeature.getFeatureData();
    }

    // PointCollection
    @Override
    public PointFeatureCollection subset(LatLonRect boundingBox, CalendarDateRange dateRange) throws IOException {
      if (boundingBox != null) {
        if (!boundingBox.contains(s.getLatLon())) return null;
        if (dateRange == null) return this;
      }
      return subset(dateRange);
    }

    // an iterator over the observations for this station
    @Override
    public PointFeatureIterator getPointFeatureIterator(int bufferSize) throws IOException {
      String query = PointDatasetRemote.makeQuery("stn=" + s.getName(), null, dateRange);

      InputStream in = null;
      try {
        in = CdmRemote.sendQuery(uri, query);

        PointStream.MessageType mtype = PointStream.readMagic(in);
        if (mtype == PointStream.MessageType.End) {  // no obs were found
          in.close();
          return new PointIteratorEmpty(); // return empty iterator
        }

        if (mtype != PointStream.MessageType.PointFeatureCollection) {
          throw new RuntimeException("Station Request: bad response = " + mtype);
        }

        int len = NcStream.readVInt(in);
        byte[] b = new byte[len];
        NcStream.readFully(in, b);
        PointStreamProto.PointFeatureCollection pfc = PointStreamProto.PointFeatureCollection.parseFrom(b);

        riter = new RemotePointFeatureIterator(in, new PointStream.ProtobufPointFeatureMaker(pfc));
        riter.setCalculateBounds(this);
        return riter;

      } catch (Throwable t) {
        if (in != null) in.close();
        throw new IOException(t.getMessage(), t);
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy