ucar.nc2.ft.grid.impl.CoverageCSFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cdm Show documentation
Show all versions of cdm Show documentation
The NetCDF-Java Library is a Java interface to NetCDF files,
as well as to many other types of scientific data formats.
The newest version!
package ucar.nc2.ft.grid.impl;
import ucar.nc2.Dimension;
import ucar.nc2.constants.AxisType;
import ucar.nc2.dataset.*;
import ucar.nc2.ft.grid.CoverageCS;
import ucar.nc2.units.SimpleUnit;
import ucar.unidata.geoloc.ProjectionImpl;
import ucar.unidata.geoloc.projection.RotatedPole;
import java.util.*;
/**
* Factory for Coverage Coordinate Systems.
* Replaces complexity in ucar.nc2.dt.grid.GridCoordSys.isGridCoordSys()
*
* @author John
* @since 12/23/12
*/
public class CoverageCSFactory {
public static CoverageCS make(NetcdfDataset ds, CoordinateSystem cs) {
CoverageCSFactory fac = new CoverageCSFactory();
fac.type = fac.classify(ds, cs, null);
switch (fac.type) {
case Curvilinear:
case Coverage:
return new CoverageCSImpl(ds, cs, fac);
case Grid:
return new GridCSImpl(ds, cs, fac);
case Fmrc:
return new FmrcCSImpl(ds, cs, fac);
case Swath:
return new SwathCSImpl(ds, cs, fac);
}
return null;
}
public static String describe(Formatter f, NetcdfDataset ds) {
CoverageCSFactory fac = new CoverageCSFactory();
fac.type = fac.classify(ds, f);
return fac.toString();
}
public static String describe(Formatter f, CoordinateSystem cs) {
CoverageCSFactory fac = new CoverageCSFactory();
fac.type = fac.classify(null, cs, f);
return fac.toString();
}
/////////
//NetcdfDataset ds;
CoverageCS.Type type;
CoordinateAxis vertAxis;
CoordinateAxis timeAxis;
List standardAxes;
List otherAxes;
CoverageCSFactory() {
}
CoverageCS.Type classify(NetcdfDataset ds, Formatter errlog) {
if (errlog != null) errlog.format("CoverageFactory for '%s'%n", ds.getLocation());
// sort by largest size first
List css = new ArrayList(ds.getCoordinateSystems());
Collections.sort(css, new Comparator() {
public int compare(CoordinateSystem o1, CoordinateSystem o2) {
return o2.getCoordinateAxes().size() - o1.getCoordinateAxes().size();
}
});
CoverageCS.Type isMine = null;
for (CoordinateSystem cs : css) {
isMine = classify(ds, cs, errlog);
if (isMine != null) break;
}
if (errlog != null) errlog.format("coverage = %s%n", isMine);
return isMine;
}
CoverageCS.Type classify(NetcdfDataset ds, CoordinateSystem cs, Formatter errlog) {
// must be at least 2 axes
if (cs.getRankDomain() < 2) {
if (errlog != null) errlog.format("CoordinateSystem '%s': domain rank < 2%n", cs.getName());
return null;
}
// must be lat/lon or have x,y and projection
if (!cs.isLatLon()) {
// do check for GeoXY
if ((cs.getXaxis() == null) || (cs.getYaxis() == null)) {
if (errlog != null) {
errlog.format("%s: NO Lat,Lon or X,Y axis%n", cs.getName());
}
return null;
}
if (null == cs.getProjection()) {
if (errlog != null) {
errlog.format("%s: NO projection found%n", cs.getName());
}
return null;
}
}
// obtain the x,y or lat/lon axes. x,y normally must be convertible to km
CoordinateAxis xaxis, yaxis;
if (cs.isGeoXY()) {
xaxis = cs.getXaxis();
yaxis = cs.getYaxis();
ProjectionImpl p = cs.getProjection();
if (!(p instanceof RotatedPole)) {
if (!SimpleUnit.kmUnit.isCompatible(xaxis.getUnitsString())) {
if (errlog != null) {
errlog.format("%s: X axis units are not convertible to km%n", cs.getName());
}
//return false;
}
if (!SimpleUnit.kmUnit.isCompatible(yaxis.getUnitsString())) {
if (errlog != null) {
errlog.format("%s: Y axis units are not convertible to km%n", cs.getName());
}
//return false;
}
}
} else {
xaxis = cs.getLonAxis();
yaxis = cs.getLatAxis();
}
// check x,y rank <= 2
if ((xaxis.getRank() > 2) || (yaxis.getRank() > 2)) {
if (errlog != null) errlog.format("%s: X and Y axis rank must be <= 2%n", cs.getName());
return null;
}
// check x,y with size 1
if ((xaxis.getSize() < 2) || (yaxis.getSize() < 2)) {
if (errlog != null) errlog.format("%s: X and Y axis size must be >= 2%n", cs.getName());
return null;
}
// check that the x,y have at least 2 dimensions between them ( this eliminates point data)
List xyDomain = CoordinateSystem.makeDomain(new CoordinateAxis[]{xaxis, yaxis});
if (xyDomain.size() < 2) {
if (errlog != null) errlog.format("%s: X and Y axis must have 2 or more dimensions%n", cs.getName());
return null;
}
standardAxes = new ArrayList();
standardAxes.add(xaxis);
standardAxes.add(yaxis);
//int countRangeRank = 2;
vertAxis = cs.getHeightAxis();
if ((vertAxis == null) || (vertAxis.getRank() > 1)) {
if (cs.getPressureAxis() != null) vertAxis = cs.getPressureAxis();
}
if ((vertAxis == null) || (vertAxis.getRank() > 1)) {
if (cs.getZaxis() != null) vertAxis = cs.getZaxis();
}
if (vertAxis != null)
standardAxes.add(vertAxis);
// tom margolis 3/2/2010
// allow runtime independent of time
CoordinateAxis t = cs.getTaxis();
CoordinateAxis rt = cs.findAxis(AxisType.RunTime);
// A runtime axis must be one-dimensional
if (rt != null && !(rt instanceof CoordinateAxis1D)) {
if (errlog != null) errlog.format("%s: RunTime axis must be 1D%n", cs.getName());
return null;
}
// If time axis is two-dimensional...
if ((t != null) && !(t instanceof CoordinateAxis1D) && (t.getRank() != 0)) {
if (rt != null) { // runtime needs 2d time with first dimension == runtime dimension
if (rt.getRank() != 1) {
if (errlog != null) errlog.format("%s: Runtime axis must be 1D%n", cs.getName());
return null;
}
// time may be 1 or 2 dimensional, but first dimension must agree
if (!rt.getDimension(0).equals(t.getDimension(0))) {
if (errlog != null) errlog.format("%s: Time axis must use first RunTime dimension%n", cs.getName());
return null;
}
}
}
// convert time axis if possible
if (ds != null && t != null) {
if (t instanceof CoordinateAxis1D) {
try {
if (t instanceof CoordinateAxis1DTime)
timeAxis = t;
else {
t = timeAxis = CoordinateAxis1DTime.factory(ds, t, errlog);
}
} catch (Exception e) {
if (errlog != null)
errlog.format("%s: Error reading time coord= %s err= %s%n", t.getDatasetLocation(), t.getFullName(), e.getMessage());
}
} else { // 2d LOOK ??
timeAxis = t;
}
}
// Set the primary temporal axis - either Time or Runtime
if (t != null) {
standardAxes.add(t);
} else if (rt != null) {
standardAxes.add(rt);
}
// construct list of non standard axes
List css = cs.getCoordinateAxes();
if (standardAxes.size() < css.size()) {
otherAxes = new ArrayList(3);
for (CoordinateAxis axis : css)
if (!standardAxes.contains(axis)) otherAxes.add(axis);
}
// now to classify
CoverageCS.Type result = null;
// 2D x,y
if (cs.isLatLon() && (xaxis.getRank() == 2) && (yaxis.getRank() == 2)) {
if ((rt != null) && (t != null && t.getRank() == 2)) // fmrc with curvilinear coordinates
result = CoverageCS.Type.Fmrc;
else if (t != null) { // is t independent or not
if (CoordinateSystem.isSubset(t.getDimensionsAll(), xyDomain))
result = CoverageCS.Type.Swath;
else
result = CoverageCS.Type.Curvilinear;
} else
result = CoverageCS.Type.Curvilinear; // if no time coordinate. call it curvilinear
} else {
if ((xaxis.getRank() == 1) && (yaxis.getRank() == 1) && (vertAxis == null || vertAxis.getRank() == 1)) {
if ((rt != null) && (t != null && t.getRank() == 2))
result = CoverageCS.Type.Fmrc;
else
result = CoverageCS.Type.Grid;
} else {
result = CoverageCS.Type.Coverage;
}
}
return result;
}
public String toString() {
if (type == null) return "";
Formatter f2 = new Formatter();
f2.format("%s", type);
f2.format("(");
int count = 0;
Collections.sort(standardAxes, new Comparator() { // sort by axis type
public int compare(CoordinateAxis o1, CoordinateAxis o2) {
AxisType t1 = o1.getAxisType();
AxisType t2 = o2.getAxisType();
if (t1 != null && t2 != null)
return t1.axisOrder() - t2.axisOrder();
return (t1 == null) ? ((t2 == null) ? 0 : -1) : 1;
}
});
for (CoordinateAxis axis : standardAxes) {
if (count++ > 0) f2.format(",");
f2.format("%s", axis.getAxisType() == null ? "none" : axis.getAxisType().getCFAxisName());
}
f2.format(")");
if (otherAxes != null && otherAxes.size() > 0) {
f2.format(": ");
count = 0;
for (CoordinateAxis axis : otherAxes) {
if (count++ > 0) f2.format(",");
f2.format("%s", axis.getShortName());
}
}
return f2.toString();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy