Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentDensity.java @ 8064:50102c41151e
Sediment load: Ensure that the lists of values are always ordered station wise. This was a hidden bug. :-/
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Wed, 30 Jul 2014 18:54:14 +0200 |
parents | 41d9014bfa02 |
children | fdb26fe898dc |
comparison
equal
deleted
inserted
replaced
8063:41d9014bfa02 | 8064:50102c41151e |
---|---|
9 package org.dive4elements.river.artifacts.model.minfo; | 9 package org.dive4elements.river.artifacts.model.minfo; |
10 | 10 |
11 import java.io.Serializable; | 11 import java.io.Serializable; |
12 import java.util.ArrayList; | 12 import java.util.ArrayList; |
13 import java.util.Collections; | 13 import java.util.Collections; |
14 import java.util.Comparator; | |
14 import java.util.HashMap; | 15 import java.util.HashMap; |
15 import java.util.Iterator; | 16 import java.util.Iterator; |
16 import java.util.List; | 17 import java.util.List; |
17 import java.util.Map; | 18 import java.util.Map; |
18 import java.util.Set; | 19 import java.util.Set; |
67 | 68 |
68 public Map<Integer, List<SedimentDensityValue>> getDensities() { | 69 public Map<Integer, List<SedimentDensityValue>> getDensities() { |
69 return densities; | 70 return densities; |
70 } | 71 } |
71 | 72 |
73 private static final Comparator<SedimentDensityValue> BY_KM = | |
74 new Comparator<SedimentDensityValue>() { | |
75 @Override | |
76 public int compare(SedimentDensityValue a, SedimentDensityValue b) { | |
77 double diff = a.getKm() - b.getKm(); | |
78 if (diff < 0.0) return -1; | |
79 if (diff > 0.0) return +1; | |
80 return 0; | |
81 } | |
82 }; | |
83 | |
72 public void addDensity(double km, double density, int year) { | 84 public void addDensity(double km, double density, int year) { |
73 | 85 |
74 logger.debug("adding " + year); | 86 logger.debug("adding " + year); |
75 | 87 |
76 Integer key = Integer.valueOf(year); | 88 Integer key = Integer.valueOf(year); |
80 if (list == null) { | 92 if (list == null) { |
81 list = new ArrayList<SedimentDensityValue>(); | 93 list = new ArrayList<SedimentDensityValue>(); |
82 densities.put(key, list); | 94 densities.put(key, list); |
83 } | 95 } |
84 | 96 |
85 list.add(new SedimentDensityValue(km, density, year)); | 97 // Keep list sorted by km. |
98 SedimentDensityValue sdv = new SedimentDensityValue(km, density, year); | |
99 int index = Collections.binarySearch(list, sdv, BY_KM); | |
100 | |
101 if (index < 0) { | |
102 // index = -(insertion point) - 1 | |
103 // -(index + 1) = insertion point | |
104 index = -(index + 1); | |
105 } | |
106 | |
107 list.add(index, sdv); | |
86 } | 108 } |
87 | 109 |
88 /** | 110 /** |
89 * Get the density at year. | 111 * Get the density at year. |
90 * Measured densities are valid until the next measurement. | 112 * Measured densities are valid until the next measurement. |
100 Map.Entry<Integer, List<SedimentDensityValue>> entry = densities.firstEntry(); | 122 Map.Entry<Integer, List<SedimentDensityValue>> entry = densities.firstEntry(); |
101 return entry.getKey() <= year | 123 return entry.getKey() <= year |
102 ? getDensityAtKm(entry.getValue(), km) | 124 ? getDensityAtKm(entry.getValue(), km) |
103 : SEDIMNET_DENSITY_FACTOR; | 125 : SEDIMNET_DENSITY_FACTOR; |
104 } | 126 } |
127 | |
105 Iterator<Map.Entry<Integer, List<SedimentDensityValue>>> iter = | 128 Iterator<Map.Entry<Integer, List<SedimentDensityValue>>> iter = |
106 densities.entrySet().iterator(); | 129 densities.entrySet().iterator(); |
107 | 130 |
108 Map.Entry<Integer, List<SedimentDensityValue>> last = iter.next(); | 131 Map.Entry<Integer, List<SedimentDensityValue>> last = iter.next(); |
109 | 132 |
144 } | 167 } |
145 | 168 |
146 /** Get points km,density (sorted by km), for a given year. */ | 169 /** Get points km,density (sorted by km), for a given year. */ |
147 public double[][] getDensities(int year) | 170 public double[][] getDensities(int year) |
148 { | 171 { |
149 TreeMap<Double, Double> map = new TreeMap<Double,Double>(); | |
150 List<SedimentDensityValue> list = densities.get(year); | 172 List<SedimentDensityValue> list = densities.get(year); |
151 if (list == null) { | 173 if (list == null) { |
152 return new double[2][0]; | 174 return new double[2][0]; |
153 } | 175 } |
154 for (SedimentDensityValue sdv: densities.get(year)) { | 176 // List is sorted in km. |
155 map.put(sdv.getKm(), sdv.getDensity()); | 177 double[][] points = new double[2][list.size()]; |
156 } | |
157 double[][] points = new double[2][map.size()]; | |
158 int i = 0; | 178 int i = 0; |
159 for (Map.Entry<Double, Double> kmDens: map.entrySet()) { | 179 for (SedimentDensityValue sdv: list) { |
160 points[0][i] = kmDens.getKey(); | 180 points[0][i] = sdv.getKm(); |
161 points[1][i] = kmDens.getValue(); | 181 points[1][i] = sdv.getDensity(); |
162 i++; | 182 i++; |
163 } | 183 } |
164 | 184 |
165 return points; | 185 return points; |
166 } | 186 } |
167 | 187 |
168 /** Get value at km, interpolated. */ | 188 /** Get value at km, interpolated. */ |
169 private double getDensityAtKm( | 189 private static double getDensityAtKm( |
170 List<SedimentDensityValue> values, | 190 List<SedimentDensityValue> values, |
171 double km | 191 double km |
172 ) { | 192 ) { |
173 SedimentDensityValue prev = null; | 193 SedimentDensityValue prev = null; |
174 SedimentDensityValue next = null; | 194 SedimentDensityValue next = null; |
175 for (SedimentDensityValue sdv: values) { | 195 for (SedimentDensityValue sdv: values) { |
176 logger.debug("year: " + sdv.getYear()); | |
177 if (Math.abs(sdv.getKm() - km) < 0.00001) { | 196 if (Math.abs(sdv.getKm() - km) < 0.00001) { |
178 return prev.getDensity(); | 197 return prev.getDensity(); |
179 } | 198 } |
180 if (sdv.getKm() > km) { | 199 if (sdv.getKm() > km) { |
181 next = sdv; | 200 next = sdv; |