comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadData.java @ 8034:b6e7cfcabf2c

Wire the neighbors to the measurement stations together. This eases the lookup for same types (suspended or bed load).
author Sascha L. Teichmann <teichmann@intevation.de>
date Tue, 15 Jul 2014 18:52:22 +0200
parents 5e3f4b4fcb28
children f2dc7992b8a3
comparison
equal deleted inserted replaced
8033:5e3f4b4fcb28 8034:b6e7cfcabf2c
7 */ 7 */
8 package org.dive4elements.river.artifacts.model.minfo; 8 package org.dive4elements.river.artifacts.model.minfo;
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.Collections; 12 import java.util.Collection;
13 import java.util.Date; 13 import java.util.Date;
14 import java.util.List; 14 import java.util.List;
15 import java.util.NavigableMap;
16 import java.util.TreeMap; 15 import java.util.TreeMap;
17 16
18 import org.dive4elements.river.utils.EpsilonComparator; 17 import org.dive4elements.river.utils.EpsilonComparator;
19 18
20 public class SedimentLoadData implements Serializable 19 public class SedimentLoadData implements Serializable
118 117
119 private int type; 118 private int type;
120 119
121 private List<List<Value>> grainFractions; 120 private List<List<Value>> grainFractions;
122 121
122 private Station next;
123 private Station prev;
124
123 public Station() { 125 public Station() {
124 this(BED_LOAD, 0.0); 126 this(BED_LOAD, 0.0);
125 } 127 }
126 128
127 public Station(int type, double station) { 129 public Station(int type, double station) {
139 141
140 public int getType() { 142 public int getType() {
141 return type; 143 return type;
142 } 144 }
143 145
146 public void setNext(Station next) {
147 this.next = next;
148 }
149
150 public Station getNext() {
151 return next;
152 }
153
154 public void setPrev(Station prev) {
155 this.prev = next;
156 }
157
158 public Station getPrev() {
159 return prev;
160 }
161
144 public void addValue(int grainFraction, Value value) { 162 public void addValue(int grainFraction, Value value) {
145 grainFractions.get(grainFraction).add(value); 163 grainFractions.get(grainFraction).add(value);
146 } 164 }
147 165
148 public boolean hasGrainFraction(String grainFraction) { 166 public boolean hasGrainFraction(String grainFraction) {
173 } 191 }
174 192
175 public boolean inside(double a, double b) { 193 public boolean inside(double a, double b) {
176 return station >= a && station <= b; 194 return station >= a && station <= b;
177 } 195 }
196
197 public double findValueByLoadId(int id) {
198 for (List<Value> values: grainFractions) {
199 double value = findValueByLoadId(values, id);
200 if (!Double.isNaN(value)) {
201 return value;
202 }
203 }
204 return Double.NaN;
205 }
206
207 private static final double findValueByLoadId(
208 List<Value> values,
209 int id
210 ) {
211 // List is ordered by station id -> binary search.
212 int lo = 0, hi = values.size()-1;
213 while (lo <= hi) {
214 int mid = (lo + hi)/2;
215 Value v = values.get(mid);
216 int xid = v.getLoad().getId();
217 if (xid < id) hi = mid-1;
218 else if (xid > id) lo = mid+1;
219 else return v.getValue();
220 }
221
222 return Double.NaN;
223 }
178 } // class Station 224 } // class Station
179 225
180 226
181 private TreeMap<Double, List<Station>> stations; 227 private List<List<Station>> stations;
182 228
183 public SedimentLoadData() { 229 public SedimentLoadData() {
184 stations = new TreeMap<Double, List<Station>>(EpsilonComparator.CMP); 230 }
185 } 231
186 232 public SedimentLoadData(Collection<Station> stations) {
187 public void addStation(Station station) { 233 setStations(stations);
188 Double key = station.getStation(); 234 }
189 List<Station> sts = stations.get(key); 235
190 if (sts == null) { 236 public void setStations(Collection<Station> stations) {
191 sts = new ArrayList<Station>(2); 237 TreeMap<Double, List<Station>> same =
192 stations.put(key, sts); 238 new TreeMap<Double, List<Station>>(EpsilonComparator.CMP);
193 } 239 for (Station station: stations) {
194 sts.add(station); 240 Double key = station.getStation();
195 } 241 List<Station> sts = same.get(key);
196 242 if (sts == null) {
197 243 sts = new ArrayList<Station>(2);
198 public NavigableMap<Double, List<Station>> range(double from, double to) { 244 same.put(key, sts);
199 245 }
200 if (from > to) { 246 sts.add(station);
201 double t = from; from = to; to = t; 247 }
202 } 248 this.stations = new ArrayList<List<Station>>(same.values());
203 249 wireNeighbors();
204 return stations.subMap(from, true, to, true); 250 }
251
252 private void wireNeighbors() {
253 for (int i = 0, N = stations.size()-1; i < N; ++i) {
254 for (Station current: stations.get(i)) {
255 int type = current.getType();
256 NEXT: for (int j = i+1; j < N; ++j) {
257 for (Station next: stations.get(j)) {
258 if (next.getType() == type) {
259 current.setNext(next);
260 next.setPrev(current);
261 break NEXT;
262 }
263 }
264 }
265 }
266 }
205 } 267 }
206 } 268 }
207 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : 269 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org