Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java @ 9157:f9bb5d0a6ff3
Added the S-Info collision calculation and chart output
author | mschaefer |
---|---|
date | Tue, 19 Jun 2018 14:19:32 +0200 |
parents | 23945061daec |
children | 1614cb14308f |
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java Tue Jun 19 14:16:45 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java Tue Jun 19 14:19:32 2018 +0200 @@ -11,6 +11,8 @@ 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; @@ -18,12 +20,18 @@ 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.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.River; +import org.dive4elements.river.model.sinfo.CollisionAggregateValue; +import org.dive4elements.river.model.sinfo.CollisionValue; class CollisionCalculation { @@ -39,46 +47,89 @@ final String user = CalculationUtils.findArtifactUser(this.context, sinfo); - /* access input data */ + // 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 diff pair */ + // calculate results for each year or epoch final Calculation problems = new Calculation(); - final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange); - final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name()); - final int[] years = access.getYears(); - final int[][] epochs = access.getEpochs(); + 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(), 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, GaugeDischargeZoneFinder> zoneFinders = new HashMap<>(); + for (final Gauge gauge : river.determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble())) { + qFinders.put(gauge, GaugeDischargeValuesFinder.loadValues(gauge, problems)); + zoneFinders.put(gauge, GaugeDischargeZoneFinder.loadValues(gauge, problems)); + } final Collection<ResultRow> detailsRows = new ArrayList<>(); - // TODO: calculate - - final CollisionCalculationResults results = new CollisionCalculationResults(calcModeLabel, user, riverInfo, calcRange); - - final ResultRow row = ResultRow.create().putValue(GeneralResultType.station, 8888.888); - final ResultRow row2 = ResultRow.create().putValue(GeneralResultType.station, 777.888); - - for (int i = 0; i < 300; i++) { - overViewRows.add(row); - overViewRows.add(row2); + // 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); } - final CollisionCalcOverviewResult overviewResult = new CollisionCalcOverviewResult("Overview", overViewRows); // TODO: get Title-Strings from messages - results.addResult(overviewResult, problems); - for (int i = 0; i < 200; i++) { - detailsRows.add(row); - detailsRows.add(row2); + 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, GaugeDischargeZoneFinder> 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).getDischargeZone(q))); + } + } } \ No newline at end of file