9145
|
1 /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde |
|
2 * Software engineering by Intevation GmbH |
|
3 * |
|
4 * This file is Free Software under the GNU AGPL (>=v3) |
|
5 * and comes with ABSOLUTELY NO WARRANTY! Check out the |
|
6 * documentation coming with Dive4Elements River for details. |
|
7 */ |
|
8 |
|
9 package org.dive4elements.river.artifacts.sinfo.flood_duration; |
|
10 |
|
11 import java.io.OutputStream; |
|
12 import java.text.NumberFormat; |
|
13 import java.util.ArrayList; |
|
14 import java.util.Collection; |
|
15 import java.util.List; |
|
16 |
|
17 import org.apache.log4j.Logger; |
|
18 import org.dive4elements.river.artifacts.common.GeneralResultType; |
|
19 import org.dive4elements.river.artifacts.common.JasperDesigner; |
|
20 import org.dive4elements.river.artifacts.common.JasperReporter; |
|
21 import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource; |
|
22 import org.dive4elements.river.artifacts.common.ResultRow; |
|
23 import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoExporter; |
|
24 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; |
|
25 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; |
|
26 import org.dive4elements.river.artifacts.sinfo.util.WstInfo; |
|
27 |
|
28 import au.com.bytecode.opencsv.CSVWriter; |
|
29 import net.sf.jasperreports.engine.JRException; |
|
30 |
|
31 /** |
|
32 * Generates different output formats (csv, pdf) of data that resulted from a flow depths min/max computation. |
|
33 * |
|
34 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> |
|
35 * @author Gernot Belger |
|
36 */ |
|
37 // REMARK: must be public because its registered in generators.xml |
|
38 public class FloodDurationExporter extends AbstractSInfoExporter<FloodDurationCalculationResult, FloodDurationCalculationResults> { |
|
39 |
|
40 /** The log used in this exporter. */ |
|
41 private static Logger log = Logger.getLogger(FloodDurationExporter.class); |
|
42 |
|
43 private final String getJasperFile(final int waterlevelCount) { |
|
44 if (waterlevelCount <= 1) |
|
45 return "/jasper/templates/sinfo.floodduration.jrxml"; // TODO use jrxml-path all over the project |
|
46 else |
|
47 return "/jasper/templates/sinfo.floodduration2.jrxml"; |
|
48 } |
|
49 |
|
50 private static final int maxPdfWspls = 3; |
|
51 |
|
52 @Override |
|
53 protected Logger getLog() { |
|
54 return log; |
|
55 } |
|
56 |
|
57 @Override |
|
58 protected void writeCSVGlobalMetadata(final CSVWriter writer, final FloodDurationCalculationResults results) { |
|
59 log.info("FloodDurationExporter.writeCSVMeta"); |
|
60 super.writeCSVGlobalMetadataDefaults(writer, results); |
|
61 } |
|
62 |
|
63 @Override |
|
64 protected void writeCSVResultMetadata(final CSVWriter writer, final FloodDurationCalculationResults results, final FloodDurationCalculationResult result) { |
|
65 |
|
66 final WstInfo wst = result.getWst(); |
|
67 super.writeCSVWaterlevelMetadata(writer, wst); // TODO: Abweichend vom Allgemeinen werden hier andere Felder benötigt bei den Wasserspiegellagen |
|
68 |
|
69 writer.writeNext(new String[] { "" }); // break line |
|
70 |
|
71 } |
|
72 |
|
73 /** |
|
74 * Write the header, with different headings depending on whether at a |
|
75 * gauge or at a location. |
|
76 * |
|
77 * @param river |
|
78 * @param useTkh |
|
79 */ |
|
80 @Override |
|
81 protected void writeCSVHeader(final CSVWriter writer, final FloodDurationCalculationResults results, final RiverInfo river) { |
|
82 log.info("FloodDurationExporter.writeCSVHeader"); |
|
83 |
|
84 final Collection<String> header = new ArrayList<>(99); |
|
85 |
|
86 header.add(msg(GeneralResultType.station.getCsvHeader())); |
|
87 header.add(msg(SInfoResultType.riverside.getCsvHeader())); |
|
88 header.add(msg(SInfoResultType.inundationduration.getCsvHeader())); |
|
89 header.add(msg(SInfoResultType.inundationdurationq.getCsvHeader())); |
|
90 header.add(msg(SInfoResultType.infrastructureHeight.getCsvHeader())); |
|
91 header.add(msg(SInfoResultType.infrastructuretype.getCsvHeader())); |
|
92 // add dynamic headers |
|
93 final int waterlevelCount = getWaterlevelCount(); |
|
94 for (int i = 0; i < waterlevelCount; i++) { |
|
95 final int naturalIndex = i + 1; |
|
96 final String appendIndex = new StringBuilder().append("_").append(naturalIndex).toString(); |
|
97 final Object[] args = new Object[] { appendIndex }; |
|
98 // new StringBuilder().append('\u2081').toString(); // schlechter UTF-8-Support für subscript ints |
|
99 header.add(msg(DurationWaterlevel.getHeaderW(), new Object[] { appendIndex, "results.getRiver().getWstUnit()" })); |
|
100 header.add(msg(DurationWaterlevel.getHeaderFloodDurPerYear(), args)); |
|
101 header.add(msg(DurationWaterlevel.getHeaderQ(), args)); |
|
102 header.add(msg(DurationWaterlevel.getHeaderBezeichn(), args)); |
|
103 } |
|
104 |
|
105 header.add(msg(SInfoResultType.gaugeLabel.getCsvHeader())); |
|
106 header.add(msg(SInfoResultType.location.getCsvHeader())); |
|
107 |
|
108 writer.writeNext(header.toArray(new String[header.size()])); |
|
109 } |
|
110 |
|
111 private int getWaterlevelCount() { |
|
112 final FloodDurationCalculationResults results = getData(); |
|
113 if (results != null) { |
|
114 final List<FloodDurationCalculationResult> list = results.getResults(); |
|
115 if (list != null && list.size() > 0) { |
|
116 final FloodDurationCalculationResult result = list.get(0); |
|
117 return result.getWaterlevelCount(); |
|
118 } |
|
119 } |
|
120 return 0; |
|
121 } |
|
122 |
|
123 @Override |
|
124 protected String[] formatRow(final FloodDurationCalculationResults results, final ResultRow row, final ExportMode mode) { |
|
125 |
|
126 final Collection<String> lines = new ArrayList<>(99); |
|
127 |
|
128 lines.add(row.exportValue(this.context, GeneralResultType.station)); |
|
129 lines.add(row.exportValue(this.context, SInfoResultType.riverside)); |
|
130 lines.add(row.exportValue(this.context, SInfoResultType.inundationduration)); |
|
131 lines.add(row.exportValue(this.context, SInfoResultType.inundationdurationq)); |
|
132 lines.add(row.exportValue(this.context, SInfoResultType.infrastructureHeight)); |
|
133 lines.add(row.exportValue(this.context, SInfoResultType.infrastructuretype)); |
|
134 |
|
135 final int waterlevelcount = this.getWaterlevelCount(); |
|
136 |
|
137 final List<DurationWaterlevel> waterlevelList = (List<DurationWaterlevel>) row.getValue(SInfoResultType.customMultiRowColWaterlevel); |
|
138 if (waterlevelList != null) { |
|
139 final NumberFormat wFormatter = getFlowDepthFormatter(); |
|
140 final NumberFormat qFormatter = getQFormatter(); |
|
141 |
|
142 for (int i = 0; i < waterlevelList.size(); i++) { |
|
143 |
|
144 if (i == FloodDurationExporter.maxPdfWspls && mode == ExportMode.pdf) |
|
145 break; |
|
146 |
|
147 final DurationWaterlevel item = waterlevelList.get(i); |
|
148 lines.add(item.getWFormatted(wFormatter)); |
|
149 lines.add(item.getFloodDurDaysPerYearFormatted()); |
|
150 lines.add(item.getQFormatted(qFormatter)); |
|
151 lines.add(item.getBezeichnung()); |
|
152 } |
|
153 } |
|
154 |
|
155 if ((waterlevelcount == 0 || waterlevelcount == 2) && mode == ExportMode.pdf) { |
|
156 lines.add("dummy"); |
|
157 lines.add("dummy"); |
|
158 lines.add("dummy"); |
|
159 lines.add("dummy"); |
|
160 } |
|
161 |
|
162 lines.add(row.exportValue(this.context, SInfoResultType.gaugeLabel)); |
|
163 lines.add(row.exportValue(this.context, SInfoResultType.location)); |
|
164 return lines.toArray(new String[lines.size()]); |
|
165 } |
|
166 |
|
167 @Override |
|
168 protected void writePDF(final OutputStream out) { |
|
169 |
|
170 try { |
|
171 final MetaAndTableJRDataSource source = createJRData(this.data); |
|
172 final JasperReporter reporter = new JasperReporter(); |
|
173 final int waterlevelCount = getWaterlevelCount(); |
|
174 final JasperDesigner design = reporter.addReport(getJasperFile(waterlevelCount), source); |
|
175 |
|
176 if (waterlevelCount == 0 || waterlevelCount == 2) { |
|
177 design.removeColumn("wOpt"); |
|
178 design.removeColumn("qOpt"); |
|
179 design.removeColumn("bezOpt"); |
|
180 design.removeColumn("durOpt"); |
|
181 } |
|
182 |
|
183 reporter.exportPDF(out); |
|
184 } |
|
185 catch (final JRException je) { |
|
186 getLog().warn("Error generating PDF Report!", je); |
|
187 } |
|
188 } |
|
189 |
|
190 @Override |
|
191 protected final void addJRMetaData(final MetaAndTableJRDataSource source, final FloodDurationCalculationResults results) { |
|
192 |
|
193 /* general metadata */ |
|
194 super.addJRMetaData(source, results); |
|
195 |
|
196 /* column headings */ |
|
197 source.addMetaData("station_header", GeneralResultType.station.getPdfHeader(this.context.getMeta())); |
|
198 source.addMetaData("riverside_header", SInfoResultType.riverside.getPdfHeader(this.context.getMeta())); |
|
199 source.addMetaData("inundationduration_header", SInfoResultType.inundationduration.getPdfHeader(this.context.getMeta())); |
|
200 source.addMetaData("inundationduration_q_header", SInfoResultType.inundationdurationq.getPdfHeader(this.context.getMeta())); |
|
201 source.addMetaData("infrastructure_height_header", SInfoResultType.infrastructureHeightFloodDur.getPdfHeader(this.context.getMeta())); |
|
202 source.addMetaData("infrastructure_type_header", SInfoResultType.infrastructuretype.getPdfHeader(this.context.getMeta())); |
|
203 |
|
204 // add dynamic headers |
|
205 |
|
206 final int waterlevelCount = getWaterlevelCount() > FloodDurationExporter.maxPdfWspls ? FloodDurationExporter.maxPdfWspls : getWaterlevelCount(); |
|
207 |
|
208 if (waterlevelCount == 0 || waterlevelCount == 2) { |
|
209 source.addMetaData("dummy", "dummy"); |
|
210 source.addMetaData("dummy", "dummy"); |
|
211 source.addMetaData("dummy", "dummy"); |
|
212 source.addMetaData("dummy", "dummy"); |
|
213 } |
|
214 |
|
215 for (int i = 0; i < waterlevelCount; i++) { |
|
216 final int naturalIndex = i + 1; |
|
217 |
|
218 final Object[] args = new String[] { new StringBuilder().append("_").append(naturalIndex).toString() }; |
|
219 source.addMetaData(getPdfHeader("w", naturalIndex), msg(DurationWaterlevel.getHeaderW(), args)); |
|
220 source.addMetaData(getPdfHeader("duration", naturalIndex), msg(DurationWaterlevel.getHeaderFloodDurPerYear(), args)); |
|
221 source.addMetaData(getPdfHeader("q", naturalIndex), msg(DurationWaterlevel.getHeaderQ(), args)); |
|
222 source.addMetaData(getPdfHeader("bezeichnung", naturalIndex), msg(DurationWaterlevel.getHeaderBezeichn(), args)); |
|
223 |
|
224 } |
|
225 |
|
226 source.addMetaData("gauge_header", SInfoResultType.gaugeLabel.getPdfHeader(this.context.getMeta())); |
|
227 source.addMetaData("location_header", SInfoResultType.location.getPdfHeader(this.context.getMeta())); |
|
228 |
|
229 } |
|
230 |
|
231 private String getPdfHeader(final String rootStr, final int index) { |
|
232 final String hd = "_header"; |
|
233 final StringBuilder builder = new StringBuilder(); |
|
234 return builder.append(rootStr).append("_").append(index).append(hd).toString(); |
|
235 } |
|
236 |
|
237 } |