ingo@389: package de.intevation.flys.exports;
ingo@389:
ingo@446: import java.io.IOException;
ingo@389: import java.io.OutputStream;
ingo@2045: import java.text.DateFormat;
ingo@418: import java.text.NumberFormat;
ingo@389: import java.util.ArrayList;
raimund@2176: import java.util.Map;
raimund@2176: import java.util.HashMap;
ingo@2045: import java.util.Date;
ingo@389: import java.util.List;
ingo@2045: import java.util.Locale;
ingo@2035: import java.util.regex.Matcher;
ingo@2035: import java.util.regex.Pattern;
ingo@389:
ingo@389: import org.w3c.dom.Document;
ingo@389:
ingo@389: import org.apache.log4j.Logger;
ingo@389:
ingo@389: import au.com.bytecode.opencsv.CSVWriter;
ingo@389:
raimund@2176: import net.sf.jasperreports.engine.JasperExportManager;
raimund@2176: import net.sf.jasperreports.engine.JasperFillManager;
raimund@2176: import net.sf.jasperreports.engine.JasperPrint;
raimund@2176: import net.sf.jasperreports.engine.JRException;
raimund@2176:
ingo@389: import de.intevation.artifacts.CallContext;
ingo@2045: import de.intevation.artifacts.CallMeta;
raimund@2185: import de.intevation.artifacts.common.utils.Config;
ingo@389:
ingo@2066: import de.intevation.flys.model.Gauge;
ingo@2066:
ingo@2045: import de.intevation.flys.artifacts.FLYSArtifact;
ingo@2035: import de.intevation.flys.artifacts.WINFOArtifact;
sascha@709: import de.intevation.flys.artifacts.model.CalculationResult;
ingo@749: import de.intevation.flys.artifacts.model.WQCKms;
ingo@389: import de.intevation.flys.artifacts.model.WQKms;
raimund@2176: import de.intevation.flys.artifacts.model.WKmsJRDataSource;
ingo@3462: import de.intevation.flys.artifacts.model.fixings.FixRealizingResult;
ingo@2045: import de.intevation.flys.artifacts.resources.Resources;
sascha@706:
ingo@2035: import de.intevation.flys.utils.FLYSUtils;
ingo@2065: import de.intevation.flys.utils.FLYSUtils.WQ_MODE;
ingo@445: import de.intevation.flys.utils.Formatter;
ingo@389:
ingo@389:
ingo@389: /**
felix@3252: * Generates different output formats (wst, csv, pdf) of data that resulted from
felix@3252: * a waterlevel computation.
felix@3252: *
ingo@389: * @author Ingo Weinzierl
ingo@389: */
ingo@391: public class WaterlevelExporter extends AbstractExporter {
ingo@389:
ingo@389: /** The logger used in this exporter.*/
ingo@389: private static Logger logger = Logger.getLogger(WaterlevelExporter.class);
ingo@389:
ingo@446: public static final String FACET_WST = "wst";
ingo@446:
ingo@416: public static final String CSV_KM_HEADER =
ingo@416: "export.waterlevel.csv.header.km";
ingo@416:
ingo@416: public static final String CSV_W_HEADER =
ingo@416: "export.waterlevel.csv.header.w";
ingo@416:
ingo@416: public static final String CSV_Q_HEADER =
ingo@416: "export.waterlevel.csv.header.q";
ingo@416:
ingo@2063: public static final String CSV_Q_DESC_HEADER =
ingo@2063: "export.waterlevel.csv.header.q.desc";
ingo@2063:
ingo@2068: public static final String CSV_W_DESC_HEADER =
ingo@2068: "export.waterlevel.csv.header.w.desc";
ingo@2068:
ingo@2063: public static final String CSV_LOCATION_HEADER =
ingo@2063: "export.waterlevel.csv.header.location";
ingo@2063:
ingo@2063: public static final String CSV_GAUGE_HEADER =
ingo@2063: "export.waterlevel.csv.header.gauge";
ingo@2063:
ingo@2045: public static final String CSV_META_RESULT =
ingo@2045: "export.waterlevel.csv.meta.result";
ingo@2045:
ingo@2045: public static final String CSV_META_CREATION =
ingo@2045: "export.waterlevel.csv.meta.creation";
ingo@2045:
ingo@2045: public static final String CSV_META_CALCULATIONBASE =
ingo@2045: "export.waterlevel.csv.meta.calculationbase";
ingo@2045:
ingo@2045: public static final String CSV_META_RIVER =
ingo@2045: "export.waterlevel.csv.meta.river";
ingo@2045:
ingo@2045: public static final String CSV_META_RANGE =
ingo@2045: "export.waterlevel.csv.meta.range";
ingo@2045:
ingo@2045: public static final String CSV_META_GAUGE =
ingo@2045: "export.waterlevel.csv.meta.gauge";
ingo@2045:
ingo@2045: public static final String CSV_META_Q =
ingo@2045: "export.waterlevel.csv.meta.q";
ingo@2045:
ingo@2045: public static final String CSV_META_W =
ingo@2045: "export.waterlevel.csv.meta.w";
ingo@2045:
ingo@2066: public static final String CSV_NOT_IN_GAUGE_RANGE =
ingo@2066: "export.waterlevel.csv.not.in.gauge.range";
ingo@2066:
ingo@2045:
ingo@2035: public static final Pattern NUMBERS_PATTERN =
ingo@2035: Pattern.compile("\\D*(\\d++.\\d*)\\D*");
ingo@2035:
ingo@2063: public static final String DEFAULT_CSV_KM_HEADER = "Fluss-Km";
ingo@2063: public static final String DEFAULT_CSV_W_HEADER = "W [NN + m]";
ingo@2063: public static final String DEFAULT_CSV_Q_HEADER = "Q [m\u00b3/s]";
ingo@2063: public static final String DEFAULT_CSV_Q_DESC_HEADER = "Bezeichnung";
ingo@2068: public static final String DEFAULT_CSV_W_DESC_HEADER = "W/Pegel [cm]";
ingo@2063: public static final String DEFAULT_CSV_LOCATION_HEADER = "Lage";
ingo@2063: public static final String DEFAULT_CSV_GAUGE_HEADER = "Bezugspegel";
ingo@2066: public static final String DEFAULT_CSV_NOT_IN_GAUGE_RANGE =
ingo@2066: "außerhalb des gewählten Bezugspegels";
ingo@416:
raimund@2176: public static final String PDF_HEADER_MODE = "export.waterlevel.pdf.mode";
felix@2284: public static final String JASPER_FILE = "export.waterlevel.pdf.file";
ingo@416:
ingo@389: /** The storage that contains all WQKms objects for the different facets.*/
ingo@389: protected List data;
ingo@389:
ingo@389:
ingo@389: public void init(Document request, OutputStream out, CallContext context) {
ingo@389: logger.debug("WaterlevelExporter.init");
ingo@389:
ingo@391: super.init(request, out, context);
ingo@389:
ingo@391: this.data = new ArrayList();
ingo@389: }
ingo@389:
ingo@389:
ingo@446: @Override
ingo@446: public void generate()
ingo@446: throws IOException
ingo@446: {
ingo@446: logger.debug("WaterlevelExporter.generate");
ingo@446:
ingo@446: if (facet != null && facet.equals(AbstractExporter.FACET_CSV)) {
ingo@446: generateCSV();
ingo@446: }
ingo@446: else if (facet != null && facet.equals(FACET_WST)) {
ingo@446: generateWST();
ingo@446: }
raimund@2176: else if (facet != null && facet.equals(AbstractExporter.FACET_PDF)) {
raimund@2176: generatePDF();
raimund@2176: }
ingo@446: else {
ingo@446: throw new IOException("invalid facet for exporter");
ingo@446: }
ingo@446: }
ingo@446:
ingo@446:
sascha@701: @Override
sascha@701: protected void addData(Object d) {
sascha@709: if (d instanceof CalculationResult) {
sascha@709: d = ((CalculationResult)d).getData();
sascha@709: if (d instanceof WQKms []) {
sascha@709: data.add((WQKms [])d);
sascha@709: }
ingo@3462: else if (d instanceof FixRealizingResult) {
ingo@3462: data.add(((FixRealizingResult) d).getWQKms());
ingo@3462: }
sascha@701: }
ingo@389: }
ingo@389:
ingo@389:
ingo@2035: /**
ingo@2035: * This method is used to prepare the column titles of waterlevel exports.
ingo@2035: * Titles in this export include the Q value. If a Q value matches a named
ingo@2035: * main value (as HQ100 or MNQ) this named main value should be used as
ingo@2035: * title. This method resets the name of the wqkms object if such
ingo@2035: * named main value fits to the chosen Q.
ingo@2035: *
ingo@2035: * @param winfo A WINFO Artifact.
ingo@2035: * @param wqkms A WQKms object that should be prepared.
ingo@2035: */
ingo@2038: protected String getColumnTitle(WINFOArtifact winfo, WQKms wqkms) {
ingo@2035: logger.debug("WaterlevelExporter.prepareNamedValue");
ingo@2035:
ingo@2035: String name = wqkms.getName();
ingo@2035:
ingo@2035: logger.debug("Name of WQKms = '" + name + "'");
ingo@2035:
ingo@2038: if (name.indexOf("W=") >= 0) {
ingo@2038: return name;
ingo@2038: }
ingo@2038:
ingo@2035: Matcher m = NUMBERS_PATTERN.matcher(name);
ingo@2035:
ingo@2035: if (m.matches()) {
ingo@2035: String raw = m.group(1);
ingo@2035:
ingo@2035: try {
ingo@2035: double v = Double.valueOf(raw);
ingo@2035:
ingo@2038: String nmv = FLYSUtils.getNamedMainValue(winfo, v);
ingo@2035:
ingo@2035: if (nmv != null && nmv.length() > 0) {
ingo@2596: nmv = FLYSUtils.stripNamedMainValue(nmv);
ingo@2596: nmv += "=" + String.valueOf(v);
ingo@2035: logger.debug("Set named main value '" + nmv + "'");
ingo@2035:
ingo@2038: return nmv;
ingo@2035: }
ingo@2035: }
ingo@2035: catch (NumberFormatException nfe) {
ingo@2035: // do nothing here
ingo@2035: }
ingo@2035: }
ingo@2038:
ingo@2038: return name;
ingo@2035: }
ingo@2035:
ingo@2035:
ingo@2087: protected String getCSVRowTitle(WINFOArtifact winfo, WQKms wqkms) {
ingo@2087: logger.debug("WaterlevelExporter.prepareNamedValue");
ingo@2087:
ingo@2087: String name = wqkms.getName();
ingo@2087:
ingo@2087: logger.debug("Name of WQKms = '" + name + "'");
ingo@2087:
ingo@2087: WQ_MODE wqmode = FLYSUtils.getWQMode(winfo);
ingo@2087:
ingo@2087: if (wqmode == WQ_MODE.WFREE || wqmode == WQ_MODE.QGAUGE) {
ingo@2087: return localizeWQKms(winfo, wqkms);
ingo@2087: }
ingo@2087:
ingo@2087: Double v = wqkms.getRawValue();
ingo@2087:
ingo@2087: String nmv = FLYSUtils.getNamedMainValue(winfo, v);
ingo@2087:
ingo@2087: if (nmv != null && nmv.length() > 0) {
ingo@2087: nmv = FLYSUtils.stripNamedMainValue(nmv);
ingo@2087: logger.debug("Set named main value '" + nmv + "'");
ingo@2087:
ingo@2087: return nmv;
ingo@2087: }
ingo@2087:
ingo@2087: return localizeWQKms(winfo, wqkms);
ingo@2087: }
ingo@2087:
ingo@2087:
felix@3252: /**
felix@3252: * Get a string like 'W=' or 'Q=' with a number following in localized
felix@3252: * format.
felix@3252: */
ingo@2087: protected String localizeWQKms(WINFOArtifact winfo, WQKms wqkms) {
ingo@2087: WQ_MODE wqmode = FLYSUtils.getWQMode(winfo);
ingo@2087: Double rawValue = wqkms.getRawValue();
ingo@2087:
ingo@2087: if (rawValue == null) {
ingo@2087: return wqkms.getName();
ingo@2087: }
ingo@2087:
ingo@2087: NumberFormat nf = Formatter.getRawFormatter(context);
ingo@2087:
ingo@2087: if (wqmode == WQ_MODE.WFREE || wqmode == WQ_MODE.WGAUGE) {
ingo@2087: return "W=" + nf.format(rawValue);
ingo@2087: }
ingo@2087: else {
ingo@2087: return "Q=" + nf.format(rawValue);
ingo@2087: }
ingo@2087: }
ingo@2087:
ingo@2087:
sascha@701: @Override
ingo@391: protected void writeCSVData(CSVWriter writer) {
ingo@391: logger.info("WaterlevelExporter.writeData");
ingo@389:
felix@3252: WQ_MODE mode = FLYSUtils.getWQMode((FLYSArtifact)master);
felix@3252: boolean atGauge = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.WGAUGE;
felix@3252: boolean isQ = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.QFREE;
raimund@2555: FLYSUtils.WQ_INPUT input
raimund@2555: = FLYSUtils.getWQInputMode((FLYSArtifact)master);
ingo@2065:
ingo@2045: writeCSVMeta(writer);
ingo@2068: writeCSVHeader(writer, atGauge, isQ);
ingo@416:
ingo@389: for (WQKms[] tmp: data) {
ingo@389: for (WQKms wqkms: tmp) {
felix@3252: wQKms2CSV(writer, wqkms, atGauge, isQ);
ingo@389: }
ingo@389: }
ingo@389: }
ingo@389:
ingo@389:
ingo@2045: protected void writeCSVMeta(CSVWriter writer) {
ingo@2045: logger.info("WaterlevelExporter.writeCSVMeta");
ingo@2045:
ingo@2045: CallMeta meta = context.getMeta();
ingo@2045:
ingo@2045: FLYSArtifact flys = (FLYSArtifact) master;
ingo@2045:
ingo@2045: writer.writeNext(new String[] {
ingo@2045: Resources.getMsg(
ingo@2045: meta,
ingo@2045: CSV_META_RESULT,
ingo@2045: CSV_META_RESULT,
ingo@2045: new Object[] { FLYSUtils.getRivername(flys) })
ingo@2045: });
ingo@2045:
ingo@2045: Locale locale = Resources.getLocale(meta);
ingo@2045: DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
ingo@2045:
ingo@2045: writer.writeNext(new String[] {
ingo@2045: Resources.getMsg(
ingo@2045: meta,
ingo@2045: CSV_META_CREATION,
ingo@2045: CSV_META_CREATION,
ingo@2045: new Object[] { df.format(new Date()) })
ingo@2045: });
ingo@2045:
ingo@2045: writer.writeNext(new String[] {
ingo@2045: Resources.getMsg(
ingo@2045: meta,
ingo@2045: CSV_META_CALCULATIONBASE,
ingo@2045: CSV_META_CALCULATIONBASE,
ingo@2045: new Object[] { "" }) // TODO what is required at this place?
ingo@2045: });
ingo@2045:
ingo@2045: writer.writeNext(new String[] {
ingo@2045: Resources.getMsg(
ingo@2045: meta,
ingo@2045: CSV_META_RIVER,
ingo@2045: CSV_META_RIVER,
ingo@2045: new Object[] { FLYSUtils.getRivername(flys) })
ingo@2045: });
ingo@2045:
ingo@2045: double[] kms = FLYSUtils.getKmRange(flys);
ingo@2045: writer.writeNext(new String[] {
ingo@2045: Resources.getMsg(
ingo@2045: meta,
ingo@2045: CSV_META_RANGE,
ingo@2045: CSV_META_RANGE,
ingo@2045: new Object[] { kms[0], kms[kms.length-1] })
ingo@2045: });
ingo@2045:
ingo@2045: writer.writeNext(new String[] {
ingo@2045: Resources.getMsg(
ingo@2045: meta,
ingo@2045: CSV_META_GAUGE,
ingo@2045: CSV_META_GAUGE,
ingo@2045: new Object[] { FLYSUtils.getGaugename(flys) })
ingo@2045: });
ingo@2045:
ingo@2045: FLYSUtils.WQ_MODE wq = FLYSUtils.getWQMode(flys);
ingo@2045: if (wq == FLYSUtils.WQ_MODE.QFREE || wq == FLYSUtils.WQ_MODE.QGAUGE) {
ingo@2045: double[] qs = FLYSUtils.getQs(flys);
raimund@2555: FLYSUtils.WQ_INPUT input = FLYSUtils.getWQInputMode(flys);
ingo@2045:
raimund@2555: String data = "";
ingo@2045:
raimund@2555: if ((input == FLYSUtils.WQ_INPUT.ADAPTED ||
raimund@2555: input == FLYSUtils.WQ_INPUT.RANGE) &&
raimund@2555: qs != null && qs.length > 0)
raimund@2555: {
raimund@2555: data = String.valueOf(qs[0]);
raimund@2555: data += " - " + String.valueOf(qs[qs.length-1]);
raimund@2555: }
raimund@2555: else if (input == FLYSUtils.WQ_INPUT.SINGLE && qs != null){
raimund@2555: data = String.valueOf(qs[0]);
raimund@2555: for (int i = 1; i < qs.length; i++) {
raimund@2555: data += ", " + String.valueOf(qs[i]);
raimund@2555: }
ingo@2045: }
ingo@2045: else {
ingo@2045: logger.warn("Could not determine Q range!");
ingo@2045: }
ingo@2045:
ingo@2045: writer.writeNext(new String[] {
ingo@2045: Resources.getMsg(
ingo@2045: meta,
ingo@2045: CSV_META_Q,
ingo@2045: CSV_META_Q,
raimund@2555: new Object[] {data})
ingo@2045: });
ingo@2045: }
ingo@2045: else {
ingo@2045: double[] ws = FLYSUtils.getWs(flys);
ingo@2045:
ingo@2045: String lower = "";
ingo@2045: String upper = "";
ingo@2045:
ingo@2045: if (ws != null && ws.length > 0) {
ingo@2045: lower = String.valueOf(ws[0]);
ingo@2045: upper = String.valueOf(ws[ws.length-1]);
ingo@2045: }
ingo@2045: else {
ingo@2045: logger.warn("Could not determine W range!");
ingo@2045: }
ingo@2045:
ingo@2045: writer.writeNext(new String[] {
ingo@2045: Resources.getMsg(
ingo@2045: meta,
ingo@2045: CSV_META_W,
ingo@2045: CSV_META_W,
ingo@2045: new Object[] { lower, upper })
ingo@2045: });
ingo@2045: }
ingo@2045:
ingo@2045: writer.writeNext(new String[] { "" });
ingo@2045: }
ingo@2045:
ingo@2045:
ingo@2068: protected void writeCSVHeader(
ingo@2068: CSVWriter writer,
ingo@2068: boolean atGauge,
ingo@2068: boolean isQ
ingo@2068: ) {
ingo@416: logger.info("WaterlevelExporter.writeCSVHeader");
ingo@416:
ingo@2065: if (atGauge) {
ingo@2065: writer.writeNext(new String[] {
ingo@2065: msg(CSV_KM_HEADER, DEFAULT_CSV_KM_HEADER),
ingo@2065: msg(CSV_W_HEADER, DEFAULT_CSV_W_HEADER),
ingo@2065: msg(CSV_Q_HEADER, DEFAULT_CSV_Q_HEADER),
ingo@2068: (isQ
ingo@2068: ? msg(CSV_Q_DESC_HEADER, DEFAULT_CSV_Q_DESC_HEADER)
ingo@2068: : msg(CSV_W_DESC_HEADER, DEFAULT_CSV_W_DESC_HEADER)),
ingo@2065: msg(CSV_LOCATION_HEADER, DEFAULT_CSV_LOCATION_HEADER),
ingo@2065: msg(CSV_GAUGE_HEADER, DEFAULT_CSV_GAUGE_HEADER)
ingo@2065: });
ingo@2065: }
ingo@2065: else {
ingo@2065: writer.writeNext(new String[] {
ingo@2065: msg(CSV_KM_HEADER, DEFAULT_CSV_KM_HEADER),
ingo@2065: msg(CSV_W_HEADER, DEFAULT_CSV_W_HEADER),
ingo@2065: msg(CSV_Q_HEADER, DEFAULT_CSV_Q_HEADER),
ingo@2065: msg(CSV_LOCATION_HEADER, DEFAULT_CSV_LOCATION_HEADER)
ingo@2065: });
ingo@2065: }
ingo@416: }
ingo@416:
ingo@416:
felix@3252: /**
felix@3252: * Write "rows" of csv data from wqkms with writer.
felix@3252: */
ingo@2068: protected void wQKms2CSV(
ingo@2068: CSVWriter writer,
ingo@2068: WQKms wqkms,
ingo@2068: boolean atGauge,
felix@3252: boolean isQ
ingo@2068: ) {
ingo@389: logger.debug("WaterlevelExporter.wQKms2CSV");
ingo@389:
ingo@418: NumberFormat kmf = getKmFormatter();
ingo@418: NumberFormat wf = getWFormatter();
ingo@418: NumberFormat qf = getQFormatter();
ingo@418:
ingo@389: int size = wqkms.size();
ingo@389: double[] result = new double[3];
ingo@389:
ingo@2066: FLYSArtifact flys = (FLYSArtifact) master;
ingo@2066: Gauge gauge = FLYSUtils.getGauge(flys);
ingo@2066: String gaugeName = gauge.getName();
ingo@2066: String desc = "";
ingo@2066: String notinrange = msg(
ingo@2066: CSV_NOT_IN_GAUGE_RANGE,
ingo@2066: DEFAULT_CSV_NOT_IN_GAUGE_RANGE);
ingo@2066:
ingo@2066: double a = gauge.getRange().getA().doubleValue();
ingo@2066: double b = gauge.getRange().getB().doubleValue();
ingo@2065:
ingo@2068: if (flys instanceof WINFOArtifact && isQ) {
ingo@2087: desc = getCSVRowTitle((WINFOArtifact)flys, wqkms);
ingo@2065: }
ingo@2068: else if (!isQ) {
ingo@2068: Double value = FLYSUtils.getValueFromWQ(wqkms);
ingo@2068: desc = value != null
ingo@2068: ? Formatter.getWaterlevelW(context).format(value) : null;
ingo@2068: }
ingo@2063:
sascha@2144: long startTime = System.currentTimeMillis();
sascha@2144:
felix@3313: String colDesc = desc;
felix@3313: if (flys instanceof WINFOArtifact) {
felix@3313: if (wqkms != null && wqkms.getRawValue() != null) {
felix@3313: WINFOArtifact winfo = (WINFOArtifact) flys;
felix@3313: colDesc = FLYSUtils.getNamedMainValue(winfo, wqkms.getRawValue());
felix@3313: }
felix@3313: }
sascha@2612:
ingo@389: for (int i = 0; i < size; i ++) {
ingo@389: result = wqkms.get(i, result);
ingo@389:
ingo@2065: if (atGauge) {
ingo@2065: writer.writeNext(new String[] {
ingo@2065: kmf.format(result[2]),
ingo@2065: wf.format(result[0]),
ingo@2065: qf.format(result[1]),
sascha@2612: colDesc,
ingo@2065: FLYSUtils.getLocationDescription(flys, result[2]),
ingo@2066: result[2] >= a && result[2] <= b
ingo@2066: ? gaugeName
ingo@2066: : notinrange
ingo@2065: });
ingo@2065: }
ingo@2065: else {
ingo@2065: writer.writeNext(new String[] {
ingo@2065: kmf.format(result[2]),
ingo@2065: wf.format(result[0]),
ingo@2065: qf.format(result[1]),
ingo@2065: FLYSUtils.getLocationDescription(flys, result[2])
ingo@2065: });
ingo@2065: }
ingo@389: }
sascha@2144:
sascha@2144: long stopTime = System.currentTimeMillis();
sascha@2144:
sascha@2144: if (logger.isDebugEnabled()) {
sascha@2144: logger.debug("Writing CSV took " +
sascha@2144: (float)(stopTime-startTime)/1000f + " secs.");
sascha@2144: }
ingo@389: }
ingo@418:
ingo@418:
ingo@418: /**
ingo@446: * Generates the output in WST format.
ingo@446: */
ingo@446: protected void generateWST()
ingo@446: throws IOException
ingo@446: {
ingo@446: logger.info("WaterlevelExporter.generateWST");
ingo@446:
ingo@446: int cols = data.get(0).length;
ingo@446: WstWriter writer = new WstWriter(cols);
ingo@446:
ingo@446: writeWSTData(writer);
ingo@446:
ingo@446: writer.write(out);
ingo@446: }
ingo@446:
ingo@446:
ingo@446: protected void writeWSTData(WstWriter writer) {
ingo@446: logger.debug("WaterlevelExporter.writeWSTData");
ingo@446:
ingo@749: double[] result = new double[4];
ingo@446:
ingo@446: for (WQKms[] tmp: data) {
ingo@446: for (WQKms wqkms: tmp) {
ingo@446: int size = wqkms != null ? wqkms.size() : 0;
ingo@446:
ingo@450: addWSTColumn(writer, wqkms);
ingo@447:
ingo@446: for (int i = 0; i < size; i++) {
ingo@446: result = wqkms.get(i, result);
ingo@446:
ingo@446: writer.add(result);
ingo@446: }
ingo@749:
ingo@749: if (wqkms instanceof WQCKms) {
ingo@749: addWSTColumn(writer, wqkms);
ingo@749:
ingo@749: for (int c = 0; c < size; c++) {
ingo@749: result = wqkms.get(c, result);
ingo@749:
ingo@749: writer.addCorrected(result);
ingo@749: }
ingo@749: }
ingo@446: }
ingo@446: }
ingo@446: }
ingo@446:
ingo@446:
ingo@2038: /**
ingo@2038: * This method is used to register a new column at writer. The name /
ingo@2038: * title of the column depends on the Q or W value of wqkms. If a Q
ingo@2038: * was selected and the Q fits to a named main value, the title is set to
ingo@2038: * the named main value. Otherwise, the name returned by
ingo@2038: * WQKms.getName() is set.
ingo@2038: *
ingo@2038: * @param writer The WstWriter.
ingo@2038: * @param wqkms The new WST column.
ingo@2038: */
ingo@450: protected void addWSTColumn(WstWriter writer, WQKms wqkms) {
ingo@2038: if (master instanceof WINFOArtifact) {
ingo@2038: writer.addColumn(getColumnTitle((WINFOArtifact) master, wqkms));
ingo@2038: }
ingo@2038: else {
ingo@2038: writer.addColumn(wqkms.getName());
ingo@2038: }
ingo@450: }
ingo@450:
ingo@450:
ingo@446: /**
raimund@2176: *
raimund@2176: */
raimund@2176: @Override
raimund@2176: protected void writePDF(OutputStream out) {
raimund@2176: logger.debug("write PDF");
raimund@2176: WKmsJRDataSource source = createJRData();
raimund@2185:
raimund@2185: String jasperFile = Resources.getMsg(
raimund@2185: context.getMeta(),
raimund@2185: JASPER_FILE,
raimund@2185: "/jasper/waterlevel_en.jasper");
raimund@2185: String confPath = Config.getConfigDirectory().toString();
raimund@2185:
raimund@2185:
raimund@2176: Map parameters = new HashMap();
raimund@2176: parameters.put("ReportTitle", "Exported Data");
raimund@2176: try {
raimund@2176: JasperPrint print = JasperFillManager.fillReport(
raimund@2185: confPath + jasperFile,
raimund@2176: parameters,
raimund@2176: source);
raimund@2176: JasperExportManager.exportReportToPdfStream(print, out);
raimund@2176: }
raimund@2176: catch(JRException je) {
raimund@2176: logger.warn("Error generating PDF Report!");
raimund@2176: je.printStackTrace();
raimund@2176: }
raimund@2176: }
raimund@2176:
raimund@2176: protected WKmsJRDataSource createJRData() {
raimund@2176: WKmsJRDataSource source = new WKmsJRDataSource();
raimund@2176:
raimund@2176: WQ_MODE mode = FLYSUtils.getWQMode((FLYSArtifact)master);
raimund@2176: boolean atGauge = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.WGAUGE;
raimund@2176: boolean isQ = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.QFREE;
raimund@2176:
raimund@2176: addMetaData(source);
raimund@2176: for (WQKms[] tmp: data) {
raimund@2176: for (WQKms wqkms: tmp) {
raimund@2176: addWKmsData(wqkms, atGauge, isQ, source);
raimund@2176: }
raimund@2176: }
raimund@2176: return source;
raimund@2176: }
raimund@2176:
raimund@2176: protected void addMetaData(WKmsJRDataSource source) {
raimund@2176: CallMeta meta = context.getMeta();
raimund@2176:
raimund@2176: FLYSArtifact flys = (FLYSArtifact) master;
raimund@2176:
raimund@2176: source.addMetaData ("river", FLYSUtils.getRivername(flys));
raimund@2176:
raimund@2176: Locale locale = Resources.getLocale(meta);
raimund@2176: DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
raimund@2176:
raimund@2176: source.addMetaData("date", df.format(new Date()));
raimund@2176:
raimund@2176: double[] kms = FLYSUtils.getKmRange(flys);
raimund@2176: source.addMetaData("range", kms[0] + " - " + kms[kms.length-1]);
raimund@2176:
raimund@2176: source.addMetaData("gauge", FLYSUtils.getGaugename(flys));
raimund@2176:
raimund@2176: source.addMetaData("calculation", Resources.getMsg(
raimund@2176: locale,
raimund@2176: PDF_HEADER_MODE,
raimund@2176: "Waterlevel"));
raimund@2176: }
raimund@2176:
raimund@2176: protected void addWKmsData(
raimund@2176: WQKms wqkms,
raimund@2176: boolean atGauge,
raimund@2176: boolean isQ,
raimund@2176: WKmsJRDataSource source)
raimund@2176: {
raimund@2176: logger.debug("WaterlevelExporter.addWKmsData");
raimund@2176:
raimund@2176: NumberFormat kmf = getKmFormatter();
raimund@2176: NumberFormat wf = getWFormatter();
raimund@2176: NumberFormat qf = getQFormatter();
raimund@2176:
raimund@2176: int size = wqkms.size();
raimund@2176: double[] result = new double[3];
raimund@2176:
raimund@2176: FLYSArtifact flys = (FLYSArtifact) master;
raimund@2176: Gauge gauge = FLYSUtils.getGauge(flys);
raimund@2176: String gaugeName = gauge.getName();
raimund@2176: String desc = "";
raimund@2176: String notinrange = msg(
raimund@2176: CSV_NOT_IN_GAUGE_RANGE,
raimund@2176: DEFAULT_CSV_NOT_IN_GAUGE_RANGE);
raimund@2176:
raimund@2176: double a = gauge.getRange().getA().doubleValue();
raimund@2176: double b = gauge.getRange().getB().doubleValue();
raimund@2176:
raimund@2176: if (flys instanceof WINFOArtifact && isQ) {
raimund@2176: desc = getCSVRowTitle((WINFOArtifact)flys, wqkms);
raimund@2176: }
raimund@2176: else if (!isQ) {
raimund@2176: Double value = FLYSUtils.getValueFromWQ(wqkms);
raimund@2176: desc = value != null
raimund@2176: ? Formatter.getWaterlevelW(context).format(value) : null;
raimund@2176: }
raimund@2176:
raimund@2176: long startTime = System.currentTimeMillis();
raimund@2176:
raimund@2176: for (int i = 0; i < size; i ++) {
raimund@2176: result = wqkms.get(i, result);
raimund@2176:
raimund@2176: if (atGauge) {
raimund@2176: source.addData(new String[] {
raimund@2176: kmf.format(result[2]),
raimund@2176: wf.format(result[0]),
raimund@2176: qf.format(result[1]),
raimund@2176: desc,
raimund@2176: FLYSUtils.getLocationDescription(flys, result[2]),
raimund@2176: result[2] >= a && result[2] <= b
raimund@2176: ? gaugeName
raimund@2176: : notinrange
raimund@2176: });
raimund@2176: }
raimund@2176: else {
raimund@2176: source.addData(new String[] {
raimund@2176: kmf.format(result[2]),
raimund@2176: wf.format(result[0]),
raimund@2176: qf.format(result[1]),
raimund@2764: desc,
raimund@2764: FLYSUtils.getLocationDescription(flys, result[2]),
raimund@2764: result[2] >= a && result[2] <= b
raimund@2764: ? gaugeName
raimund@2764: : notinrange
raimund@2176: });
raimund@2176: }
raimund@2176: }
raimund@2176:
raimund@2176: long stopTime = System.currentTimeMillis();
raimund@2176:
raimund@2176: if (logger.isDebugEnabled()) {
raimund@2176: logger.debug("Writing PDF data took " +
raimund@2176: (float)(stopTime-startTime)/1000f + " secs.");
raimund@2176: }
raimund@2176: }
ingo@389: }
ingo@389: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :