/*
* Geotoolkit - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2014, Geomatys
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotoolkit.sos.netcdf;
import java.util.List;
import ucar.ma2.Array;
import ucar.ma2.ArrayDouble;
import ucar.ma2.ArrayFloat;
import ucar.ma2.ArrayInt;
import ucar.ma2.ArrayLong;
import ucar.ma2.ArrayShort;
import ucar.ma2.DataType;
import ucar.nc2.Dimension;
import ucar.nc2.Variable;
import ucar.nc2.iosp.netcdf3.N3iosp;
import ucar.nc2.time.CalendarDate;
import ucar.nc2.time.CalendarDateUnit;
/**
*
* @author Guilhem Legal (Geomatys)
*/
public class NetCDFUtils {
public static final double FILL_VALUE = Double.parseDouble("1.e+36");
public static double getDoubleValue(final Array array, final int i, final Number fillValue) {
if (array instanceof ArrayInt.D1) {
int val = ((ArrayInt.D1)array).get(i);
if (val != N3iosp.NC_FILL_INT) {
return val;
}
} else if (array instanceof ArrayDouble.D1) {
double val = ((ArrayDouble.D1)array).get(i);
if (val != N3iosp.NC_FILL_DOUBLE && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayFloat.D1) {
float val = ((ArrayFloat.D1)array).get(i);
if (val != N3iosp.NC_FILL_FLOAT && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayShort.D1) {
short val = ((ArrayShort.D1)array).get(i);
if (val != N3iosp.NC_FILL_SHORT && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayLong.D1) {
long val = ((ArrayLong.D1)array).get(i);
if (val != N3iosp.NC_FILL_LONG && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else {
throw new IllegalArgumentException("Unexpected Array type for field:" + array.getClass().getName() + " expecting D1");
}
return Double.NaN;
}
public static double getDoubleValue(final Array array, final Number fillValue) {
if (array instanceof ArrayInt.D0) {
int val = ((ArrayInt.D0)array).get();
if (val != N3iosp.NC_FILL_INT && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayDouble.D0) {
double val = ((ArrayDouble.D0)array).get();
if (val != N3iosp.NC_FILL_DOUBLE && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayFloat.D0) {
float val = ((ArrayFloat.D0)array).get();
if (val != N3iosp.NC_FILL_FLOAT && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayShort.D0) {
short val = ((ArrayShort.D0)array).get();
if (val != N3iosp.NC_FILL_SHORT && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayLong.D0) {
long val = ((ArrayLong.D0)array).get();
if (val != N3iosp.NC_FILL_LONG && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else {
throw new IllegalArgumentException("Unexpected Array type for field:" + array.getClass().getName() + " expecting D0");
}
return Double.NaN;
}
public static double getDoubleValue(final boolean mainFirst, final Array array, int i, int j, final Number fillValue) {
if (!mainFirst) {
final int tmp = i;
i = j;
j = tmp;
}
if (array instanceof ArrayInt.D2) {
int val = ((ArrayInt.D2)array).get(i, j);
if (val != N3iosp.NC_FILL_INT && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayDouble.D2) {
double val = ((ArrayDouble.D2)array).get(i, j);
if (val != N3iosp.NC_FILL_DOUBLE && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayFloat.D2) {
float val = ((ArrayFloat.D2)array).get(i, j);
if (val != N3iosp.NC_FILL_FLOAT && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayShort.D2) {
short val = ((ArrayShort.D2)array).get(i, j);
if (val != N3iosp.NC_FILL_SHORT && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayLong.D2) {
long val = ((ArrayLong.D2)array).get(i, j);
if (val != N3iosp.NC_FILL_LONG && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else {
throw new IllegalArgumentException("Unexpected Array type for field:" + array.getClass().getName() + " expecting D2");
}
return Double.NaN;
}
public static double getDoubleValue(final Array array, int i, int j, int k, final Number fillValue) {
if (array instanceof ArrayInt.D3) {
int val = ((ArrayInt.D3)array).get(i, j, k);
if (val != N3iosp.NC_FILL_INT && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayDouble.D3) {
double val = ((ArrayDouble.D3)array).get(i, j, k);
if (val != N3iosp.NC_FILL_DOUBLE && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayFloat.D3) {
float val = ((ArrayFloat.D3)array).get(i, j, k);
if (val != N3iosp.NC_FILL_FLOAT && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayShort.D3) {
short val = ((ArrayShort.D3)array).get(i, j, k);
if (val != N3iosp.NC_FILL_SHORT && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else if (array instanceof ArrayLong.D3) {
long val = ((ArrayLong.D3)array).get(i, j, k);
if (val != N3iosp.NC_FILL_LONG && (fillValue == null || !fillValue.equals(val))) {
return val;
}
} else {
throw new IllegalArgumentException("Unexpected Array type for field:" + array.getClass().getName() + " expecting D3");
}
return Double.NaN;
}
public static long getTimeValue(final String units, final boolean mainFirst, boolean constantT, final Array array, int i, int j) {
if (constantT) {
return getTimeValue(units, array, i);
} else {
if (!mainFirst) {
final int tmp = i;
i = j;
j = tmp;
}
if (array instanceof ArrayInt.D2) {
final int value = ((ArrayInt.D2)array).get(i, j);
return parseTime(value, units);
} else if (array instanceof ArrayDouble.D2) {
final Double value = ((ArrayDouble.D2)array).get(i, j);
return parseTime(value.longValue(), units);
} else {
throw new IllegalArgumentException("Unexpected Array type for time field:" + array.getClass().getName());
}
}
}
public static long getTimeValue(final String units, final Array array, final int i) {
if (array instanceof ArrayInt.D1) {
final int value = ((ArrayInt.D1)array).get(i);
return parseTime(value, units);
} else if (array instanceof ArrayDouble.D1) {
final Double value = ((ArrayDouble.D1)array).get(i);
return parseTime(value.longValue(), units);
} else if (array instanceof ArrayFloat.D1) {
final Float value = ((ArrayFloat.D1)array).get(i);
return parseTime(value.longValue(), units);
} else if (array instanceof ArrayShort.D1) {
final Long value = ((ArrayShort.D1)array).getLong(i);
return parseTime(value, units);
} else {
throw new IllegalArgumentException("Unexpected Array type for time field:" + array.getClass().getName() + " expecting D1");
}
}
public static double getZValue(final boolean mainFirst, boolean constantZ, final Array zArray, final int i, final int j, final Number fillValue) {
if (constantZ) {
return getDoubleValue(zArray, i, fillValue);
} else {
return getDoubleValue(mainFirst, zArray, i, j, fillValue);
}
}
public static Type getTypeFromDataType(final DataType type) {
switch(type) {
case BOOLEAN:
return Type.BOOLEAN;
case BYTE:
return Type.UNSUPPORTED;
case CHAR:
return Type.STRING;
case SHORT:
return Type.INT;
case INT:
return Type.INT;
case LONG:
return Type.INT;
case FLOAT:
return Type.DOUBLE;
case DOUBLE:
return Type.DOUBLE;
case SEQUENCE:
return Type.UNSUPPORTED;
case STRING:
return Type.STRING;
case STRUCTURE:
return Type.UNSUPPORTED;
case ENUM1:
return Type.UNSUPPORTED;
case ENUM2:
return Type.UNSUPPORTED;
case ENUM4:
return Type.UNSUPPORTED;
case OPAQUE:
return Type.UNSUPPORTED;
/*case OBJECT:
return Type.UNSUPPORTED;*/
default: return Type.UNSUPPORTED;
}
}
public static Dimension getGoodTimeDimension(final Variable timeVar, final String separatorDim) {
if (separatorDim == null || timeVar.getDimensions().size() == 1) {
return timeVar.getDimension(0);
} else {
for (Dimension d : timeVar.getDimensions()) {
if (!d.getFullName().equals(separatorDim)) {
return d;
}
}
}
return null;
}
/**
* The method Variable.getDimensionsString() seems to have issues.
* @param var
* @return
*/
public static String getDimensionString(final Variable var) {
final List<Dimension> dims = var.getDimensions();
final StringBuilder result = new StringBuilder();
for (Dimension dim : dims) {
result.append(dim.getFullName()).append(' ');
}
if (result.length() > 0) {
result.deleteCharAt(result.length() -1);
}
return result.toString();
}
public static long parseTime(final long l, final String unit) {
final CalendarDateUnit c = CalendarDateUnit.of("gregorian", unit);
final CalendarDate date = c.makeCalendarDate(l);
return date.getMillis();
}
}