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 :

http://dive4elements.wald.intevation.org