package nl.wldelft.fews.pi; import nl.wldelft.util.geodatum.GeoDatum; import nl.wldelft.util.io.LineReader; import nl.wldelft.util.io.VirtualInputDir; import nl.wldelft.util.io.VirtualInputDirConsumer; import nl.wldelft.util.io.XmlParser; import nl.wldelft.util.timeseries.DefaultTimeSeriesHeader; import nl.wldelft.util.timeseries.LockableContentHandler; import nl.wldelft.util.timeseries.TimeSeriesContentHandler; import nl.wldelft.util.timeseries.TimeSeriesHeader; import org.apache.log4j.Logger; import javax.xml.stream.XMLStreamReader; import java.io.BufferedInputStream; import java.io.File; public class PiMapStackParser implements XmlParser<TimeSeriesContentHandler>, VirtualInputDirConsumer { private static final Logger log = Logger.getLogger(PiMapStackParser.class); private DefaultTimeSeriesHeader timeSeriesHeader = new DefaultTimeSeriesHeader(); private VirtualInputDir virtualInputDir = null; private PiMapStacksReader mapStackReader = null; private LockableContentHandler contentHandler = null; private String virtualFileName = null; @Override public void parse(XMLStreamReader reader, String virtualFileName, TimeSeriesContentHandler contentHandler) throws Exception { this.virtualFileName = virtualFileName; this.mapStackReader = new PiMapStacksReader(reader, virtualFileName, contentHandler.getDefaultTimeZone(), contentHandler.getDefaultGeoDatum()); try { parse(contentHandler); } finally { mapStackReader.close(); } } private void parse(final TimeSeriesContentHandler contentHandler) throws Exception { GeoDatum mapStackGeoDatum = mapStackReader.getGeoDatum(); final GeoDatum geoDatum = mapStackGeoDatum != null ? mapStackGeoDatum : contentHandler.getDefaultGeoDatum(); this.contentHandler = new LockableContentHandler(contentHandler) { @Override public void setNewTimeSeriesHeader(TimeSeriesHeader header) { // only called for bil files timeSeriesHeader.setEnsembleMemberIndex(timeSeriesHeader.getEnsembleMemberIndex() + 1); contentHandler.setNewTimeSeriesHeader(timeSeriesHeader); } @Override public GeoDatum getDefaultGeoDatum() { return geoDatum; } }; this.contentHandler.setLockedHeader(timeSeriesHeader); this.contentHandler.setHeaderLocked(true); while (mapStackReader.next()) { timeSeriesHeader.setLocationId(mapStackReader.getLocationId()); timeSeriesHeader.setParameterId(mapStackReader.getParameterId()); timeSeriesHeader.setTimeStep(mapStackReader.getTimeStep()); timeSeriesHeader.setEnsembleMemberIndex(-1); contentHandler.setComment(mapStackReader.getComment()); long[] times = mapStackReader.getTimes(); switch (mapStackReader.getFormatType()) { case ASCII: parseAscii(times); break; case PCRGRID: parsePcRaster(times); break; case USGS: parseUsgs(times); break; } } } private void parseAscii(long[] times) throws Exception { String fileNamePattern = mapStackReader.getFileName(); contentHandler.setNewTimeSeriesHeader(timeSeriesHeader); EsriAsciiGridParser ascParser = new EsriAsciiGridParser(); for (int i = 0; i < times.length; i++) { ascParser.setTime(times[i]); String fileName = PiMapStackUtils.replacePattern(fileNamePattern, i, times.length); if (!virtualInputDir.exists(fileName)) { log.error(fileName + " referenced in " + virtualFileName + " is missing"); contentHandler.setTime(times[i]); contentHandler.setCoverageValues(null); contentHandler.applyCurrentFields(); continue; } LineReader ascReader = virtualInputDir.getReader(fileName); try { ascParser.parse(ascReader, fileName, contentHandler); } finally { ascReader.close(); } } } private void parsePcRaster(long[] times) throws Exception { String fileNamePattern = mapStackReader.getFileName(); contentHandler.setNewTimeSeriesHeader(timeSeriesHeader); PcRasterParser pcrParser = new PcRasterParser(); for (int i = 0; i < times.length; i++) { pcrParser.setTime(times[i]); String fileName = PiMapStackUtils.replacePattern(fileNamePattern, i, times.length); if (!virtualInputDir.exists(fileName)) { if (log.isDebugEnabled()) log.debug(fileName + " is missing, assume missing value grid"); contentHandler.setTime(times[i]); contentHandler.setCoverageValues(null); contentHandler.applyCurrentFields(); continue; } // todo handle virtual file File file = new File(fileName); if (!file.isAbsolute()) { File defaultDir = new File(virtualFileName).getParentFile(); file = new File(defaultDir, fileName); } pcrParser.parse(file, this.contentHandler); } } private void parseUsgs(long[] times) throws Exception { PiBilParser bilParser = new PiBilParser(); bilParser.setTimes(times); bilParser.setVirtualInputDir(virtualInputDir); bilParser.setOverrulingHeaderFileName(mapStackReader.getHeaderFileName()); BufferedInputStream inputStream = virtualInputDir.getInputStream(mapStackReader.getFileName()); try { bilParser.parse(inputStream, mapStackReader.getFileName(), this.contentHandler); } finally { inputStream.close(); } } @Override public void setVirtualInputDir(VirtualInputDir virtualInputDir) { this.virtualInputDir = virtualInputDir; } }