/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2014, Open Source Geospatial Foundation (OSGeo)
*
* 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;
* version 2.1 of the License.
*
* 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.geotools.imageio.netcdf.cv;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.logging.Logger;
import org.geotools.imageio.netcdf.utilities.NetCDFCRSUtilities;
import org.geotools.imageio.netcdf.utilities.NetCDFTimeUtilities;
import org.geotools.imageio.netcdf.utilities.NetCDFUtilities;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import ucar.nc2.Attribute;
import ucar.nc2.constants.AxisType;
import ucar.nc2.dataset.CoordinateAxis;
/**
* @author Simone Giannecchini, GeoSolutions SAS
* @author Niels Charlier
* TODO caching
*/
class TimeCoordinateVariable extends CoordinateVariable<Date> {
/** The LOGGER for this class. */
private static final Logger LOGGER = Logger.getLogger(TimeCoordinateVariable.class.toString());
private String units;
private int baseTimeUnits;
private Date epoch;
/**
* @param binding
* @param coordinateAxis
*/
public TimeCoordinateVariable(CoordinateAxis coordinateAxis) {
super(Date.class, coordinateAxis);
units = coordinateAxis.getUnitsString();
/*
* Gets the axis origin. In the particular case of time axis, units are typically written in the form "days since 1990-01-01
* 00:00:00". We extract the part before "since" as the units and the part after "since" as the date.
*/
String origin = null;
final String[] unitsParts = units.split("(?i)\\s+since\\s+");
if (unitsParts.length == 2) {
units = unitsParts[0].trim();
origin = unitsParts[1].trim();
} else {
final Attribute attribute = coordinateAxis.findAttribute("time_origin");
if (attribute != null) {
origin = attribute.getStringValue();
}
}
baseTimeUnits = NetCDFTimeUtilities.getTimeUnits(units, null);
if (baseTimeUnits == -1) {
throw new IllegalArgumentException(
"Couldn't determine time units from unit string '" + units + "'");
}
if (origin != null) {
origin = NetCDFTimeUtilities.trimFractionalPart(origin);
// add 0 digits if absent
origin = NetCDFTimeUtilities.checkDateDigits(origin);
try {
epoch = (Date) NetCDFUtilities.getAxisFormat(AxisType.Time, origin)
.parseObject(origin);
} catch (ParseException e) {
LOGGER.warning("Error while parsing time Axis. Skip setting the TemporalExtent from coordinateAxis");
}
}
init();
}
@Override
public boolean isNumeric() {
return false;
}
@Override
protected synchronized CoordinateReferenceSystem buildCoordinateReferenceSystem() {
return NetCDFCRSUtilities.buildTemporalCrs(coordinateAxis);
}
@Override
protected Date convertValue(Object o) {
final Calendar cal = new GregorianCalendar();
if (epoch != null) {
cal.setTime(epoch);
} else {
cal.setTimeInMillis(0);
}
cal.setTimeZone(NetCDFTimeUtilities.UTC_TIMEZONE);
final double coordValue = ((Number) o).doubleValue();
long vi = (long) Math.floor(coordValue);
double vd = coordValue - vi;
NetCDFTimeUtilities.addTimeUnit(cal, baseTimeUnits, vi);
if (vd != 0.0) {
NetCDFTimeUtilities.addTimeUnit(cal,
NetCDFTimeUtilities.getTimeUnits(units, vd),
NetCDFTimeUtilities.getTimeSubUnitsValue(units, vd));
}
return cal.getTime();
}
}