changeset 2176:65dac9cf6ff5

Issue 138. PDF output for waterlevel calculation result. flys-artifacts/trunk@3774 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Raimund Renkert <raimund.renkert@intevation.de>
date Thu, 26 Jan 2012 15:38:46 +0000
parents 3f90f4d37c8d
children 28dbeb64ce7c
files flys-artifacts/ChangeLog flys-artifacts/doc/conf/artifacts/winfo.xml flys-artifacts/doc/conf/jasper/waterlevel.jasper flys-artifacts/pom.xml flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WKmsJRDataSource.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WaterlevelState.java flys-artifacts/src/main/java/de/intevation/flys/exports/AbstractExporter.java flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveExporter.java flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveExporter.java flys-artifacts/src/main/java/de/intevation/flys/exports/WDifferencesExporter.java flys-artifacts/src/main/java/de/intevation/flys/exports/WaterlevelExporter.java flys-artifacts/src/main/resources/messages.properties flys-artifacts/src/main/resources/messages_de.properties flys-artifacts/src/main/resources/messages_de_DE.properties flys-artifacts/src/main/resources/messages_en.properties
diffstat 16 files changed, 356 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/ChangeLog	Thu Jan 26 15:38:46 2012 +0000
@@ -1,3 +1,45 @@
+2012-01-26  Raimund Renkert <raimund.renkert@intevation.de>
+
+	Issue 138: PDF output for calculations.
+
+	* pom.xml: New Dependency to net.sf.jasperreports/jasperreports and
+	  org.codehaus.groovy/groovy-all.
+
+	* src/main/java/de/intevation/flys/exports/AbstractExporter.java:
+	  Added methods for PDF generation.
+
+	* src/main/java/de/intevation/flys/exports/WaterlevelExporter.java:
+	  Create the PDF data source and generate the PDF report output.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WKmsJRDataSource.java:
+	  New. Data source for jasper reports containing the waterlevel calculation
+	  result.
+
+	* src/main/java/de/intevation/flys/artifacts/states/WaterlevelState.java:
+	  Added facet for PDF export to state.
+
+	* src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java:
+	  Added PDF facet type.
+
+	* src/main/java/de/intevation/flys/exports/DurationCurveExporter.java,
+	  src/main/java/de/intevation/flys/exports/ComputedDischargeCurveExporter.java,
+	  src/main/java/de/intevation/flys/exports/WDifferencesExporter.java:
+	  Added stub for inherited abstract method.
+
+	* doc/conf/artifacts/winfo.xml:
+	  Added PDF facet to outputmode 'export'.
+
+	* doc/conf/jasper,
+	  doc/conf/jasper/waterlevel.jasper:
+	  New. Folder for jasperreports templates and first template for
+	  waterlevel report.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Added i18n string for calculation mode.
+
 2012-01-26  Felix Wolfsteller	<felix.wolfsteller@intevation.de>
 
 	Renderer 'manual' points in LongitudinalSectionGenerator.
--- a/flys-artifacts/doc/conf/artifacts/winfo.xml	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/doc/conf/artifacts/winfo.xml	Thu Jan 26 15:38:46 2012 +0000
@@ -285,6 +285,7 @@
                   <facets>
                     <facet name="csv" description="facet.waterlevel_export.csv" />
                     <facet name="wst" description="facet.waterlevel_export.wst" />
+                    <facet name="pdf" description="facet.waterlevel_export.pdf" />
                   </facets>
                 </outputmode>
                 <outputmode name="waterlevel_report" description="output.waterlevel_report" mime-type="text/xml" type="report">
Binary file flys-artifacts/doc/conf/jasper/waterlevel.jasper has changed
--- a/flys-artifacts/pom.xml	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/pom.xml	Thu Jan 26 15:38:46 2012 +0000
@@ -130,6 +130,16 @@
       <artifactId>velocity</artifactId>
       <version>1.7</version>
     </dependency>
+    <dependency>
+      <groupId>net.sf.jasperreports</groupId>
+      <artifactId>jasperreports</artifactId>
+      <version>4.5.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.groovy</groupId>
+      <artifactId>groovy-all</artifactId>
+      <version>1.6.0</version>
+    </dependency>
   </dependencies>
   <repositories>
     <repository>
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java	Thu Jan 26 15:38:46 2012 +0000
@@ -93,6 +93,7 @@
     String CSV = "csv";
     String WST = "wst";
     String AT  = "at";
