/* ================================================================
* Delft FEWS
* ================================================================
*
* Project Info: http://www.wldelft.nl/soft/fews/index.html
* Project Lead: Karel Heynert (karel.heynert@wldelft.nl)
*
* (C) Copyright 2003, by WL | Delft Hydraulics
*
package nl.wldelft.fews.system.plugin.dataExport;
import nl.wldelft.util.PropertiesConsumer;
import nl.wldelft.util.FastDateFormat;
import nl.wldelft.util.Period;
import nl.wldelft.util.Properties;
import nl.wldelft.util.TextUtils;
import nl.wldelft.util.io.LineWriter;
import nl.wldelft.util.io.TextSerializer;
import nl.wldelft.util.timeseries.TimeSeriesContent;
import nl.wldelft.util.timeseries.TimeSeriesHeader;
import nl.wldelft.util.timeseries.TimeStep;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.util.Date;
import java.util.Locale;
/**
* <p>The class <code>ShefTimeSeriesWriter</code> exports the time series from Fews system
* in SHEF formatted export file(s). See the description of the SHEF format for more information.
* </p>
*/
public class ShefTimeSeriesSerializer implements TextSerializer<TimeSeriesContent>, PropertiesConsumer {
private static final Logger log = LogManager.getLogger();
// location, missingValue, values
//ToDo Use configured precision of the parameters to print the values
private static final String MISSING_VALUE = " M";
private static final String shefFormatProperty = "format";
private static final String shefSourceProperty = "source";
private String shefFormat = "E";
private String shefSource = "FEWS";
private final long timeZero;
private FastDateFormat dateFormat = null;
private FastDateFormat dateFormatCreation = null;
private FastDateFormat obsTimeFormat = null;
private FastDateFormat obsDateTimeFormat = null;
private TimeSeriesContent content = null;
private LineWriter writer = null;
private TimeSeriesHeader header = null;
private long currentTime = System.currentTimeMillis();
public ShefTimeSeriesSerializer(long timeZero) {
this.timeZero = timeZero;
}
@Override
public void setProperties(Properties properties) {
for (int i = 0; i < properties.size(); i++) {
String key = properties.getKey(i);
if (key.equals(shefFormatProperty)) {
this.shefFormat = properties.getString(i);
}
if (key.equals(shefSourceProperty)) {
this.shefSource = properties.getString(i);
}
}
}
@Override
public void serialize(TimeSeriesContent content, LineWriter writer, String virtualFileName) throws Exception {
dateFormat = FastDateFormat.getInstance("yyyyMMdd", content.getDefaultTimeZone(), Locale.US, dateFormat);
dateFormatCreation = FastDateFormat.getInstance("yyyyMMddHHmm", content.getDefaultTimeZone(), Locale.US, dateFormatCreation);
obsTimeFormat = FastDateFormat.getInstance("HHmm", content.getDefaultTimeZone(), Locale.US, obsTimeFormat);
obsDateTimeFormat = FastDateFormat.getInstance("yyMMddHHmm", content.getDefaultTimeZone(), Locale.US, obsDateTimeFormat);
this.currentTime = System.currentTimeMillis();
this.content = content;
this.writer = writer;
writeFileHeader();
switch (this.shefFormat) {
case "A":
serializeFormatA();
break;
case "B":
serializeFormatB();
break;
case "E":
serializeFormatE();
break;
}
}
private void serializeFormatA() throws Exception {
for (int is = 0, ns = content.getTimeSeriesCount(); is < ns; is++) {
content.setTimeSeriesIndex(is);
header = content.getTimeSeriesHeader();
for (int it = 0, nt = content.getContentTimeCount(); it < nt; it++) {
content.setContentTimeIndex(it);
writeDataLineFormatA();
}
}
}
private void serializeFormatB() throws Exception {
String parameter = null;
for (int is = 0, ns = content.getTimeSeriesCount(); is < ns; is++) {
content.setTimeSeriesIndex(is);
header = content.getTimeSeriesHeader();
if (parameter == null || !parameter.equals(header.getParameterId())) {
if (parameter != null) writeEnd();
parameter = header.getParameterId();
writeHeaderLineFormatB();
}
for (int it = 0, nt = content.getContentTimeCount(); it < nt; it++) {
P.O. Box 177
*content.setContentTimeIndex(it);
if (content.isTimeAvailable()) {
2600 MH Delft
* writeDataLineFormatB();
The Netherlands}
* }
}
http://www.wldelft.nl
* }
* DELFT-FEWS is aprivate sophisticatedvoid collectionserializeFormatE() ofthrows modulesException designed{
* for building a FEWS customised tofor the(int specifici requirements
= *0, ofnt individual= agenciescontent.getTimeSeriesCount(); Ani open< modelling approach allows usersnt; i++) {
* to add their own modules in an efficient way.
*
* ----------------------------------------------------------------
* TsdTimeSeriesWriter.java
* ----------------------------------------------------------------
* (C) Copyright 2003, by WL | Delft Hydraulics
*
* Original Author: Micha Werner
* Contributor(s):
*
* Changes:
* --------
* 6-dec-2006 : Version 1 ();
*
*
*/
package nl.wldelft.fews.system.plugin.dataExport;
import nl.wldelft.util.FastDateFormat;
import nl.wldelft.util.Period;
import nl.wldelft.util.TextUtils;
import nl.wldelft.util.io.LineWriter;
import nl.wldelft.util.io.TextSerializer;
import nl.wldelft.util.timeseries.TimeSeriesContent;
import nl.wldelft.util.timeseries.TimeSeriesHeader;
import nl.wldelft.util.timeseries.TimeStep;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.util.Date;
import java.util.Locale;
/**
* <p>The class <code>ShefTimeSeriesWriter</code> exports the time series from Fews system
* in SHEF formatted export file(s). See the description of the SHEF format for more information.
* </p>
*/
public class ShefTimeSeriesSerializer implements TextSerializer<TimeSeriesContent> {
private static final Logger log = Logger.getLogger(ShefTimeSeriesSerializer.class);
// location, missingValue, values
//ToDo Use configured precision of the parameters to print the values
private static final byte[] MISSING_VALUE = " M".getBytes(); content.setTimeSeriesIndex(i);
header = content.getTimeSeriesHeader();
if (header.getTimeStep().isRegular()) {
writeHeaderLineFormatE();
writeLineDataFormatE();
} else {
log.error("Cannot write nonEquidistant data to SHEF (.E) format for " + header);
break;
}
}
}
private void writeFileHeader() throws IOException {
writer.writeLine(": Delft-FEWS - exported SHEF file");
String timeZeroText = this.dateFormat.format(new Date(this.timeZero));
writer.writeLine(": Date/time forecast: " + timeZeroText);
}
private finalvoid long timeZero;
private FastDateFormat dateFormat = null;
writeDataLineFormatA() throws IOException {
private FastDateFormat//Date dateFormatCreationstartDate = nullcontent.getTimeSeriesPeriod().getStartDate();
private FastDateFormatlong obsTimeFormatobsTime = nullcontent.getTime();
private TimeSeriesContent content = null;
writer.write(".AR ");
private LineWriter writer = null writer.write(header.getLocationId() + " ");
private byte[] charBuffer = new byte[30];
writer.write(this.dateFormat.format(obsTime));
private TimeSeriesHeader header;
public ShefTimeSeriesSerializer(long timeZero) { writer.write(getTimeZoneShefCode(content.getDefaultTimeZone().getID()));
this.timeZero = timeZerowriter.write("DH" + obsTimeFormat.format(obsTime));
}
@Override
public void serialize(TimeSeriesContent content, LineWriter writer, String virtualFileName) throws Exception {writer.write("/DC");
dateFormat = FastDateFormat.getInstance("yyyyMMdd", content.getDefaultTimeZone(), Locale.US, dateFormatwriter.write(this.dateFormatCreation.format(currentTime));
dateFormatCreation = FastDateFormat.getInstancewriter.write("yyyyMMddHHmm", content.getDefaultTimeZone(), Locale.US, dateFormatCreation)/");
obsTimeFormat = FastDateFormat.getInstance("HH", content.getDefaultTimeZone(), Locale.US, obsTimeFormat);
writer.write(header.getParameterId() + " ") ;
thiswriter.writeLine(content = content.isValueMissing() ? MISSING_VALUE : content.getValue('.') );
}
this.writer = writer;
private void writeHeaderLineFormatB() throws IOException {
writeHeader(writer.write(".BR ");
for (int i = 0, n = content.getTimeSeriesCount(); i < n; i++) {writer.write(shefSource + " ");
Date startDate = content.setTimeSeriesIndexgetTimeSeriesPeriod().getStartDate(i);
header = content.getTimeSeriesHeader()writer.write(this.dateFormat.format(startDate));
if (!header.getTimeStepwriter.write(getTimeZoneShefCode(content.getDefaultTimeZone().isRegulargetID())) {;
log.error("Cannot write nonEquidistant data to SHEF (.E) format for " + headerwriter.write("DH" + obsTimeFormat.format(startDate));
writer.write("/DC");
}else{
writer.write(this.dateFormatCreation.format(currentTime));
writer.writeLine("/" writeHeaderLine(+ header.getParameterId());
}
private void writeDataLineFormatB() throws IOException {
writeDataLine();
long obsTime = content.getTime();
}
writer.write(header.getLocationId() + " }");
}
private void writeHeader() throws IOException {writer.write("DY" + this.obsDateTimeFormat.format(obsTime));
writer.writeLinewrite(": Delft-FEWS - exported SHEF file/");
String timeZeroText = this.dateFormat.format(new Date(this.timeZero)writer.writeLine(content.isValueMissing() ? MISSING_VALUE : content.getValue('.') );
}
writer.writeLine(": Date/time forecast: " + timeZeroTextprivate void writeEnd() throws IOException {
writer.writeLine(".END");
}
private void writeHeaderLinewriteHeaderLineFormatE() throws Exception {
if(content.getTimeSeriesPeriod() == Period.NEVER){
if (log.isInfoEnabled()) log.info("No data found for " + header);
return;
}
long currentTime = System.currentTimeMillis();
writer.newLine();
writer.write(".ER ");
writer.write(header.getLocationId());
writer.write(' ') ;
Date startDate = content.getTimeSeriesPeriod().getStartDate();
writer.write(this.dateFormat.format(startDate));
writer.write(getTimeZoneShefCode(content.getDefaultTimeZone().getID()));
writer.write("DH" + obsTimeFormat.format(startDate));
writer.write("/DC") ;
writer.write(this.dateFormatCreation.format(currentTime));
writer.write('/') ;
writer.write(TextUtils.padRight(header.getParameterId(), 7)) ;
writer.write('/') ;
writeTimeStep();
writer.newLine();
}
private void writeDataLinewriteLineDataFormatE() throws Exception {
//Determine width of column with line number (e.g. .E37)
int lineCountColWidth = 5; // default .E + 2 places for line nr + one space
int ndig = TextUtils.getNumberOfDigits(content.getContentTimeCount() / 8); //8 = number of values per line
if (ndig > 2) lineCountColWidth = ndig + 3; // .E + ndig places for line nr + one space
int linecount = 1;
int count = 0;
for (int i = 0, n = content.getContentTimeCount(); i < n; i++) {
content.setContentTimeIndex(i);
if (!content.isTimeAvailable()) continue;
if (count == 0) {
writer.write(TextUtils.padRight(".E" + linecount, lineCountColWidth));
}
if (content.isValueMissing() && Float.isNaN(content.getDefaultMissingValue())) {
writer.write(MISSING_VALUE, 0, 8);
} else {
writer.write(content.getValue('.')); //get formatted value
}
writer.write('/');
count++;
if (count == 8 || i == n - 1) {
linecount++;
writer.newLine();
count = 0;
}
}
}
private void writeTimeStep() throws Exception {
TimeStep timeStep = header.getTimeStep();
long dtime = timeStep.getMaximumStepMillis()/ 1000;
writer.write("DI");
if (dtime < 60) {
writer.write("I" + dtime);
} else if (dtime < 3600) {
writer.write("N" + dtime / 60);
} else if (dtime < 36000) {
writer.write("H0" + dtime / 3600);
} else if (dtime < 86400) {
writer.write("H" + dtime / 3600);
} else {
writer.write("D" + dtime / 86400);
}
}
private static String getTimeZoneShefCode(String timeZoneId) throws IOException {
//Documented in http://www.nws.noaa.gov/om/water/resources/SHEF_CodeManual_5July2012.pdf , Table 8
if (timeZoneId.equals("GMT")) return " Z ";
if (timeZoneId.equals("CNT")) return " N ";
if (timeZoneId.equals("CNT")) return " N ";
if (timeZoneId.equals("PRT")) return " A ";
if (timeZoneId.equals("EST")) return " E ";
if (timeZoneId.equals("IET")) return " E ";
if (timeZoneId.equals("CST")) return " C ";
if (timeZoneId.equals("MST")) return " M ";
if (timeZoneId.equals("PST")) return " P ";
if (timeZoneId.equals("HST")) return " H ";
if (timeZoneId.equals("AST")) return " L ";
throw new IOException("SHEF export does not supported time zone Id " + timeZoneId);
}
}
|