cdm/src/main/java/ucar/nc2/dt/grid/GridCoordSys.java
@Override
  public List<Range> getRangesFromLatLonRect(LatLonRect rect) throws InvalidRangeException {
    double minx, maxx, miny, maxy;

    ProjectionImpl proj = getProjection();
    if (proj != null && !(proj instanceof VerticalPerspectiveView) && !(proj instanceof MSGnavigation)
         && !(proj instanceof Geostationary)) { // LOOK kludge - how to do this generrally ??
      // first clip the request rectangle to the bounding box of the grid
      LatLonRect bb = getLatLonBoundingBox();
      LatLonRect rect2 = bb.intersect(rect);
      if (null == rect2)
        throw new InvalidRangeException("Request Bounding box does not intersect Grid ");
      rect = rect2;
    }

    CoordinateAxis xaxis = getXHorizAxis();
    CoordinateAxis yaxis = getYHorizAxis();

    if (isLatLon()) {

      LatLonPointImpl llpt = rect.getLowerLeftPoint();
      LatLonPointImpl urpt = rect.getUpperRightPoint();
      LatLonPointImpl lrpt = rect.getLowerRightPoint();
      LatLonPointImpl ulpt = rect.getUpperLeftPoint();

      minx = getMinOrMaxLon(llpt.getLongitude(), ulpt.getLongitude(), true);
      miny = Math.min(llpt.getLatitude(), lrpt.getLatitude());
      maxx = getMinOrMaxLon(urpt.getLongitude(), lrpt.getLongitude(), false);
      maxy = Math.min(ulpt.getLatitude(), urpt.getLatitude());

      // normalize to [minLon,minLon+360]
      double minLon = xaxis.getMinValue();
      minx = LatLonPointImpl.lonNormalFrom( minx, minLon);
      maxx = LatLonPointImpl.lonNormalFrom( maxx, minLon);

    } else {
      ProjectionRect prect = getProjection().latLonToProjBB(rect); // allow projection to override
      minx = prect.getMinPoint().getX();
      miny = prect.getMinPoint().getY();
      maxx = prect.getMaxPoint().getX();
      maxy = prect.getMaxPoint().getY();

      /*
      see ProjectionImpl.latLonToProjBB2()
      Projection dataProjection = getProjection();
      ProjectionPoint ll = dataProjection.latLonToProj(llpt, new ProjectionPointImpl());
      ProjectionPoint ur = dataProjection.latLonToProj(urpt, new ProjectionPointImpl());
      ProjectionPoint lr = dataProjection.latLonToProj(lrpt, new ProjectionPointImpl());
      ProjectionPoint ul = dataProjection.latLonToProj(ulpt, new ProjectionPointImpl());

      minx = Math.min(ll.getX(), ul.getX());
      miny = Math.min(ll.getY(), lr.getY());
      maxx = Math.max(ur.getX(), lr.getX());
      maxy = Math.max(ul.getY(), ur.getY()); */
    }


    if ((xaxis instanceof CoordinateAxis1D) && (yaxis instanceof CoordinateAxis1D)) {
      CoordinateAxis1D xaxis1 = (CoordinateAxis1D) xaxis;
      CoordinateAxis1D yaxis1 = (CoordinateAxis1D) yaxis;

      int minxIndex = xaxis1.findCoordElementBounded(minx);
      int minyIndex = yaxis1.findCoordElementBounded(miny);

      int maxxIndex = xaxis1.findCoordElementBounded(maxx);
      int maxyIndex = yaxis1.findCoordElementBounded(maxy);

      List<Range> list = new ArrayList<>();
      list.add(new Range(Math.min(minyIndex, maxyIndex), Math.max(minyIndex, maxyIndex)));
      list.add(new Range(Math.min(minxIndex, maxxIndex), Math.max(minxIndex, maxxIndex)));
      return list;

    } else if ((xaxis instanceof CoordinateAxis2D) && (yaxis instanceof CoordinateAxis2D) && isLatLon()) {
      CoordinateAxis2D lon_axis = (CoordinateAxis2D) xaxis;
      CoordinateAxis2D lat_axis = (CoordinateAxis2D) yaxis;
      int shape[] = lon_axis.getShape();
      int nj = shape[0];
      int ni = shape[1];

      int mini = Integer.MAX_VALUE, minj = Integer.MAX_VALUE;
      int maxi = -1, maxj = -1;

      // margolis 2/18/2010
      //minx = LatLonPointImpl.lonNormal( minx ); // <-- THIS IS NEW
      //maxx = LatLonPointImpl.lonNormal( maxx ); // <-- THIS IS NEW

      // brute force, examine every point LOOK BAD
      for (int j = 0; j < nj; j++) {
        for (int i = 0; i < ni; i++) {
          double lat = lat_axis.getCoordValue(j, i);
          double lon = lon_axis.getCoordValue(j, i);
          //lon = LatLonPointImpl.lonNormal( lon ); // <-- THIS IS NEW      

          if ((lat >= miny) && (lat <= maxy) && (lon >= minx) && (lon <= maxx)) {
            if (i > maxi) maxi = i;
            if (i < mini) mini = i;
            if (j > maxj) maxj = j;
            if (j < minj) minj = j;
            //System.out.println(j+" "+i+" lat="+lat+" lon="+lon);
          }
        }
      }

      // this is the case where no points are included
      if ((mini > maxi) || (minj > maxj)) {
        mini = 0;
        minj = 0;
        maxi = -1;
        maxj = -1;
      }

      ArrayList<Range> list = new ArrayList<>();
      list.add(new Range(minj, maxj));
      list.add(new Range(mini, maxi));
      return list;

    } else {
      throw new IllegalArgumentException("must be 1D or 2D/LatLon ");
    }

  }
