cdm/src/main/java/ucar/nc2/dt/grid/GridCoordSys.java
public List<NamedObject> getLevels() {
    if (vertZaxis == null)
      return new ArrayList<>(0);

    int n = (int) vertZaxis.getSize();
    List<NamedObject> levels = new ArrayList<>(n);
    for (int i = 0; i < n; i++)
      levels.add(new ucar.nc2.util.NamedAnything(vertZaxis.getCoordName(i), vertZaxis.getUnitsString()));

    return levels;
  }

 /**
   * Get the String name for the ith level(z) coordinate.
   *
   * @param index which level coordinate
   * @return level name
   */
  public String getLevelName(int index) {
    if ((vertZaxis == null) || (index < 0) || (index >= vertZaxis.getSize()))
      throw new IllegalArgumentException("getLevelName = " + index);
    return vertZaxis.getCoordName(index).trim();
  }

  /**
   * Get the index corresponding to the level name.
   *
   * @param name level name
   * @return level index, or -1 if not found
   */
  public int getLevelIndex(String name) {
    if ((vertZaxis == null) || (name == null)) return -1;

    for (int i = 0; i < vertZaxis.getSize(); i++) {
      if (vertZaxis.getCoordName(i).trim().equals(name))
        return i;
    }
    return -1;
  }

  /**
   * Get the list of time names, to be used for user selection.
   * The ith one refers to the ith time coordinate.
   *
   * @return List of ucar.nc2.util.NamedObject, or empty list.
   */
  public List<NamedObject> getTimes() {
    List<CalendarDate> cdates = getCalendarDates();
    List<NamedObject> times = new ArrayList<>( cdates.size());
    for (CalendarDate cd: cdates) {
      times.add(new ucar.nc2.util.NamedAnything(cd.toString(), "calendar date"));
    }
    return times;
  }

   ///////////////////////////////////////////////////////////////////////////
  // deprecated

  /**
   * Given a point in x,y coordinate space, find the x,y index in the coordinate system.
   *
   * @deprecated use findXYindexFromCoord
   */
  public int[] findXYCoordElement(double x_coord, double y_coord, int[] result) {
    return findXYindexFromCoord(x_coord, y_coord, result);
  }

  /**
   * Get the date range
   * @return date range
   * @deprecated  use getCalendarDateRange
   */
  public DateRange getDateRange() {
    Date[] dates = getTimeDates();
    if (dates.length > 0)
      return new DateRange(dates[0], dates[dates.length - 1]);
    return null;
  }

  /**
   * Get the list of times as Dates.
   * If 2D, return list of unique dates.
   *
   * @return array of java.util.Date, or Date[0].
   * @deprecated  use getCalendarDates
   */
  public java.util.Date[] getTimeDates() {
    if ((timeTaxis != null) && (timeTaxis.getSize() > 0)) {
      return timeTaxis.getTimeDates();

    } else if ((tAxis != null) && (tAxis.getSize() > 0))  {
      return makeTimes2D();
    }

    return new Date[0];
  }

  private Date[] makeTimes2D() {
    Set<Date> dates = new HashSet<>();

    try {
      // common case: see if it has a valid udunits unit
      String units = tAxis.getUnitsString();
      if (units != null && SimpleUnit.isDateUnit(units) && tAxis.getDataType().isNumeric()) {
        DateUnit du = new DateUnit(units);
        Array data = tAxis.read();
        data.resetLocalIterator();
        while (data.hasNext()) {
          Date d = du.makeDate(data.nextDouble());
          dates.add(d);
        }

      } else if (tAxis.getDataType() == DataType.STRING) {
        // otherwise, see if its a String or CHAR, and if we can parse the values as an ISO date
        DateFormatter formatter = new DateFormatter();
        Array data = tAxis.read();
        data.resetLocalIterator();
        while (data.hasNext()) {
          Date d = formatter.getISODate((String) data.next());
          dates.add(d);
        }

      } else if (tAxis.getDataType() == DataType.CHAR) {
        DateFormatter formatter = new DateFormatter();
        ArrayChar data = (ArrayChar) tAxis.read();
        ArrayChar.StringIterator iter = data.getStringIterator();
        while (iter.hasNext()) {
          Date d = formatter.getISODate(iter.next());
          dates.add(d);
        }

      } else {
        return new Date[0];
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    // sorted list
    int n = dates.size();
    Date[] dd = dates.toArray(new Date[n]);
    List<Date> dateList = Arrays.asList(dd);
    Collections.sort(dateList);
    Date[] timeDates = new Date[n];
    int count=0;
    for (Date d : dateList)
      timeDates[count++] = d;

    return timeDates;
  }

  /* old way
  private boolean makeTimes1D() {
    int n = (int) timeTaxis.getSize();
    timeDates = new Date[n];

    // common case: see if it has a valid udunits unit
    try {
      DateUnit du = null;
      String units = timeTaxis.getUnitsString();
      if (units != null)
        du = new DateUnit(units);
      for (int i = 0; i < n; i++) {
        Date d = du.makeDate(timeTaxis.getCoordValue(i));
        timeDates[i] = d;
      }
      isDate = true;
      return true;
    } catch (Exception e) {
      // ok to fall through
    }

    // otherwise, see if its a String, and if we can parse the values as an ISO date
    if ((timeTaxis.getDataType() == DataType.STRING) || (timeTaxis.getDataType() == DataType.CHAR)) {
      DateFormatter formatter = new DateFormatter();
      for (int i = 0; i < n; i++) {
        String coordValue = timeTaxis.getCoordName(i);
        Date d = formatter.getISODate(coordValue);
        if (d == null) {
          isDate = false;
          return false;
        } else {
          timeDates[i] = d;
        }
      }
      isDate = true;
      return true;
    }

    return false;
  }  */



  /**
   * Get the string name for the ith time coordinate.
   *
   * @param index which time coordinate
   * @return time name.
   * @deprecated
   */
  public String getTimeName(int index) {
    List<CalendarDate> cdates = getCalendarDates();

    if ((index < 0) || (index >= cdates.size()))
      throw new IllegalArgumentException("getTimeName illegal index = " + index);

    return cdates.get(index).toString();
  }

  /**
   * Get the index corresponding to the time name.
   *
   * @param name time name
   * @return time index, or -1 if not found
   * @deprecated
   */
  public int getTimeIndex(String name) {
    List<CalendarDate> cdates = getCalendarDates();
    for (int i=0; i < cdates.size(); i++) {
      if( cdates.get(i).toString().equals(name)) return i;
    }

    return -1;
  }

  /**
   * Only works if coordsys has 1d time axis
   * @deprecated use CoordinateAxis1DTime.findTimeIndexFromDate
   */
  public int findTimeIndexFromDate(java.util.Date d) {
    if (timeTaxis == null) return -1;
    return timeTaxis.findTimeIndexFromDate(d);
  }

  ///////////////////////////////////////////////////////////////////////
  // experimental

  static private double getMinOrMaxLon(double lon1, double lon2, boolean wantMin) {
    double midpoint = (lon1 + lon2) / 2;
    lon1 = LatLonPointImpl.lonNormal(lon1, midpoint);
    lon2 = LatLonPointImpl.lonNormal(lon2, midpoint);

    return wantMin ? Math.min(lon1, lon2) : Math.max(lon1, lon2);
  }

  static public LatLonRect getLatLonBoundingBox(Projection proj, double startx, double starty, double endx, double endy) {

    if (proj instanceof LatLonProjection) {
      double deltaLat = endy - starty;
      double deltaLon = endx - startx;

      LatLonPoint llpt = new LatLonPointImpl(starty, startx);
      return new LatLonRect(llpt, deltaLat, deltaLon);

    }

    ProjectionRect bb = new ProjectionRect(startx, starty, endx, endy);

    // look at all 4 corners of the bounding box
    LatLonPointImpl llpt = (LatLonPointImpl) proj.projToLatLon(bb.getLowerLeftPoint(), new LatLonPointImpl());
    LatLonPointImpl lrpt = (LatLonPointImpl) proj.projToLatLon(bb.getLowerRightPoint(), new LatLonPointImpl());
    LatLonPointImpl urpt = (LatLonPointImpl) proj.projToLatLon(bb.getUpperRightPoint(), new LatLonPointImpl());
    LatLonPointImpl ulpt = (LatLonPointImpl) proj.projToLatLon(bb.getUpperLeftPoint(), new LatLonPointImpl());

    // Check if grid contains poles. LOOK disabled
    boolean includesNorthPole = false;
    /* int[] resultNP = new int[2];
    resultNP = findXYindexFromLatLon(90.0, 0, null);
    if (resultNP[0] != -1 && resultNP[1] != -1)
      includesNorthPole = true;  */

    boolean includesSouthPole = false;
    /* int[] resultSP = new int[2];
    resultSP = findXYindexFromLatLon(-90.0, 0, null);
    if (resultSP[0] != -1 && resultSP[1] != -1)
      includesSouthPole = true;  */

    LatLonRect llbb;

    if (includesNorthPole && !includesSouthPole) {
      llbb = new LatLonRect(llpt, new LatLonPointImpl(90.0, 0.0)); // ??? lon=???
      llbb.extend(lrpt);
      llbb.extend(urpt);
      llbb.extend(ulpt);

    } else if (includesSouthPole && !includesNorthPole) {
      llbb = new LatLonRect(llpt, new LatLonPointImpl(-90.0, -180.0)); // ??? lon=???
      llbb.extend(lrpt);
      llbb.extend(urpt);
      llbb.extend(ulpt);

    } else {
      double latMin = Math.min(llpt.getLatitude(), lrpt.getLatitude());
      double latMax = Math.max(ulpt.getLatitude(), urpt.getLatitude());

      // longitude is a bit tricky as usual
      double lonMin = getMinOrMaxLon(llpt.getLongitude(), ulpt.getLongitude(), true);
      double lonMax = getMinOrMaxLon(lrpt.getLongitude(), urpt.getLongitude(), false);

      llpt.set(latMin, lonMin);
      urpt.set(latMax, lonMax);

      llbb = new LatLonRect(llpt, urpt);
    }
    return llbb;
  }
}
public List<NamedObject> getLevels() {
    if (vertZaxis == null)
      return new ArrayList<>(0);

    int n = (int) vertZaxis.getSize();
    List<NamedObject> levels = new ArrayList<>(n);
    for (int i = 0; i < n; i++)
      levels.add(new ucar.nc2.util.NamedAnything(vertZaxis.getCoordName(i), vertZaxis.getUnitsString()));

    return levels;
  }

 /**
   * Get the String name for the ith level(z) coordinate.
   *
   * @param index which level coordinate
   * @return level name
   */
  public String getLevelName(int index) {
    if ((vertZaxis == null) || (index < 0) || (index >= vertZaxis.getSize()))
      throw new IllegalArgumentException("getLevelName = " + index);
    return vertZaxis.getCoordName(index).trim();
  }

  /**
   * Get the index corresponding to the level name.
   *
   * @param name level name
   * @return level index, or -1 if not found
   */
  public int getLevelIndex(String name) {
    if ((vertZaxis == null) || (name == null)) return -1;

    for (int i = 0; i < vertZaxis.getSize(); i++) {
      if (vertZaxis.getCoordName(i).trim().equals(name))
        return i;
    }
    return -1;
  }

  /**
   * Get the list of time names, to be used for user selection.
   * The ith one refers to the ith time coordinate.
   *
   * @return List of ucar.nc2.util.NamedObject, or empty list.
   */
  public List<NamedObject> getTimes() {
    List<CalendarDate> cdates = getCalendarDates();
    List<NamedObject> times = new ArrayList<>( cdates.size());
    for (CalendarDate cd: cdates) {
      times.add(new ucar.nc2.util.NamedAnything(cd.toString(), "calendar date"));
    }
    return times;
  }

   ///////////////////////////////////////////////////////////////////////////
  // deprecated

  /**
   * Given a point in x,y coordinate space, find the x,y index in the coordinate system.
   *
   * @deprecated use findXYindexFromCoord
   */
  public int[] findXYCoordElement(double x_coord, double y_coord, int[] result) {
    return findXYindexFromCoord(x_coord, y_coord, result);
  }

  /**
   * Get the date range
   * @return date range
   * @deprecated  use getCalendarDateRange
   */
  public DateRange getDateRange() {
    Date[] dates = getTimeDates();
    if (dates.length > 0)
      return new DateRange(dates[0], dates[dates.length - 1]);
    return null;
  }

  /**
   * Get the list of times as Dates.
   * If 2D, return list of unique dates.
   *
   * @return array of java.util.Date, or Date[0].
   * @deprecated  use getCalendarDates
   */
  public java.util.Date[] getTimeDates() {
    if ((timeTaxis != null) && (timeTaxis.getSize() > 0)) {
      return timeTaxis.getTimeDates();

    } else if ((tAxis != null) && (tAxis.getSize() > 0))  {
      return makeTimes2D();
    }

    return new Date[0];
  }

  private Date[] makeTimes2D() {
    Set<Date> dates = new HashSet<>();

    try {
      // common case: see if it has a valid udunits unit
      String units = tAxis.getUnitsString();
      if (units != null && SimpleUnit.isDateUnit(units) && tAxis.getDataType().isNumeric()) {
        DateUnit du = new DateUnit(units);
        Array data = tAxis.read();
        data.resetLocalIterator();
        while (data.hasNext()) {
          Date d = du.makeDate(data.nextDouble());
          dates.add(d);
        }

      } else if (tAxis.getDataType() == DataType.STRING) {
        // otherwise, see if its a String or CHAR, and if we can parse the values as an ISO date
        DateFormatter formatter = new DateFormatter();
        Array data = tAxis.read();
        data.resetLocalIterator();
        while (data.hasNext()) {
          Date d = formatter.getISODate((String) data.next());
          dates.add(d);
        }

      } else if (tAxis.getDataType() == DataType.CHAR) {
        DateFormatter formatter = new DateFormatter();
        ArrayChar data = (ArrayChar) tAxis.read();
        ArrayChar.StringIterator iter = data.getStringIterator();
        while (iter.hasNext()) {
          Date d = formatter.getISODate(iter.next());
          dates.add(d);
        }

      } else {
        return new Date[0];
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    // sorted list
    int n = dates.size();
    Date[] dd = dates.toArray(new Date[n]);
    List<Date> dateList = Arrays.asList(dd);
    Collections.sort(dateList);
    Date[] timeDates = new Date[n];
    int count=0;
    for (Date d : dateList)
      timeDates[count++] = d;

    return timeDates;
  }

  /* old way
  private boolean makeTimes1D() {
    int n = (int) timeTaxis.getSize();
    timeDates = new Date[n];

    // common case: see if it has a valid udunits unit
    try {
      DateUnit du = null;
      String units = timeTaxis.getUnitsString();
      if (units != null)
        du = new DateUnit(units);
      for (int i = 0; i < n; i++) {
        Date d = du.makeDate(timeTaxis.getCoordValue(i));
        timeDates[i] = d;
      }
      isDate = true;
      return true;
    } catch (Exception e) {
      // ok to fall through
    }

    // otherwise, see if its a String, and if we can parse the values as an ISO date
    if ((timeTaxis.getDataType() == DataType.STRING) || (timeTaxis.getDataType() == DataType.CHAR)) {
      DateFormatter formatter = new DateFormatter();
      for (int i = 0; i < n; i++) {
        String coordValue = timeTaxis.getCoordName(i);
        Date d = formatter.getISODate(coordValue);
        if (d == null) {
          isDate = false;
          return false;
        } else {
          timeDates[i] = d;
        }
      }
      isDate = true;
      return true;
    }

    return false;
  }  */



  /**
   * Get the string name for the ith time coordinate.
   *
   * @param index which time coordinate
   * @return time name.
   * @deprecated
   */
  public String getTimeName(int index) {
    List<CalendarDate> cdates = getCalendarDates();

    if ((index < 0) || (index >= cdates.size()))
      throw new IllegalArgumentException("getTimeName illegal index = " + index);

    return cdates.get(index).toString();
  }

  /**
   * Get the index corresponding to the time name.
   *
   * @param name time name
   * @return time index, or -1 if not found
   * @deprecated
   */
  public int getTimeIndex(String name) {
    List<CalendarDate> cdates = getCalendarDates();
    for (int i=0; i < cdates.size(); i++) {
      if( cdates.get(i).toString().equals(name)) return i;
    }

    return -1;
  }

  /**
   * Only works if coordsys has 1d time axis
   * @deprecated use CoordinateAxis1DTime.findTimeIndexFromDate
   */
  public int findTimeIndexFromDate(java.util.Date d) {
    if (timeTaxis == null) return -1;
    return timeTaxis.findTimeIndexFromDate(d);
  }

  ///////////////////////////////////////////////////////////////////////
  // experimental

  static private double getMinOrMaxLon(double lon1, double lon2, boolean wantMin) {
    double midpoint = (lon1 + lon2) / 2;
    lon1 = LatLonPointImpl.lonNormal(lon1, midpoint);
    lon2 = LatLonPointImpl.lonNormal(lon2, midpoint);

    return wantMin ? Math.min(lon1, lon2) : Math.max(lon1, lon2);
  }

  static public LatLonRect getLatLonBoundingBox(Projection proj, double startx, double starty, double endx, double endy) {

    if (proj instanceof LatLonProjection) {
      double deltaLat = endy - starty;
      double deltaLon = endx - startx;

      LatLonPoint llpt = new LatLonPointImpl(starty, startx);
      return new LatLonRect(llpt, deltaLat, deltaLon);

    }

    ProjectionRect bb = new ProjectionRect(startx, starty, endx, endy);

    // look at all 4 corners of the bounding box
    LatLonPointImpl llpt = (LatLonPointImpl) proj.projToLatLon(bb.getLowerLeftPoint(), new LatLonPointImpl());
    LatLonPointImpl lrpt = (LatLonPointImpl) proj.projToLatLon(bb.getLowerRightPoint(), new LatLonPointImpl());
    LatLonPointImpl urpt = (LatLonPointImpl) proj.projToLatLon(bb.getUpperRightPoint(), new LatLonPointImpl());
    LatLonPointImpl ulpt = (LatLonPointImpl) proj.projToLatLon(bb.getUpperLeftPoint(), new LatLonPointImpl());

    // Check if grid contains poles. LOOK disabled
    boolean includesNorthPole = false;
    /* int[] resultNP = new int[2];
    resultNP = findXYindexFromLatLon(90.0, 0, null);
    if (resultNP[0] != -1 && resultNP[1] != -1)
      includesNorthPole = true;  */

    boolean includesSouthPole = false;
    /* int[] resultSP = new int[2];
    resultSP = findXYindexFromLatLon(-90.0, 0, null);
    if (resultSP[0] != -1 && resultSP[1] != -1)
      includesSouthPole = true;  */

    LatLonRect llbb;

    if (includesNorthPole && !includesSouthPole) {
      llbb = new LatLonRect(llpt, new LatLonPointImpl(90.0, 0.0)); // ??? lon=???
      llbb.extend(lrpt);
      llbb.extend(urpt);
      llbb.extend(ulpt);

    } else if (includesSouthPole && !includesNorthPole) {
      llbb = new LatLonRect(llpt, new LatLonPointImpl(-90.0, -180.0)); // ??? lon=???
      llbb.extend(lrpt);
      llbb.extend(urpt);
      llbb.extend(ulpt);

    } else {
      double latMin = Math.min(llpt.getLatitude(), lrpt.getLatitude());
      double latMax = Math.max(ulpt.getLatitude(), urpt.getLatitude());

      // longitude is a bit tricky as usual
      double lonMin = getMinOrMaxLon(llpt.getLongitude(), ulpt.getLongitude(), true);
      double lonMax = getMinOrMaxLon(lrpt.getLongitude(), urpt.getLongitude(), false);

      llpt.set(latMin, lonMin);
      urpt.set(latMax, lonMax);

      llbb = new LatLonRect(llpt, urpt);
    }
    return llbb;
  }
}
public List < NamedObject > getLevels ( ) { if ( vertZaxis == null ) return new ArrayList <> ( 0 ) ; int n = ( int ) vertZaxis . getSize ( ) ; List < NamedObject > levels = new ArrayList <> ( n ) ; for ( int i = 0 ; i < n ; i ++ ) levels . ( new ucar . nc2 . util . NamedAnything ( vertZaxis . getCoordName ( i ) , vertZaxis . getUnitsString ( ) ) ) ; return levels ; } /**
   * Get the String name for the ith level(z) coordinate.
   *
   * @param index which level coordinate
   * @return level name
   */ public String getLevelName ( int index ) { if ( ( vertZaxis == null ) || ( index < 0 ) || ( index >= vertZaxis . getSize ( ) ) ) throw new IllegalArgumentException ( "getLevelName = " + index ) ; return vertZaxis . getCoordName ( index ) . trim ( ) ; } /**
   * Get the index corresponding to the level name.
   *
   * @param name level name
   * @return level index, or -1 if not found
   */ public int getLevelIndex ( String name ) { if ( ( vertZaxis == null ) || ( name == null ) ) return - 1 ; for ( int i = 0 ; i < vertZaxis . getSize ( ) ; i ++ ) { if ( vertZaxis . getCoordName ( i ) . trim ( ) . equals ( name ) ) return i ; } return - 1 ; } /**
   * Get the list of time names, to be used for user selection.
   * The ith one refers to the ith time coordinate.
   *
   * @return List of ucar.nc2.util.NamedObject, or empty list.
   */ public List < NamedObject > getTimes ( ) { List < CalendarDate > cdates = getCalendarDates ( ) ; List < NamedObject > times = new ArrayList <> ( cdates . size ( ) ) ; for ( CalendarDate cd : cdates ) { times . add ( new ucar . nc2 . util . NamedAnything ( cd . toString ( ) , "calendar date" ) ) ; } return times ; } ///////////////////////////////////////////////////////////////////////////
 // deprecated
 /**
   * Given a point in x,y coordinate space, find the x,y index in the coordinate system.
   *
   * @deprecated use findXYindexFromCoord
   */ public int [ ] findXYCoordElement ( double x_coord , double y_coord , int [ ] result ) { return findXYindexFromCoord ( x_coord , y_coord , result ) ; } /**
   * Get the date range
   * @return date range
   * @deprecated  use getCalendarDateRange
   */ public DateRange getDateRange ( ) { Date [ ] dates = getTimeDates ( ) ; if ( dates . length > 0 ) return new DateRange ( dates [ 0 ] , dates [ dates . length - 1 ] ) ; return null ; } /**
   * Get the list of times as Dates.
   * If 2D, return list of unique dates.
   *
   * @return array of java.util.Date, or Date[0].
   * @deprecated  use getCalendarDates
   */ public java . util . Date [ ] getTimeDates ( ) { if ( ( timeTaxis != null ) && ( timeTaxis . getSize ( ) > 0 ) ) { return timeTaxis . getTimeDates ( ) ; } else if ( ( tAxis != null ) && ( tAxis . getSize ( ) > 0 ) ) { return makeTimes2D ( ) ; } return new Date [ 0 ] ; } private Date [ ] makeTimes2D ( ) { Set < Date > dates = new HashSet <> ( ) ; try { // common case: see if it has a valid udunits unit
 String units = tAxis . getUnitsString ( ) ; if ( units != null && SimpleUnit . isDateUnit ( units ) && tAxis . getDataType ( ) . isNumeric ( ) ) { DateUnit du = new DateUnit ( units ) ; Array data = tAxis . read ( ) ; data . resetLocalIterator ( ) ; while ( data . hasNext ( ) ) { Date d = du . makeDate ( data . nextDouble ( ) ) ; dates . add ( d ) ; } } else if ( tAxis . getDataType ( ) == DataType . STRING ) { // otherwise, see if its a String or CHAR, and if we can parse the values as an ISO date
 DateFormatter formatter = new DateFormatter ( ) ; Array data = tAxis . read ( ) ; data . resetLocalIterator ( ) ; while ( data . hasNext ( ) ) { Date d = formatter . getISODate ( ( String ) data . next ( ) ) ; dates . add ( d ) ; } } else if ( tAxis . getDataType ( ) == DataType . CHAR ) { DateFormatter formatter = new DateFormatter ( ) ; ArrayChar data = ( ArrayChar ) tAxis . read ( ) ; ArrayChar . StringIterator iter = data . getStringIterator ( ) ; while ( iter . hasNext ( ) ) { Date d = formatter . getISODate ( iter . next ( ) ) ; dates . add ( d ) ; } } else { return new Date [ 0 ] ; } } catch ( Exception e ) { throw new RuntimeException ( e ) ; } // sorted list
 int n = dates . size ( ) ; Date [ ] dd = dates . toArray ( new Date [ n ] ) ; List < Date > dateList = Arrays . asList ( dd ) ; Collections . sort ( dateList ) ; Date [ ] timeDates = new Date [ n ] ; int count = 0 ; for ( Date d : dateList ) timeDates [ count ++ ] = ; return timeDates ; } /* old way
  private boolean makeTimes1D() {
    int n = (int) timeTaxis.getSize();
    timeDates = new Date[n];

    // common case: see if it has a valid udunits unit
    try {
      DateUnit du = null;
      String units = timeTaxis.getUnitsString();
      if (units != null)
        du = new DateUnit(units);
      for (int i = 0; i < n; i++) {
        Date d = du.makeDate(timeTaxis.getCoordValue(i));
        timeDates[i] = d;
      }
      isDate = true;
      return true;
    } catch (Exception e) {
      // ok to fall through
    }

    // otherwise, see if its a String, and if we can parse the values as an ISO date
    if ((timeTaxis.getDataType() == DataType.STRING) || (timeTaxis.getDataType() == DataType.CHAR)) {
      DateFormatter formatter = new DateFormatter();
      for (int i = 0; i < n; i++) {
        String coordValue = timeTaxis.getCoordName(i);
        Date d = formatter.getISODate(coordValue);
        if (d == null) {
          isDate = false;
          return false;
        } else {
          timeDates[i] = d;
        }
      }
      isDate = true;
      return true;
    }

    return false;
  }  */ /**
   * Get the string name for the ith time coordinate.
   *
   * @param index which time coordinate
   * @return time name.
   * @deprecated
   */ public String getTimeName ( int index ) { List < CalendarDate > cdates = getCalendarDates ( ) ; if ( ( index < 0 ) || ( index >= cdates . size ( ) ) ) throw new IllegalArgumentException ( "getTimeName illegal index = " + index ) ; return cdates . get ( index ) . toString ( ) ; } /**
   * Get the index corresponding to the time name.
   *
   * @param name time name
   * @return time index, or -1 if not found
   * @deprecated
   */ public int getTimeIndex ( String name ) { List < CalendarDate > cdates = getCalendarDates ( ) ; for ( int i = 0 ; i < cdates . size ( ) ; i ++ ) { if ( cdates . get ( i ) . toString ( ) . equals ( name ) ) return i ; } return - 1 ; } /**
   * Only works if coordsys has 1d time axis
   * @deprecated use CoordinateAxis1DTime.findTimeIndexFromDate
   */ public int findTimeIndexFromDate ( java . util . Date d ) { if ( timeTaxis == null ) return - 1 ; return timeTaxis . findTimeIndexFromDate ( d ) ; } ///////////////////////////////////////////////////////////////////////
 // experimental
 static private double getMinOrMaxLon ( double lon1 , double lon2 , boolean wantMin ) { double midpoint = ( lon1 + lon2 ) / 2 ; lon1 = LatLonPointImpl . lonNormal ( lon1 , midpoint ) ; lon2 = LatLonPointImpl . lonNormal ( lon2 , midpoint ) ; return wantMin ? Math . min ( lon1 , lon2 ) : Math . max ( lon1 , lon2 ) ; } static public LatLonRect getLatLonBoundingBox ( Projection proj , double startx , double starty , double endx , double endy ) { if ( proj instanceof LatLonProjection ) { double deltaLat = endy - starty ; double deltaLon = endx - startx ; LatLonPoint llpt = new LatLonPointImpl ( starty , startx ) ; return new LatLonRect ( llpt , deltaLat , deltaLon ) ; } ProjectionRect bb = new ProjectionRect ( startx , starty , endx , endy ) ; // look at all 4 corners of the bounding box
 LatLonPointImpl llpt = ( LatLonPointImpl ) proj . projToLatLon ( bb . getLowerLeftPoint ( ) , new LatLonPointImpl ( ) ) ; LatLonPointImpl lrpt = ( LatLonPointImpl ) proj . projToLatLon ( bb . getLowerRightPoint ( ) , new LatLonPointImpl ( ) ) ; LatLonPointImpl urpt = ( LatLonPointImpl ) proj . projToLatLon ( bb . getUpperRightPoint ( ) , new LatLonPointImpl ( ) ) ; LatLonPointImpl ulpt = ( LatLonPointImpl ) proj . projToLatLon ( bb . getUpperLeftPoint ( ) , new LatLonPointImpl ( ) ) ; // Check if grid contains poles. LOOK disabled
 boolean includesNorthPole = false ; /* int[] resultNP = new int[2];
    resultNP = findXYindexFromLatLon(90.0, 0, null);
    if (resultNP[0] != -1 && resultNP[1] != -1)
      includesNorthPole = true;  */ boolean includesSouthPole = false ; /* int[] resultSP = new int[2];
    resultSP = findXYindexFromLatLon(-90.0, 0, null);
    if (resultSP[0] != -1 && resultSP[1] != -1)
      includesSouthPole = true;  */ LatLonRect llbb ; if ( includesNorthPole && ! includesSouthPole ) { llbb = new LatLonRect ( llpt , new LatLonPointImpl ( 90.0 , 0.0 ) ) ; // ??? lon=???
 llbb . extend ( lrpt ) ; llbb . extend ( urpt ) ; llbb . extend ( ulpt ) ; } else if ( includesSouthPole && ! includesNorthPole ) { llbb = new LatLonRect ( llpt , new LatLonPointImpl ( - 90.0 , - 180.0 ) ) ; // ??? lon=???
 llbb . extend ( lrpt ) ; llbb . extend ( urpt ) ; llbb . extend ( ulpt ) ; } else { double latMin = Math . min ( llpt . getLatitude ( ) , lrpt . getLatitude ( ) ) ; double latMax = Math . max ( ulpt . getLatitude ( ) , urpt . getLatitude ( ) ) ; // longitude is a bit tricky as usual
 double lonMin = getMinOrMaxLon ( llpt . getLongitude ( ) , ulpt . getLongitude ( ) , true ) ; double lonMax = getMinOrMaxLon ( lrpt . getLongitude ( ) , urpt . getLongitude ( ) , false ) ; llpt . set ( latMin , lonMin ) ; urpt . set ( latMax , lonMax ) ; llbb = new LatLonRect ( llpt , urpt ) ; } return llbb ; } }
Get the list of level names, to be used for user selection.
The ith one refers to the ith level coordinate.

@return List of ucar.nc2.util.NamedObject, or empty list.
Get the list of level names to be used for user selection . The ith one refers to the ith level coordinate .