Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/BedQualityD50TimeRangeConfig.java @ 9559:ba0561906f81
Uinfo inundation duration workflow (vegetation zones, scenario), wms-config changed
author | gernotbelger |
---|---|
date | Wed, 24 Oct 2018 18:40:38 +0200 |
parents | 8e6b9cb9486a |
children |
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.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TimeZone; 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, CalRange[]> cache = new HashMap<>(); private static BedQualityD50TimeRangeConfig INSTANCE = new BedQualityD50TimeRangeConfig(); private static class BedQualityParseException extends Exception { private static final long serialVersionUID = 1L; public BedQualityParseException(final String message, final Throwable cause) { super(message, cause); } } public static synchronized DateRange getDefaults(final River river, final int soundingYear, final Calculation problems) { return INSTANCE.getBedHeightDefaultsForRiver(river, soundingYear, problems); } private synchronized DateRange getBedHeightDefaultsForRiver(final River river, final int soundingYear, final Calculation problems) { final String rivername = river.getName(); final CalRange[] ranges = getRanges(rivername, problems); if (ranges == null) return null; for (final CalRange range : ranges) { if (range.isSoundingYearInRange(soundingYear)) return new DateRange(range.getStartTimeQuery(), range.getEndTimeQuery()); } // Message for admin, not translated final File file = TsvHelper.makeFile2(CONFIG_FILE, rivername); final String message = "Die angegebene d50-Sohlkorndurchmesser Konfigurationsdatei enthält keinen gültigen Bereich für das konfigurierte Peiljahr."; //$NON-NLS-1$ problems.addProblem("sinfo.bedqualityd50config.configfile.loaderror", file.getPath(), message); return null; } private CalRange[] getRanges(final String rivername, final Calculation problems) { if (this.cache.containsKey(rivername)) return this.cache.get(rivername); final CalRange[] ranges = loadRanges(rivername, problems); if (ranges == null) { /* do not cache so we always get the problem message again */ return null; } this.cache.put(rivername, ranges); return ranges; } private CalRange[] loadRanges(final String rivername, final Calculation problems) { final File file = TsvHelper.makeFile2(CONFIG_FILE, rivername); final File fileCheck = TsvHelper.checkFile(file); if (fileCheck == null) return new CalRange[] { new CalRange(null, null, null, null) }; // automatically dateRange min/max will be taken try { final List<String[]> results = TsvHelper.readTsv(file, 4); final Collection<CalRange> ranges = new ArrayList<>(results.size()); for (final String[] line : results) { if (line != null && line.length == 4) ranges.add(new CalRange(parseInput(line[0]), parseInput(line[1]), parseInput(line[2]), parseInput(line[3]))); } return ranges.toArray(new CalRange[ranges.size()]); } catch (final TsvReaderException | IOException | BedQualityParseException e) { problems.addProblem("sinfo.bedqualityd50config.configfile.loaderror", file.getPath(), e.getLocalizedMessage()); return null; } } 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; 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 static long getLongValForYear(final int year, final int month0based, final int dayOfMonth) { final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+1")); cal.clear(); cal.set(year, month0based, dayOfMonth); return cal.getTimeInMillis(); } public boolean isSoundingYearInRange(final int soundingYear) { final long time = getLongValForYear(soundingYear, 5, 5); // random date in the middle of the year if (time > this.startTimeSounding && time < this.endTimeSounding) return true; return false; } } }