Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/exports/ATWriter.java @ 3318:dbe2f85bf160
merged flys-artifacts/2.8
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:35 +0200 |
parents | 0c8a6145098b |
children | 67bbcee26e21 |
comparison
equal
deleted
inserted
replaced
2987:98c7a46ec5ae | 3318:dbe2f85bf160 |
---|---|
1 package de.intevation.flys.exports; | |
2 | |
3 import java.io.IOException; | |
4 import java.io.Writer; | |
5 import java.io.PrintWriter; | |
6 | |
7 import java.util.Locale; | |
8 | |
9 import de.intevation.artifacts.CallMeta; | |
10 | |
11 import de.intevation.flys.artifacts.model.WQ; | |
12 import de.intevation.flys.artifacts.resources.Resources; | |
13 | |
14 import org.apache.commons.math.analysis.UnivariateRealFunction; | |
15 | |
16 import org.apache.commons.math.analysis.interpolation.SplineInterpolator; | |
17 import org.apache.commons.math.analysis.interpolation.LinearInterpolator; | |
18 | |
19 import org.apache.commons.math.analysis.polynomials.PolynomialFunction; | |
20 | |
21 import org.apache.commons.math.FunctionEvaluationException; | |
22 | |
23 import org.apache.log4j.Logger; | |
24 | |
25 public class ATWriter | |
26 { | |
27 private static Logger logger = Logger.getLogger(ATWriter.class); | |
28 | |
29 public static final int COLUMNS = 10; | |
30 | |
31 public static final String I18N_AT_HEADER = | |
32 "export.discharge.curve.at.header"; | |
33 | |
34 public static final String EMPTY = " "; | |
35 | |
36 protected double minW; | |
37 protected double maxW; | |
38 protected double minQ; | |
39 protected double maxQ; | |
40 | |
41 protected UnivariateRealFunction qFunc; | |
42 | |
43 public ATWriter() { | |
44 } | |
45 | |
46 public ATWriter(WQ wq) throws IllegalArgumentException { | |
47 | |
48 int [] bounds = wq.longestIncreasingWRangeIndices(); | |
49 | |
50 if (logger.isDebugEnabled()) { | |
51 logger.debug("exporting w between indices " + | |
52 bounds[0] + " and " + bounds[1] + " (" + | |
53 wq.getW(bounds[0]) + ", " + wq.getW(bounds[1])); | |
54 } | |
55 | |
56 if (bounds[1]-bounds[0] < 1) { // Only first w can be written out. | |
57 minW = maxW = wq.getW(bounds[0]); | |
58 minQ = maxQ = wq.getQ(bounds[0]); | |
59 // constant function | |
60 qFunc = new PolynomialFunction(new double [] { minQ }); | |
61 return; | |
62 } | |
63 | |
64 double [] ws = new double[bounds[1]-bounds[0]]; | |
65 double [] qs = new double[ws.length]; | |
66 | |
67 for (int i = 0; i < ws.length; ++i) { | |
68 int idx = bounds[0]+i; | |
69 ws[i] = wq.getW(idx); | |
70 qs[i] = wq.getQ(idx); | |
71 } | |
72 | |
73 qFunc = ws.length < 3 | |
74 ? new LinearInterpolator().interpolate(ws, qs) | |
75 : new SplineInterpolator().interpolate(ws, qs); | |
76 | |
77 minW = wq.getW(bounds[0]); | |
78 maxW = wq.getW(bounds[1]); | |
79 minQ = wq.getQ(bounds[0]); | |
80 maxQ = wq.getQ(bounds[1]); | |
81 } | |
82 | |
83 public double getQ(double w) { | |
84 | |
85 try { | |
86 return qFunc.value(w); | |
87 } | |
88 catch (FunctionEvaluationException aode) { | |
89 // should not happen | |
90 logger.warn("spline interpolation failed", aode); | |
91 return w <= minW ? minQ : maxQ; | |
92 } | |
93 } | |
94 | |
95 public static void printQ(PrintWriter out, double q) { | |
96 String format; | |
97 if (q < 1d) format = " % 8.3f"; | |
98 else if (q < 10d) format = " % 8.2f"; | |
99 else if (q < 100d) format = " % 8.1f"; | |
100 else { | |
101 format = " % 8.0f"; | |
102 if (q > 1000d) q = Math.rint(q/10d)*10d; | |
103 } | |
104 out.printf(Locale.US, format, q); | |
105 } | |
106 | |
107 | |
108 protected static void printHeader( | |
109 PrintWriter out, | |
110 CallMeta callMeta, | |
111 String river, | |
112 double km | |
113 ) { | |
114 out.println(Resources.getMsg( | |
115 callMeta, | |
116 I18N_AT_HEADER, | |
117 I18N_AT_HEADER, | |
118 new Object[] { river, km } )); | |
119 } | |
120 | |
121 | |
122 public void write(Writer writer, CallMeta meta, String river, double km) | |
123 throws IOException | |
124 { | |
125 PrintWriter out = new PrintWriter(writer); | |
126 | |
127 // a header is required, because the desktop version of FLYS will skip | |
128 // the first row. | |
129 printHeader(out, meta, river, km); | |
130 | |
131 double rest = (minW * 100.0) % 10.0; | |
132 | |
133 double startW = Math.rint((minW - rest*0.01)*10.0)*0.1; | |
134 | |
135 if (logger.isDebugEnabled()) { | |
136 logger.debug("startW: " + startW); | |
137 logger.debug("rest: " + rest); | |
138 } | |
139 | |
140 int col = 0; | |
141 for (double w = startW; w <= maxW; w += 0.01) { | |
142 if (col == 0) { | |
143 out.printf(Locale.US, "%8d", (int)Math.round(w*100.0)); | |
144 } | |
145 | |
146 if (w < minW) { | |
147 out.print(EMPTY); | |
148 } | |
149 else { | |
150 printQ(out, getQ(w)); | |
151 } | |
152 | |
153 if (++col >= COLUMNS) { | |
154 out.println(); | |
155 col = 0; | |
156 } | |
157 } | |
158 | |
159 if (col > 0) { | |
160 out.println(); | |
161 } | |
162 | |
163 out.flush(); | |
164 } | |
165 } | |
166 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |