Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/exports/WaterlevelExporter.java @ 9082:42c15e2f95fb
2.3.4.1.4 Wasserstand falsche Einheit
FixAnalysis PDF start
author | gernotbelger |
---|---|
date | Fri, 25 May 2018 10:44:24 +0200 |
parents | 5294114b1df4 |
children | 740d65e4aa14 |
comparison
equal
deleted
inserted
replaced
9081:a0feac6ea1ba | 9082:42c15e2f95fb |
---|---|
11 import java.io.IOException; | 11 import java.io.IOException; |
12 import java.io.OutputStream; | 12 import java.io.OutputStream; |
13 import java.text.DateFormat; | 13 import java.text.DateFormat; |
14 import java.text.NumberFormat; | 14 import java.text.NumberFormat; |
15 import java.util.ArrayList; | 15 import java.util.ArrayList; |
16 import java.util.Map; | 16 import java.util.Date; |
17 import java.util.HashMap; | 17 import java.util.HashMap; |
18 import java.util.Date; | |
19 import java.util.List; | 18 import java.util.List; |
20 import java.util.Locale; | 19 import java.util.Locale; |
20 import java.util.Map; | |
21 import java.util.regex.Matcher; | 21 import java.util.regex.Matcher; |
22 import java.util.regex.Pattern; | 22 import java.util.regex.Pattern; |
23 | 23 |
24 import org.apache.log4j.Logger; | 24 import org.apache.log4j.Logger; |
25 import org.dive4elements.artifacts.Artifact; | |
26 import org.dive4elements.artifacts.CallMeta; | |
27 import org.dive4elements.artifacts.common.utils.Config; | |
28 import org.dive4elements.river.artifacts.D4EArtifact; | |
29 import org.dive4elements.river.artifacts.FixationArtifact; | |
30 import org.dive4elements.river.artifacts.StaticWQKmsArtifact; | |
31 import org.dive4elements.river.artifacts.WINFOArtifact; | |
32 import org.dive4elements.river.artifacts.access.FixRealizingAccess; | |
33 import org.dive4elements.river.artifacts.access.IsOfficialAccess; | |
34 import org.dive4elements.river.artifacts.access.RangeAccess; | |
35 import org.dive4elements.river.artifacts.model.CalculationResult; | |
36 import org.dive4elements.river.artifacts.model.ConstantWQKms; | |
37 import org.dive4elements.river.artifacts.model.Segment; | |
38 import org.dive4elements.river.artifacts.model.WKmsJRDataSource; | |
39 import org.dive4elements.river.artifacts.model.WQCKms; | |
40 import org.dive4elements.river.artifacts.model.WQKms; | |
41 import org.dive4elements.river.artifacts.model.WQKmsResult; | |
42 import org.dive4elements.river.artifacts.model.WstLine; | |
43 import org.dive4elements.river.artifacts.resources.Resources; | |
44 import org.dive4elements.river.model.Gauge; | |
45 import org.dive4elements.river.utils.Formatter; | |
46 import org.dive4elements.river.utils.RiverUtils; | |
47 import org.dive4elements.river.utils.RiverUtils.WQ_MODE; | |
25 | 48 |
26 import au.com.bytecode.opencsv.CSVWriter; | 49 import au.com.bytecode.opencsv.CSVWriter; |
27 | |
28 import gnu.trove.TDoubleArrayList; | 50 import gnu.trove.TDoubleArrayList; |
29 | 51 import net.sf.jasperreports.engine.JRException; |
30 import org.dive4elements.river.artifacts.model.ConstantWQKms; | |
31 | |
32 import net.sf.jasperreports.engine.JasperExportManager; | 52 import net.sf.jasperreports.engine.JasperExportManager; |
33 import net.sf.jasperreports.engine.JasperFillManager; | 53 import net.sf.jasperreports.engine.JasperFillManager; |
34 import net.sf.jasperreports.engine.JasperPrint; | 54 import net.sf.jasperreports.engine.JasperPrint; |
35 import net.sf.jasperreports.engine.JRException; | |
36 | |
37 import org.dive4elements.artifacts.Artifact; | |
38 import org.dive4elements.artifacts.CallMeta; | |
39 import org.dive4elements.artifacts.common.utils.Config; | |
40 | |
41 import org.dive4elements.river.model.Gauge; | |
42 | |
43 import org.dive4elements.river.artifacts.access.FixRealizingAccess; | |
44 import org.dive4elements.river.artifacts.access.IsOfficialAccess; | |
45 import org.dive4elements.river.artifacts.access.RangeAccess; | |
46 import org.dive4elements.river.artifacts.FixationArtifact; | |
47 import org.dive4elements.river.artifacts.D4EArtifact; | |
48 import org.dive4elements.river.artifacts.WINFOArtifact; | |
49 import org.dive4elements.river.artifacts.StaticWQKmsArtifact; | |
50 import org.dive4elements.river.artifacts.model.CalculationResult; | |
51 import org.dive4elements.river.artifacts.model.Segment; | |
52 import org.dive4elements.river.artifacts.model.WQCKms; | |
53 import org.dive4elements.river.artifacts.model.WQKms; | |
54 import org.dive4elements.river.artifacts.model.WstLine; | |
55 import org.dive4elements.river.artifacts.model.WKmsJRDataSource; | |
56 import org.dive4elements.river.artifacts.model.WQKmsResult; | |
57 import org.dive4elements.river.artifacts.resources.Resources; | |
58 | |
59 import org.dive4elements.river.utils.RiverUtils; | |
60 import org.dive4elements.river.utils.RiverUtils.WQ_MODE; | |
61 import org.dive4elements.river.utils.Formatter; | |
62 | 55 |
63 /** | 56 /** |
64 * Generates different output formats (wst, csv, pdf) of data that resulted from | 57 * Generates different output formats (wst, csv, pdf) of data that resulted from |
65 * a waterlevel computation. | 58 * a waterlevel computation. |
66 * | 59 * |
67 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> | 60 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> |
68 */ | 61 */ |
69 public class WaterlevelExporter extends AbstractExporter { | 62 public class WaterlevelExporter extends AbstractExporter { |
70 | 63 |
71 /** The log used in this exporter.*/ | 64 /** The log used in this exporter. */ |
72 private static Logger log = Logger.getLogger(WaterlevelExporter.class); | 65 private static Logger log = Logger.getLogger(WaterlevelExporter.class); |
73 | 66 |
74 public static final String FACET_WST = "wst"; | 67 public static final String FACET_WST = "wst"; |
75 | 68 |
76 /* This should be the same as in the StaticWQKmsArtifact */ | 69 /* This should be the same as in the StaticWQKmsArtifact */ |
77 public static final String STATICWQKMSNAME = "staticwqkms"; | 70 public static final String STATICWQKMSNAME = "staticwqkms"; |
78 | 71 |
79 public static final String CSV_KM_HEADER = | 72 public static final String CSV_KM_HEADER = "export.waterlevel.csv.header.km"; |
80 "export.waterlevel.csv.header.km"; | 73 |
81 | 74 public static final String CSV_W_HEADER = "export.waterlevel.csv.header.w"; |
82 public static final String CSV_W_HEADER = | 75 |
83 "export.waterlevel.csv.header.w"; | 76 public static final String CSV_Q_HEADER = "export.waterlevel.csv.header.q"; |
84 | |
85 public static final String CSV_Q_HEADER = | |
86 "export.waterlevel.csv.header.q"; | |
87 | 77 |
88 /** | 78 /** |
89 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. | 79 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. |
90 */ | 80 */ |
91 @Deprecated | 81 @Deprecated |
92 public static final String CSV_Q_DESC_HEADER = | 82 public static final String CSV_Q_DESC_HEADER = "export.waterlevel.csv.header.q.desc"; |
93 "export.waterlevel.csv.header.q.desc"; | |
94 | 83 |
95 /** | 84 /** |
96 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. | 85 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. |
97 */ | 86 */ |
98 @Deprecated | 87 @Deprecated |
99 public static final String CSV_W_DESC_HEADER = | 88 public static final String CSV_W_DESC_HEADER = "export.waterlevel.csv.header.w.desc"; |
100 "export.waterlevel.csv.header.w.desc"; | 89 |
101 | 90 public static final String CSV_LOCATION_HEADER = "export.waterlevel.csv.header.location"; |
102 public static final String CSV_LOCATION_HEADER = | 91 |
103 "export.waterlevel.csv.header.location"; | 92 public static final String CSV_GAUGE_HEADER = "export.waterlevel.csv.header.gauge"; |
104 | 93 |
105 public static final String CSV_GAUGE_HEADER = | 94 public static final String CSV_META_RESULT = "export.waterlevel.csv.meta.result"; |
106 "export.waterlevel.csv.header.gauge"; | 95 |
107 | 96 public static final String CSV_META_CREATION = "export.waterlevel.csv.meta.creation"; |
108 public static final String CSV_META_RESULT = | 97 |
109 "export.waterlevel.csv.meta.result"; | 98 public static final String CSV_META_CALCULATIONBASE = "export.waterlevel.csv.meta.calculationbase"; |
110 | 99 |
111 public static final String CSV_META_CREATION = | 100 public static final String CSV_META_RIVER = "export.waterlevel.csv.meta.river"; |
112 "export.waterlevel.csv.meta.creation"; | 101 |
113 | 102 public static final String CSV_META_RANGE = "export.waterlevel.csv.meta.range"; |
114 public static final String CSV_META_CALCULATIONBASE = | 103 |
115 "export.waterlevel.csv.meta.calculationbase"; | 104 public static final String CSV_META_GAUGE = "export.waterlevel.csv.meta.gauge"; |
116 | 105 |
117 public static final String CSV_META_RIVER = | 106 public static final String CSV_META_Q = "export.waterlevel.csv.meta.q"; |
118 "export.waterlevel.csv.meta.river"; | 107 |
119 | 108 public static final String CSV_META_W = "export.waterlevel.csv.meta.w"; |
120 public static final String CSV_META_RANGE = | 109 |
121 "export.waterlevel.csv.meta.range"; | 110 public static final String CSV_NOT_IN_GAUGE_RANGE = "export.waterlevel.csv.not.in.gauge.range"; |
122 | 111 |
123 public static final String CSV_META_GAUGE = | 112 public static final Pattern NUMBERS_PATTERN = Pattern.compile("\\D*(\\d++.\\d*)\\D*"); |
124 "export.waterlevel.csv.meta.gauge"; | 113 |
125 | 114 public static final String DEFAULT_CSV_KM_HEADER = "Fluss-Km"; |
126 public static final String CSV_META_Q = | 115 public static final String DEFAULT_CSV_W_HEADER = "W [NN + m]"; |
127 "export.waterlevel.csv.meta.q"; | 116 public static final String DEFAULT_CSV_Q_HEADER = "Q [m\u00b3/s]"; |
128 | |
129 public static final String CSV_META_W = | |
130 "export.waterlevel.csv.meta.w"; | |
131 | |
132 public static final String CSV_NOT_IN_GAUGE_RANGE = | |
133 "export.waterlevel.csv.not.in.gauge.range"; | |
134 | |
135 public static final Pattern NUMBERS_PATTERN = | |
136 Pattern.compile("\\D*(\\d++.\\d*)\\D*"); | |
137 | |
138 public static final String DEFAULT_CSV_KM_HEADER = "Fluss-Km"; | |
139 public static final String DEFAULT_CSV_W_HEADER = "W [NN + m]"; | |
140 public static final String DEFAULT_CSV_Q_HEADER = "Q [m\u00b3/s]"; | |
141 /** | 117 /** |
142 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. | 118 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. |
143 */ | 119 */ |
144 @Deprecated | 120 @Deprecated |
145 public static final String DEFAULT_CSV_Q_DESC_HEADER = "Bezeichnung"; | 121 public static final String DEFAULT_CSV_Q_DESC_HEADER = "Bezeichnung"; |
146 /** | 122 /** |
147 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. | 123 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. |
148 */ | 124 */ |
149 @Deprecated | 125 @Deprecated |
150 public static final String DEFAULT_CSV_W_DESC_HEADER = "W/Pegel [cm]"; | 126 public static final String DEFAULT_CSV_W_DESC_HEADER = "W/Pegel [cm]"; |
151 public static final String DEFAULT_CSV_LOCATION_HEADER = "Lage"; | 127 public static final String DEFAULT_CSV_LOCATION_HEADER = "Lage"; |
152 public static final String DEFAULT_CSV_GAUGE_HEADER = "Bezugspegel"; | 128 public static final String DEFAULT_CSV_GAUGE_HEADER = "Bezugspegel"; |
153 public static final String DEFAULT_CSV_NOT_IN_GAUGE_RANGE = | 129 public static final String DEFAULT_CSV_NOT_IN_GAUGE_RANGE = "außerhalb des gewählten Bezugspegels"; |
154 "außerhalb des gewählten Bezugspegels"; | |
155 | 130 |
156 public static final String PDF_HEADER_MODE = "export.waterlevel.pdf.mode"; | 131 public static final String PDF_HEADER_MODE = "export.waterlevel.pdf.mode"; |
157 public static final String JASPER_FILE = "export.waterlevel.pdf.file"; | 132 public static final String JASPER_FILE = "export.waterlevel.pdf.file"; |
158 | 133 |
159 /** The storage that contains all WQKms objects that are calculated.*/ | 134 /** The storage that contains all WQKms objects that are calculated. */ |
160 protected List<WQKms[]> data; | 135 protected List<WQKms[]> data; |
161 | 136 |
162 /** The storage that contains official fixings if available.*/ | 137 /** The storage that contains official fixings if available. */ |
163 protected List<WQKms> officalFixings; | 138 protected List<WQKms> officalFixings; |
164 | 139 |
165 public WaterlevelExporter() { | 140 public WaterlevelExporter() { |
166 data = new ArrayList<WQKms[]>(); | 141 this.data = new ArrayList<>(); |
167 } | 142 } |
168 | 143 |
169 @Override | 144 @Override |
170 public void generate() | 145 public void generate() throws IOException { |
171 throws IOException | |
172 { | |
173 log.debug("WaterlevelExporter.generate"); | 146 log.debug("WaterlevelExporter.generate"); |
174 | 147 |
175 /* Check for official fixings. They should also be included in the | 148 /* |
176 * export but only the calculation result is added with addData */ | 149 * Check for official fixings. They should also be included in the |
177 | 150 * export but only the calculation result is added with addData |
178 officalFixings = new ArrayList<WQKms>(); | 151 */ |
179 | 152 |
180 for (Artifact art: collection.getArtifactsByName( | 153 this.officalFixings = new ArrayList<>(); |
181 STATICWQKMSNAME, context) | 154 |
182 ) { | 155 for (final Artifact art : this.collection.getArtifactsByName(STATICWQKMSNAME, this.context)) { |
183 if (art instanceof StaticWQKmsArtifact) { | 156 if (art instanceof StaticWQKmsArtifact) { |
184 IsOfficialAccess access = | 157 final IsOfficialAccess access = new IsOfficialAccess((D4EArtifact) art); |
185 new IsOfficialAccess((D4EArtifact)art); | 158 final StaticWQKmsArtifact sart = (StaticWQKmsArtifact) art; |
186 StaticWQKmsArtifact sart = (StaticWQKmsArtifact) art; | |
187 if (!access.isOfficial()) { | 159 if (!access.isOfficial()) { |
188 continue; | 160 continue; |
189 } | 161 } |
190 | 162 |
191 /* Check that we add the data only once */ | 163 /* Check that we add the data only once */ |
192 WQKms toAdd = sart.getWQKms(); | 164 final WQKms toAdd = sart.getWQKms(); |
193 String newName = toAdd.getName(); | 165 final String newName = toAdd.getName(); |
194 | 166 |
195 boolean exists = false; | 167 boolean exists = false; |
196 for (WQKms wqkm: officalFixings) { | 168 for (final WQKms wqkm : this.officalFixings) { |
197 /* The same official fixing could be in two | 169 /* |
198 artifacts/outs so let's deduplicate */ | 170 * The same official fixing could be in two |
171 * artifacts/outs so let's deduplicate | |
172 */ | |
199 if (wqkm.getName().equals(newName)) { | 173 if (wqkm.getName().equals(newName)) { |
200 exists = true; | 174 exists = true; |
201 } | 175 } |
202 } | 176 } |
203 if (!exists) { | 177 if (!exists) { |
204 officalFixings.add(toAdd); | 178 this.officalFixings.add(toAdd); |
205 log.debug("Adding additional offical fixing: " + newName); | 179 log.debug("Adding additional offical fixing: " + newName); |
206 } | 180 } |
207 } | 181 } |
208 } | 182 } |
209 | 183 |
210 if (facet != null && facet.equals(AbstractExporter.FACET_CSV)) { | 184 if (this.facet != null && this.facet.equals(AbstractExporter.FACET_CSV)) { |
211 generateCSV(); | 185 generateCSV(); |
212 } | 186 } else if (this.facet != null && this.facet.equals(FACET_WST)) { |
213 else if (facet != null && facet.equals(FACET_WST)) { | |
214 generateWST(); | 187 generateWST(); |
215 } | 188 } else if (this.facet != null && this.facet.equals(AbstractExporter.FACET_PDF)) { |
216 else if (facet != null && facet.equals(AbstractExporter.FACET_PDF)) { | |
217 generatePDF(); | 189 generatePDF(); |
218 } | 190 } else { |
219 else { | |
220 throw new IOException("invalid facet for exporter"); | 191 throw new IOException("invalid facet for exporter"); |
221 } | 192 } |
222 } | 193 } |
223 | |
224 | 194 |
225 @Override | 195 @Override |
226 protected void addData(Object d) { | 196 protected void addData(Object d) { |
227 if (d instanceof CalculationResult) { | 197 if (d instanceof CalculationResult) { |
228 d = ((CalculationResult)d).getData(); | 198 d = ((CalculationResult) d).getData(); |
229 if (d instanceof WQKms []) { | 199 if (d instanceof WQKms[]) { |
230 data.add((WQKms [])d); | 200 this.data.add((WQKms[]) d); |
231 } | 201 } else if (d instanceof WQKmsResult) { |
232 else if (d instanceof WQKmsResult) { | 202 this.data.add(((WQKmsResult) d).getWQKms()); |
233 data.add(((WQKmsResult) d).getWQKms()); | 203 } |
234 } | 204 } |
235 } | 205 } |
236 } | |
237 | |
238 | 206 |
239 /** | 207 /** |
240 * Prepare the column titles of waterlevel exports. | 208 * Prepare the column titles of waterlevel exports. |
241 * Titles in this export include the Q value. If a Q value matches a named | 209 * Titles in this export include the Q value. If a Q value matches a named |
242 * main value (as HQ100 or MNQ) this named main value should be used as | 210 * main value (as HQ100 or MNQ) this named main value should be used as |
243 * title. This method resets the name of the <i>wqkms</i> object if such | 211 * title. This method resets the name of the <i>wqkms</i> object if such |
244 * named main value fits to the chosen Q. | 212 * named main value fits to the chosen Q. |
245 * | 213 * |
246 * @param winfo A WINFO Artifact. | 214 * @param winfo |
247 * @param wqkms A WQKms object that should be prepared. | 215 * A WINFO Artifact. |
248 */ | 216 * @param wqkms |
249 protected String getColumnTitle(WINFOArtifact winfo, WQKms wqkms) { | 217 * A WQKms object that should be prepared. |
218 */ | |
219 protected String getColumnTitle(final WINFOArtifact winfo, final WQKms wqkms) { | |
250 log.debug("WaterlevelExporter.getColumnTitle"); | 220 log.debug("WaterlevelExporter.getColumnTitle"); |
251 | 221 |
252 String name = wqkms.getName(); | 222 final String name = wqkms.getName(); |
253 | 223 |
254 log.debug("Name of WQKms = '" + name + "'"); | 224 log.debug("Name of WQKms = '" + name + "'"); |
255 | 225 |
256 if (name.indexOf("W=") >= 0) { | 226 if (name.indexOf("W=") >= 0) { |
257 return name; | 227 return name; |
258 } | 228 } |
259 | 229 |
260 Matcher m = NUMBERS_PATTERN.matcher(name); | 230 final Matcher m = NUMBERS_PATTERN.matcher(name); |
261 | 231 |
262 if (m.matches()) { | 232 if (m.matches()) { |
263 String raw = m.group(1); | 233 final String raw = m.group(1); |
264 | 234 |
265 try { | 235 try { |
266 double v = Double.valueOf(raw); | 236 final double v = Double.valueOf(raw); |
267 | 237 |
268 String nmv = RiverUtils.getNamedMainValue(winfo, v); | 238 String nmv = RiverUtils.getNamedMainValue(winfo, v); |
269 | 239 |
270 if (nmv != null && nmv.length() > 0) { | 240 if (nmv != null && nmv.length() > 0) { |
271 nmv = RiverUtils.stripNamedMainValue(nmv); | 241 nmv = RiverUtils.stripNamedMainValue(nmv); |
272 nmv += "=" + String.valueOf(v); | 242 nmv += "=" + String.valueOf(v); |
273 log.debug("Set named main value '" + nmv + "'"); | 243 log.debug("Set named main value '" + nmv + "'"); |
274 | 244 |
275 return nmv; | 245 return nmv; |
276 } | 246 } |
277 } | 247 } |
278 catch (NumberFormatException nfe) { | 248 catch (final NumberFormatException nfe) { |
279 // do nothing here | 249 // do nothing here |
280 } | 250 } |
281 } | 251 } |
282 | 252 |
283 return name; | 253 return name; |
284 } | 254 } |
285 | 255 |
286 | |
287 /** | 256 /** |
288 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. | 257 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. |
289 */ | 258 */ |
290 @Deprecated | 259 @Deprecated |
291 protected String getCSVRowTitle(WINFOArtifact winfo, WQKms wqkms) { | 260 protected String getCSVRowTitle(final WINFOArtifact winfo, final WQKms wqkms) { |
292 log.debug("WaterlevelExporter.prepareNamedValue"); | 261 log.debug("WaterlevelExporter.prepareNamedValue"); |
293 | 262 |
294 String name = wqkms.getName(); | 263 final String name = wqkms.getName(); |
295 | 264 |
296 log.debug("Name of WQKms = '" + name + "'"); | 265 log.debug("Name of WQKms = '" + name + "'"); |
297 | 266 |
298 WQ_MODE wqmode = RiverUtils.getWQMode(winfo); | 267 final WQ_MODE wqmode = RiverUtils.getWQMode(winfo); |
299 | 268 |
300 if (wqmode == WQ_MODE.WFREE || wqmode == WQ_MODE.QGAUGE) { | 269 if (wqmode == WQ_MODE.WFREE || wqmode == WQ_MODE.QGAUGE) { |
301 return localizeWQKms(winfo, wqkms); | 270 return localizeWQKms(winfo, wqkms); |
302 } | 271 } |
303 | 272 |
304 Double v = wqkms.getRawValue(); | 273 final Double v = wqkms.getRawValue(); |
305 | 274 |
306 String nmv = RiverUtils.getNamedMainValue(winfo, v); | 275 String nmv = RiverUtils.getNamedMainValue(winfo, v); |
307 | 276 |
308 if (nmv != null && nmv.length() > 0) { | 277 if (nmv != null && nmv.length() > 0) { |
309 nmv = RiverUtils.stripNamedMainValue(nmv); | 278 nmv = RiverUtils.stripNamedMainValue(nmv); |
313 } | 282 } |
314 | 283 |
315 return localizeWQKms(winfo, wqkms); | 284 return localizeWQKms(winfo, wqkms); |
316 } | 285 } |
317 | 286 |
318 | |
319 /** | 287 /** |
320 * Get a string like 'W=' or 'Q=' with a number following in localized | 288 * Get a string like 'W=' or 'Q=' with a number following in localized |
321 * format. | 289 * format. |
322 * | 290 * |
323 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. | 291 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. |
324 */ | 292 */ |
325 @Deprecated | 293 @Deprecated |
326 protected String localizeWQKms(WINFOArtifact winfo, WQKms wqkms) { | 294 protected String localizeWQKms(final WINFOArtifact winfo, final WQKms wqkms) { |
327 WQ_MODE wqmode = RiverUtils.getWQMode(winfo); | 295 final WQ_MODE wqmode = RiverUtils.getWQMode(winfo); |
328 Double rawValue = wqkms.getRawValue(); | 296 final Double rawValue = wqkms.getRawValue(); |
329 | 297 |
330 if (rawValue == null) { | 298 if (rawValue == null) { |
331 return wqkms.getName(); | 299 return wqkms.getName(); |
332 } | 300 } |
333 | 301 |
334 NumberFormat nf = Formatter.getRawFormatter(context); | 302 final NumberFormat nf = Formatter.getRawFormatter(this.context); |
335 | 303 |
336 if (wqmode == WQ_MODE.WFREE || wqmode == WQ_MODE.WGAUGE) { | 304 if (wqmode == WQ_MODE.WFREE || wqmode == WQ_MODE.WGAUGE) { |
337 return "W=" + nf.format(rawValue); | 305 return "W=" + nf.format(rawValue); |
338 } | 306 } else { |
339 else { | |
340 return "Q=" + nf.format(rawValue); | 307 return "Q=" + nf.format(rawValue); |
341 } | 308 } |
342 } | 309 } |
343 | 310 |
344 | |
345 @Override | 311 @Override |
346 protected void writeCSVData(CSVWriter writer) { | 312 protected void writeCSVData(final CSVWriter writer) { |
347 log.info("WaterlevelExporter.writeData"); | 313 log.info("WaterlevelExporter.writeData"); |
348 | 314 |
349 WQ_MODE mode = RiverUtils.getWQMode((D4EArtifact)master); | 315 final WQ_MODE mode = RiverUtils.getWQMode((D4EArtifact) this.master); |
350 boolean atGauge = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.WGAUGE; | 316 final boolean atGauge = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.WGAUGE; |
351 boolean isQ = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.QFREE; | 317 final boolean isQ = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.QFREE; |
352 RiverUtils.WQ_INPUT input | 318 final RiverUtils.WQ_INPUT input = RiverUtils.getWQInputMode((D4EArtifact) this.master); |
353 = RiverUtils.getWQInputMode((D4EArtifact)master); | |
354 | 319 |
355 writeCSVMeta(writer); | 320 writeCSVMeta(writer); |
356 writeCSVHeader(writer, atGauge, isQ); | 321 writeCSVHeader(writer, atGauge, isQ); |
357 | 322 |
358 Double first = Double.NaN; | 323 Double first = Double.NaN; |
359 Double last = Double.NaN; | 324 Double last = Double.NaN; |
360 | 325 |
361 for (WQKms[] tmp: data) { | 326 for (final WQKms[] tmp : this.data) { |
362 for (WQKms wqkms: tmp) { | 327 for (final WQKms wqkms : tmp) { |
363 wQKms2CSV(writer, wqkms, atGauge, isQ); | 328 wQKms2CSV(writer, wqkms, atGauge, isQ); |
364 double[] firstLast = wqkms.getFirstLastKM(); | 329 final double[] firstLast = wqkms.getFirstLastKM(); |
365 if (first.isNaN()) { | 330 if (first.isNaN()) { |
366 /* Initialize */ | 331 /* Initialize */ |
367 first = firstLast[0]; | 332 first = firstLast[0]; |
368 last = firstLast[1]; | 333 last = firstLast[1]; |
369 } | 334 } |
370 if (firstLast[0] > firstLast[1]) { | 335 if (firstLast[0] > firstLast[1]) { |
371 /* Calculating upstream we assert that it is | 336 /* |
337 * Calculating upstream we assert that it is | |
372 * impossible that the direction changes during this | 338 * impossible that the direction changes during this |
373 * loop */ | 339 * loop |
340 */ | |
374 first = Math.max(first, firstLast[0]); | 341 first = Math.max(first, firstLast[0]); |
375 last = Math.min(last, firstLast[1]); | 342 last = Math.min(last, firstLast[1]); |
376 } else if (firstLast[0] < firstLast[1]) { | 343 } else if (firstLast[0] < firstLast[1]) { |
377 first = Math.min(first, firstLast[0]); | 344 first = Math.min(first, firstLast[0]); |
378 last = Math.max(last, firstLast[1]); | 345 last = Math.max(last, firstLast[1]); |
380 first = last = firstLast[0]; | 347 first = last = firstLast[0]; |
381 } | 348 } |
382 } | 349 } |
383 } | 350 } |
384 /* Append the official fixing at the bottom */ | 351 /* Append the official fixing at the bottom */ |
385 for (WQKms wqkms: officalFixings) { | 352 for (final WQKms wqkms : this.officalFixings) { |
386 wQKms2CSV(writer, filterWQKms(wqkms, first, last), atGauge, isQ); | 353 wQKms2CSV(writer, filterWQKms(wqkms, first, last), atGauge, isQ); |
387 } | 354 } |
388 } | 355 } |
389 | 356 |
390 | 357 /** |
391 /** Filter a wqkms object to a distance. | 358 * Filter a wqkms object to a distance. |
392 * | 359 * |
393 * To handle upstream / downstream and to limit | 360 * To handle upstream / downstream and to limit |
394 * the officialFixings to the calculation distance | 361 * the officialFixings to the calculation distance |
395 * we create a new wqkms object here and fill it only | 362 * we create a new wqkms object here and fill it only |
396 * with the relevant data. | 363 * with the relevant data. |
397 * | 364 * |
398 * @param wqkms: The WQKms Object to filter | 365 * @param wqkms: |
399 * @param first: The fist kilometer of the range | 366 * The WQKms Object to filter |
400 * @param last: The last kilometer of the range | 367 * @param first: |
368 * The fist kilometer of the range | |
369 * @param last: | |
370 * The last kilometer of the range | |
401 * | 371 * |
402 * @return A new WQKms with the relevant data sorted by direction | 372 * @return A new WQKms with the relevant data sorted by direction |
403 */ | 373 */ |
404 private WQKms filterWQKms(WQKms wqkms, Double first, Double last) { | 374 private WQKms filterWQKms(final WQKms wqkms, final Double first, final Double last) { |
405 if (first.isNaN() || last.isNaN()) { | 375 if (first.isNaN() || last.isNaN()) { |
406 log.warn("Filtering official fixing without valid first/last."); | 376 log.warn("Filtering official fixing without valid first/last."); |
407 return wqkms; | 377 return wqkms; |
408 } | 378 } |
409 int firstIdx = first > last ? wqkms.size() - 1 : 0; | 379 final int firstIdx = first > last ? wqkms.size() - 1 : 0; |
410 int lastIdx = first > last ? 0 : wqkms.size() -1; | 380 final int lastIdx = first > last ? 0 : wqkms.size() - 1; |
411 WQKms filtered = new WQKms (wqkms.size()); | 381 final WQKms filtered = new WQKms(wqkms.size()); |
412 filtered.setName(wqkms.getName()); | 382 filtered.setName(wqkms.getName()); |
413 double [] dp = new double [3]; | 383 double[] dp = new double[3]; |
414 | 384 |
415 if (first > last) { | 385 if (first > last) { |
416 for (int i = wqkms.size() - 1; i >= 0; i--) { | 386 for (int i = wqkms.size() - 1; i >= 0; i--) { |
417 dp = wqkms.get(i, dp); | 387 dp = wqkms.get(i, dp); |
418 if (dp[2] <= first + 1E-5 && dp[2] > last - 1E-5) { | 388 if (dp[2] <= first + 1E-5 && dp[2] > last - 1E-5) { |
428 } | 398 } |
429 } | 399 } |
430 return filtered; | 400 return filtered; |
431 } | 401 } |
432 | 402 |
433 | 403 protected void writeCSVMeta(final CSVWriter writer) { |
434 protected void writeCSVMeta(CSVWriter writer) { | |
435 log.info("WaterlevelExporter.writeCSVMeta"); | 404 log.info("WaterlevelExporter.writeCSVMeta"); |
436 | 405 |
437 // TODO use Access instead of RiverUtils | 406 // TODO use Access instead of RiverUtils |
438 | 407 |
439 CallMeta meta = context.getMeta(); | 408 final CallMeta meta = this.context.getMeta(); |
440 | 409 |
441 D4EArtifact flys = (D4EArtifact) master; | 410 final D4EArtifact flys = (D4EArtifact) this.master; |
442 | 411 |
443 writer.writeNext(new String[] { | 412 writer.writeNext(new String[] { Resources.getMsg(meta, CSV_META_RESULT, CSV_META_RESULT, new Object[] { RiverUtils.getRivername(flys) }) }); |
444 Resources.getMsg( | 413 |
445 meta, | 414 final Locale locale = Resources.getLocale(meta); |
446 CSV_META_RESULT, | 415 final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale); |
447 CSV_META_RESULT, | 416 |
448 new Object[] { RiverUtils.getRivername(flys) }) | 417 writer.writeNext(new String[] { Resources.getMsg(meta, CSV_META_CREATION, CSV_META_CREATION, new Object[] { df.format(new Date()) }) }); |
418 | |
419 writer.writeNext(new String[] { Resources.getMsg(meta, CSV_META_CALCULATIONBASE, CSV_META_CALCULATIONBASE, new Object[] { "" }) // TODO what is required | |
420 // at this place? | |
449 }); | 421 }); |
450 | 422 |
451 Locale locale = Resources.getLocale(meta); | 423 writer.writeNext(new String[] { Resources.getMsg(meta, CSV_META_RIVER, CSV_META_RIVER, new Object[] { RiverUtils.getRivername(flys) }) }); |
452 DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale); | 424 |
453 | 425 final RangeAccess rangeAccess = new RangeAccess(flys); |
454 writer.writeNext(new String[] { | 426 final double[] kms = rangeAccess.getKmRange(); |
455 Resources.getMsg( | 427 writer.writeNext(new String[] { Resources.getMsg(meta, CSV_META_RANGE, CSV_META_RANGE, new Object[] { kms[0], kms[kms.length - 1] }) }); |
456 meta, | 428 |
457 CSV_META_CREATION, | 429 writer.writeNext(new String[] { Resources.getMsg(meta, CSV_META_GAUGE, CSV_META_GAUGE, new Object[] { RiverUtils.getGaugename(flys) }) }); |
458 CSV_META_CREATION, | |
459 new Object[] { df.format(new Date()) }) | |
460 }); | |
461 | |
462 writer.writeNext(new String[] { | |
463 Resources.getMsg( | |
464 meta, | |
465 CSV_META_CALCULATIONBASE, | |
466 CSV_META_CALCULATIONBASE, | |
467 new Object[] { "" }) // TODO what is required at this place? | |
468 }); | |
469 | |
470 writer.writeNext(new String[] { | |
471 Resources.getMsg( | |
472 meta, | |
473 CSV_META_RIVER, | |
474 CSV_META_RIVER, | |
475 new Object[] { RiverUtils.getRivername(flys) }) | |
476 }); | |
477 | |
478 RangeAccess rangeAccess = new RangeAccess(flys); | |
479 double[] kms = rangeAccess.getKmRange(); | |
480 writer.writeNext(new String[] { | |
481 Resources.getMsg( | |
482 meta, | |
483 CSV_META_RANGE, | |
484 CSV_META_RANGE, | |
485 new Object[] { kms[0], kms[kms.length-1] }) | |
486 }); | |
487 | |
488 writer.writeNext(new String[] { | |
489 Resources.getMsg( | |
490 meta, | |
491 CSV_META_GAUGE, | |
492 CSV_META_GAUGE, | |
493 new Object[] { RiverUtils.getGaugename(flys) }) | |
494 }); | |
495 | 430 |
496 // TODO: code extracted into WaterlevelDescriptionBuilder, should be used instead. | 431 // TODO: code extracted into WaterlevelDescriptionBuilder, should be used instead. |
497 RiverUtils.WQ_MODE wq = RiverUtils.getWQMode(flys); | 432 final RiverUtils.WQ_MODE wq = RiverUtils.getWQMode(flys); |
498 if (wq == RiverUtils.WQ_MODE.QFREE || wq == RiverUtils.WQ_MODE.QGAUGE) { | 433 if (wq == RiverUtils.WQ_MODE.QFREE || wq == RiverUtils.WQ_MODE.QGAUGE) { |
499 double[] qs = RiverUtils.getQs(flys); | 434 final double[] qs = RiverUtils.getQs(flys); |
500 RiverUtils.WQ_INPUT input = RiverUtils.getWQInputMode(flys); | 435 final RiverUtils.WQ_INPUT input = RiverUtils.getWQInputMode(flys); |
501 | 436 |
502 String data = ""; | 437 String data = ""; |
503 | 438 |
504 if ((input == RiverUtils.WQ_INPUT.ADAPTED || | 439 if ((input == RiverUtils.WQ_INPUT.ADAPTED || input == RiverUtils.WQ_INPUT.RANGE) && qs != null && qs.length > 0) { |
505 input == RiverUtils.WQ_INPUT.RANGE) && | |
506 qs != null && qs.length > 0) | |
507 { | |
508 data = String.valueOf(qs[0]); | 440 data = String.valueOf(qs[0]); |
509 data += " - " + String.valueOf(qs[qs.length-1]); | 441 data += " - " + String.valueOf(qs[qs.length - 1]); |
510 } | 442 } else if (input == RiverUtils.WQ_INPUT.SINGLE && qs != null) { |
511 else if (input == RiverUtils.WQ_INPUT.SINGLE && qs != null){ | |
512 data = String.valueOf(qs[0]); | 443 data = String.valueOf(qs[0]); |
513 for (int i = 1; i < qs.length; i++) { | 444 for (int i = 1; i < qs.length; i++) { |
514 data += ", " + String.valueOf(qs[i]); | 445 data += ", " + String.valueOf(qs[i]); |
515 } | 446 } |
516 } | 447 } else { |
517 else { | |
518 log.warn("Could not determine Q range!"); | 448 log.warn("Could not determine Q range!"); |
519 } | 449 } |
520 | 450 |
521 writer.writeNext(new String[] { | 451 writer.writeNext(new String[] { Resources.getMsg(meta, CSV_META_Q, CSV_META_Q, new Object[] { data }) }); |
522 Resources.getMsg( | 452 } else { |
523 meta, | 453 final double[] ws = RiverUtils.getWs(flys); |
524 CSV_META_Q, | |
525 CSV_META_Q, | |
526 new Object[] {data}) | |
527 }); | |
528 } | |
529 else { | |
530 double[] ws = RiverUtils.getWs(flys); | |
531 | 454 |
532 String lower = ""; | 455 String lower = ""; |
533 String upper = ""; | 456 String upper = ""; |
534 | 457 |
535 if (ws != null && ws.length > 0) { | 458 if (ws != null && ws.length > 0) { |
536 lower = String.valueOf(ws[0]); | 459 lower = String.valueOf(ws[0]); |
537 upper = String.valueOf(ws[ws.length-1]); | 460 upper = String.valueOf(ws[ws.length - 1]); |
538 } | 461 } else { |
539 else { | |
540 log.warn("Could not determine W range!"); | 462 log.warn("Could not determine W range!"); |
541 } | 463 } |
542 | 464 |
543 writer.writeNext(new String[] { | 465 writer.writeNext(new String[] { Resources.getMsg(meta, CSV_META_W, CSV_META_W, new Object[] { lower, upper }) }); |
544 Resources.getMsg( | |
545 meta, | |
546 CSV_META_W, | |
547 CSV_META_W, | |
548 new Object[] { lower, upper }) | |
549 }); | |
550 } | 466 } |
551 | 467 |
552 writer.writeNext(new String[] { "" }); | 468 writer.writeNext(new String[] { "" }); |
553 } | 469 } |
554 | |
555 | 470 |
556 /** | 471 /** |
557 * Write the header, with different headings depending on whether at a | 472 * Write the header, with different headings depending on whether at a |
558 * gauge or at a location. | 473 * gauge or at a location. |
559 */ | 474 */ |
560 protected void writeCSVHeader( | 475 protected void writeCSVHeader(final CSVWriter writer, final boolean atGauge, final boolean isQ) { |
561 CSVWriter writer, | |
562 boolean atGauge, | |
563 boolean isQ | |
564 ) { | |
565 log.info("WaterlevelExporter.writeCSVHeader"); | 476 log.info("WaterlevelExporter.writeCSVHeader"); |
566 | 477 |
567 String unit = RiverUtils.getRiver( | 478 final String unit = RiverUtils.getRiver((D4EArtifact) this.master).getWstUnit().getName(); |
568 (D4EArtifact) master).getWstUnit().getName(); | |
569 | 479 |
570 if (atGauge) { | 480 if (atGauge) { |
571 writer.writeNext(new String[] { | 481 writer.writeNext(new String[] { msg(CSV_KM_HEADER, DEFAULT_CSV_KM_HEADER), msg(CSV_W_HEADER, DEFAULT_CSV_W_HEADER, new Object[] { unit }), |
572 msg(CSV_KM_HEADER, DEFAULT_CSV_KM_HEADER), | 482 msg(CSV_Q_HEADER, DEFAULT_CSV_Q_HEADER), |
573 msg(CSV_W_HEADER, DEFAULT_CSV_W_HEADER, new Object[] { unit }), | 483 |
574 msg(CSV_Q_HEADER, DEFAULT_CSV_Q_HEADER), | 484 // FIXME: use WaterlevelDescriptionBuilder instead and also remove all this duplicate code. |
575 | 485 (isQ ? msg(CSV_Q_DESC_HEADER, DEFAULT_CSV_Q_DESC_HEADER) : msg(CSV_W_DESC_HEADER, DEFAULT_CSV_W_DESC_HEADER)), |
576 // FIXME: use WaterlevelDescriptionBuilder instead and also remove all this duplicate code. | 486 msg(CSV_LOCATION_HEADER, DEFAULT_CSV_LOCATION_HEADER), msg(CSV_GAUGE_HEADER, DEFAULT_CSV_GAUGE_HEADER) }); |
577 (isQ | 487 } else { |
578 ? msg(CSV_Q_DESC_HEADER, DEFAULT_CSV_Q_DESC_HEADER) | 488 writer.writeNext(new String[] { msg(CSV_KM_HEADER, DEFAULT_CSV_KM_HEADER), |
579 : msg(CSV_W_DESC_HEADER, DEFAULT_CSV_W_DESC_HEADER)), | |
580 msg(CSV_LOCATION_HEADER, DEFAULT_CSV_LOCATION_HEADER), | |
581 msg(CSV_GAUGE_HEADER, DEFAULT_CSV_GAUGE_HEADER) | |
582 }); | |
583 } | |
584 else { | |
585 writer.writeNext(new String[] { | |
586 msg(CSV_KM_HEADER, DEFAULT_CSV_KM_HEADER), | |
587 // TODO flys/issue1128 (unit per river) | 489 // TODO flys/issue1128 (unit per river) |
588 msg(CSV_W_HEADER, DEFAULT_CSV_W_HEADER, new Object[] { unit }), | 490 msg(CSV_W_HEADER, DEFAULT_CSV_W_HEADER, new Object[] { unit }), msg(CSV_Q_HEADER, DEFAULT_CSV_Q_HEADER), |
589 msg(CSV_Q_HEADER, DEFAULT_CSV_Q_HEADER), | 491 msg(CSV_LOCATION_HEADER, DEFAULT_CSV_LOCATION_HEADER) }); |
590 msg(CSV_LOCATION_HEADER, DEFAULT_CSV_LOCATION_HEADER) | 492 } |
591 }); | 493 } |
592 } | |
593 } | |
594 | |
595 | 494 |
596 /** Linearly search for gauge which is valid at km. */ | 495 /** Linearly search for gauge which is valid at km. */ |
597 private static Gauge findGauge(double km, List<Gauge> gauges) { | 496 private static Gauge findGauge(final double km, final List<Gauge> gauges) { |
598 for (Gauge gauge: gauges) { | 497 for (final Gauge gauge : gauges) { |
599 if (gauge.getRange().contains(km)) { | 498 if (gauge.getRange().contains(km)) { |
600 return gauge; | 499 return gauge; |
601 } | 500 } |
602 } | 501 } |
603 return null; | 502 return null; |
604 } | 503 } |
605 | 504 |
606 private static Segment findSegment(double km, List<Segment> segments) { | 505 private static Segment findSegment(final double km, final List<Segment> segments) { |
607 for (Segment segment: segments) { | 506 for (final Segment segment : segments) { |
608 if (segment.inside(km)) { | 507 if (segment.inside(km)) { |
609 return segment; | 508 return segment; |
610 } | 509 } |
611 } | 510 } |
612 return null; | 511 return null; |
613 } | 512 } |
614 | 513 |
615 | 514 private void writeRow4(final CSVWriter writer, final double wqkm[], final D4EArtifact flys) { |
616 private void writeRow4(CSVWriter writer, double wqkm[], D4EArtifact flys) { | 515 final NumberFormat kmf = getKmFormatter(); |
617 NumberFormat kmf = getKmFormatter(); | 516 final NumberFormat wf = getWFormatter(); |
618 NumberFormat wf = getWFormatter(); | 517 final NumberFormat qf = getQFormatter(); |
619 NumberFormat qf = getQFormatter(); | 518 writer.writeNext(new String[] { kmf.format(wqkm[2]), wf.format(wqkm[0]), qf.format(RiverUtils.roundQ(wqkm[1])), |
620 writer.writeNext(new String[] { | 519 RiverUtils.getLocationDescription(flys, wqkm[2]) }); |
621 kmf.format(wqkm[2]), | |
622 wf.format(wqkm[0]), | |
623 qf.format(RiverUtils.roundQ(wqkm[1])), | |
624 RiverUtils.getLocationDescription(flys, wqkm[2]) | |
625 }); | |
626 } | 520 } |
627 | 521 |
628 /** Write an csv-row at gauge location. */ | 522 /** Write an csv-row at gauge location. */ |
629 private void writeRow6(CSVWriter writer, double wqkm[], String wOrQDesc, | 523 private void writeRow6(final CSVWriter writer, final double wqkm[], final String wOrQDesc, final D4EArtifact flys, final String gaugeName) { |
630 D4EArtifact flys, String gaugeName) { | 524 final NumberFormat kmf = getKmFormatter(); |
631 NumberFormat kmf = getKmFormatter(); | 525 final NumberFormat wf = getWFormatter(); |
632 NumberFormat wf = getWFormatter(); | 526 final NumberFormat qf = getQFormatter(); |
633 NumberFormat qf = getQFormatter(); | 527 |
634 | 528 writer.writeNext(new String[] { kmf.format(wqkm[2]), wf.format(wqkm[0]), qf.format(RiverUtils.roundQ(wqkm[1])), wOrQDesc, |
635 writer.writeNext(new String[] { | 529 RiverUtils.getLocationDescription(flys, wqkm[2]), gaugeName }); |
636 kmf.format(wqkm[2]), | |
637 wf.format(wqkm[0]), | |
638 qf.format(RiverUtils.roundQ(wqkm[1])), | |
639 wOrQDesc, | |
640 RiverUtils.getLocationDescription(flys, wqkm[2]), | |
641 gaugeName | |
642 }); | |
643 } | 530 } |
644 | 531 |
645 /** | 532 /** |
646 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. | 533 * @deprecated Use {@link WaterlevelDescriptionBuilder} instead. |
647 */ | 534 */ |
648 @Deprecated | 535 @Deprecated |
649 private String getDesc(WQKms wqkms, boolean isQ) | 536 private String getDesc(final WQKms wqkms, final boolean isQ) { |
650 { | 537 final D4EArtifact flys = (D4EArtifact) this.master; |
651 D4EArtifact flys = (D4EArtifact) master; | |
652 String colDesc = ""; | 538 String colDesc = ""; |
653 | 539 |
654 if (flys instanceof WINFOArtifact && isQ) { | 540 if (flys instanceof WINFOArtifact && isQ) { |
655 colDesc = getCSVRowTitle((WINFOArtifact)flys, wqkms); | 541 colDesc = getCSVRowTitle((WINFOArtifact) flys, wqkms); |
656 } | 542 } else if (!isQ) { |
657 else if (!isQ) { | 543 final Double value = RiverUtils.getValueFromWQ(wqkms); |
658 Double value = RiverUtils.getValueFromWQ(wqkms); | 544 colDesc = (value != null) ? Formatter.getWaterlevelW(this.context).format(value) : null; |
659 colDesc = (value != null) ? | |
660 Formatter.getWaterlevelW(context).format(value) : null; | |
661 } | 545 } |
662 | 546 |
663 if (flys instanceof WINFOArtifact) { | 547 if (flys instanceof WINFOArtifact) { |
664 if (wqkms != null && wqkms.getRawValue() != null) { | 548 if (wqkms != null && wqkms.getRawValue() != null) { |
665 WINFOArtifact winfo = (WINFOArtifact) flys; | 549 final WINFOArtifact winfo = (WINFOArtifact) flys; |
666 colDesc = RiverUtils.getNamedMainValue( | 550 colDesc = RiverUtils.getNamedMainValue(winfo, wqkms.getRawValue()); |
667 winfo, wqkms.getRawValue()); | |
668 // For 'W am Pegel' s | 551 // For 'W am Pegel' s |
669 if (colDesc == null) { | 552 if (colDesc == null) { |
670 Double value = RiverUtils.getValueFromWQ(wqkms); | 553 final Double value = RiverUtils.getValueFromWQ(wqkms); |
671 colDesc = (value != null) ? | 554 colDesc = (value != null) ? Formatter.getWaterlevelW(this.context).format(value) : null; |
672 Formatter.getWaterlevelW(context).format(value) : null; | |
673 } | 555 } |
674 } | 556 } |
675 } | 557 } |
676 if (colDesc != null) { | 558 if (colDesc != null) { |
677 /* Quick hack. Can be removed when database strings are | 559 /* |
678 * adapted or left in here as it should never be harmful. */ | 560 * Quick hack. Can be removed when database strings are |
561 * adapted or left in here as it should never be harmful. | |
562 */ | |
679 colDesc = colDesc.replace("Amtl.Festlegung_", "Amtl. "); | 563 colDesc = colDesc.replace("Amtl.Festlegung_", "Amtl. "); |
680 } | 564 } |
681 | 565 |
682 return colDesc == null ? "" : colDesc; | 566 return colDesc == null ? "" : colDesc; |
683 } | 567 } |
684 | 568 |
685 /** | 569 /** |
686 * Write "rows" of csv data from wqkms with writer. | 570 * Write "rows" of csv data from wqkms with writer. |
687 */ | 571 */ |
688 protected void wQKms2CSV( | 572 protected void wQKms2CSV(final CSVWriter writer, final WQKms wqkms, final boolean atGauge, final boolean isQ) { |
689 CSVWriter writer, | |
690 WQKms wqkms, | |
691 boolean atGauge, | |
692 boolean isQ | |
693 ) { | |
694 log.debug("WaterlevelExporter.wQKms2CSV"); | 573 log.debug("WaterlevelExporter.wQKms2CSV"); |
695 | 574 |
696 // Skip constant data. | 575 // Skip constant data. |
697 if (wqkms instanceof ConstantWQKms) { | 576 if (wqkms instanceof ConstantWQKms) { |
698 return; | 577 return; |
699 } | 578 } |
700 | 579 |
701 NumberFormat kmf = getKmFormatter(); | 580 final NumberFormat kmf = getKmFormatter(); |
702 NumberFormat wf = getWFormatter(); | 581 final NumberFormat wf = getWFormatter(); |
703 NumberFormat qf = getQFormatter(); | 582 final NumberFormat qf = getQFormatter(); |
704 | 583 |
705 int size = wqkms.size(); | 584 final int size = wqkms.size(); |
706 double[] result = new double[3]; | 585 double[] result = new double[3]; |
707 | 586 |
708 D4EArtifact flys = (D4EArtifact) master; | 587 final D4EArtifact flys = (D4EArtifact) this.master; |
709 RangeAccess rangeAccess = new RangeAccess(flys); | 588 final RangeAccess rangeAccess = new RangeAccess(flys); |
710 | 589 |
711 List<Gauge> gauges = RiverUtils.getGauges(flys); | 590 final List<Gauge> gauges = RiverUtils.getGauges(flys); |
712 | 591 |
713 Gauge gauge = rangeAccess.getRiver().determineRefGauge( | 592 final Gauge gauge = rangeAccess.getRiver().determineRefGauge(rangeAccess.getKmRange(), rangeAccess.isRange()); |
714 rangeAccess.getKmRange(), rangeAccess.isRange()); | 593 |
715 | 594 final String gaugeName = gauge.getName(); |
716 String gaugeName = gauge.getName(); | 595 String desc = ""; |
717 String desc = ""; | 596 final String notinrange = msg(CSV_NOT_IN_GAUGE_RANGE, DEFAULT_CSV_NOT_IN_GAUGE_RANGE); |
718 String notinrange = msg( | |
719 CSV_NOT_IN_GAUGE_RANGE, | |
720 DEFAULT_CSV_NOT_IN_GAUGE_RANGE); | |
721 List<Segment> segments = null; | 597 List<Segment> segments = null; |
722 boolean isFixRealize = false; | 598 boolean isFixRealize = false; |
723 | 599 |
724 double a = gauge.getRange().getA().doubleValue(); | 600 final double a = gauge.getRange().getA().doubleValue(); |
725 double b = gauge.getRange().getB().doubleValue(); | 601 final double b = gauge.getRange().getB().doubleValue(); |
726 long startTime = System.currentTimeMillis(); | 602 final long startTime = System.currentTimeMillis(); |
727 | 603 |
728 desc = getDesc(wqkms, isQ); | 604 desc = getDesc(wqkms, isQ); |
729 | 605 |
730 if (flys instanceof FixationArtifact) { | 606 if (flys instanceof FixationArtifact) { |
731 // Get W/Q input per gauge for this case. | 607 // Get W/Q input per gauge for this case. |
732 FixRealizingAccess fixAccess = new FixRealizingAccess(flys); | 608 final FixRealizingAccess fixAccess = new FixRealizingAccess(flys); |
733 segments = fixAccess.getSegments(); | 609 segments = fixAccess.getSegments(); |
734 if (segments != null && !segments.isEmpty()) { | 610 if (segments != null && !segments.isEmpty()) { |
735 isFixRealize = true; | 611 isFixRealize = true; |
736 } | 612 } |
737 } | 613 } |
739 if (atGauge) { // "At gauge" needs more output. | 615 if (atGauge) { // "At gauge" needs more output. |
740 | 616 |
741 // Kms tend to be close together so caching the last sector | 617 // Kms tend to be close together so caching the last sector |
742 // is a good time saving heuristic. | 618 // is a good time saving heuristic. |
743 Segment lastSegment = null; | 619 Segment lastSegment = null; |
744 Gauge lastGauge = null; | 620 Gauge lastGauge = null; |
745 | 621 |
746 NumberFormat nf = | 622 final NumberFormat nf = Formatter.getFormatter(this.context.getMeta(), 0, 0); |
747 Formatter.getFormatter(context.getMeta(), 0, 0); | |
748 | 623 |
749 for (int i = 0; i < size; ++i) { | 624 for (int i = 0; i < size; ++i) { |
750 result = wqkms.get(i, result); | 625 result = wqkms.get(i, result); |
751 double km = result[2]; | 626 final double km = result[2]; |
752 | 627 |
753 if (segments != null) { | 628 if (segments != null) { |
754 Segment found = lastSegment != null | 629 final Segment found = lastSegment != null && lastSegment.inside(km) ? lastSegment : findSegment(km, segments); |
755 && lastSegment.inside(km) | |
756 ? lastSegment | |
757 : findSegment(km, segments); | |
758 | 630 |
759 if (found != null) { | 631 if (found != null) { |
760 desc = nf.format(found.getValues()[0]); | 632 desc = nf.format(found.getValues()[0]); |
761 } | 633 } |
762 lastSegment = found; | 634 lastSegment = found; |
763 } | 635 } |
764 | 636 |
765 String gaugeN; | 637 String gaugeN; |
766 if (isFixRealize) { | 638 if (isFixRealize) { |
767 Gauge found = lastGauge != null | 639 final Gauge found = lastGauge != null && lastGauge.getRange().contains(km) ? lastGauge : findGauge(km, gauges); |
768 && lastGauge.getRange().contains(km) | |
769 ? lastGauge | |
770 : findGauge(km, gauges); | |
771 | 640 |
772 gaugeN = found != null ? found.getName() : notinrange; | 641 gaugeN = found != null ? found.getName() : notinrange; |
773 lastGauge = found; | 642 lastGauge = found; |
774 } | 643 } else { |
775 else { | |
776 // TODO issue1114: Take correct gauge | 644 // TODO issue1114: Take correct gauge |
777 gaugeN = km >= a && km <= b | 645 gaugeN = km >= a && km <= b ? gaugeName : notinrange; |
778 ? gaugeName | |
779 : notinrange; | |
780 } | 646 } |
781 writeRow6(writer, result, desc, flys, gaugeN); | 647 writeRow6(writer, result, desc, flys, gaugeN); |
782 } | 648 } |
783 } | 649 } else { // Not at gauge. |
784 else { // Not at gauge. | |
785 for (int i = 0; i < size; ++i) { | 650 for (int i = 0; i < size; ++i) { |
786 result = wqkms.get(i, result); | 651 result = wqkms.get(i, result); |
787 writeRow4(writer, result, flys); | 652 writeRow4(writer, result, flys); |
788 } | 653 } |
789 } | 654 } |
790 | 655 |
791 long stopTime = System.currentTimeMillis(); | 656 final long stopTime = System.currentTimeMillis(); |
792 | 657 |
793 if (log.isDebugEnabled()) { | 658 if (log.isDebugEnabled()) { |
794 log.debug("Writing CSV took " + | 659 log.debug("Writing CSV took " + (stopTime - startTime) / 1000f + " secs."); |
795 (float)(stopTime-startTime)/1000f + " secs."); | 660 } |
796 } | 661 } |
797 } | |
798 | |
799 | 662 |
800 /** | 663 /** |
801 * Generates the output in WST format. | 664 * Generates the output in WST format. |
802 */ | 665 */ |
803 protected void generateWST() | 666 protected void generateWST() throws IOException { |
804 throws IOException | |
805 { | |
806 log.info("WaterlevelExporter.generateWST"); | 667 log.info("WaterlevelExporter.generateWST"); |
807 | 668 |
808 int cols = data.get(0).length + officalFixings.size(); | 669 final int cols = this.data.get(0).length + this.officalFixings.size(); |
809 WstWriter writer = new WstWriter(cols); | 670 final WstWriter writer = new WstWriter(cols); |
810 | 671 |
811 writeWSTData(writer); | 672 writeWSTData(writer); |
812 | 673 |
813 writer.write(out); | 674 writer.write(this.out); |
814 } | 675 } |
815 | 676 |
816 | 677 protected void writeWSTData(final WstWriter writer) { |
817 protected void writeWSTData(WstWriter writer) { | |
818 log.debug("WaterlevelExporter.writeWSTData"); | 678 log.debug("WaterlevelExporter.writeWSTData"); |
819 | 679 |
820 double[] result = new double[4]; | 680 double[] result = new double[4]; |
821 | 681 |
822 for (WQKms[] tmp: data) { | 682 for (final WQKms[] tmp : this.data) { |
823 for (WQKms wqkms: tmp) { | 683 for (final WQKms wqkms : tmp) { |
824 if (wqkms instanceof ConstantWQKms) { | 684 if (wqkms instanceof ConstantWQKms) { |
825 continue; | 685 continue; |
826 } | 686 } |
827 int size = wqkms != null ? wqkms.size() : 0; | 687 final int size = wqkms != null ? wqkms.size() : 0; |
828 | 688 |
829 addWSTColumn(writer, wqkms); | 689 addWSTColumn(writer, wqkms); |
830 | 690 |
831 for (int i = 0; i < size; i++) { | 691 for (int i = 0; i < size; i++) { |
832 result = wqkms.get(i, result); | 692 result = wqkms.get(i, result); |
848 | 708 |
849 // Append the official fixing interpolated to the calculation steps | 709 // Append the official fixing interpolated to the calculation steps |
850 // | 710 // |
851 // There was some confusion how to implement this. see flys/issue1620 | 711 // There was some confusion how to implement this. see flys/issue1620 |
852 // for details. | 712 // for details. |
853 for (WQKms wqkms: officalFixings) { | 713 for (final WQKms wqkms : this.officalFixings) { |
854 // To add some spaces here or to add them in the writer,.. | 714 // To add some spaces here or to add them in the writer,.. |
855 writer.addColumn(getDesc(wqkms, true)); | 715 writer.addColumn(getDesc(wqkms, true)); |
856 | 716 |
857 // Get all lines from the calculation | 717 // Get all lines from the calculation |
858 Map <Double, WstLine> calcLines = writer.getLines(); | 718 final Map<Double, WstLine> calcLines = writer.getLines(); |
859 | 719 |
860 // All KM values where we have a point for | 720 // All KM values where we have a point for |
861 TDoubleArrayList officialKms = wqkms.allKms(); | 721 final TDoubleArrayList officialKms = wqkms.allKms(); |
862 | 722 |
863 for (Map.Entry<Double, WstLine> entry : calcLines.entrySet()) { | 723 for (final Map.Entry<Double, WstLine> entry : calcLines.entrySet()) { |
864 // Bad for perfomance but the user can wait a bit for WST | 724 // Bad for perfomance but the user can wait a bit for WST |
865 // so lets not spend time optimizing too much,.. *hides* | 725 // so lets not spend time optimizing too much,.. *hides* |
866 double km = entry.getKey().doubleValue(); | 726 final double km = entry.getKey().doubleValue(); |
867 int idx = officialKms.indexOf(km); | 727 final int idx = officialKms.indexOf(km); |
868 if (idx != -1) { | 728 if (idx != -1) { |
869 entry.getValue().add(wqkms.getW(idx), wqkms.getQ(idx)); | 729 entry.getValue().add(wqkms.getW(idx), wqkms.getQ(idx)); |
870 } | 730 } |
871 } | 731 } |
872 } | 732 } |
873 } | 733 } |
874 | |
875 | 734 |
876 /** | 735 /** |
877 * Register a new column at <i>writer</i>. The name / | 736 * Register a new column at <i>writer</i>. The name / |
878 * title of the column depends on the Q or W value of <i>wqkms</i>. If a Q | 737 * title of the column depends on the Q or W value of <i>wqkms</i>. If a Q |
879 * was selected and the Q fits to a named main value, the title is set to | 738 * was selected and the Q fits to a named main value, the title is set to |
880 * the named main value. Otherwise, the name returned by | 739 * the named main value. Otherwise, the name returned by |
881 * <i>WQKms.getName()</i> is set. | 740 * <i>WQKms.getName()</i> is set. |
882 * | 741 * |
883 * @param writer The WstWriter. | 742 * @param writer |
884 * @param wqkms The new WST column. | 743 * The WstWriter. |
885 */ | 744 * @param wqkms |
886 protected void addWSTColumn(WstWriter writer, WQKms wqkms) { | 745 * The new WST column. |
746 */ | |
747 protected void addWSTColumn(final WstWriter writer, final WQKms wqkms) { | |
887 if (wqkms instanceof ConstantWQKms) { | 748 if (wqkms instanceof ConstantWQKms) { |
888 return; | 749 return; |
889 } | 750 } |
890 if (master instanceof WINFOArtifact) { | 751 if (this.master instanceof WINFOArtifact) { |
891 writer.addColumn(getColumnTitle((WINFOArtifact) master, wqkms)); | 752 writer.addColumn(getColumnTitle((WINFOArtifact) this.master, wqkms)); |
892 } | 753 } else { |
893 else { | |
894 writer.addColumn(wqkms.getName()); | 754 writer.addColumn(wqkms.getName()); |
895 } | 755 } |
896 } | 756 } |
897 | 757 |
898 | |
899 @Override | 758 @Override |
900 protected void writePDF(OutputStream out) { | 759 protected void writePDF(final OutputStream out) { |
901 log.debug("write PDF"); | 760 log.debug("write PDF"); |
902 WKmsJRDataSource source = createJRData(); | 761 final WKmsJRDataSource source = createJRData(); |
903 | 762 |
904 String jasperFile = Resources.getMsg( | 763 final String jasperFile = // "/jasper/waterlevel_en.jasper"; |
905 context.getMeta(), | 764 Resources.getMsg(this.context.getMeta(), JASPER_FILE, "/jasper/waterlevel_en.jasper"); |
906 JASPER_FILE, | 765 final String confPath = Config.getConfigDirectory().toString(); |
907 "/jasper/waterlevel_en.jasper"); | 766 |
908 String confPath = Config.getConfigDirectory().toString(); | 767 final Map parameters = new HashMap(); |
909 | |
910 | |
911 Map parameters = new HashMap(); | |
912 parameters.put("ReportTitle", "Exported Data"); | 768 parameters.put("ReportTitle", "Exported Data"); |
913 try { | 769 try { |
914 JasperPrint print = JasperFillManager.fillReport( | 770 final JasperPrint print = JasperFillManager.fillReport(confPath + jasperFile, parameters, source); |
915 confPath + jasperFile, | |
916 parameters, | |
917 source); | |
918 JasperExportManager.exportReportToPdfStream(print, out); | 771 JasperExportManager.exportReportToPdfStream(print, out); |
919 } | 772 } |
920 catch(JRException je) { | 773 catch (final JRException je) { |
921 log.warn("Error generating PDF Report!", je); | 774 log.warn("Error generating PDF Report!", je); |
922 } | 775 } |
923 } | 776 } |
924 | 777 |
925 protected WKmsJRDataSource createJRData() { | 778 protected WKmsJRDataSource createJRData() { |
926 WKmsJRDataSource source = new WKmsJRDataSource(); | 779 final WKmsJRDataSource source = new WKmsJRDataSource(); |
927 | 780 |
928 WQ_MODE mode = RiverUtils.getWQMode((D4EArtifact)master); | 781 final WQ_MODE mode = RiverUtils.getWQMode((D4EArtifact) this.master); |
929 boolean atGauge = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.WGAUGE; | 782 final boolean atGauge = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.WGAUGE; |
930 boolean isQ = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.QFREE; | 783 final boolean isQ = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.QFREE; |
931 | 784 |
932 Double first = Double.NaN; | 785 Double first = Double.NaN; |
933 Double last = Double.NaN; | 786 Double last = Double.NaN; |
934 | 787 |
935 addMetaData(source); | 788 addMetaData(source); |
936 for (WQKms[] tmp: data) { | 789 for (final WQKms[] tmp : this.data) { |
937 for (WQKms wqkms: tmp) { | 790 for (final WQKms wqkms : tmp) { |
938 addWKmsData(wqkms, atGauge, isQ, source); | 791 addWKmsData(wqkms, atGauge, isQ, source); |
939 double[] firstLast = wqkms.getFirstLastKM(); | 792 final double[] firstLast = wqkms.getFirstLastKM(); |
940 if (first.isNaN()) { | 793 if (first.isNaN()) { |
941 /* Initialize */ | 794 /* Initialize */ |
942 first = firstLast[0]; | 795 first = firstLast[0]; |
943 last = firstLast[1]; | 796 last = firstLast[1]; |
944 } | 797 } |
945 if (firstLast[0] > firstLast[1]) { | 798 if (firstLast[0] > firstLast[1]) { |
946 /* Calculating upstream we assert that it is | 799 /* |
800 * Calculating upstream we assert that it is | |
947 * impossible that the direction changes during this | 801 * impossible that the direction changes during this |
948 * loop */ | 802 * loop |
803 */ | |
949 first = Math.max(first, firstLast[0]); | 804 first = Math.max(first, firstLast[0]); |
950 last = Math.min(last, firstLast[1]); | 805 last = Math.min(last, firstLast[1]); |
951 } else if (firstLast[0] < firstLast[1]) { | 806 } else if (firstLast[0] < firstLast[1]) { |
952 first = Math.min(first, firstLast[0]); | 807 first = Math.min(first, firstLast[0]); |
953 last = Math.max(last, firstLast[1]); | 808 last = Math.max(last, firstLast[1]); |
956 } | 811 } |
957 } | 812 } |
958 } | 813 } |
959 | 814 |
960 /* Append the official fixing at the bottom */ | 815 /* Append the official fixing at the bottom */ |
961 for (WQKms wqkms: officalFixings) { | 816 for (final WQKms wqkms : this.officalFixings) { |
962 addWKmsData(filterWQKms(wqkms, first, last), atGauge, isQ, source); | 817 addWKmsData(filterWQKms(wqkms, first, last), atGauge, isQ, source); |
963 } | 818 } |
964 return source; | 819 return source; |
965 } | 820 } |
966 | 821 |
967 protected void addMetaData(WKmsJRDataSource source) { | 822 protected void addMetaData(final WKmsJRDataSource source) { |
968 CallMeta meta = context.getMeta(); | 823 final CallMeta meta = this.context.getMeta(); |
969 | 824 |
970 D4EArtifact flys = (D4EArtifact) master; | 825 final D4EArtifact flys = (D4EArtifact) this.master; |
971 | 826 |
972 source.addMetaData ("river", RiverUtils.getRivername(flys)); | 827 source.addMetaData("river", RiverUtils.getRivername(flys)); |
973 | 828 |
974 Locale locale = Resources.getLocale(meta); | 829 final Locale locale = Resources.getLocale(meta); |
975 DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale); | 830 final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale); |
976 NumberFormat kmf = getKmFormatter(); | 831 final NumberFormat kmf = getKmFormatter(); |
977 | 832 |
978 source.addMetaData("date", df.format(new Date())); | 833 source.addMetaData("date", df.format(new Date())); |
979 | 834 |
980 RangeAccess rangeAccess = new RangeAccess(flys); | 835 final RangeAccess rangeAccess = new RangeAccess(flys); |
981 double[] kms = rangeAccess.getKmRange(); | 836 final double[] kms = rangeAccess.getKmRange(); |
982 source.addMetaData("range", | 837 source.addMetaData("range", kmf.format(kms[0]) + " - " + kmf.format(kms[kms.length - 1])); |
983 kmf.format(kms[0]) + " - " + kmf.format(kms[kms.length-1])); | |
984 | 838 |
985 source.addMetaData("gauge", RiverUtils.getGaugename(flys)); | 839 source.addMetaData("gauge", RiverUtils.getGaugename(flys)); |
986 | 840 |
987 source.addMetaData("calculation", Resources.getMsg( | 841 source.addMetaData("calculation", Resources.getMsg(locale, PDF_HEADER_MODE, "Waterlevel")); |
988 locale, | 842 } |
989 PDF_HEADER_MODE, | 843 |
990 "Waterlevel")); | 844 protected void addWKmsData(final WQKms wqkms, final boolean atGauge, final boolean isQ, final WKmsJRDataSource source) { |
991 } | |
992 | |
993 protected void addWKmsData( | |
994 WQKms wqkms, | |
995 boolean atGauge, | |
996 boolean isQ, | |
997 WKmsJRDataSource source) | |
998 { | |
999 log.debug("WaterlevelExporter.addWKmsData"); | 845 log.debug("WaterlevelExporter.addWKmsData"); |
1000 | 846 |
1001 // Skip constant data. | 847 // Skip constant data. |
1002 if (wqkms instanceof ConstantWQKms) { | 848 if (wqkms instanceof ConstantWQKms) { |
1003 return; | 849 return; |
1004 } | 850 } |
1005 | 851 |
1006 NumberFormat kmf = getKmFormatter(); | 852 final NumberFormat kmf = getKmFormatter(); |
1007 NumberFormat wf = getWFormatter(); | 853 final NumberFormat wf = getWFormatter(); |
1008 NumberFormat qf = getQFormatter(); | 854 final NumberFormat qf = getQFormatter(); |
1009 | 855 |
1010 int size = wqkms.size(); | 856 final int size = wqkms.size(); |
1011 double[] result = new double[3]; | 857 double[] result = new double[3]; |
1012 | 858 |
1013 D4EArtifact flys = (D4EArtifact) master; | 859 final D4EArtifact flys = (D4EArtifact) this.master; |
1014 RangeAccess rangeAccess = new RangeAccess(flys); | 860 final RangeAccess rangeAccess = new RangeAccess(flys); |
1015 | 861 |
1016 Gauge gauge = rangeAccess.getRiver().determineRefGauge( | 862 final Gauge gauge = rangeAccess.getRiver().determineRefGauge(rangeAccess.getKmRange(), rangeAccess.isRange()); |
1017 rangeAccess.getKmRange(), rangeAccess.isRange()); | 863 |
1018 | 864 final String gaugeName = gauge.getName(); |
1019 String gaugeName = gauge.getName(); | 865 String desc = ""; |
1020 String desc = ""; | 866 final String notinrange = msg(CSV_NOT_IN_GAUGE_RANGE, DEFAULT_CSV_NOT_IN_GAUGE_RANGE); |
1021 String notinrange = msg( | 867 |
1022 CSV_NOT_IN_GAUGE_RANGE, | 868 final double a = gauge.getRange().getA().doubleValue(); |
1023 DEFAULT_CSV_NOT_IN_GAUGE_RANGE); | 869 final double b = gauge.getRange().getB().doubleValue(); |
1024 | |
1025 double a = gauge.getRange().getA().doubleValue(); | |
1026 double b = gauge.getRange().getB().doubleValue(); | |
1027 | 870 |
1028 desc = getDesc(wqkms, isQ); | 871 desc = getDesc(wqkms, isQ); |
1029 long startTime = System.currentTimeMillis(); | 872 final long startTime = System.currentTimeMillis(); |
1030 | 873 |
1031 for (int i = 0; i < size; i ++) { | 874 for (int i = 0; i < size; i++) { |
1032 result = wqkms.get(i, result); | 875 result = wqkms.get(i, result); |
1033 | 876 |
1034 if (atGauge) { | 877 if (atGauge) { |
1035 source.addData(new String[] { | 878 source.addData(new String[] { kmf.format(result[2]), wf.format(result[0]), qf.format(RiverUtils.roundQ(result[1])), desc, |
1036 kmf.format(result[2]), | 879 RiverUtils.getLocationDescription(flys, result[2]), result[2] >= a && result[2] <= b ? gaugeName : notinrange }); |
1037 wf.format(result[0]), | 880 } else { |
1038 qf.format(RiverUtils.roundQ(result[1])), | 881 source.addData(new String[] { kmf.format(result[2]), wf.format(result[0]), qf.format(RiverUtils.roundQ(result[1])), desc, |
1039 desc, | 882 RiverUtils.getLocationDescription(flys, result[2]), result[2] >= a && result[2] <= b ? gaugeName : notinrange }); |
1040 RiverUtils.getLocationDescription(flys, result[2]), | 883 } |
1041 result[2] >= a && result[2] <= b | 884 } |
1042 ? gaugeName | 885 |
1043 : notinrange | 886 final long stopTime = System.currentTimeMillis(); |
1044 }); | |
1045 } | |
1046 else { | |
1047 source.addData(new String[] { | |
1048 kmf.format(result[2]), | |
1049 wf.format(result[0]), | |
1050 qf.format(RiverUtils.roundQ(result[1])), | |
1051 desc, | |
1052 RiverUtils.getLocationDescription(flys, result[2]), | |
1053 result[2] >= a && result[2] <= b | |
1054 ? gaugeName | |
1055 : notinrange | |
1056 }); | |
1057 } | |
1058 } | |
1059 | |
1060 long stopTime = System.currentTimeMillis(); | |
1061 | 887 |
1062 if (log.isDebugEnabled()) { | 888 if (log.isDebugEnabled()) { |
1063 log.debug("Writing PDF data took " + | 889 log.debug("Writing PDF data took " + (stopTime - startTime) / 1000f + " secs."); |
1064 (float)(stopTime-startTime)/1000f + " secs."); | |
1065 } | 890 } |
1066 } | 891 } |
1067 } | 892 } |
1068 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : | 893 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |