/* * Copyright 1998-2014 University Corporation for Atmospheric Research/Unidata * * Portions of this software were developed by the Unidata Program at the * University Corporation for Atmospheric Research. * * Access and use of this software shall impose the following obligations * and understandings on the user. The user is granted the right, without * any fee or cost, to use, copy, modify, alter, enhance and distribute * this software, and any derivative works thereof, and its supporting * documentation for any purpose whatsoever, provided that this entire * notice appears in all copies of the software, derivative works and * supporting documentation. Further, UCAR requests that the user credit * UCAR/Unidata in any publications that result from the use of this * software or in any product that includes this software. The names UCAR * and/or Unidata, however, may not be used in any advertising or publicity * to endorse or promote any products or commercial entity unless specific * written permission is obtained from UCAR/Unidata. The user also * understands that UCAR/Unidata is not obligated to provide the user with * any support, consulting, training or assistance of any kind with regard * to the use, operation and performance of this software nor to provide * the user with any updates, revisions, new versions or "bug fixes." * * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. */ package thredds.server.ncss.view.gridaspoint.netcdf; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import thredds.server.ncss.dataservice.StructureDataFactory; import thredds.server.ncss.util.NcssRequestUtils; import ucar.ma2.StructureData; import ucar.nc2.Attribute; import ucar.nc2.NetcdfFileWriter; import ucar.nc2.VariableSimpleIF; import ucar.nc2.constants.CDM; import ucar.nc2.dataset.CoordinateAxis1D; import ucar.nc2.dataset.NetcdfDataset; import ucar.nc2.dt.GridDataset; import ucar.nc2.dt.GridDatatype; import ucar.nc2.dt.grid.GridAsPointDataset; import ucar.nc2.ft.point.writer.CFPointWriterUtils; import ucar.nc2.time.CalendarDate; import ucar.nc2.units.DateUnit; import ucar.unidata.geoloc.LatLonPoint; import ucar.unidata.geoloc.Station; import ucar.unidata.geoloc.StationImpl; /** * @author mhermida * */ public final class CFStationCollectionWriterWrapper implements CFPointWriterWrapper { static private Logger log = LoggerFactory.getLogger(CFStationCollectionWriterWrapper.class); public static CFStationCollectionWriterWrapper factory(NetcdfFileWriter.Version version, String filePath, List<Attribute> atts) throws IOException{ return new CFStationCollectionWriterWrapper(version, filePath, atts); } private WriterCFStationCollection writerCFStationCollection; private GridAsPointDataset gap; private CalendarDate timeOrigin; private CFStationCollectionWriterWrapper(){} private CFStationCollectionWriterWrapper(NetcdfFileWriter.Version version, String filePath, List<Attribute> atts) throws IOException{ writerCFStationCollection = new WriterCFStationCollection(version, filePath, atts); } @Override public boolean header(Map<String, List<String>> groupedVars, GridDataset gridDataset, List<CalendarDate> wDates, List<Attribute> timeDimAtts, LatLonPoint point, Double vertCoord) { //timeOrigin = dateUnit.makeCalendarDate(0); boolean headerDone = false; Attribute unitsAtt = CFPointWriterUtils.findCDMAtt(timeDimAtts, CDM.UNITS); DateUnit dateUnit; try { dateUnit = new DateUnit(unitsAtt.getStringValue()); timeOrigin = dateUnit.makeCalendarDate(0); } catch (Exception e) { log.error("Error creating time units for: "+unitsAtt.getStringValue()); return headerDone; } String stnName = "GridPoint"; String desc = "Grid Point at lat/lon="+point.getLatitude()+","+point.getLongitude(); Station s = new StationImpl( stnName, desc, "", point.getLatitude(), point.getLongitude(), Double.NaN); List<ucar.unidata.geoloc.Station> stnList = new ArrayList<>(); stnList.add(s); NetcdfDataset ncfile = (NetcdfDataset) gridDataset.getNetcdfFile(); // fake-arino List<String> vars = (new ArrayList<>(groupedVars.values())).get(0); gap = NcssRequestUtils.buildGridAsPointDataset(gridDataset, vars); List<VariableSimpleIF> wantedVars = NcssRequestUtils.wantedVars2VariableSimple( vars , gridDataset, ncfile); try { writerCFStationCollection.writeHeader(stnList, wantedVars, gridDataset, timeDimAtts, ""); headerDone= true; } catch (IOException ioe) { log.error("Error writing header", ioe); } return headerDone; } @Override public boolean write(Map<String, List<String>> groupedVars, GridDataset gridDataset, CalendarDate date, LatLonPoint point, Double targetLevel){ boolean allDone = false; List<String> vars = (new ArrayList<>(groupedVars.values())).get(0); StructureData sdata = StructureDataFactory.getFactory().createSingleStructureData(gridDataset, point, vars, true); GridDatatype timeGrid = NcssRequestUtils.getTimeGrid(groupedVars, gridDataset); if(timeGrid == null){ throw new IllegalArgumentException("Variables do not have time dimension"); } Double timeCoordValue = NcssRequestUtils.getTimeCoordValue(timeGrid, date, timeOrigin); sdata.findMember("time").getDataArray().setDouble(0, timeCoordValue); //Ensemble... CoordinateAxis1D ensAxis = gridDataset.findGridDatatype(vars.get(0)).getCoordinateSystem().getEnsembleAxis(); double[] ensCoords = new double[]{-1}; if( ensAxis != null ){ ensCoords = ensAxis.getCoordValues(); } try{ int ensIdx =0; for(double ensCoord : ensCoords){ if(ensCoord >=0){ writerCFStationCollection.writeEnsCoord(ensIdx, ensCoord); ensIdx++; } //int cont =0; // Iterating vars Iterator<String> itVars = vars.iterator(); while (itVars.hasNext()) { String varName = itVars.next(); GridDatatype grid = gridDataset.findGridDatatype(varName); if (gap.hasTime(grid, date) ) { GridAsPointDataset.Point p = gap.readData(grid, date, ensCoord, -1, point.getLatitude(), point.getLongitude()); sdata.findMember(varName).getDataArray().setDouble(0, p.dataValue ); }else{ //Set missing value sdata.findMember(varName).getDataArray().setDouble(0, gap.getMissingValue(grid) ); } //cont++; } if(ensCoord < 0) writerCFStationCollection.writeRecord((String)sdata.findMember("station").getDataArray().getObject(0), timeCoordValue, date, sdata); else writerCFStationCollection.writeRecord((String)sdata.findMember("station").getDataArray().getObject(0), timeCoordValue, date, ensCoord, sdata); allDone = true; } }catch(IOException ioe){ log.error("Error writing data", ioe); } return allDone; } public boolean trailer(){ boolean finished = false; try { writerCFStationCollection.finish(); finished = true; } catch (IOException ioe) { log.error("Error finishing WriterCFStationCollection"+ioe); } return finished; } }