Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/exports/WstWriter.java @ 9299:4a6cc7c6716a
uinfo.inundation_duration veg'zone select
author | gernotbelger |
---|---|
date | Wed, 25 Jul 2018 14:42:44 +0200 |
parents | e4606eae8ea5 |
children |
comparison
equal
deleted
inserted
replaced
9298:0b1a51b0c42e | 9299:4a6cc7c6716a |
---|---|
10 | 10 |
11 import java.io.BufferedWriter; | 11 import java.io.BufferedWriter; |
12 import java.io.OutputStream; | 12 import java.io.OutputStream; |
13 import java.io.OutputStreamWriter; | 13 import java.io.OutputStreamWriter; |
14 import java.io.PrintWriter; | 14 import java.io.PrintWriter; |
15 | |
16 import java.util.ArrayList; | 15 import java.util.ArrayList; |
17 import java.util.Collection; | 16 import java.util.Collection; |
18 import java.util.HashMap; | 17 import java.util.HashMap; |
19 import java.util.List; | 18 import java.util.List; |
20 import java.util.Locale; | 19 import java.util.Locale; |
21 import java.util.Map; | 20 import java.util.Map; |
22 import java.util.TreeMap; | 21 import java.util.TreeMap; |
23 | 22 |
23 import org.apache.commons.lang.StringUtils; | |
24 import org.apache.log4j.Logger; | 24 import org.apache.log4j.Logger; |
25 import org.apache.commons.lang.StringUtils; | |
26 | |
27 import org.dive4elements.river.artifacts.model.WstLine; | 25 import org.dive4elements.river.artifacts.model.WstLine; |
28 | |
29 | 26 |
30 /** | 27 /** |
31 * A writer that creates WSTs. | 28 * A writer that creates WSTs. |
32 * | 29 * |
33 * Wst files follow this basic structure: | 30 * Wst files follow this basic structure: |
47 | 44 |
48 /** The log used in this class. */ | 45 /** The log used in this class. */ |
49 private static Logger log = Logger.getLogger(WstWriter.class); | 46 private static Logger log = Logger.getLogger(WstWriter.class); |
50 | 47 |
51 /** The default unit that is written into the header of the WST. */ | 48 /** The default unit that is written into the header of the WST. */ |
52 public static final String DEFAULT_UNIT = "Wassserstand [NN + m]"; | 49 public static final String DEFAULT_UNIT = "Wasserstand [NN + m]"; |
53 | 50 |
54 /** The lines that need to be included for the export. */ | 51 /** The lines that need to be included for the export. */ |
55 protected Map<Double, WstLine> lines; | 52 protected Map<Double, WstLine> lines; |
56 | 53 |
57 /** The column names. */ | 54 /** The column names. */ |
64 protected int cols; | 61 protected int cols; |
65 | 62 |
66 /** The last Q values. */ | 63 /** The last Q values. */ |
67 protected double[] qs; | 64 protected double[] qs; |
68 | 65 |
69 /** Workaround for one use of wrongly imported files: ignore the Qs at | 66 /** |
70 * all. */ | 67 * Workaround for one use of wrongly imported files: ignore the Qs at |
68 * all. | |
69 */ | |
71 protected boolean ignoreQs; | 70 protected boolean ignoreQs; |
72 | 71 |
73 /** | 72 /** |
74 * This constructor creates a new WstWriter with a number of Q columns. | 73 * This constructor creates a new WstWriter with a number of Q columns. |
75 * | 74 * |
76 * @param columns The number of columns of the resulting WST. | 75 * @param columns |
77 */ | 76 * The number of columns of the resulting WST. |
78 public WstWriter(int columns) { | 77 */ |
78 public WstWriter(final int columns) { | |
79 this(columns, false); | 79 this(columns, false); |
80 } | 80 } |
81 | 81 |
82 /** | 82 /** |
83 * This constructor creates a new WstWriter with a number of Q columns. | 83 * This constructor creates a new WstWriter with a number of Q columns. |
84 * | 84 * |
85 * @param columns The number of columns of the resulting WST. | 85 * @param columns |
86 * @param workaroundIgnoreQs do not write QLines to shadow broken data. | 86 * The number of columns of the resulting WST. |
87 */ | 87 * @param workaroundIgnoreQs |
88 public WstWriter(int columns, boolean workaroundIgnoreQs) { | 88 * do not write QLines to shadow broken data. |
89 this.cols = columns; | 89 */ |
90 this.columnNames = new ArrayList<String>(cols); | 90 public WstWriter(final int columns, final boolean workaroundIgnoreQs) { |
91 this.lines = new HashMap<Double, WstLine>(); | 91 this.cols = columns; |
92 this.qs = new double[cols]; | 92 this.columnNames = new ArrayList<>(this.cols); |
93 this.locale = Locale.US; | 93 this.lines = new HashMap<>(); |
94 this.ignoreQs = workaroundIgnoreQs; | 94 this.qs = new double[this.cols]; |
95 } | 95 this.locale = Locale.US; |
96 | 96 this.ignoreQs = workaroundIgnoreQs; |
97 } | |
97 | 98 |
98 /** | 99 /** |
99 * This method is used to create the WST from the data that has been | 100 * This method is used to create the WST from the data that has been |
100 * inserted using add(double[]) before. | 101 * inserted using add(double[]) before. |
101 * @param out Where to write to. | 102 * |
102 */ | 103 * @param out |
103 public void write(OutputStream out) { | 104 * Where to write to. |
105 */ | |
106 public void write(final OutputStream out) { | |
104 log.info("WstWriter.write"); | 107 log.info("WstWriter.write"); |
105 | 108 |
106 PrintWriter writer = new PrintWriter( | 109 final PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(out))); |
107 new BufferedWriter( | 110 |
108 new OutputStreamWriter(out))); | 111 this.qs = new double[this.cols]; |
109 | |
110 this.qs = new double[cols]; | |
111 | 112 |
112 writeHeader(writer); | 113 writeHeader(writer); |
113 | 114 |
114 Collection<WstLine> collection = new TreeMap(lines).values(); | 115 final Collection<WstLine> collection = new TreeMap(this.lines).values(); |
115 | 116 |
116 for (WstLine line: collection) { | 117 for (final WstLine line : collection) { |
117 writeWLine(writer, line); | 118 writeWLine(writer, line); |
118 } | 119 } |
119 | 120 |
120 writer.flush(); | 121 writer.flush(); |
121 writer.close(); | 122 writer.close(); |
122 } | 123 } |
123 | 124 |
124 | |
125 /** | 125 /** |
126 * This method is used to add a new line to the WST. | 126 * This method is used to add a new line to the WST. |
127 * | 127 * |
128 * @param wqkms A 3dim double array with [W, Q, KM]. | 128 * @param wqkms |
129 */ | 129 * A 3dim double array with [W, Q, KM]. |
130 public void add(double[] wqkms) { | 130 */ |
131 Double km = wqkms[2]; | 131 public void add(final double[] wqkms) { |
132 | 132 final Double km = wqkms[2]; |
133 WstLine line = lines.get(km); | 133 |
134 WstLine line = this.lines.get(km); | |
134 | 135 |
135 if (line == null) { | 136 if (line == null) { |
136 line = new WstLine(km.doubleValue()); | 137 line = new WstLine(km.doubleValue()); |
137 lines.put(km, line); | 138 this.lines.put(km, line); |
138 } | 139 } |
139 | 140 |
140 line.add(wqkms[0], wqkms[1]); | 141 line.add(wqkms[0], wqkms[1]); |
141 } | 142 } |
142 | 143 |
143 | 144 public void addCorrected(final double[] wqckms) { |
144 public void addCorrected(double[] wqckms) { | 145 final Double km = wqckms[2]; |
145 Double km = wqckms[2]; | 146 |
146 | 147 WstLine line = this.lines.get(km); |
147 WstLine line = lines.get(km); | |
148 | 148 |
149 if (line == null) { | 149 if (line == null) { |
150 line = new WstLine(km.doubleValue()); | 150 line = new WstLine(km.doubleValue()); |
151 lines.put(km, line); | 151 this.lines.put(km, line); |
152 } | 152 } |
153 | 153 |
154 line.add(wqckms[3], wqckms[1]); | 154 line.add(wqckms[3], wqckms[1]); |
155 } | 155 } |
156 | 156 |
157 | |
158 /** | 157 /** |
159 * Adds a further column name. | 158 * Adds a further column name. |
160 * | 159 * |
161 * @param name The name of the new column. | 160 * @param name |
161 * The name of the new column. | |
162 */ | 162 */ |
163 public void addColumn(String name) { | 163 public void addColumn(String name) { |
164 if (name != null) { | 164 if (name != null) { |
165 cols++; | 165 this.cols++; |
166 | 166 |
167 int i = 0; | 167 int i = 0; |
168 String basename = name; | 168 final String basename = name; |
169 while (columnNames.contains(name)) { | 169 while (this.columnNames.contains(name)) { |
170 name = basename + "_" + i++; | 170 name = basename + "_" + i++; |
171 } | 171 } |
172 | 172 |
173 columnNames.add(name); | 173 this.columnNames.add(name); |
174 } | 174 } |
175 } | 175 } |
176 | |
177 | 176 |
178 /** | 177 /** |
179 * This method writes the header of the WST. | 178 * This method writes the header of the WST. |
180 * | 179 * |
181 * @param writer The PrintWriter that creates the output. | 180 * @param writer |
182 */ | 181 * The PrintWriter that creates the output. |
183 protected void writeHeader(PrintWriter writer) { | 182 */ |
183 protected void writeHeader(final PrintWriter writer) { | |
184 log.debug("WstWriter.writeHeader"); | 184 log.debug("WstWriter.writeHeader"); |
185 | 185 |
186 writer.println(cols); | 186 writer.println(this.cols); |
187 | 187 |
188 writer.print("*!column-bez-text "); | 188 writer.print("*!column-bez-text "); |
189 | 189 |
190 List<String> quotedNames = new ArrayList<String>(columnNames.size()); | 190 final List<String> quotedNames = new ArrayList<>(this.columnNames.size()); |
191 | 191 |
192 for (String name: columnNames) { | 192 for (String name : this.columnNames) { |
193 if (name.contains(" ")) { | 193 if (name.contains(" ")) { |
194 name = '"' + name + '"'; | 194 name = '"' + name + '"'; |
195 } | 195 } |
196 quotedNames.add(name); | 196 quotedNames.add(name); |
197 } | 197 } |
198 writer.println(StringUtils.join(quotedNames, " ")); | 198 writer.println(StringUtils.join(quotedNames, " ")); |
199 writer.print(" "); | 199 writer.print(" "); |
200 | 200 |
201 for (String columnName: columnNames) { | 201 for (final String columnName : this.columnNames) { |
202 if (columnName.length() > 9) { | 202 if (columnName.length() > 9) { |
203 writer.printf(locale, "%9s", | 203 writer.printf(this.locale, "%9s", columnName.substring(columnName.length() - 9)); |
204 columnName.substring(columnName.length() - 9)); | |
205 } else { | 204 } else { |
206 writer.printf(locale, "%9s", columnName); | 205 writer.printf(this.locale, "%9s", columnName); |
207 // This is weird but i was to lazy to lookup | 206 // This is weird but i was to lazy to lookup |
208 // how to do this another way. | 207 // how to do this another way. |
209 for (int i = 9 - columnName.length(); i > 0; i--) { | 208 for (int i = 9 - columnName.length(); i > 0; i--) { |
210 writer.print(" "); | 209 writer.print(" "); |
211 } | 210 } |
217 writer.write("* KM "); | 216 writer.write("* KM "); |
218 writer.write(DEFAULT_UNIT); | 217 writer.write(DEFAULT_UNIT); |
219 writer.println(); | 218 writer.println(); |
220 } | 219 } |
221 | 220 |
222 | |
223 /** | 221 /** |
224 * This method writes a line with W values and a certain kilometer. | 222 * This method writes a line with W values and a certain kilometer. |
225 * | 223 * |
226 * @param writer The PrintWriter that is used to create the output. | 224 * @param writer |
227 * @param line The WstLine that should be written to the output. | 225 * The PrintWriter that is used to create the output. |
228 */ | 226 * @param line |
229 protected void writeWLine(PrintWriter writer, WstLine line) { | 227 * The WstLine that should be written to the output. |
230 double km = line.getKm(); | 228 */ |
231 double[] qs = line.getQs(); | 229 protected void writeWLine(final PrintWriter writer, final WstLine line) { |
232 int num = line.getSize(); | 230 final double km = line.getKm(); |
233 | 231 final double[] qs = line.getQs(); |
234 if (!ignoreQs && dischargesChanged(qs)) { | 232 final int num = line.getSize(); |
233 | |
234 if (!this.ignoreQs && dischargesChanged(qs)) { | |
235 writeQLine(writer, qs); | 235 writeQLine(writer, qs); |
236 } | 236 } |
237 | 237 |
238 writer.printf(locale, "%8.3f", km); | 238 writer.printf(this.locale, "%8.3f", km); |
239 | 239 |
240 for (int i = 0; i < num; i++) { | 240 for (int i = 0; i < num; i++) { |
241 writer.printf(locale, "%9.2f", line.getW(i)); | 241 writer.printf(this.locale, "%9.2f", line.getW(i)); |
242 } | 242 } |
243 | 243 |
244 writer.println(); | 244 writer.println(); |
245 } | 245 } |
246 | |
247 | 246 |
248 /** | 247 /** |
249 * Writes a discharge line (Q values) into a WST. | 248 * Writes a discharge line (Q values) into a WST. |
250 * | 249 * |
251 * @param qs the Q values for the next range. | 250 * @param qs |
252 */ | 251 * the Q values for the next range. |
253 protected void writeQLine(PrintWriter writer, double[] qs) { | 252 */ |
253 protected void writeQLine(final PrintWriter writer, final double[] qs) { | |
254 writer.write("*\u001f "); | 254 writer.write("*\u001f "); |
255 | 255 |
256 for (int i = 0; i < qs.length; i++) { | 256 for (int i = 0; i < qs.length; i++) { |
257 this.qs[i] = qs[i]; | 257 this.qs[i] = qs[i]; |
258 | 258 |
259 writer.printf(locale, "%9.2f", qs[i]); | 259 writer.printf(this.locale, "%9.2f", qs[i]); |
260 } | 260 } |
261 | 261 |
262 writer.println(); | 262 writer.println(); |
263 } | 263 } |
264 | |
265 | 264 |
266 /** | 265 /** |
267 * This method determines if a Q has changed from the last line to the | 266 * This method determines if a Q has changed from the last line to the |
268 * current one. | 267 * current one. |
269 * | 268 * |
270 * @param newQs The Q values of the next line. | 269 * @param newQs |
270 * The Q values of the next line. | |
271 * | 271 * |
272 * @return true, if a Q value have changed, otherwise false. | 272 * @return true, if a Q value have changed, otherwise false. |
273 */ | 273 */ |
274 protected boolean dischargesChanged(double[] newQs) { | 274 protected boolean dischargesChanged(final double[] newQs) { |
275 // XXX maybe there is a way to do this faster | 275 // XXX maybe there is a way to do this faster |
276 for (int i = 0; i < cols && i < qs.length && i < newQs.length; i++) { | 276 for (int i = 0; i < this.cols && i < this.qs.length && i < newQs.length; i++) { |
277 if (Math.abs(newQs[i] - qs[i]) >= 0.001) { | 277 if (Math.abs(newQs[i] - this.qs[i]) >= 0.001) { |
278 return true; | 278 return true; |
279 } | 279 } |
280 } | 280 } |
281 | 281 |
282 return false; | 282 return false; |
285 /** | 285 /** |
286 * Get the lines that have alreay been added to this writer | 286 * Get the lines that have alreay been added to this writer |
287 * lines are a map with km as the key and a wstline as value. | 287 * lines are a map with km as the key and a wstline as value. |
288 */ | 288 */ |
289 public Map<Double, WstLine> getLines() { | 289 public Map<Double, WstLine> getLines() { |
290 return lines; | 290 return this.lines; |
291 } | 291 } |
292 } | 292 } |
293 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : | 293 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |