Mercurial > dive4elements > river
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 } |