Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/exports/ATWriter.java @ 5838:5aa05a7a34b7
Rename modules to more fitting names.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2013 15:23:37 +0200 |
parents | flys-artifacts/src/main/java/org/dive4elements/river/exports/ATWriter.java@bd047b71ab37 |
children | 4897a58c8746 |
comparison
equal
deleted
inserted
replaced
5837:d9901a08d0a6 | 5838:5aa05a7a34b7 |
---|---|
1 package org.dive4elements.river.exports; | |
2 | |
3 import java.io.IOException; | |
4 import java.io.Writer; | |
5 import java.io.PrintWriter; | |
6 import java.math.BigDecimal; | |
7 | |
8 import java.text.DateFormat; | |
9 import java.util.Date; | |
10 import java.util.Locale; | |
11 | |
12 import org.dive4elements.artifacts.CallMeta; | |
13 | |
14 import org.dive4elements.river.artifacts.model.WQ; | |
15 import org.dive4elements.river.artifacts.resources.Resources; | |
16 | |
17 import org.apache.commons.math.analysis.UnivariateRealFunction; | |
18 | |
19 import org.apache.commons.math.analysis.interpolation.SplineInterpolator; | |
20 import org.apache.commons.math.analysis.interpolation.LinearInterpolator; | |
21 | |
22 import org.apache.commons.math.analysis.polynomials.PolynomialFunction; | |
23 | |
24 import org.apache.commons.math.FunctionEvaluationException; | |
25 | |
26 import org.apache.log4j.Logger; | |
27 | |
28 /** Write AT files. */ | |
29 public class ATWriter | |
30 { | |
31 private static Logger logger = Logger.getLogger(ATWriter.class); | |
32 | |
33 public static final int COLUMNS = 10; | |
34 | |
35 public static final String I18N_AT_HEADER = | |
36 "export.discharge.curve.at.header"; | |
37 | |
38 public static final String I18N_AT_GAUGE_HEADER = | |
39 "export.discharge.curve.at.gauge.header"; | |
40 | |
41 public static final String EMPTY = " "; | |
42 | |
43 protected double minW; | |
44 protected double maxW; | |
45 protected double minQ; | |
46 protected double maxQ; | |
47 | |
48 protected UnivariateRealFunction qFunc; | |
49 | |
50 public ATWriter() { | |
51 } | |
52 | |
53 public ATWriter(WQ wq) throws IllegalArgumentException { | |
54 | |
55 int [] bounds = wq.longestIncreasingWRangeIndices(); | |
56 | |
57 if (logger.isDebugEnabled()) { | |
58 logger.debug("exporting w between indices " + | |
59 bounds[0] + " and " + bounds[1] + " (" + | |
60 wq.getW(bounds[0]) + ", " + wq.getW(bounds[1])); | |
61 } | |
62 | |
63 if (bounds[1]-bounds[0] < 1) { // Only first w can be written out. | |
64 minW = maxW = wq.getW(bounds[0]); | |
65 minQ = maxQ = wq.getQ(bounds[0]); | |
66 // constant function | |
67 qFunc = new PolynomialFunction(new double [] { minQ }); | |
68 return; | |
69 } | |
70 | |
71 double [] ws = new double[bounds[1]-bounds[0]]; | |
72 double [] qs = new double[ws.length]; | |
73 | |
74 for (int i = 0; i < ws.length; ++i) { | |
75 int idx = bounds[0]+i; | |
76 ws[i] = wq.getW(idx); | |
77 qs[i] = wq.getQ(idx); | |
78 } | |
79 | |
80 qFunc = ws.length < 3 | |
81 ? new LinearInterpolator().interpolate(ws, qs) | |
82 : new SplineInterpolator().interpolate(ws, qs); | |
83 | |
84 minW = wq.getW(bounds[0]); | |
85 maxW = wq.getW(bounds[1]); | |
86 minQ = wq.getQ(bounds[0]); | |
87 maxQ = wq.getQ(bounds[1]); | |
88 } | |
89 | |
90 public double getQ(double w) { | |
91 | |
92 try { | |
93 return qFunc.value(w); | |
94 } | |
95 catch (FunctionEvaluationException aode) { | |
96 // should not happen | |
97 logger.warn("spline interpolation failed", aode); | |
98 return w <= minW ? minQ : maxQ; | |
99 } | |
100 } | |
101 | |
102 public static void printQ(PrintWriter out, double q) { | |
103 String format; | |
104 if (q < 1d) format = " % 8.3f"; | |
105 else if (q < 10d) format = " % 8.2f"; | |
106 else if (q < 100d) format = " % 8.1f"; | |
107 else { | |
108 format = " % 8.0f"; | |
109 if (q > 1000d) q = Math.rint(q/10d)*10d; | |
110 } | |
111 out.printf(Locale.US, format, q); | |
112 } | |
113 | |
114 | |
115 protected static void printGaugeHeader( | |
116 PrintWriter out, | |
117 CallMeta callMeta, | |
118 String river, | |
119 double km, | |
120 String gName, | |
121 BigDecimal datum, | |
122 Date date | |
123 ) { | |
124 DateFormat f = DateFormat.getDateInstance(); | |
125 out.print(Resources.getMsg( | |
126 callMeta, | |
127 I18N_AT_GAUGE_HEADER, | |
128 I18N_AT_GAUGE_HEADER, | |
129 new Object[] { river, gName, f.format(date), datum } )); | |
130 out.print("\r\n"); | |
131 } | |
132 | |
133 protected static void printHeader( | |
134 PrintWriter out, | |
135 CallMeta callMeta, | |
136 String river, | |
137 double km | |
138 ) { | |
139 out.print(Resources.getMsg( | |
140 callMeta, | |
141 I18N_AT_HEADER, | |
142 I18N_AT_HEADER, | |
143 new Object[] { river, km } )); | |
144 out.print("\r\n"); | |
145 } | |
146 | |
147 public void write( | |
148 Writer writer, | |
149 CallMeta meta, | |
150 String river, | |
151 double km, | |
152 String gName, | |
153 BigDecimal datum, | |
154 Date date, | |
155 double scale) | |
156 throws IOException | |
157 { | |
158 PrintWriter out = new PrintWriter(writer); | |
159 | |
160 // A header is required, because the desktop version of FLYS will skip | |
161 // the first row. | |
162 if (gName != null) { | |
163 printGaugeHeader(out, meta, river, km, gName, datum, date); | |
164 } | |
165 else { | |
166 printHeader(out, meta, river, km); | |
167 } | |
168 | |
169 double rest = (minW * 100.0) % 10.0; | |
170 | |
171 double startW = Math.rint((minW - rest*0.01)*10.0)*0.1; | |
172 | |
173 if (logger.isDebugEnabled()) { | |
174 logger.debug("startW: " + startW); | |
175 logger.debug("rest: " + rest); | |
176 } | |
177 | |
178 int col = 0; | |
179 for (double w = startW; w <= maxW; w += 0.01) { | |
180 if (col == 0) { | |
181 out.printf(Locale.US, "%8d", (int)Math.round(w * scale)); | |
182 } | |
183 | |
184 if (w < minW) { | |
185 out.print(EMPTY); | |
186 } | |
187 else { | |
188 printQ(out, getQ(w)); | |
189 } | |
190 | |
191 if (++col >= COLUMNS) { | |
192 out.print("\r\n"); | |
193 col = 0; | |
194 } | |
195 } | |
196 | |
197 if (col > 0) { | |
198 out.print("\r\n"); | |
199 } | |
200 | |
201 out.flush(); | |
202 } | |
203 } | |
204 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |