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

ucar.nc2.ft2.coverage.writer.CoverageAsPoint Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1998-2018 John Caron and University Corporation for Atmospheric Research/Unidata
 * See LICENSE for license information.
 */
package ucar.nc2.ft2.coverage.writer;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;

import ucar.ma2.Array;
import ucar.ma2.IndexIterator;
import ucar.ma2.InvalidRangeException;
import ucar.ma2.StructureData;
import ucar.ma2.StructureDataScalar;
import ucar.nc2.VariableSimpleIF;
import ucar.nc2.VariableSimpleImpl;
import ucar.nc2.constants.FeatureType;
import ucar.nc2.ft.FeatureDatasetPoint;
import ucar.nc2.ft.PointFeature;
import ucar.nc2.ft.PointFeatureIterator;
import ucar.nc2.ft.point.PointFeatureImpl;
import ucar.nc2.ft.point.PointIteratorAbstract;
import ucar.nc2.ft.point.StationFeature;
import ucar.nc2.ft.point.StationHelper;
import ucar.nc2.ft.point.StationPointFeature;
import ucar.nc2.ft.point.StationTimeSeriesCollectionImpl;
import ucar.nc2.ft.point.StationTimeSeriesFeatureImpl;
import ucar.nc2.ft2.coverage.Coverage;
import ucar.nc2.ft2.coverage.CoverageCollection;
import ucar.nc2.ft2.coverage.CoverageCoordAxis;
import ucar.nc2.ft2.coverage.CoverageCoordAxis1D;
import ucar.nc2.ft2.coverage.CoverageCoordSys;
import ucar.nc2.ft2.coverage.GeoReferencedArray;
import ucar.nc2.ft2.coverage.SubsetParams;
import ucar.nc2.time.CalendarDateUnit;
import ucar.nc2.util.Misc;
import ucar.unidata.geoloc.LatLonPointImpl;
import ucar.unidata.util.StringUtil2;

/**
 * Write DSG CF-1.6 file from a Coverage Dataset
 *
 * @author caron
 * @since 7/8/2015
 */
public class CoverageAsPoint {
  private static final boolean debug = false;

  private CoverageCollection gcd;
  private List varData;
  private SubsetParams subset;
  private LatLonPointImpl latLonPoint;
  private CalendarDateUnit dateUnit;

  private class VarData {
    Coverage cov;
    GeoReferencedArray array;

    public VarData(Coverage cov) throws IOException {
      this.cov = cov;
      try {
        this.array = cov.readData(subset);
        if (debug)
          System.out.printf(" Coverage %s data shape = %s%n", cov.getName(), Misc.showInts(array.getData().getShape()));
      } catch (InvalidRangeException e) {
        e.printStackTrace();
      }
    }
  }

  public CoverageAsPoint(CoverageCollection gcd, List varNames, SubsetParams subset) throws IOException {
    this.gcd = gcd;
    this.subset = subset;

    latLonPoint = (LatLonPointImpl) subset.get(SubsetParams.latlonPoint);
    if (latLonPoint == null)
      throw new IllegalArgumentException("No latlon point");

    varData = new ArrayList<>(varNames.size());
    for (String varName : varNames) {
      Coverage cov = gcd.findCoverage(varName); // LOOK we should read all at once if possible
      if (cov != null) {
        varData.add(new VarData(cov));

        if (dateUnit == null) { // assume all have the same time unit, just use the first one
          CoverageCoordSys csys = cov.getCoordSys();
          CoverageCoordAxis timeAxis = csys.getTimeAxis();
          this.dateUnit = timeAxis.getCalendarDateUnit();
        }
      }
    }
  }

  public FeatureDatasetPoint asFeatureDatasetPoint() {
    // for the moment, assume a single station, no vert coord, single lat/lon
    return new CoverageAsFeatureDatasetPoint(FeatureType.STATION);
  }

  private class CoverageAsFeatureDatasetPoint extends ucar.nc2.ft.point.PointDatasetImpl {
    protected CoverageAsFeatureDatasetPoint(FeatureType featureType) {
      super(featureType);
      CoverageAsStationFeatureCollection fc = new CoverageAsStationFeatureCollection(gcd.getName() + " AsStationFeatureCollection", dateUnit, null);
      setPointFeatureCollection(fc);

      List dataVars = new ArrayList<>();
      for (VarData vd : varData) {                    // String name, String desc, String units, DataType dt
        VariableSimpleIF simple = VariableSimpleImpl.makeScalar(vd.cov.getName(), vd.cov.getDescription(), vd.cov.getUnitsString(), vd.cov.getDataType());
        dataVars.add(simple);
      }
      this.dataVariables = dataVars;
    }
  }

