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

ucar.nc2.ft.point.standard.StandardSectionCollectionImpl 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.ft.point.standard;

import java.io.IOException;
import java.util.Iterator;
import javax.annotation.Nonnull;

import ucar.ma2.StructureData;
import ucar.ma2.StructureDataIterator;
import ucar.nc2.ft.PointFeature;
import ucar.nc2.ft.PointFeatureCC;
import ucar.nc2.ft.PointFeatureCCIterator;
import ucar.nc2.ft.PointFeatureCollection;
import ucar.nc2.ft.PointFeatureCollectionIterator;
import ucar.nc2.ft.PointFeatureIterator;
import ucar.nc2.ft.TrajectoryProfileFeature;
import ucar.nc2.ft.point.CollectionInfo;
import ucar.nc2.ft.point.DsgCollectionImpl;
import ucar.nc2.ft.point.NestedCollectionIteratorAdapter;
import ucar.nc2.ft.point.ProfileFeatureImpl;
import ucar.nc2.ft.point.SectionCollectionImpl;
import ucar.nc2.ft.point.SectionFeatureImpl;
import ucar.nc2.time.CalendarDate;
import ucar.nc2.time.CalendarDateUnit;
import ucar.nc2.util.IOIterator;

/**
 * Nested Table implementation of SectionCollection.
 * a collection of section features
 *
 * @author caron
 * @since Oct 22, 2009
 */


public class StandardSectionCollectionImpl extends SectionCollectionImpl {
  private NestedTable ft;

  StandardSectionCollectionImpl(NestedTable ft, CalendarDateUnit timeUnit, String altUnits) throws IOException {
    super(ft.getName(), timeUnit, altUnits);
    this.ft = ft;
    this.extras = ft.getExtras();
  }

