[thredds] 'As Point Dataset' Subset Service / Bounding Box issue with Polar Stereographic Data

Hello John (and all),

We've run into a problem using the 'As Point Dataset' time series request
with Polar Stereographic data on the TDS (version 4.2.10).  For some
requests we are getting the message:

Requested Lat/Lon Point (+80.33N 138.6W) is not contained in the Data
Data Bounding Box =  lat= [30.92,90.00] lon= [-80.73,168.34]

as seen in this request:

The underlying issue seems to be in how the GridDataset CDM class
calculates the bounding box for this Polar Stereographic dataset.  The
bounding box should be something like lat=[31, 90], lon=[-180, 180].  Has
anyone else run into problems with the Bounding Box calculations for
projected datasets?  Perhaps the NetCDF-Java API is only sampling the
corners (and perhaps some points in between) of the coordinate axes to
determine the bounding box.  I would think this works for the other
NetCDF-Java supported projections, but might cause issues with the
Stereographic projections.

I'm pasting some sample code below to show that brute force reading of each
coordinate axis element value produces the correct bounding box:

Thanks for your help!


package steve.test;

import ucar.ma2.Array;
import ucar.nc2.dt.GridDatatype;
import ucar.nc2.dt.grid.GridDataset;
import ucar.unidata.geoloc.LatLonPoint;
import ucar.unidata.geoloc.LatLonPointImpl;
import ucar.unidata.geoloc.Projection;
import ucar.unidata.geoloc.ProjectionPoint;
import ucar.unidata.geoloc.ProjectionPointImpl;

public class TestGridAsPointSubsetService {

public static void main(String[] args) {
 try {
 String dodsURL = "
 GridDataset gds = GridDataset.open(dodsURL);

GridDatatype grid = gds.findGridDatatype("seaice_conc_cdr");
 double minX = grid.getCoordinateSystem().getXHorizAxis().getMinValue();
double maxX = grid.getCoordinateSystem().getXHorizAxis().getMaxValue();
double minY = grid.getCoordinateSystem().getYHorizAxis().getMinValue();
double maxY = grid.getCoordinateSystem().getYHorizAxis().getMaxValue();
 System.out.println("min x: "+minX);
System.out.println("max x: "+maxX);
System.out.println("min y: "+minY);
System.out.println("max y: "+maxY);
 Projection proj = grid.getProjection();
ProjectionPoint projPointLL = new ProjectionPointImpl(minX, minY);
LatLonPoint llPointLL = proj.projToLatLon(projPointLL, new
ProjectionPoint projPointUR = new ProjectionPointImpl(maxX, maxY);
LatLonPoint llPointUR = proj.projToLatLon(projPointUR, new
 System.out.println(llPointLL + " , "+llPointUR);
 Array xAxisData = grid.getCoordinateSystem().getXHorizAxis().read();
Array yAxisData = grid.getCoordinateSystem().getYHorizAxis().read();
double minLat = Double.POSITIVE_INFINITY;
double maxLat = Double.NEGATIVE_INFINITY;
double minLon = Double.POSITIVE_INFINITY;
double maxLon = Double.NEGATIVE_INFINITY;
LatLonPointImpl llp = new LatLonPointImpl();
ProjectionPointImpl ppt = new ProjectionPointImpl();
float[] xData = (float[])xAxisData.copyTo1DJavaArray();
float[] yData = (float[])yAxisData.copyTo1DJavaArray();

for (float y : yData) {
for (float x : xData) {
ppt.setLocation(x, y);
llp = (LatLonPointImpl) proj.projToLatLon(ppt, llp);
minLat = (llp.getLatitude() < minLat) ? llp.getLatitude() : minLat;
maxLat = (llp.getLatitude() > maxLat) ? llp.getLatitude() : maxLat;
minLon = (llp.getLongitude() < minLon) ? llp.getLongitude() : minLon;
maxLon = (llp.getLongitude() > maxLon) ? llp.getLongitude() : maxLon;
 // brute force range
System.out.println("brute force lat range: "+minLat+" , "+maxLat + " | lon
range: " + minLon + " , " + maxLon);
 // subset service TDS URL:
  } catch (Exception e) {