package nl.wldelft.fews.system.plugin.dataImport;

import nl.wldelft.util.ObjectArrayUtils;
import nl.wldelft.util.TextUtils;
import nl.wldelft.util.io.LineReader;
import nl.wldelft.util.io.TextParser;
import nl.wldelft.util.timeseries.DefaultTimeSeriesHeader;
import nl.wldelft.util.timeseries.TimeSeriesContentHandler;
import nl.wldelft.util.timeseries.OutOfDetectionRangeFlag;

public class KnmiSynopsTimeSeriesParser implements TextParser<TimeSeriesContentHandler> {
    private static final String[] COLUMNS = {"IX", null, "N", null, "ff", "fxfx", "TTT", "TnTnTn", "TxTxTx", "TgTgTg",
    "TwTwTw", "TdTdTd", "UU", "VVVV", "PPPP", "tr", "RRR", "RhRhRh", "Dr", "QQQ", "ddd"};

    private static final int PARAM_IDX_OFFSET = 6;
    private static final int DDD_COLUMN_INDEX = ObjectArrayUtils.indexOf(COLUMNS, "ddd");

    @Override
    public void parse(LineReader reader, String virtualFileName, TimeSeriesContentHandler contentHandler) throws Exception {
        String line;
        // find first line
        while ((line = reader.readLine()) != null && line.length() < 2) {
            // do nothing
        }

        contentHandler.addMissingValue("*");
        String[] lineItems = new String[28];
        // lines are spread actually over two rows
        DefaultTimeSeriesHeader header = new DefaultTimeSeriesHeader();
        while (line != null && line.length() > 1) {
            line += reader.readLine();
            int count = TextUtils.split(line, ';', '\"', lineItems);

            if (count != 28)
                throw new Exception("read data does not contain expected number of columns");

            contentHandler.setTime(contentHandler.getDefaultTimeZone(), "yyyyMMddHH", lineItems[0]);

            for (int i = 0; i < COLUMNS.length; i++) {
                if (COLUMNS[i] == null) continue;
                String value = lineItems[i + PARAM_IDX_OFFSET].trim();
                if (value.length() == 0) continue;
                if (i == DDD_COLUMN_INDEX && value.equals("990")) {
                    contentHandler.setValue(Float.NaN);
                    contentHandler.setOutOfDetectionRangeFlag(OutOfDetectionRangeFlag.VARYING);
                } else {
                    contentHandler.setValue('.', value);
                    contentHandler.setOutOfDetectionRangeFlag(OutOfDetectionRangeFlag.INSIDE_DETECTION_RANGE);
                }
                header.setLocationId(lineItems[1]);
                header.setParameterId(COLUMNS[i]);
                contentHandler.setTimeSeriesHeader(header);
                contentHandler.applyCurrentFields();
            }
            // read next line to start gathering new line info
            line = reader.readLine();
        }
    }
}
  • No labels