+    String PDF = "pdf";
 
     String REPORT = "report";
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WKmsJRDataSource.java	Thu Jan 26 15:38:46 2012 +0000
@@ -0,0 +1,108 @@
+package de.intevation.flys.artifacts.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.apache.log4j.Logger;
+
+import net.sf.jasperreports.engine.JRDataSource;
+import net.sf.jasperreports.engine.JRException;
+import net.sf.jasperreports.engine.JRField;
+
+
+/**
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class WKmsJRDataSource implements JRDataSource
+{
+    /** The logger used in this exporter.*/
+    private static Logger logger = Logger.getLogger(WKmsJRDataSource.class);
+
+    /**
+     *
+     */
+    private ArrayList<String[]> data;
+    private HashMap<String, String> metaData;
+
+    private int index = -1;
+
+    /**
+     *
+     */
+    public WKmsJRDataSource()
+    {
+        data = new ArrayList<String[]>();
+        metaData = new HashMap<String, String>();
+    }
+
+
+    /**
+     *
+     */
+    public void addData(String[] data) {
+        this.data.add(data);
+    }
+
+
+    /**
+     *
+     */
+    public void addMetaData(String key, String value) {
+        this.metaData.put(key, value);
+    }
+
+
+    /**
+     *
+     */
+    public boolean next() throws JRException
+    {
+        index++;
+
+        return (index < data.size());
+    }
+
+
+    /**
+     *
+     */
+    public Object getFieldValue(JRField field) throws JRException
+    {
+        Object value = "";
+        String fieldName = field.getName();
+        if ("river".equals(fieldName)) {
+            value = metaData.get("river");
+        }
+        if ("date".equals(fieldName)) {
+            value = metaData.get("date");
+        }
+        if ("range".equals(fieldName)) {
+            value = metaData.get("range");
+        }
+        if ("gauge".equals(fieldName)) {
+            value = metaData.get("gauge");
+        }
+        if ("calculation".equals(fieldName)) {
+            value = metaData.get("calculation");
+        }
+        if ("km".equals(fieldName)) {
+            value = data.get(index)[0];
+        }
+        if ("W".equals(fieldName)) {
+            value = data.get(index)[1];
+        }
+        if ("Q".equals(fieldName)) {
+            value = data.get(index)[2];
+        }
+        if ("description".equals(fieldName)) {
+            value = data.get(index)[3];
+        }
+        if ("location".equals(fieldName)) {
+            value = data.get(index)[4];
+        }
+        if ("gaugename".equals(fieldName)) {
+            value = data.get(index)[5];
+        }
+        return value;
+    }
+}
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WaterlevelState.java	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WaterlevelState.java	Thu Jan 26 15:38:46 2012 +0000
@@ -89,9 +89,12 @@
                 WST, "WST data", ComputeType.ADVANCE, hash, id);
             Facet csv = new DataFacet(
                 CSV, "CSV data", ComputeType.ADVANCE, hash, id);
+            Facet pdf = new DataFacet(
+                PDF, "PDF data", ComputeType.ADVANCE, hash, id);
 
             facets.add(wst);
             facets.add(csv);
