comparison flys-artifacts/src/main/java/de/intevation/flys/exports/WstWriter.java @ 2424:092e519ff461

merged flys-artifacts/2.6.1
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:26 +0200
parents 72bcbc308501
children d9fb3a178be4
comparison
equal deleted inserted replaced
2392:8112ec686a9a 2424:092e519ff461
1 package de.intevation.flys.exports;
2
3 import java.io.BufferedWriter;
4 import java.io.OutputStream;
5 import java.io.OutputStreamWriter;
6 import java.io.PrintWriter;
7
8 import java.util.ArrayList;
9 import java.util.Collection;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Locale;
13 import java.util.Map;
14 import java.util.TreeMap;
15
16 import org.apache.log4j.Logger;
17
18 import de.intevation.flys.artifacts.model.WstLine;
19
20
21 /**
22 * A writer that creates WSTs.
23 *
24 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
25 */
26 public class WstWriter {
27
28 /** The logger used in this class.*/
29 private static Logger logger = Logger.getLogger(WstWriter.class);
30
31
32 /** The default unit that is written into the header of the WST.*/
33 public static final String DEFAULT_UNIT = "Wassserstand [NN + m]";
34
35
36 /** The lines that need to be included for the export.*/
37 protected Map<Double, WstLine> lines;
38
39 /** The column names.*/
40 protected List<String> columnNames;
41
42 /** The locale used to format the values.*/
43 protected Locale locale;
44
45 /** The number of discharge columns.*/
46 protected int cols;
47
48 /** The last Q values.*/
49 protected double[] qs;
50
51
52
53 /**
54 * This constructor creates a new WstWriter with an OutputStream and a
55 * number of Q columns.
56 *
57 * @param out The output stream where the WST is written to.
58 * @param cols The number of columns of the resulting WST.
59 */
60 public WstWriter(int cols) {
61 this.columnNames = new ArrayList<String>(cols);
62 this.lines = new HashMap<Double, WstLine>();
63 this.qs = new double[cols];
64 this.locale = Locale.US;
65 }
66
67
68 /**
69 * This method is used to create the WST from the data that has been
70 * inserted using add(double[]) before.
71 */
72 public void write(OutputStream out) {
73 logger.info("WstWriter.write");
74
75 PrintWriter writer = new PrintWriter(
76 new BufferedWriter(
77 new OutputStreamWriter(out)));
78
79 this.qs = new double[cols];
80
81 writeHeader(writer);
82
83 Collection<WstLine> collection = new TreeMap(lines).values();
84
85 for (WstLine line: collection) {
86 writeWLine(writer, line);
87 }
88
89 writer.flush();
90 writer.close();
91 }
92
93
94 /**
95 * This method is used to add a new line to the WST.
96 *
97 * @param wqkms A 3dim double array with [W,Q, KM].
98 */
99 public void add(double[] wqkms) {
100 Double km = wqkms[2];
101
102 WstLine line = lines.get(km);
103
104 if (line == null) {
105 line = new WstLine(km.doubleValue());
106 lines.put(km, line);
107 }
108
109 line.add(wqkms[0], wqkms[1]);
110 }
111
112
113 public void addCorrected(double[] wqckms) {
114 Double km = wqckms[2];
115
116 WstLine line = lines.get(km);
117
118 if (line == null) {
119 line = new WstLine(km.doubleValue());
120 lines.put(km, line);
121 }
122
123 line.add(wqckms[3], wqckms[1]);
124 }
125
126
127 /**
128 * Adds a further column name.
129 *
130 * @param name The name of the new column.
131 */
132 public void addColumn(String name) {
133 if (name != null) {
134 cols++;
135
136 String basename = name;
137
138 int i = 0;
139 while (columnNames.contains(name)) {
140 name = basename + "_" + i++;
141
142 if (name.length() > 9) {
143 name = name.substring(name.length() - 9);
144 }
145 }
146
147 columnNames.add(name);
148 }
149 }
150
151
152 /**
153 * This method writes the header of the WST.
154 *
155 * @param writer The PrintWriter that creates the output.
156 */
157 protected void writeHeader(PrintWriter writer) {
158 logger.debug("WstWriter.writeHeader");
159
160 writer.println(cols);
161 writer.print(" ");
162
163 for (String columnName: columnNames) {
164 writer.printf(locale, "%9s", columnName);
165 }
166
167 writer.println();
168
169 writer.write("* KM ");
170 writer.write(DEFAULT_UNIT);
171 writer.println();
172 }
173
174
175 /**
176 * This method writes a line with W values and a certain kilometer.
177 *
178 * @param writer The PrintWriter that is used to create the output.
179 * @param line The WstLine that should be written to the output.
180 */
181 protected void writeWLine(PrintWriter writer, WstLine line) {
182 double km = line.getKm();
183 double[] qs = line.getQs();
184 int num = line.getSize();
185
186 if (dischargesChanged(qs)) {
187 writeQLine(writer, qs);
188 }
189
190 writer.printf(locale, "%8.3f", km);
191
192 for (int i = 0; i < num; i++) {
193 writer.printf(locale, "%9.2f", line.getW(i));
194 }
195
196 writer.println();
197 }
198
199
200 /**
201 * Writes a discharge line (Q values) into a WST.
202 *
203 * @param qs the Q values for the next range.
204 */
205 protected void writeQLine(PrintWriter writer, double[] qs) {
206 writer.write("*\u001f ");
207
208 for (int i = 0; i < qs.length; i++) {
209 this.qs[i] = qs[i];
210
211 writer.printf(locale, "%9.2f", qs[i]);
212 }
213
214 writer.println();
215 }
216
217
218 /**
219 * This method determines if a Q has changed from the last line to the
220 * current one.
221 *
222 * @param newQs The Q values of the next line.
223 *
224 * @return true, if a Q value have changed, otherwise false.
225 */
226 protected boolean dischargesChanged(double[] newQs) {
227 // XXX maybe there is a way to do this faster
228 for (int i = 0; i < cols; i++) {
229 if (Math.abs(newQs[i] - qs[i]) >= 0.001) {
230 return true;
231 }
232 }
233
234 return false;
235 }
236 }
237 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org