/*
* (c) 1998-2016 University Corporation for Atmospheric Research/Unidata
*/
package thredds.server.ncss.view.gridaspoint;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import ucar.ma2.InvalidRangeException;
import ucar.nc2.dataset.CoordinateAxis1D;
import ucar.nc2.dt.GridCoordSystem;
import ucar.nc2.dt.GridDataset;
import ucar.nc2.dt.GridDatatype;
import ucar.unidata.geoloc.vertical.VerticalTransform;
public class GeoCsvWriter extends CSVPointDataWriter {
static private final String GEOCSV_CONTAINER_TYPE = "GeoCSV 2.0";
static private final String DELIMITER = ",";
static private final String DEFAULT_MISSING_VALUE = "";
static private final String UNKNOWN_UNIT = "unknown";
private List<String> fieldNames = new ArrayList<>();
private List<String> fieldUnits = new ArrayList<>();
private List<String> fieldTypes = new ArrayList<>();
private List<String> fieldMissing = new ArrayList<>();
protected GeoCsvWriter(OutputStream os) {
super(os);
}
public static GeoCsvWriter factory(OutputStream os) {
return new GeoCsvWriter(os);
}
/**
* Helper to append new metadata to header. Use this when the variable
* does not have a missing value defined.
*
* @param name name of the variable
* @param unit unit of measurement
* @param type data type of the variable
*/
private void appendMetadata(String name, String unit, String type) {
appendMetadata(name, unit, type, "");
}
/**
* Helper to append new metadata to header
*
* @param name name of the variable
* @param unit unit of measurement
* @param type data type of the variable
* @param missing missing value
*/
private void appendMetadata(String name, String unit, String type, String missing) {
fieldNames.add(name);
fieldUnits.add(unit);
fieldTypes.add(type);
fieldMissing.add(missing);
}
/**
* Write out the header of the GeoCSV file
*
* @param varGroup List of Variables
* @param gridDataset GridDataset
* @param hasEnsAxis Has an ensemble axis?
* @param hasTimeAxis Has a time axis?
*/
@Override
protected void writeGroupHeader(List<String> varGroup, GridDataset gridDataset, boolean hasEnsAxis, boolean hasTimeAxis) {
if (hasTimeAxis) {
appendMetadata("time", "ISO_8601", "datetime");
}
appendMetadata("latitude", "degrees_north", "double");
appendMetadata("longitude", "degrees_east", "double");
if (hasEnsAxis) {
appendMetadata("ensMember", "unitless", "double");
}
GridCoordSystem coordSystem = gridDataset.findGridDatatype(varGroup.get(0)).getCoordinateSystem();
CoordinateAxis1D zAxis = coordSystem.getVerticalAxis();
if (zAxis != null) {
appendMetadata("vertCoord,", zAxis.getUnitsString(), zAxis.getDataType().toString(), "");
}
VerticalTransform vt = coordSystem.getVerticalTransform();
if (vt != null) {
String ft = "unknown";
try {
ft = vt.getCoordinateArray(0).getDataType().toString();
} catch (IOException e) {
// should get caught in super
} catch (InvalidRangeException e) {
// should get caught in super
}
appendMetadata("vertCoord", vt.getUnitString(), ft, "");
}
Iterator<String> it = varGroup.iterator();
while (it.hasNext()) {
GridDatatype grid = gridDataset.findGridDatatype(it.next());
String name = grid.getName();
String unit = UNKNOWN_UNIT;
if (grid.getUnitsString() != null) {
unit = grid.getUnitsString();
}
String type = grid.getDataType().toString();
String missing = DEFAULT_MISSING_VALUE;
if (grid.hasMissingData()) {
missing = grid.findAttributeIgnoreCase("missing_value").getStringValue();
}
appendMetadata(name, unit, type, missing);
}
printWriter.print("# dataset: ".concat(GEOCSV_CONTAINER_TYPE));
printWriter.println();
printWriter.print("# delimiter: ".concat(DELIMITER));
printWriter.println();
printWriter.print("# field_unit: ".concat(StringUtils.join(fieldUnits, DELIMITER)));
printWriter.println();
printWriter.print("# field_types: ".concat(StringUtils.join(fieldTypes, DELIMITER)));
printWriter.println();
printWriter.print("# field_missing: ".concat(StringUtils.join(fieldMissing, DELIMITER)));
printWriter.println();
printWriter.print(StringUtils.join(fieldNames, DELIMITER));
printWriter.println();
}
}