package thredds.server.ncss.view.dsg.station;
import org.springframework.http.HttpHeaders;
import thredds.server.ncss.controller.NcssController;
import thredds.server.ncss.exception.NcssException;
import thredds.server.ncss.params.NcssParamsBean;
import thredds.server.ncss.util.NcssRequestUtils;
import thredds.util.ContentType;
import ucar.nc2.Attribute;
import ucar.nc2.NetcdfFileWriter;
import ucar.nc2.constants.AxisType;
import ucar.nc2.constants.CDM;
import ucar.nc2.dataset.CoordinateAxis;
import ucar.nc2.dataset.NetcdfDataset;
import ucar.nc2.ft.FeatureDatasetPoint;
import ucar.nc2.ft.point.StationPointFeature;
import ucar.nc2.ft.point.writer.CFPointWriterConfig;
import ucar.nc2.ft.point.writer.WriterCFStationCollection;
import ucar.nc2.units.DateUnit;
import ucar.nc2.util.DiskCache2;
import ucar.nc2.util.IO;
import ucar.unidata.geoloc.Station;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created by cwardgar on 2014/05/29.
*/
public class StationSubsetWriterNetcdf extends AbstractStationSubsetWriter {
private final OutputStream out;
private final NetcdfFileWriter.Version version;
private final File netcdfResult;
private final WriterCFStationCollection cfWriter;
public StationSubsetWriterNetcdf(FeatureDatasetPoint fdPoint, NcssParamsBean ncssParams,
DiskCache2 diskCache, OutputStream out, NetcdfFileWriter.Version version) throws NcssException, IOException {
super(fdPoint, ncssParams);
this.out = out;
this.version = version;
this.netcdfResult = diskCache.createUniqueFile("ncssTemp", ".nc");
List<Attribute> attribs = new ArrayList<>();
attribs.add(new Attribute(CDM.TITLE, "Extracted data from TDS Feature Collection " + fdPoint.getLocation()));
// A default value in case we can't find a better one in the dataset.
// This is the same default that is used in PointDatasetStandard.
DateUnit timeUnit = DateUnit.factory("seconds since 1970-01-01");
// If this remains null, it means the dataset has no altitude variable.
String altUnit = null;
if (fdPoint.getNetcdfFile() instanceof NetcdfDataset) {
NetcdfDataset dataset = (NetcdfDataset) fdPoint.getNetcdfFile();
CoordinateAxis timeAxis = dataset.findCoordinateAxis(AxisType.Time);
if (timeAxis != null && timeAxis.getUnitsString() != null) {
timeUnit = DateUnit.factory(timeAxis.getUnitsString());
}
CoordinateAxis altAxis = dataset.findCoordinateAxis(AxisType.Height);
if (altAxis != null) {
altUnit = altAxis.getUnitsString();
}
}
this.cfWriter = new WriterCFStationCollection( netcdfResult.getAbsolutePath(), attribs, wantedVariables, null,
timeUnit, altUnit, new CFPointWriterConfig(version) );
}
@Override
public HttpHeaders getHttpHeaders(String datasetPath, boolean isStream) {
HttpHeaders httpHeaders = new HttpHeaders();
String fileName = NcssRequestUtils.getFileNameForResponse(datasetPath, version);
String url = NcssRequestUtils.getTdsContext().getContextPath() +
NcssController.getServletCachePath() + "/" + fileName;
if (version == NetcdfFileWriter.Version.netcdf3) {
httpHeaders.set(ContentType.HEADER, ContentType.netcdf.getContentHeader());
} else if (version == NetcdfFileWriter.Version.netcdf4 || version == NetcdfFileWriter.Version.netcdf4_classic) {
httpHeaders.set(ContentType.HEADER, ContentType.netcdf4.getContentHeader());
}
httpHeaders.set("Content-Location", url);
httpHeaders.set("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
return httpHeaders;
}
@Override
protected void writeHeader(StationPointFeature stationPointFeat) throws Exception {
cfWriter.writeHeader(wantedStations, stationPointFeat);
}
@Override
protected void writeStationPointFeature(StationPointFeature stationPointFeat) throws Exception {
Station station = stationPointFeat.getStation();
cfWriter.writeRecord(station, stationPointFeat, stationPointFeat.getFeatureData());
}
@Override
protected void writeFooter() throws Exception {
cfWriter.finish();
IO.copyFileB(netcdfResult, out, 60000); // Copy the file in to the OutputStream.
out.flush();
}
}