  private class CoverageAsStationFeatureCollection extends StationTimeSeriesCollectionImpl {

    public CoverageAsStationFeatureCollection(String name, CalendarDateUnit dateUnit, String altUnits) {
      super(name, dateUnit, altUnits);
    }

    @Override
    protected StationHelper createStationHelper() throws IOException {
      StationHelper helper = new StationHelper();
      String name = String.format("GridPointAt[%s]", latLonPoint.toString(3));
      name = StringUtil2.replace(name.trim(), ' ', "_");
      helper.addStation(new MyStationFeature(name, name, null, latLonPoint.getLatitude(), latLonPoint.getLongitude(), 0.0, dateUnit, null, -1));
      return helper;
    }

  }

  private class MyStationFeature extends StationTimeSeriesFeatureImpl {

    public MyStationFeature(String name, String desc, String wmoId, double lat, double lon, double alt, CalendarDateUnit timeUnit, String altUnits, int npts) {
      // String name, String desc, String wmoId, double lat, double lon, double alt, DateUnit timeUnit, String altUnits, int npts
      super(name, desc, wmoId, lat, lon, alt, timeUnit, altUnits, npts, StructureData.EMPTY);
    }

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

    @Override
    public PointFeatureIterator getPointFeatureIterator() throws IOException {
      return new TimeseriesIterator();
    }

    private class VarIter {
      Coverage cov;
      GeoReferencedArray geoA;
      IndexIterator dataIter;

      public VarIter(Coverage cov, GeoReferencedArray array, IndexIterator dataIter) {
        this.cov = cov;
        this.geoA = array;
        this.dataIter = dataIter;
      }
    }

    private class TimeseriesIterator extends PointIteratorAbstract {
      int curr = 0;
      int nvalues;
      List varIters;
      CoverageCoordAxis1D timeAxis;

      TimeseriesIterator() {
        varIters = new ArrayList<>();
        for (VarData vd : varData) {
          Array data = vd.array.getData();
          if (debug) System.out.printf("%s shape=%s%n", vd.cov.getName(), Misc.showInts(data.getShape()));
          varIters.add(new VarIter(vd.cov, vd.array, data.getIndexIterator()));
          nvalues = (int) data.getSize();

          if (timeAxis == null) { // assume they are all the same (!)
            CoverageCoordSys csys = vd.array.getCoordSysForData();
            timeAxis = (CoverageCoordAxis1D) csys.getTimeAxis();   // LOOK may not be right
          }
        }
      }

      @Override
      public boolean hasNext() {
        boolean more =  curr < nvalues;
        if (!more) close();
        return more;
      }

      @Override
      public PointFeature next() {
        double obsTime = timeAxis.getCoordMidpoint(curr);

        StructureDataScalar coords = new StructureDataScalar("Coords");
        for (VarIter vi : varIters) {
          coords.addMember(vi.cov.getName(), null, null, vi.cov.getDataType(), (Number) vi.dataIter.getObjectNext());
        }
        curr++;
        PointFeature pf = new MyPointFeature(MyStationFeature.this, obsTime, 0.0, timeUnit, coords);
        calcBounds(pf);
        return pf;
      }

      @Override
      public void close() {
        finishCalcBounds();
      }
    }

    private class MyPointFeature extends PointFeatureImpl implements StationPointFeature {
      StationFeature stn;
      StructureData sdata;

      public MyPointFeature(StationFeature stn, double obsTime, double nomTime, CalendarDateUnit timeUnit, StructureData sdata) {
        super(MyStationFeature.this, stn, obsTime, nomTime, timeUnit);
        this.stn = stn;
        this.sdata = sdata;
      }

      @Override
      @Nonnull
      public StationFeature getStation() {
        return stn;
      }

      @Override
      @Nonnull
      public StructureData getFeatureData() throws IOException {
        return sdata;
      }

      @Override
      @Nonnull
      public StructureData getDataAll() throws IOException {
        return sdata;
      }
    }

  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy