comparison artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/ChannelFinder.java @ 9432:d194c5b24bf8

Added bundu bzws w calculation and longitudinal sections of wspl and depth
author mschaefer
date Mon, 20 Aug 2018 09:46:02 +0200
parents
children ac41551a8e4d
comparison
equal deleted inserted replaced
9431:eeea16ea0980 9432:d194c5b24bf8
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
11 package org.dive4elements.river.artifacts.bundu.bezugswst;
12
13 import java.util.Map.Entry;
14 import java.util.NavigableMap;
15 import java.util.TreeMap;
16
17 import org.dive4elements.river.artifacts.math.Linear;
18 import org.dive4elements.river.artifacts.model.Calculation;
19 import org.dive4elements.river.model.River;
20 import org.dive4elements.river.model.sinfo.Channel;
21 import org.dive4elements.river.model.sinfo.ChannelValue;
22
23 /**
24 * Provides channel depth and height of a river
25 *
26 * @author Matthias Schäfer
27 */
28 public final class ChannelFinder {
29
30 /***** TYPES *****/
31
32 public enum ChannelValueType {
33 depth {
34 @Override
35 public Double getValue(final ChannelValue channelValue) {
36 return channelValue.getDepth();
37 }
38 },
39 width {
40 @Override
41 public Double getValue(final ChannelValue channelValue) {
42 return channelValue.getWidth();
43 }
44 };
45
46 public abstract Double getValue(final ChannelValue channelValue);
47 }
48
49 /***** FIELDS *****/
50
51 // private static Logger log = Logger.getLogger(ChannelFinder.class);
52
53 private static double MAX_DISTANCE_KM = 1;
54
55 private final NavigableMap<Double, ChannelValue> values = new TreeMap<>();
56
57 private Calculation problems;
58
59
60 /***** CONSTRUCTORS *****/
61
62 private ChannelFinder(final Calculation problems, final Channel channel) {
63
64 this.problems = problems;
65
66 for (final ChannelValue v : channel.getValues()) {
67 this.values.put(v.getStation(), v);
68 }
69 }
70
71 /***** METHODS *****/
72
73 /**
74 * Loads the channel values for a river and year
75 *
76 * @return Whether the load has been successful
77 */
78 public static ChannelFinder loadValues(final Calculation problems, final River river, final int year) {
79 final Channel channel = Channel.getSeries(river, year);
80 if (channel != null)
81 return new ChannelFinder(problems, channel);
82
83 problems.addProblem("channelfinder.empty");
84 return null;
85 }
86
87
88 /***** METHODS *****/
89
90 /**
91 * Searches the channel depth of a station
92 */
93 public double getDepth(final double station) {
94 final double value = interpolateChannel(station, ChannelValueType.depth);
95 if (Double.isNaN(value))
96 reportProblem(station);
97 return value;
98 }
99
100 /**
101 * Searches the channel width of a station
102 */
103 public double getWidth(final double station) {
104 final double value = interpolateChannel(station, ChannelValueType.width);
105 if (Double.isNaN(value))
106 reportProblem(station);
107 return value;
108 }
109
110 /**
111 * Searches and interpolates a channel value for a km
112 */
113 private double interpolateChannel(final double km, final ChannelValueType type) {
114
115 if (this.values.containsKey(km)) {
116 final Double value = type.getValue(this.values.get(km));
117 return (value == null) ? Double.NaN : value.doubleValue();
118 }
119
120 final Entry<Double, ChannelValue> floorEntry = this.values.floorEntry(km);
121 final Entry<Double, ChannelValue> ceilingEntry = this.values.ceilingEntry(km);
122
123 if ((floorEntry == null) || (ceilingEntry == null))
124 return Double.NaN;
125
126 final double floorKm = floorEntry.getKey().doubleValue();
127 final double ceilKm = ceilingEntry.getKey().doubleValue();
128
129 /* report once if the interpolation distance exceeds 1000m */
130 if ((Math.abs(floorKm - ceilKm) > MAX_DISTANCE_KM) && (this.problems != null)) {
131 this.problems.addProblem(km, "linearInterpolator.maxdistance", MAX_DISTANCE_KM * 1000);
132 this.problems = null;
133 return Double.NaN;
134 }
135
136 final Double floorHeight = type.getValue(floorEntry.getValue());
137 final Double ceilingHeight = type.getValue(ceilingEntry.getValue());
138
139 if (floorHeight == null || ceilingHeight == null)
140 return Double.NaN;
141
142 return Linear.linear(km, floorKm, ceilKm, floorHeight, ceilingHeight);
143 }
144
145 private void reportProblem(final double km) {
146
147 if (this.problems == null)
148 return;
149
150 this.problems.addProblem(km, "channelfinder.missing");
151
152 // report problem only once
153 this.problems = null;
154 }
155 }

http://dive4elements.wald.intevation.org