Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/BedQualityD50TimeRangeConfig.java @ 9528:55c187a0a31e
Fixed: consistent gauge assignment with downstream gauge as reference gauge for calc range starting at a gauge range limit
author | mschaefer |
---|---|
date | Tue, 02 Oct 2018 16:39:51 +0200 |
parents | 23d97d60b889 |
children | 8e6b9cb9486a |
line wrap: on
line source
/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde * Software engineering by * Björnsen Beratende Ingenieure GmbH * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt * * This file is Free Software under the GNU AGPL (>=v3) * and comes with ABSOLUTELY NO WARRANTY! Check out the * documentation coming with Dive4Elements River for details. */ package org.dive4elements.river.artifacts.sinfo.tkhstate; import java.io.File; import java.io.IOException; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dive4elements.river.artifacts.model.Calculation; import org.dive4elements.river.artifacts.model.DateRange; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.BedQualityD50KmValueFinder; import org.dive4elements.river.artifacts.sinfo.tkhstate.TsvHelper.TsvReaderException; import org.dive4elements.river.model.River; /** * Represents the contents of the 'bedheights.properties' files. * * @author Gernot Belger */ public final class BedQualityD50TimeRangeConfig { private static final String CONFIG_FILE = "d50_sohlkorndurchmesser_%s.tsv"; private final Map<String, DateRange> cache = new HashMap<>(); private static BedQualityD50TimeRangeConfig INSTANCE = new BedQualityD50TimeRangeConfig(); public static class BedQualityParseException extends Exception { private static final long serialVersionUID = 1L; BedQualityParseException(final String message) { super(message); } BedQualityParseException(final String message, final Throwable cause) { super(message, cause); } } public static synchronized DateRange getDefaults(final River river, final int soundingYear, final Calculation problems) throws BedQualityParseException { return INSTANCE.getBedHeightDefaultsForRiver(river, soundingYear, problems); } private synchronized DateRange getBedHeightDefaultsForRiver(final River river, final int soundingYear, final Calculation problems) throws BedQualityParseException { final String rivername = river.getName(); final String cacheKey = new StringBuilder().append(rivername).append(";").append(soundingYear).toString(); if (!this.cache.containsKey(cacheKey)) { final File file = TsvHelper.makeFile2(CONFIG_FILE, rivername); final File fileCheck = TsvHelper.checkFile(file); if (fileCheck == null) return null; // automatically dateRange min/max wil be taken List<String[]> results = null; try { results = TsvHelper.readTsv(file, 4); } catch (final TsvReaderException | IOException e) { problems.addProblem("sinfo.bedqualityd50config.configfile.loaderror", file.getPath(), e.getStackTrace()); } if (results != null) { for (final String[] line : results) { final CalRange range = new CalRange(parseInput(line[0]), parseInput(line[1]), parseInput(line[2]), parseInput(line[3])); if (range.isSoundingYearInRange(soundingYear)) { final DateRange dateRange = new DateRange(range.getStartTimeQuery(), range.getEndTimeQuery()); this.cache.put(cacheKey, dateRange); } } } problems.addProblem("sinfo.bedqualityd50config.configfile.loaderror", file.getPath(), " Die angegebene d50-sohlkorndurchmesser-config-file enthält keinen gültigen Bereich für das konfigurierte Peiljahr."); return null; } return this.cache.get(cacheKey); } private static Integer parseInput(final String raw) throws BedQualityParseException { final String value = raw.trim(); if (value.toUpperCase().equals("MIN") || value.toUpperCase().equals("MAX")) return null; try { return Integer.valueOf(value); } catch (final NumberFormatException e) { throw new BedQualityParseException("Invalid input; should be year ('yyyy') or 'MIN' or 'MAX'", e); } } private static final class CalRange { private final long startTimeSounding; private final long endTimeSounding; private final long startTimeQuery; private final long endTimeQuery; private final static Calendar cal = Calendar.getInstance(); public Date getStartTimeQuery() { return new Date(this.startTimeQuery); } public Date getEndTimeQuery() { return new Date(this.endTimeQuery); } public CalRange(final Integer startYearSounding, final Integer endYearSounding, final Integer startYearQuery, final Integer endYearQuery) { this.startTimeSounding = (startYearSounding != null) ? getLongValForYear(startYearSounding, 0, 1) : BedQualityD50KmValueFinder.MIN_DATE.getTime(); this.startTimeQuery = (startYearQuery != null) ? getLongValForYear(startYearQuery, 0, 1) : BedQualityD50KmValueFinder.MIN_DATE.getTime(); this.endTimeSounding = (endYearSounding != null) ? getLongValForYear(endYearSounding, 11, 31) : BedQualityD50KmValueFinder.MAX_DATE.getTime(); this.endTimeQuery = (endYearQuery != null) ? getLongValForYear(endYearQuery, 11, 31) : BedQualityD50KmValueFinder.MAX_DATE.getTime(); } private long getLongValForYear(final int year, final int month0based, final int dayOfMonth) { cal.clear(); cal.set(year, month0based, dayOfMonth); return cal.getTimeInMillis(); } public boolean isSoundingYearInRange(final int soundingYear) { cal.clear(); cal.set(soundingYear, 5, 5); // random date in the middle of the year final Long time = cal.getTimeInMillis(); if (time > this.startTimeSounding && time < this.endTimeSounding) return true; return false; } } }