/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2016, 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.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.geotools.imageio.Identification;
import org.geotools.imageio.netcdf.utilities.NetCDFCRSUtilities;
import org.geotools.imageio.netcdf.utilities.NetCDFTimeUtilities;
import org.geotools.referencing.cs.DefaultCoordinateSystemAxis;
import org.geotools.temporal.object.DefaultPosition;
import org.geotools.util.SimpleInternationalString;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.TemporalCRS;
import org.opengis.referencing.cs.AxisDirection;
import org.opengis.referencing.cs.TimeCS;
import org.opengis.referencing.datum.TemporalDatum;
import org.opengis.temporal.Position;
import ucar.nc2.dataset.CoordinateAxis;
/**
* A {@link CoordinateVariable} used to wrap Coordinates
* expressing climatological time
*/
public class ClimatologicalTimeCoordinateVariable extends CoordinateVariable<Date> {
private static final String ORIGIN_DATE = "0000-01-01T00:00:00";
private static final Logger LOGGER = Logger.getLogger(ClimatologicalTimeCoordinateVariable.class.toString());
public ClimatologicalTimeCoordinateVariable(CoordinateAxis coordinateAxis) {
super(Date.class, coordinateAxis);
init();
}
@Override
public boolean isNumeric() {
return false;
}
@Override
protected synchronized TemporalCRS buildCoordinateReferenceSystem() {
String t_datumName = new Identification("ISO8601", null, null, null).getName();
TemporalCRS temporalCRS = null;
String axisName = coordinateAxis.getFullName();
try {
String t_csName = "time_CS";
final Map<String, String> csMap = Collections.singletonMap("name", t_csName);
TimeCS timeCS = NetCDFCRSUtilities.FACTORY_CONTAINER.getCSFactory().createTimeCS(csMap,
DefaultCoordinateSystemAxis.getPredefined(axisName, AxisDirection.FUTURE));
// Creating the Temporal Datum
if (t_datumName == null) {
t_datumName = "Unknown";
}
final Map<String, String> datumMap = Collections.singletonMap("name", t_datumName);
final Position timeOrigin = new DefaultPosition(new SimpleInternationalString(
ORIGIN_DATE));
final TemporalDatum temporalDatum = NetCDFCRSUtilities.FACTORY_CONTAINER
.getDatumFactory().createTemporalDatum(datumMap, timeOrigin.getDate());
// Finally creating the Temporal CoordinateReferenceSystem
String crsName = "time_CRS";
final Map<String, String> crsMap = Collections.singletonMap("name", crsName);
temporalCRS = NetCDFCRSUtilities.FACTORY_CONTAINER.getCRSFactory().createTemporalCRS(
crsMap, temporalDatum, timeCS);
} catch (FactoryException e) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Unable to parse temporal CRS", e);
}
temporalCRS = null;
} catch (ParseException e) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Unable to parse temporal CRS", e);
}
temporalCRS = null;
}
return temporalCRS;
}
@Override
protected Date convertValue(Object o) {
String coordVal = (String) o;
Calendar cal = new GregorianCalendar(NetCDFTimeUtilities.UTC_TIMEZONE);
cal.set(Calendar.YEAR, Integer.parseInt(coordVal.substring(0, 4)));
cal.set(Calendar.MONTH, Integer.parseInt(coordVal.substring(4, 6)) - 1);
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(coordVal.substring(6, 8)));
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(coordVal.substring(8, 10)));
cal.set(Calendar.MINUTE, Integer.parseInt(coordVal.substring(10, 12)));
cal.set(Calendar.SECOND, Integer.parseInt(coordVal.substring(12, 14)));
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
}