  @Override
  public Iterator iterator() {
    try {
      PointFeatureCCIterator pfIterator = getNestedPointFeatureCollectionIterator();
      return new NestedCollectionIteratorAdapter<>(pfIterator);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  @Override // new way
  public IOIterator getCollectionIterator() throws IOException {
    return new SectionIterator();
  }

  @Override // old way
  public PointFeatureCCIterator getNestedPointFeatureCollectionIterator() throws IOException {
    return new SectionIterator();
  }

  private class SectionIterator implements PointFeatureCCIterator, IOIterator {
    private StructureDataIterator sdataIter = ft.getRootFeatureDataIterator();
    private StructureData sectionData;
    DsgCollectionImpl prev;
    CollectionInfo calcInfo;

    SectionIterator() throws IOException {
      sdataIter = ft.getRootFeatureDataIterator();
      CollectionInfo info = getInfo();
      if (!info.isComplete())
        calcInfo = info;
    }

    @Override
    public boolean hasNext() throws IOException {
      while (true) {
        if (prev != null && calcInfo != null)
          calcInfo.extend(prev.getInfo());

        if (!sdataIter.hasNext()) {
          close();
          if (calcInfo != null) calcInfo.setComplete();
          return false;
        }
        sectionData = sdataIter.next();
        if (!ft.isFeatureMissing(sectionData)) break;
      }
      return true;
    }

    @Override
    public TrajectoryProfileFeature next() throws IOException {
      Cursor cursor = new Cursor(ft.getNumberOfLevels());
      cursor.recnum[2] = sdataIter.getCurrentRecno();
      cursor.tableData[2] = sectionData; // obs(leaf) = 0, profile=1, section(root)=2
      cursor.currentIndex = 2;
      ft.addParentJoin(cursor); // there may be parent joins

      TrajectoryProfileFeature result = new StandardSectionFeature(cursor, sectionData);
      prev = (DsgCollectionImpl) result;
      return result;
    }

    @Override
    public void close() {
      sdataIter.close();
    }
  }

  // a single section: a collection of profiles along a trajectory
  private class StandardSectionFeature extends SectionFeatureImpl {
    Cursor cursor;
    StructureData sectionData;

    StandardSectionFeature(Cursor cursor, StructureData sectionData) {
      super(ft.getFeatureName(cursor), StandardSectionCollectionImpl.this.getTimeUnit(), StandardSectionCollectionImpl.this.getAltUnits());
      this.cursor = cursor;
      this.sectionData = sectionData;
    }

    @Override
    public PointFeatureCollectionIterator getPointFeatureCollectionIterator() throws IOException {
      return new ProfileIterator(cursor.copy());
    }

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

    @Override
    public IOIterator getCollectionIterator() throws IOException {
      return new ProfileIterator(cursor.copy());
    }
  }

  private class ProfileIterator implements PointFeatureCollectionIterator, IOIterator {
    Cursor cursor;
    private ucar.ma2.StructureDataIterator sdataIter;
    StructureData profileData;
    DsgCollectionImpl prev;
    CollectionInfo calcInfo;

    ProfileIterator(Cursor cursor) throws IOException {
      this.cursor = cursor;
      sdataIter = ft.getMiddleFeatureDataIterator(cursor);
      CollectionInfo info = getInfo();
      if (!info.isComplete())
        calcInfo = info;
    }

    @Override
    public boolean hasNext() throws IOException {
      if (prev != null && calcInfo != null)
        calcInfo.extend(prev.getInfo());

      boolean more = sdataIter.hasNext();
      if (!more) {
        sdataIter.close();
        if (calcInfo != null) calcInfo.setComplete();
      }
      return more;
    }

    @Override
    public PointFeatureCollection next() throws IOException {
      Cursor cursorIter = cursor.copy();
      profileData = sdataIter.next();
      cursorIter.tableData[1] = profileData;
      cursorIter.recnum[1] = sdataIter.getCurrentRecno();
      cursorIter.currentIndex = 1;
      ft.addParentJoin(cursorIter); // there may be parent joins LOOK cursor or cursorIter ?

      // double time = ft.getObsTime(cursorIter);
      PointFeatureCollection result = new StandardSectionProfileFeature(cursorIter, ft.getObsTime(cursor), profileData);
      prev = (DsgCollectionImpl) result; // common for Station and StationProfile
      return result;
    }

    @Override
    public void close() {
      sdataIter.close();
    }
  }

  // LOOK duplicate from StandardProfileCollection - also check StationProfile
  private class StandardSectionProfileFeature extends ProfileFeatureImpl {
    Cursor cursor;
    StructureData profileData;

    StandardSectionProfileFeature(Cursor cursor, double time, StructureData profileData) {
      super(ft.getFeatureName(cursor), StandardSectionCollectionImpl.this.getTimeUnit(), StandardSectionCollectionImpl.this.getAltUnits(),
              ft.getLatitude(cursor), ft.getLongitude(cursor), time, -1);

      this.cursor = cursor;
      this.profileData = profileData;

      if (Double.isNaN(time)) { // gotta read an obs to get the time
        try {
          PointFeatureIterator iter = getPointFeatureIterator();
          if (iter.hasNext()) {
            PointFeature pf = iter.next();
            this.time = pf.getObservationTime();
            this.name = timeUnit.makeCalendarDate(this.time).toString();
          } else {
            this.name = "empty";
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }

    @Override
    public PointFeatureIterator getPointFeatureIterator() throws IOException {
      Cursor cursorIter = cursor.copy();
      StructureDataIterator siter = ft.getLeafFeatureDataIterator(cursorIter);
      return new PointIterator(ft, timeUnit, siter, cursorIter);
    }

    @Nonnull
    @Override
    public CalendarDate getTime() {
      return timeUnit.makeCalendarDate(time);
    }

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

    private class PointIterator extends StandardPointFeatureIterator {

      PointIterator(NestedTable ft, CalendarDateUnit timeUnit, StructureDataIterator structIter, Cursor cursor) throws IOException {
        super(StandardSectionProfileFeature.this, ft, timeUnit, structIter, cursor);
      }

      @Override
      protected boolean isMissing() throws IOException {
        if (super.isMissing()) return true;
        // must also check for missing z values
        return ft.isAltMissing(this.cursor);
      }
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy