comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadData.java @ 8044:86fa217c24d5

Sediment load: Merge measurement stations if they have the same km. The chaining was too complicated to build algorithms on top of it.
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 17 Jul 2014 07:45:14 +0200
parents 01ad09af0975
children c835f3cf098e
comparison
equal deleted inserted replaced
8042:9342d7fe0ee7 8044:86fa217c24d5
9 9
10 import java.io.Serializable; 10 import java.io.Serializable;
11 import java.util.ArrayList; 11 import java.util.ArrayList;
12 import java.util.Collection; 12 import java.util.Collection;
13 import java.util.Collections; 13 import java.util.Collections;
14 import java.util.Comparator;
14 import java.util.Date; 15 import java.util.Date;
15 import java.util.List; 16 import java.util.List;
16 import java.util.TreeMap; 17 import java.util.TreeMap;
17 18
18 import org.dive4elements.river.utils.EpsilonComparator; 19 import org.dive4elements.river.utils.EpsilonComparator;
116 } 117 }
117 } // class SedimentLoad 118 } // class SedimentLoad
118 119
119 public static class Station implements Serializable { 120 public static class Station implements Serializable {
120 121
121 public static final int BED_LOAD = 0; 122 public static final int BED_LOAD = 1;
122 public static final int SUSPENDED = 1; 123 public static final int SUSPENDED = 2;
123 124
124 private double station; 125 private double station;
125 126
126 private int type; 127 private int type;
127 128
128 private List<List<Value>> grainFractions; 129 private List<List<Value>> grainFractions;
129 130
130 private Station next; 131 private Station next;
131 private Station prev; 132 private Station prev;
132
133 private Station chain;
134 133
135 public Station() { 134 public Station() {
136 this(BED_LOAD, 0.0); 135 this(BED_LOAD, 0.0);
137 } 136 }
138 137
151 150
152 public int getType() { 151 public int getType() {
153 return type; 152 return type;
154 } 153 }
155 154
155 public boolean isType(int type) {
156 return (this.type & type) == type;
157 }
158
156 public void setNext(Station next) { 159 public void setNext(Station next) {
157 this.next = next; 160 this.next = next;
158 } 161 }
159 162
160 public Station getNext() { 163 public Station getNext() {
175 178
176 public Station getPrev(boolean isKMUp) { 179 public Station getPrev(boolean isKMUp) {
177 return isKMUp ? getPrev() : getNext(); 180 return isKMUp ? getPrev() : getNext();
178 } 181 }
179 182
180 public Station nextChain() { 183 public void merge(Station other) {
181 return chain; 184 this.type |= other.type;
182 } 185 for (int i = 0, N = grainFractions.size(); i < N; ++i) {
183 186 grainFractions.set(i,
184 public void append(Station station) { 187 mergeValues(grainFractions.get(i), other.grainFractions.get(i)));
185 station.chain = chain; 188 }
186 chain = station; 189 }
190
191 private static final Comparator<Value> ID_CMP = new Comparator<Value>() {
192 @Override
193 public int compare(Value a, Value b) {
194 return a.getLoad().getId() - b.getLoad().getId();
195 }
196 };
197
198 private static List<Value> mergeValues(List<Value> a, List<Value> b) {
199 if (a == null) return b;
200 if (b == null) return a;
201 a.addAll(b);
202 // re-establish id order.
203 Collections.sort(a, ID_CMP);
204 return a;
205 }
206
207 public Station nextByType(int type, boolean isKMUp) {
208 for (Station curr = this; curr != null; curr = curr.getNext(isKMUp)) {
209 if (curr.isType(type)) {
210 return curr;
211 }
212 }
213 return null;
214 }
215
216 public Station prevByType(int type, boolean isKMUp) {
217 for (Station curr = this; curr != null; curr = curr.getPrev(isKMUp)) {
218 if (curr.isType(type)) {
219 return curr;
220 }
221 }
222 return null;
187 } 223 }
188 224
189 public void addValue(int grainFraction, Value value) { 225 public void addValue(int grainFraction, Value value) {
190 List<Value> values = grainFractions.get(grainFraction); 226 List<Value> values = grainFractions.get(grainFraction);
191 if (values == null) { 227 if (values == null) {
246 else return v.getValue(); 282 else return v.getValue();
247 } 283 }
248 284
249 return Double.NaN; 285 return Double.NaN;
250 } 286 }
251
252 public Station firstOfType(int type) {
253 for (Station curr = this; curr != null; curr = curr.chain) {
254 if (curr.getType() == type) {
255 return curr;
256 }
257 }
258 return null;
259 }
260 } // class Station 287 } // class Station
261 288
262 289
263 private Station [] stations; 290 private Station [] stations;
264 291
277 Double key = station.getStation(); 304 Double key = station.getStation();
278 Station st = same.get(key); 305 Station st = same.get(key);
279 if (st == null) { 306 if (st == null) {
280 same.put(key, station); 307 same.put(key, station);
281 } else { 308 } else {
282 st.append(station); 309 st.merge(station);
283 } 310 }
284 } 311 }
285 this.stations = new Station[same.size()]; 312 this.stations = new Station[same.size()];
286 int i = 0; 313 int i = 0;
287 for (Station station: same.values()) { 314 for (Station station: same.values()) {
289 } 316 }
290 wireNeighbors(); 317 wireNeighbors();
291 } 318 }
292 319
293 private void wireNeighbors() { 320 private void wireNeighbors() {
294 for (int i = 0, N = stations.length; i < N-1; ++i) { 321 for (int i = 1; i < stations.length; ++i) {
295 for (Station curr = stations[i]; curr != null; curr = curr.nextChain()) { 322 stations[i-1].setNext(stations[i]);
296 int type = curr.getType(); 323 stations[i].setPrev(stations[i-1]);
297 NEXT: for (int j = i+1; j < N; ++j) {
298 Station next = stations[j].firstOfType(type);
299 if (next != null) {
300 curr.setNext(next);
301 next.setPrev(curr);
302 break NEXT;
303 }
304 }
305 }
306 } 324 }
307 } 325 }
308 326
309 private void recursiveFindStations( 327 private void recursiveFindStations(
310 double a, double b, 328 double a, double b,

http://dive4elements.wald.intevation.org