comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationExporter.java @ 9145:e6b63b2b41b9

sinfo.flood_duration pdf, csv, ui
author gernotbelger
date Tue, 12 Jun 2018 10:23:23 +0200
parents
children 23945061daec
comparison
equal deleted inserted replaced
9144:7879c2ca8bd3 9145:e6b63b2b41b9
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 }

http://dive4elements.wald.intevation.org