comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java @ 8854:7bbfb24e6eec

SINFO - first prototype of BArt Fließtiefen
author gernotbelger
date Thu, 18 Jan 2018 18:34:41 +0100
parents
children 1009cab0f86b
comparison
equal deleted inserted replaced
8853:8c64617a7991 8854:7bbfb24e6eec
1 /* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
2 * Software engineering by
3 * Björnsen Beratende Ingenieure GmbH
4 * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
5 *
6 * This file is Free Software under the GNU AGPL (>=v3)
7 * and comes with ABSOLUTELY NO WARRANTY! Check out the
8 * documentation coming with Dive4Elements River for details.
9 */
10 package org.dive4elements.river.artifacts.sinfo.flowdepth;
11
12 import java.util.Collection;
13 import java.util.List;
14
15 import org.dive4elements.artifacts.CallContext;
16 import org.dive4elements.river.artifacts.BedHeightsArtifact;
17 import org.dive4elements.river.artifacts.model.Calculation;
18 import org.dive4elements.river.artifacts.model.CalculationResult;
19 import org.dive4elements.river.artifacts.model.LocationProvider;
20 import org.dive4elements.river.artifacts.model.WKms;
21 import org.dive4elements.river.artifacts.resources.Resources;
22 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
23 import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthAccess.DifferencesPair;
24 import org.dive4elements.river.artifacts.states.WDifferencesState;
25 import org.dive4elements.river.model.BedHeight;
26 import org.dive4elements.river.model.Gauge;
27 import org.dive4elements.river.model.River;
28 import org.dive4elements.river.utils.GaugeIndex;
29 import org.dive4elements.river.utils.RiverUtils;
30
31 class FlowDepthCalculation {
32
33 private static final String CSV_NOT_IN_GAUGE_RANGE = "export.waterlevel.csv.not.in.gauge.range";
34
35 private CallContext context;
36
37 public FlowDepthCalculation( final CallContext context ) {
38 this.context = context;
39 }
40
41 public CalculationResult calculate(final SINFOArtifact sinfo) {
42
43 /* access input data */
44 final FlowDepthAccess access = new FlowDepthAccess(sinfo);
45 final River river = access.getRiver();
46
47 final Collection<DifferencesPair> diffPairs = access.getDifferencePairs();
48
49 final double from = access.getFrom();
50 final double to = access.getTo();
51
52 final boolean useTkh = access.isUseTransportBodies();
53
54 /* calculate results for each diff pair */
55 final Calculation problems = new Calculation();
56
57 final List<Gauge> gauges = river.determineGauges(from, to);
58 final GaugeIndex gaugeIndex = new GaugeIndex(gauges);
59
60 final FlowDepthCalculationResults results = new FlowDepthCalculationResults(river, from, to, useTkh);
61
62 for (final DifferencesPair diffPair : diffPairs) {
63 final FlowDepthCalculationResult result = calculateResult( river, from, to, diffPair, problems, gaugeIndex );
64 if( result != null )
65 results.addResult(result);
66 }
67
68 return new CalculationResult(results,problems);
69 }
70
71 private FlowDepthCalculationResult calculateResult(final River river, final double from, final double to, final DifferencesPair diffPair, final Calculation problems, final GaugeIndex gaugeIndex) {
72
73 /* access real input data from database */
74 final String soundingId = diffPair.getSoundingId();
75 final String wstId = diffPair.getWstId();
76
77 final BedHeight bedHeight = loadBedHeight( soundingId, from, to );
78 final WKms wstKms = new WDifferencesState().getWKms(wstId, context, from, to);
79 if( bedHeight == null || wstKms == null )
80 return null;
81
82 final FlowDepthCalculationResult resultData = new FlowDepthCalculationResult(wstKms.getName(), bedHeight.getDescription());
83
84 final String notinrange = Resources.getMsg(context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, CSV_NOT_IN_GAUGE_RANGE);
85
86 // TODO: unklarheiten
87 // 'idealerweise alle 100m' was heisst das? kann doch nur durch datenverfügbarkeit bestimmt werden
88 // wie mit unterschiedlichen Ranges umgehen? Schnitt bilden? Fehlermeldung? ...?
89 // wie interpolieren? wst interpolieren? peilung interpolieren?
90
91 // FIXME: für die Berechnung der TKH sind weitere 'in FLYS vorliegende' Daten notwendig.
92 // aktuell unklar ob das durch andere Barten berechnete Werte oder Basisdaten sind
93 // TODO: check Vergleiche BArt 'Transportkörperhöhen'
94
95 // TODO: Berechnung der Transportkörperhöhen
96 // - woher kommen die zusätzlichen eingangsdaten? sind das fixe daten pro gewässer? --> falls ja, warum nicht einmal berechnen und in db ablegen?
97
98 final String bedHeightLabel = bedHeight.getDescription();
99 final String wstLabel = wstKms.getName();
100
101 for (int i = 0; i < wstKms.size(); i++) {
102
103 final double km = wstKms.getKm(i);
104 final double wst = wstKms.getW(i);
105 // FIXME: interpolate from bedheights?
106 final double meanBedHeight = 79.32;
107
108 final double flowDepth = wst - meanBedHeight;
109
110 final double tkh = 0;
111 final double flowDepthTkh = flowDepth - tkh;
112
113 // FIXME: discharge not available for all wst? or any?
114 final double discharge = 0.0;
115
116 // REMARK: access the location once only during calculation
117 final String location = LocationProvider.getLocation(river.getName(), km);
118
119 // REMARK: access the gauge once only during calculation
120 final Gauge gauge = gaugeIndex.findGauge(km);
121 final String gaugeLabel = gauge == null ? notinrange : gauge.getName();
122
123 resultData.addRow( km, flowDepth, flowDepthTkh, tkh, wst, discharge, wstLabel, gaugeLabel, meanBedHeight, bedHeightLabel, location );
124 }
125
126 return resultData;
127 }
128
129 private BedHeight loadBedHeight(final String soundingId, final double from, final double to) {
130
131 // FIXME: absolutely unbelievable....
132 // The way how bed-heights (and other data too) is accessed is different for nearly ever calculation-type throughout flys.
133 // The knowledge on how to parse the datacage-ids is spread thorugh the complete code-base...
134
135 // We use here the way on how bed-heights are accessed by the BedDifferenceAccess/BedDifferenceCalculation, but this is plain random
136 final String[] parts = soundingId.split(";");
137
138 final BedHeightsArtifact artifact = (BedHeightsArtifact) RiverUtils.getArtifact(parts[0], context);
139
140 final Integer bedheightId = artifact.getDataAsInteger("height_id");
141 // FIXME: this only works with type 'single'; unclear on how to distinguish from epoch data (or whatever the other type means)
142 // Luckily, the requirement is to only access 'single' data here.
143 // final String bedheightType = artifact.getDataAsString("type");
144
145 // FIXME: BedDifferences uses this, but we also need the metadata of the BedHeight
146 // FIXME: second absolutely awful thing: BedHeight is a hibernate binding class, accessing the database via hibernate stuff
147 // BedHeightFactory uses its own (direct) way of accessing the data, with its own implemented data classes.
148 //return BedHeightFactory.getHeight(bedheightType, bedheightId, from, to);
149
150 return BedHeight.getBedHeightById(bedheightId);
151 }
152 }

http://dive4elements.wald.intevation.org