ucar.nc2.dataset.CoordinateAxis2D Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of netcdf Show documentation
Show all versions of netcdf Show documentation
The NetCDF-Java Library is a Java interface to NetCDF files,
as well as to many other types of scientific data formats.
/*
* Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package ucar.nc2.dataset;
import ucar.ma2.*;
import ucar.nc2.Variable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* A 2-dimensional numeric Coordinate Axis. Must be invertible meaning, roughly, that
* if you draw lines connecting the points, none would cross.
*
* @see CoordinateAxis#factory
* @author john caron
*/
public class CoordinateAxis2D extends CoordinateAxis {
static private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CoordinateAxis2D.class);
static private final boolean debug = false;
/**
* Create a 2D coordinate axis from an existing VariableDS
* @param ncd the containing dataset
* @param vds create it from here
*/
public CoordinateAxis2D( NetcdfDataset ncd, VariableDS vds) {
super( ncd, vds);
}
// for section and slice
@Override
protected Variable copy() {
return new CoordinateAxis2D(this.ncd, this);
}
/** Get the coordinate value at the i, j index.
* @param i index 0
* @param j index 1
* @return coordinate value.
*/
public double getCoordValue(int i, int j) {
if (midpoint == null) doRead();
return midpoint.get( i, j);
}
private ArrayDouble.D2 midpoint = null;
private void doRead() {
Array data;
try {
data = read();
// if (!hasCachedData()) setCachedData(data, false); //cache data for subsequent reading
} catch (IOException ioe) {
log.error("Error reading coordinate values " + ioe);
throw new IllegalStateException(ioe);
}
data = data.reduce();
if (data.getRank() != 2)
throw new IllegalArgumentException("must be 2D");
if (debug)
System.out.printf("Coordinate2D read%n");
midpoint = (ArrayDouble.D2) Array.factory(double.class, data.getShape(), data.get1DJavaArray( double.class) );
}
/** Get the coordinate values as a 1D double array, in canonical order.
* @return coordinate values
* @exception UnsupportedOperationException if !isNumeric()
*/
public double[] getCoordValues() {
if (midpoint == null) doRead();
if (!isNumeric())
throw new UnsupportedOperationException("CoordinateAxis2D.getCoordValues() on non-numeric");
return (double[]) midpoint.get1DJavaArray( double.class);
}
/**
* Create a new CoordinateAxis2D as a section of this CoordinateAxis2D.
* @param r1 the section on the first index
* @param r2 the section on the second index
* @return a section of this CoordinateAxis2D
* @throws InvalidRangeException if specified Ranges are invalid
*/
public CoordinateAxis2D section(Range r1, Range r2) throws InvalidRangeException {
List section = new ArrayList();
section.add(r1);
section.add(r2);
return (CoordinateAxis2D) section( section);
}
public ArrayDouble.D2 getMidpoints() {
if (midpoint == null) doRead();
return midpoint;
}
/**
* Normal case: do something reasonable in deciding on the edges when we have the midpoints of a 2D coordinate.
* @param midx x coordinates of midpoints
* @return x coordinates of edges with shape (ny+1, nx+1)
*/
static public ArrayDouble.D2 makeXEdges(ArrayDouble.D2 midx) {
int[] shape = midx.getShape();
int ny = shape[0];
int nx = shape[1];
ArrayDouble.D2 edgex = new ArrayDouble.D2(ny+1, nx+1);
for (int y=0; y
edge[i] <= pos < edge[i+1] (if values are ascending)
edge[i] > pos >= edge[i+1] (if values are descending)
@param pos position in this coordinate system
@param lastIndex last position we looked for, or -1 if none
@return index of grid point containing it, or -1 if outside grid area
*
public int findCoordElement(double pos, int lastIndex) {
if (!isNumeric())
throw new UnsupportedOperationException("CoordinateAxis.findCoordElement() on non-numeric");
if (axisType == AxisType.Lon) {
for (int x=0; x < getSize(); x++) {
if (LatLonPointImpl.betweenLon( pos, getCoordEdge(x), getCoordEdge(x+1)))
return x;
}
return -1;
}
if (lastIndex < 0) lastIndex = (int) getSize()/2;
if (isAscending) {
if ((pos < getCoordEdge(0)) || (pos > getCoordEdge((int)getSize())))
return -1;
while (pos < getCoordEdge(lastIndex))
lastIndex--;
while (pos > getCoordEdge(lastIndex+1))
lastIndex++;
return lastIndex;
} else {
if ((pos > getCoordEdge(0)) || (pos < getCoordEdge((int)getSize())))
return -1;
while (pos > getCoordEdge(lastIndex))
lastIndex--;
while (pos < getCoordEdge(lastIndex+1))
lastIndex++;
return lastIndex;
}
}
///////////////////////////////////////////////////////////////////////////////
private boolean isAscending;
private boolean wasRead = false;
private void doRead() {
if (isNumeric()) {
readValues();
wasRead = true;
//calcIsRegular();
} else {
readStringValues();
wasRead = true;
}
isAscending = getCoordEdge(0) < getCoordEdge(1);
}
private String[] names = null;
private void readStringValues() {
int count = 0;
ArrayChar data;
try {
data = (ArrayChar) read();
} catch (IOException ioe) { return; }
ArrayChar.StringIterator iter = data.getStringIterator();
names = new String[ iter.getNumElems()];
while (iter.hasNext())
names[count++] = iter.next();
}
private double[] midpoint, edge;
private void readValues() {
midpoint = new double[ (int) getSize()];
int count = 0;
Array data;
try {
data = read();
} catch (IOException ioe) { return; }
IndexIterator iter = data.getIndexIterator();
while (iter.hasNext())
midpoint[count++] = iter.getDoubleNext();
makeEdges();
}
private void makeEdges() {
int size = (int) getSize();
edge = new double[size+1];
for(int i=1; i