@Override
  public List<Range> getRangesFromLatLonRect(LatLonRect rect) throws InvalidRangeException {
    double minx, maxx, miny, maxy;

    ProjectionImpl proj = getProjection();
    if (proj != null && !(proj instanceof VerticalPerspectiveView) && !(proj instanceof MSGnavigation)
         && !(proj instanceof Geostationary)) { // LOOK kludge - how to do this generrally ??
      // first clip the request rectangle to the bounding box of the grid
      LatLonRect bb = getLatLonBoundingBox();
      LatLonRect rect2 = bb.intersect(rect);
      if (null == rect2)
        throw new InvalidRangeException("Request Bounding box does not intersect Grid ");
      rect = rect2;
    }

    CoordinateAxis xaxis = getXHorizAxis();
    CoordinateAxis yaxis = getYHorizAxis();

    if (isLatLon()) {

      LatLonPointImpl llpt = rect.getLowerLeftPoint();
      LatLonPointImpl urpt = rect.getUpperRightPoint();
      LatLonPointImpl lrpt = rect.getLowerRightPoint();
      LatLonPointImpl ulpt = rect.getUpperLeftPoint();

      minx = getMinOrMaxLon(llpt.getLongitude(), ulpt.getLongitude(), true);
      miny = Math.min(llpt.getLatitude(), lrpt.getLatitude());
      maxx = getMinOrMaxLon(urpt.getLongitude(), lrpt.getLongitude(), false);
      maxy = Math.min(ulpt.getLatitude(), urpt.getLatitude());

      // normalize to [minLon,minLon+360]
      double minLon = xaxis.getMinValue();
      minx = LatLonPointImpl.lonNormalFrom( minx, minLon);
      maxx = LatLonPointImpl.lonNormalFrom( maxx, minLon);

    } else {
      ProjectionRect prect = getProjection().latLonToProjBB(rect); // allow projection to override
      minx = prect.getMinPoint().getX();
      miny = prect.getMinPoint().getY();
      maxx = prect.getMaxPoint().getX();
      maxy = prect.getMaxPoint().getY();

      /*
      see ProjectionImpl.latLonToProjBB2()
      Projection dataProjection = getProjection();
      ProjectionPoint ll = dataProjection.latLonToProj(llpt, new ProjectionPointImpl());
      ProjectionPoint ur = dataProjection.latLonToProj(urpt, new ProjectionPointImpl());
      ProjectionPoint lr = dataProjection.latLonToProj(lrpt, new ProjectionPointImpl());
      ProjectionPoint ul = dataProjection.latLonToProj(ulpt, new ProjectionPointImpl());

      minx = Math.min(ll.getX(), ul.getX());
      miny = Math.min(ll.getY(), lr.getY());
      maxx = Math.max(ur.getX(), lr.getX());
      maxy = Math.max(ul.getY(), ur.getY()); */
    }


    if ((xaxis instanceof CoordinateAxis1D) && (yaxis instanceof CoordinateAxis1D)) {
      CoordinateAxis1D xaxis1 = (CoordinateAxis1D) xaxis;
      CoordinateAxis1D yaxis1 = (CoordinateAxis1D) yaxis;

      int minxIndex = xaxis1.findCoordElementBounded(minx);
      int minyIndex = yaxis1.findCoordElementBounded(miny);

      int maxxIndex = xaxis1.findCoordElementBounded(maxx);
      int maxyIndex = yaxis1.findCoordElementBounded(maxy);

      List<Range> list = new ArrayList<>();
      list.add(new Range(Math.min(minyIndex, maxyIndex), Math.max(minyIndex, maxyIndex)));
      list.add(new Range(Math.min(minxIndex, maxxIndex), Math.max(minxIndex, maxxIndex)));
      return list;

    } else if ((xaxis instanceof CoordinateAxis2D) && (yaxis instanceof CoordinateAxis2D) && isLatLon()) {
      CoordinateAxis2D lon_axis = (CoordinateAxis2D) xaxis;
      CoordinateAxis2D lat_axis = (CoordinateAxis2D) yaxis;
      int shape[] = lon_axis.getShape();
      int nj = shape[0];
      int ni = shape[1];

      int mini = Integer.MAX_VALUE, minj = Integer.MAX_VALUE;
      int maxi = -1, maxj = -1;

      // margolis 2/18/2010
      //minx = LatLonPointImpl.lonNormal( minx ); // <-- THIS IS NEW
      //maxx = LatLonPointImpl.lonNormal( maxx ); // <-- THIS IS NEW

      // brute force, examine every point LOOK BAD
      for (int j = 0; j < nj; j++) {
        for (int i = 0; i < ni; i++) {
          double lat = lat_axis.getCoordValue(j, i);
          double lon = lon_axis.getCoordValue(j, i);
          //lon = LatLonPointImpl.lonNormal( lon ); // <-- THIS IS NEW      

          if ((lat >= miny) && (lat <= maxy) && (lon >= minx) && (lon <= maxx)) {
            if (i > maxi) maxi = i;
            if (i < mini) mini = i;
            if (j > maxj) maxj = j;
            if (j < minj) minj = j;
            //System.out.println(j+" "+i+" lat="+lat+" lon="+lon);
          }
        }
      }

      // this is the case where no points are included
      if ((mini > maxi) || (minj > maxj)) {
        mini = 0;
        minj = 0;
        maxi = -1;
        maxj = -1;
      }

      ArrayList<Range> list = new ArrayList<>();
      list.add(new Range(minj, maxj));
      list.add(new Range(mini, maxi));
      return list;

    } else {
      throw new IllegalArgumentException("must be 1D or 2D/LatLon ");
    }

  }