+            facets.add(pdf);
         }
 
         if (res.getReport().hasProblems()) {
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/AbstractExporter.java	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/AbstractExporter.java	Thu Jan 26 15:38:46 2012 +0000
@@ -37,6 +37,9 @@
     /** The name of the CSV facet which triggers the CSV creation. */
     public static final String FACET_CSV = "csv";
 
+    /** The name of the PDF facet which triggers the PDF creation. */
+    public static final String FACET_PDF = "pdf";
+
     /** The default charset for the CSV export. */
     public static final String DEFAULT_CSV_CHARSET = "UTF-8";
 
@@ -73,6 +76,13 @@
 
 
     /**
+     * Concrete subclasses need to use this method to write their special data
+     * objects into the PDF document.
+     */
+    protected abstract void writePDF(OutputStream out);
+
+
+    /**
      * This method enables concrete subclasses to collected its own special
      * data.
      *
@@ -140,6 +150,9 @@
         if (facet != null && facet.equals(FACET_CSV)) {
             generateCSV();
         }
+        else if (facet != null && facet.equals(FACET_PDF)) {
+            generatePDF();
+        }
         else {
             throw new IOException("invalid facet for exporter.");
         }
@@ -223,6 +236,17 @@
 
 
     /**
+     * This method starts PDF creation.
+     */
+    protected void generatePDF()
+    throws    IOException
+    {
+        logger.info("AbstractExporter.generatePDF");
+        writePDF(this.out);
+    }
+
+
+    /**
      * Returns an instance of <i>EmptySettings</i> currently!
      *
      * @return an instance of <i>EmptySettings</i>.
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveExporter.java	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveExporter.java	Thu Jan 26 15:38:46 2012 +0000
@@ -116,5 +116,9 @@
     protected NumberFormat getQFormatter() {
         return Formatter.getComputedDischargeQ(context);
     }
+
+
+    @Override
+    protected void writePDF(OutputStream out) {}
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveExporter.java	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveExporter.java	Thu Jan 26 15:38:46 2012 +0000
@@ -146,4 +146,9 @@
     protected NumberFormat getDFormatter() {
         return Formatter.getDurationD(context);
     }
+
+
+    @Override
+    protected void writePDF(OutputStream out) {}
+
 }
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/WDifferencesExporter.java	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/WDifferencesExporter.java	Thu Jan 26 15:38:46 2012 +0000
@@ -157,5 +157,9 @@
     protected NumberFormat getWFormatter() {
         return Formatter.getWaterlevelW(context);
     }
+
+
+    @Override
+    protected void writePDF(OutputStream out) {}
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/WaterlevelExporter.java	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/WaterlevelExporter.java	Thu Jan 26 15:38:46 2012 +0000
@@ -5,6 +5,8 @@
 import java.text.DateFormat;
 import java.text.NumberFormat;
 import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
 import java.util.Date;
 import java.util.List;
 import java.util.Locale;
@@ -17,6 +19,12 @@
 
 import au.com.bytecode.opencsv.CSVWriter;
 
+import net.sf.jasperreports.engine.JRDataSource;
+import net.sf.jasperreports.engine.JasperExportManager;
+import net.sf.jasperreports.engine.JasperFillManager;
+import net.sf.jasperreports.engine.JasperPrint;
+import net.sf.jasperreports.engine.JRException;
+
 import de.intevation.artifacts.CallContext;
 import de.intevation.artifacts.CallMeta;
 
@@ -27,6 +35,7 @@
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.WQCKms;
 import de.intevation.flys.artifacts.model.WQKms;
+import de.intevation.flys.artifacts.model.WKmsJRDataSource;
 import de.intevation.flys.artifacts.resources.Resources;
 
 import de.intevation.flys.utils.FLYSUtils;
@@ -108,6 +117,7 @@
     public static final String DEFAULT_CSV_NOT_IN_GAUGE_RANGE =
         "außerhalb des gewählten Bezugspegels";
 
+    public static final String PDF_HEADER_MODE = "export.waterlevel.pdf.mode";
 
     /** The storage that contains all WQKms objects for the different facets.*/
     protected List<WQKms[]> data;
@@ -134,6 +144,9 @@
         else if (facet != null && facet.equals(FACET_WST)) {
             generateWST();
         }
+        else if (facet != null && facet.equals(AbstractExporter.FACET_PDF)) {
+            generatePDF();
+        }
         else {
             throw new IOException("invalid facet for exporter");
         }
@@ -570,5 +583,138 @@
     protected NumberFormat getQFormatter() {
         return Formatter.getWaterlevelQ(context);
     }
+
+
+    /**
+     *
+     */
+    @Override
+    protected void writePDF(OutputStream out) {
+        logger.debug("write PDF");
+        WKmsJRDataSource source = createJRData();
+        Map parameters = new HashMap();
+        parameters.put("ReportTitle", "Exported Data");
+        try {
+            JasperPrint print = JasperFillManager.fillReport(
+                "conf/jasper/waterlevel.jasper",
+                parameters,
+                source);
+            JasperExportManager.exportReportToPdfStream(print, out);
+        }
+        catch(JRException je) {
+            logger.warn("Error generating PDF Report!");
+            je.printStackTrace();
+        }
+    }
+
+    protected WKmsJRDataSource createJRData() {
+        WKmsJRDataSource source = new WKmsJRDataSource();
+
+        WQ_MODE mode    = FLYSUtils.getWQMode((FLYSArtifact)master);
+        boolean atGauge = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.WGAUGE;
+        boolean isQ     = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.QFREE;
+
+        addMetaData(source);
+        for (WQKms[] tmp: data) {
+            for (WQKms wqkms: tmp) {
+                addWKmsData(wqkms, atGauge, isQ, source);
+            }
+        }
+        return source;
+    }
+
+    protected void addMetaData(WKmsJRDataSource source) {
+        CallMeta meta = context.getMeta();
+
+        FLYSArtifact flys = (FLYSArtifact) master;
+
+        source.addMetaData ("river", FLYSUtils.getRivername(flys));
+
+        Locale locale = Resources.getLocale(meta);
+        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+
+        source.addMetaData("date", df.format(new Date()));
+
+        double[] kms = FLYSUtils.getKmRange(flys);
+        source.addMetaData("range", kms[0] + " - " + kms[kms.length-1]);
+
+        source.addMetaData("gauge", FLYSUtils.getGaugename(flys));
+
+        source.addMetaData("calculation", Resources.getMsg(
+                                            locale,
+                                            PDF_HEADER_MODE,
+                                            "Waterlevel"));
+    }
+
+    protected void addWKmsData(
+        WQKms wqkms,
+        boolean atGauge,
+        boolean isQ,
+        WKmsJRDataSource source)
+    {
+        logger.debug("WaterlevelExporter.addWKmsData");
+
+        NumberFormat kmf = getKmFormatter();
+        NumberFormat wf  = getWFormatter();
+        NumberFormat qf  = getQFormatter();
+
+        int      size   = wqkms.size();
+        double[] result = new double[3];
+
+        FLYSArtifact flys       = (FLYSArtifact) master;
+        Gauge        gauge      = FLYSUtils.getGauge(flys);
+        String       gaugeName  = gauge.getName();
+        String       desc       = "";
+        String       notinrange = msg(
+            CSV_NOT_IN_GAUGE_RANGE,
+            DEFAULT_CSV_NOT_IN_GAUGE_RANGE);
+
+        double a = gauge.getRange().getA().doubleValue();
+        double b = gauge.getRange().getB().doubleValue();
+
+        if (flys instanceof WINFOArtifact && isQ) {
+            desc = getCSVRowTitle((WINFOArtifact)flys, wqkms);
+        }
+        else if (!isQ) {
+            Double value = FLYSUtils.getValueFromWQ(wqkms);
+            desc         = value != null
+                ? Formatter.getWaterlevelW(context).format(value) : null;
+        }
+
+        long startTime = System.currentTimeMillis();
+
+        for (int i = 0; i < size; i ++) {
+            result = wqkms.get(i, result);
+
+            if (atGauge) {
+                source.addData(new String[] {
+                    kmf.format(result[2]),
+                    wf.format(result[0]),
+                    qf.format(result[1]),
+                    desc,
+                    FLYSUtils.getLocationDescription(flys, result[2]),
+                    result[2] >= a && result[2] <= b
+                        ? gaugeName
+                        : notinrange
+                });
+            }
+            else {
+                source.addData(new String[] {
+                    kmf.format(result[2]),
+                    wf.format(result[0]),
+                    qf.format(result[1]),
+                    FLYSUtils.getLocationDescription(flys, result[2])
+                });
+            }
+        }
+
+        long stopTime = System.currentTimeMillis();
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("Writing PDF data took " +
+                (float)(stopTime-startTime)/1000f + " secs.");
+        }
+
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/resources/messages.properties	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/src/main/resources/messages.properties	Thu Jan 26 15:38:46 2012 +0000
@@ -107,6 +107,8 @@
 export.discharge.longitudinal.section.csv.header.q = Q [m\u00b3/s]
 export.discharge.curve.at.header = Computed Discharge Curve for {0} {0}-km: {1}
 
+export.waterlevel.pdf.mode = Waterlevel
+
 floodmap.wmsbackground = Background Map
 floodmap.riveraxis = River Axis
 floodmap.uesk = Floodmap
--- a/flys-artifacts/src/main/resources/messages_de.properties	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/src/main/resources/messages_de.properties	Thu Jan 26 15:38:46 2012 +0000
@@ -107,6 +107,8 @@
 export.discharge.longitudinal.section.csv.header.q = Q [m\u00b3/s]
 export.discharge.curve.at.header = Berechnete Abflusskurve f\u00fcr {0} {0}-km: {1}
 
+export.waterlevel.pdf.mode = Wasserstand
+
 floodmap.wmsbackground = Hintergrundkarte
 floodmap.riveraxis = Flussachse
 floodmap.uesk = \u00dcberschwemmungsfl\u00e4che
--- a/flys-artifacts/src/main/resources/messages_de_DE.properties	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/src/main/resources/messages_de_DE.properties	Thu Jan 26 15:38:46 2012 +0000
@@ -107,6 +107,8 @@
 export.discharge.longitudinal.section.csv.header.q = Q [m\u00b3/s]
 export.discharge.curve.at.header = Berechnete Abflusskurve f\u00fcr {0} {0}-km: {1}
 
+export.waterlevel.pdf.mode = Wasserstand
+
 floodmap.wmsbackground = Hintergrundkarte
 floodmap.riveraxis = Flussachse
 floodmap.uesk = \u00dcberschwemmungsfl\u00e4che
--- a/flys-artifacts/src/main/resources/messages_en.properties	Thu Jan 26 13:12:19 2012 +0000
+++ b/flys-artifacts/src/main/resources/messages_en.properties	Thu Jan 26 15:38:46 2012 +0000
@@ -103,6 +103,8 @@
 export.discharge.longitudinal.section.csv.header.q = Q [m\u00b3/s]
 export.discharge.curve.at.header = Computed Discharge Curve for {0} {0}-km: {1}
 
+export.waterlevel.pdf.mode = Waterlevel
+
 floodmap.wmsbackground = Background Map
 floodmap.riveraxis = River Axis
 floodmap.uesk = Floodmap

http://dive4elements.wald.intevation.org