Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java @ 9269:83ebeb620b5a
Station specific main value annotations in S-Info flood duration curve, corrected infrastructure flood duration calculation
author | mschaefer |
---|---|
date | Thu, 19 Jul 2018 08:07:03 +0200 |
parents | 4f411c6ee3ae |
children | 7b2b086e45f0 |
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.collision; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.math.DoubleRange; import org.dive4elements.artifacts.CallContext; import org.dive4elements.river.artifacts.common.GeneralResultType; import org.dive4elements.river.artifacts.common.ResultRow; import org.dive4elements.river.artifacts.model.Calculation; import org.dive4elements.river.artifacts.model.CalculationResult; import org.dive4elements.river.artifacts.model.DateRange; import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; import org.dive4elements.river.artifacts.sinfo.common.GaugeDischargeValuesFinder; import org.dive4elements.river.artifacts.sinfo.common.GaugeMainValueFinder; import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; import org.dive4elements.river.backend.utils.DateUtil; import org.dive4elements.river.model.Gauge; import org.dive4elements.river.model.MainValueType.MainValueTypeKey; import org.dive4elements.river.model.River; import org.dive4elements.river.model.sinfo.CollisionAggregateValue; import org.dive4elements.river.model.sinfo.CollisionValue; class CollisionCalculation { // private static Logger log = Logger.getLogger(FloodDurationCalculation.class); private final CallContext context; public CollisionCalculation(final CallContext context) { this.context = context; } public CalculationResult calculate(final SINFOArtifact sinfo) { final String user = CalculationUtils.findArtifactUser(this.context, sinfo); // access input data final CollisionAccess access = new CollisionAccess(sinfo); final River river = access.getRiver(); final RiverInfo riverInfo = new RiverInfo(river); final DoubleRange calcRange = access.getRange(); // calculate results for each year or epoch final Calculation problems = new Calculation(); final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name()); final CollisionCalculationResults results = new CollisionCalculationResults(calcModeLabel, user, riverInfo, calcRange, access.getYearsHeader()); final Collection<ResultRow> overViewRows = new ArrayList<>(); if (access.getYears() != null) { for (final int year : access.getYears()) calculateOverview(overViewRows, river, access.getLowerKm(), access.getUpperKm(), year, year, false); } else { for (final DateRange dr : access.getEpochs()) calculateOverview(overViewRows, river, access.getLowerKm(), access.getUpperKm(), dr.getFromYear(), dr.getToYear(), true); } final CollisionCalcOverviewResult overviewResult = new CollisionCalcOverviewResult(access.getYearsHeader(), access.getYears(), overViewRows); results.addResult(overviewResult, problems); // create q-for-w-finders for all gauges of the calculation km range final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange); final Map<Gauge, GaugeDischargeValuesFinder> qFinders = new HashMap<>(); final Map<Gauge, GaugeMainValueFinder> zoneFinders = new HashMap<>(); for (final Gauge gauge : river.determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble())) { qFinders.put(gauge, GaugeDischargeValuesFinder.loadValues(gauge, problems)); zoneFinders.put(gauge, GaugeMainValueFinder.loadValues(MainValueTypeKey.Q, gauge, problems)); } final Collection<ResultRow> detailsRows = new ArrayList<>(); // calculate secondary results for each year or epoch if (access.getYears() != null) { for (final int year : access.getYears()) calculateDetails(detailsRows, infoProvider, access.getLowerKm(), access.getUpperKm(), year, year, qFinders, zoneFinders); } else { for (final DateRange dr : access.getEpochs()) calculateDetails(detailsRows, infoProvider, access.getLowerKm(), access.getUpperKm(), dr.getFromYear(), dr.getToYear(), qFinders, zoneFinders); } final CollisionCalcDetailResult detailResult = new CollisionCalcDetailResult("Details", detailsRows); results.addResult(detailResult, problems); return new CalculationResult(results, problems); } /** * Calculates the collision counts for a km range of a river and a year or year range (epoch), * and adds them to a ResultRow collection */ private void calculateOverview(final Collection<ResultRow> rows, final River river, final double fromKm, final double toKm, final int fromYear, final int toYear, final boolean isEpoch) { for (final CollisionAggregateValue aggregate : CollisionAggregateValue.getValuesByKm(river, fromKm, toKm, fromYear, toYear)) { rows.add(ResultRow.create().putValue(GeneralResultType.station, aggregate.getStation()) .putValue(SInfoResultType.years, (isEpoch? String.format("%d-%d", fromYear, toYear) : Integer.toString(fromYear))) .putValue(SInfoResultType.collisionCount, aggregate.getCount())); } } /** * Calculates the collision details for a km range of a river and a year or year range (epoch), * and adds them to a ResultRow collection */ private void calculateDetails(final Collection<ResultRow> rows, final RiverInfoProvider riverInfo, final double fromKm, final double toKm, final int fromYear, final int toYear, final Map<Gauge, GaugeDischargeValuesFinder> qFinders, final Map<Gauge, GaugeMainValueFinder> zoneFinders) { for (final CollisionValue collision : CollisionValue.getValues(riverInfo.getRiver(), fromKm, toKm, DateUtil.getStartDateFromYear(fromYear), DateUtil.getEndDateFromYear(toYear))) { final Gauge gauge = riverInfo.getGauge(collision.getStation(), true); final double q = qFinders.get(gauge).getDischarge(collision.getGaugeW()); final double qOut = Double.isInfinite(q) ? Double.NaN : q; rows.add(ResultRow.create().putValue(GeneralResultType.station, collision.getStation()) .putValue(GeneralResultType.date, collision.getEventDate()) .putValue(SInfoResultType.collisionGaugeW, collision.getGaugeW()) .putValue(SInfoResultType.gaugeLabel, collision.getGaugeName()) .putValue(SInfoResultType.discharge, qOut) .putValue(SInfoResultType.dischargeZone, zoneFinders.get(gauge).findZoneName(q))); } } }