@ Override public List < Range > getRangesFromLatLonRect ( LatLonRect rect ) throws InvalidRangeException { double minx , maxx , miny , maxy ; ProjectionImpl proj = getProjection ( ) ; if ( proj != null && ! ( proj instanceof VerticalPerspectiveView ) && ! ( proj instanceof MSGnavigation ) && ! ( proj instanceof Geostationary ) ) { // LOOK kludge - how to do this generrally ??
 // first clip the request rectangle to the bounding box of the grid
 LatLonRect bb = getLatLonBoundingBox ( ) ; LatLonRect rect2 = bb . intersect ( rect ) ; if ( null == rect2 ) throw new InvalidRangeException ( "Request Bounding box does not intersect Grid " ) ; rect = rect2 ; } CoordinateAxis xaxis = getXHorizAxis ( ) ; CoordinateAxis yaxis = getYHorizAxis ( ) ; if ( isLatLon ( ) ) { LatLonPointImpl llpt = rect . getLowerLeftPoint ( ) ; LatLonPointImpl urpt = rect . getUpperRightPoint ( ) ; LatLonPointImpl lrpt = rect . getLowerRightPoint ( ) ; LatLonPointImpl ulpt = rect . getUpperLeftPoint ( ) ; minx = getMinOrMaxLon ( llpt . getLongitude ( ) , ulpt . getLongitude ( ) , true ) ; miny = Math . min ( llpt . getLatitude ( ) , lrpt . getLatitude ( ) ) ; maxx = getMinOrMaxLon ( urpt . getLongitude ( ) , lrpt . getLongitude ( ) , false ) ; maxy = Math . min ( ulpt . getLatitude ( ) , urpt . getLatitude ( ) ) ; // normalize to [minLon,minLon+360]
 double minLon = xaxis . getMinValue ( ) ; minx = LatLonPointImpl . lonNormalFrom ( minx , minLon ) ; maxx = LatLonPointImpl . lonNormalFrom ( maxx , minLon ) ; } else { ProjectionRect prect = getProjection ( ) . latLonToProjBB ( rect ) ; // allow projection to override
 minx = prect . getMinPoint ( ) . getX ( ) ; miny = prect . getMinPoint ( ) . getY ( ) ; maxx = prect . getMaxPoint ( ) . getX ( ) ; maxy = prect . getMaxPoint ( ) . getY ( ) ; /*
      see ProjectionImpl.latLonToProjBB2()
      Projection dataProjection = getProjection();
      ProjectionPoint ll = dataProjection.latLonToProj(llpt, new ProjectionPointImpl());
      ProjectionPoint ur = dataProjection.latLonToProj(urpt, new ProjectionPointImpl());
      ProjectionPoint lr = dataProjection.latLonToProj(lrpt, new ProjectionPointImpl());
      ProjectionPoint ul = dataProjection.latLonToProj(ulpt, new ProjectionPointImpl());

      minx = Math.min(ll.getX(), ul.getX());
      miny = Math.min(ll.getY(), lr.getY());
      maxx = Math.max(ur.getX(), lr.getX());
      maxy = Math.max(ul.getY(), ur.getY()); */ } if ( ( xaxis instanceof CoordinateAxis1D ) && ( yaxis instanceof CoordinateAxis1D ) ) { CoordinateAxis1D xaxis1 = ( CoordinateAxis1D ) xaxis ; CoordinateAxis1D yaxis1 = ( CoordinateAxis1D ) yaxis ; int minxIndex = xaxis1 . findCoordElementBounded ( minx ) ; int minyIndex = yaxis1 . findCoordElementBounded ( miny ) ; int maxxIndex = xaxis1 . findCoordElementBounded ( maxx ) ; int maxyIndex = yaxis1 . findCoordElementBounded ( maxy ) ; List < Range > list = new ArrayList <> ( ) ; list . add ( new Range ( Math . min ( minyIndex , maxyIndex ) , Math . max ( minyIndex , maxyIndex ) ) ) ; list . add ( new Range ( Math . min ( minxIndex , maxxIndex ) , Math . max ( minxIndex , maxxIndex ) ) ) ; return list ; } else if ( ( xaxis instanceof CoordinateAxis2D ) && ( yaxis instanceof CoordinateAxis2D ) && isLatLon ( ) ) { CoordinateAxis2D lon_axis = ( CoordinateAxis2D ) xaxis ; CoordinateAxis2D lat_axis = ( CoordinateAxis2D ) yaxis ; int shape [ ] = lon_axis . getShape ( ) ; int nj = shape [ 0 ] ; int ni = shape [ 1 ] ; int mini = Integer . MAX_VALUE , minj = Integer . MAX_VALUE ; int maxi = - 1 , maxj = - 1 ; // margolis 2/18/2010
 //minx = LatLonPointImpl.lonNormal( minx ); // <-- THIS IS NEW
 //maxx = LatLonPointImpl.lonNormal( maxx ); // <-- THIS IS NEW
 // brute force, examine every point LOOK BAD
 for ( int j = 0 ; j < nj ; j ++ ) { for ( int i = 0 ; i < ni ; i ++ ) { double lat = lat_axis . getCoordValue ( j , i ) ; double lon = lon_axis . getCoordValue ( j , i ) ; //lon = LatLonPointImpl.lonNormal( lon ); // <-- THIS IS NEW      
 if ( ( lat >= miny ) && ( lat <= maxy ) && ( lon >= minx ) && ( lon <= maxx ) ) { if ( i > maxi ) maxi = i ; if ( i < mini ) mini = i ; if ( j > maxj ) maxj = j ; if ( j < minj ) minj = j ; //System.out.println(j+" "+i+" lat="+lat+" lon="+lon);
 } } } // this is the case where no points are included
 if ( ( mini > maxi ) || ( minj > maxj ) ) { mini = 0 ; minj = 0 ; maxi = - 1 ; maxj = - 1 ; } ArrayList < Range > list = new ArrayList <> ( ) ; list . add ( new Range ( minj , maxj ) ) ; list . add ( new Range ( mini , maxi ) ) ; return list ; } else { throw new IllegalArgumentException ( "must be 1D or 2D/LatLon " ) ; } }
Get Index Ranges for the given lat, lon bounding box.
For projection, only an approximation based on latlon corners.
Must have CoordinateAxis1D or 2D for x and y axis.

@param rect the requested lat/lon bounding box
@return list of 2 Range objects, first y then x.
Get Index Ranges for the given lat lon bounding box . For projection only an approximation based on latlon corners . Must have CoordinateAxis1D or 2D for x and y axis .