Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java @ 9487:504f63512379
Sinfo collisions: calculation of multiple epochs, avoiding duplicate collision events in the details report
author | mschaefer |
---|---|
date | Tue, 18 Sep 2018 12:21:17 +0200 |
parents | 7b2b086e45f0 |
children | 853f2dafc16e |
comparison
equal
deleted
inserted
replaced
9486:ce13a2f07290 | 9487:504f63512379 |
---|---|
10 package org.dive4elements.river.artifacts.sinfo.collision; | 10 package org.dive4elements.river.artifacts.sinfo.collision; |
11 | 11 |
12 import java.util.ArrayList; | 12 import java.util.ArrayList; |
13 import java.util.Collection; | 13 import java.util.Collection; |
14 import java.util.HashMap; | 14 import java.util.HashMap; |
15 import java.util.List; | |
15 import java.util.Map; | 16 import java.util.Map; |
17 import java.util.NavigableSet; | |
18 import java.util.TreeSet; | |
16 | 19 |
17 import org.apache.commons.lang.math.DoubleRange; | 20 import org.apache.commons.lang.math.DoubleRange; |
18 import org.dive4elements.artifacts.CallContext; | 21 import org.dive4elements.artifacts.CallContext; |
19 import org.dive4elements.river.artifacts.common.GeneralResultType; | 22 import org.dive4elements.river.artifacts.common.GeneralResultType; |
20 import org.dive4elements.river.artifacts.common.ResultRow; | 23 import org.dive4elements.river.artifacts.common.ResultRow; |
64 | 67 |
65 final CollisionCalculationResults results = new CollisionCalculationResults(calcModeLabel, user, riverInfo, calcRange, access.getYearsHeader()); | 68 final CollisionCalculationResults results = new CollisionCalculationResults(calcModeLabel, user, riverInfo, calcRange, access.getYearsHeader()); |
66 | 69 |
67 final Collection<ResultRow> overViewRows = new ArrayList<>(); | 70 final Collection<ResultRow> overViewRows = new ArrayList<>(); |
68 | 71 |
72 final List<DateRange> years = new ArrayList<>(); | |
73 final NavigableSet<Integer> detailYears = new TreeSet<>(); | |
69 if (access.getYears() != null) { | 74 if (access.getYears() != null) { |
70 for (final int year : access.getYears()) | 75 for (final int year : access.getYears()) { |
71 calculateOverview(overViewRows, river, access.getLowerKm(), access.getUpperKm(), year, year, false); | 76 calculateOverview(overViewRows, river, access.getLowerKm(), access.getUpperKm(), year, year, false); |
77 years.add(new DateRange(DateUtil.getStartDateFromYear(year), DateUtil.getEndDateFromYear(year))); | |
78 detailYears.add(Integer.valueOf(year)); | |
79 } | |
72 } else { | 80 } else { |
73 for (final DateRange dr : access.getEpochs()) | 81 for (final DateRange dr : access.getEpochs()) { |
74 calculateOverview(overViewRows, river, access.getLowerKm(), access.getUpperKm(), dr.getFromYear(), dr.getToYear(), true); | 82 calculateOverview(overViewRows, river, access.getLowerKm(), access.getUpperKm(), dr.getFromYear(), dr.getToYear(), true); |
83 years.add(dr); | |
84 detailYearsAdd(detailYears, dr); | |
85 } | |
75 } | 86 } |
76 final CollisionCalcOverviewResult overviewResult = new CollisionCalcOverviewResult(access.getYearsHeader(), access.getYears(), overViewRows); | 87 final CollisionCalcOverviewResult overviewResult = new CollisionCalcOverviewResult(access.getYearsHeader(), (access.getYears() == null), years, |
88 overViewRows); | |
77 results.addResult(overviewResult, problems); | 89 results.addResult(overviewResult, problems); |
78 | 90 |
79 // create q-for-w-finders for all gauges of the calculation km range | 91 // create q-for-w-finders for all gauges of the calculation km range |
80 final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange); | 92 final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange); |
81 final Map<Gauge, GaugeDischargeValuesFinder> qFinders = new HashMap<>(); | 93 final Map<Gauge, GaugeDischargeValuesFinder> qFinders = new HashMap<>(); |
84 qFinders.put(gauge, GaugeDischargeValuesFinder.loadValues(gauge, problems)); | 96 qFinders.put(gauge, GaugeDischargeValuesFinder.loadValues(gauge, problems)); |
85 zoneFinders.put(gauge, GaugeMainValueFinder.loadValues(MainValueTypeKey.Q, gauge, problems)); | 97 zoneFinders.put(gauge, GaugeMainValueFinder.loadValues(MainValueTypeKey.Q, gauge, problems)); |
86 } | 98 } |
87 final Collection<ResultRow> detailsRows = new ArrayList<>(); | 99 final Collection<ResultRow> detailsRows = new ArrayList<>(); |
88 | 100 |
89 // calculate secondary results for each year or epoch | 101 // calculate secondary results for each year |
90 if (access.getYears() != null) { | 102 for (final Integer year : detailYears) |
91 for (final int year : access.getYears()) | 103 calculateDetails(detailsRows, infoProvider, access.getLowerKm(), access.getUpperKm(), year, qFinders, zoneFinders); |
92 calculateDetails(detailsRows, infoProvider, access.getLowerKm(), access.getUpperKm(), year, year, qFinders, zoneFinders); | |
93 } else { | |
94 for (final DateRange dr : access.getEpochs()) | |
95 calculateDetails(detailsRows, infoProvider, access.getLowerKm(), access.getUpperKm(), dr.getFromYear(), dr.getToYear(), qFinders, zoneFinders); | |
96 } | |
97 final CollisionCalcDetailResult detailResult = new CollisionCalcDetailResult("Details", detailsRows); | 104 final CollisionCalcDetailResult detailResult = new CollisionCalcDetailResult("Details", detailsRows); |
98 results.addResult(detailResult, problems); | 105 results.addResult(detailResult, problems); |
99 | 106 |
100 return new CalculationResult(results, problems); | 107 return new CalculationResult(results, problems); |
108 } | |
109 | |
110 /** | |
111 * Adds all years of an epoch to a set | |
112 */ | |
113 private void detailYearsAdd(final NavigableSet<Integer> detailYears, final DateRange epoch) { | |
114 for (int year = epoch.getFromYear(); year <= epoch.getToYear(); year++) | |
115 detailYears.add(Integer.valueOf(year)); | |
101 } | 116 } |
102 | 117 |
103 /** | 118 /** |
104 * Calculates the collision counts for a km range of a river and a year or year range (epoch), | 119 * Calculates the collision counts for a km range of a river and a year or year range (epoch), |
105 * and adds them to a ResultRow collection | 120 * and adds them to a ResultRow collection |
106 */ | 121 */ |
107 private void calculateOverview(final Collection<ResultRow> rows, final River river, final double fromKm, final double toKm, final int fromYear, | 122 private void calculateOverview(final Collection<ResultRow> rows, final River river, final double fromKm, final double toKm, final int fromYear, |
108 final int toYear, final boolean isEpoch) { | 123 final int toYear, final boolean isEpoch) { |
109 for (final CollisionAggregateValue aggregate : CollisionAggregateValue.getValuesByKm(river, fromKm, toKm, fromYear, toYear)) { | 124 for (final CollisionAggregateValue aggregate : CollisionAggregateValue.getValuesByKm(river, fromKm, toKm, fromYear, toYear)) { |
110 rows.add(ResultRow.create().putValue(GeneralResultType.station, aggregate.getStation()) | 125 rows.add(ResultRow.create().putValue(GeneralResultType.station, aggregate.getStation()) |
111 .putValue(SInfoResultType.years, (isEpoch ? String.format("%d-%d", fromYear, toYear) : Integer.toString(fromYear))) | 126 .putValue(SInfoResultType.years, yearsToString(isEpoch, fromYear, toYear)) |
112 .putValue(SInfoResultType.collisionCount, aggregate.getCount())); | 127 .putValue(SInfoResultType.collisionCount, aggregate.getCount())); |
113 } | 128 } |
114 } | 129 } |
115 | 130 |
116 /** | 131 /** |
117 * Calculates the collision details for a km range of a river and a year or year range (epoch), | 132 * Returns the string representation of a year or epoch |
118 * and adds them to a ResultRow collection | 133 */ |
134 public static String yearsToString(final boolean isEpoch, final DateRange years) { | |
135 return yearsToString(isEpoch, years.getFromYear(), years.getToYear()); | |
136 } | |
137 | |
138 /** | |
139 * Returns the string representation of a year or epoch | |
140 */ | |
141 public static String yearsToString(final boolean isEpoch, final int fromYear, final int toYear) { | |
142 return (isEpoch ? String.format("%d-%d", fromYear, toYear) : Integer.toString(fromYear)); | |
143 } | |
144 | |
145 /** | |
146 * Calculates the collision details for a km range of a river and a year, and adds them to a ResultRow collection | |
119 */ | 147 */ |
120 private void calculateDetails(final Collection<ResultRow> rows, final RiverInfoProvider riverInfo, final double fromKm, final double toKm, | 148 private void calculateDetails(final Collection<ResultRow> rows, final RiverInfoProvider riverInfo, final double fromKm, final double toKm, |
121 final int fromYear, final int toYear, final Map<Gauge, GaugeDischargeValuesFinder> qFinders, final Map<Gauge, GaugeMainValueFinder> zoneFinders) { | 149 final int year, final Map<Gauge, GaugeDischargeValuesFinder> qFinders, final Map<Gauge, GaugeMainValueFinder> zoneFinders) { |
122 for (final CollisionValue collision : CollisionValue.getValues(riverInfo.getRiver(), fromKm, toKm, DateUtil.getStartDateFromYear(fromYear), | 150 for (final CollisionValue collision : CollisionValue.getValues(riverInfo.getRiver(), fromKm, toKm, DateUtil.getStartDateFromYear(year), |
123 DateUtil.getEndDateFromYear(toYear))) { | 151 DateUtil.getEndDateFromYear(year))) { |
124 final Gauge gauge = riverInfo.getGauge(collision.getStation(), true); | 152 final Gauge gauge = riverInfo.getGauge(collision.getStation(), true); |
125 final double q = qFinders.get(gauge).getDischarge(collision.getGaugeW()); | 153 final double q = qFinders.get(gauge).getDischarge(collision.getGaugeW()); |
126 final double qOut = Double.isInfinite(q) ? Double.NaN : q; | 154 final double qOut = Double.isInfinite(q) ? Double.NaN : q; |
127 rows.add(ResultRow.create().putValue(GeneralResultType.station, collision.getStation()) | 155 rows.add(ResultRow.create().putValue(GeneralResultType.station, collision.getStation()) |
128 .putValue(GeneralResultType.dateShort, collision.getEventDate()).putValue(SInfoResultType.collisionGaugeW, collision.getGaugeW()) | 156 .putValue(GeneralResultType.dateShort, collision.getEventDate()).putValue(SInfoResultType.collisionGaugeW, collision.getGaugeW()) |