andre@8578: /* Copyright (C) 2011, 2012, 2013, 2015 by Bundesanstalt für Gewässerkunde
teichmann@5863: * Software engineering by Intevation GmbH
teichmann@5863: *
teichmann@5994: * This file is Free Software under the GNU AGPL (>=v3)
teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the
teichmann@5994: * documentation coming with Dive4Elements River for details.
teichmann@5863: */
teichmann@5863:
teichmann@5831: package org.dive4elements.river.exports.sq;
ingo@3077:
ingo@3077: import java.io.OutputStream;
ingo@3077: import java.util.ArrayList;
ingo@3077: import java.util.List;
aheinecke@6172: import java.util.Map;
aheinecke@6172: import java.util.HashMap;
aheinecke@6172: import java.util.Date;
aheinecke@6172: import java.util.Locale;
aheinecke@6172: import java.text.DateFormat;
aheinecke@6828: import java.text.NumberFormat;
ingo@3077:
aheinecke@6172: import net.sf.jasperreports.engine.JasperExportManager;
aheinecke@6172: import net.sf.jasperreports.engine.JasperFillManager;
aheinecke@6172: import net.sf.jasperreports.engine.JasperPrint;
andre@8578: import net.sf.jasperreports.engine.JRPrintPage;
aheinecke@6172: import net.sf.jasperreports.engine.JRException;
aheinecke@6172:
ingo@3077: import au.com.bytecode.opencsv.CSVWriter;
ingo@3077:
aheinecke@6172: import org.dive4elements.artifacts.CallMeta;
sascha@3392:
teichmann@5831: import org.dive4elements.river.artifacts.model.CalculationResult;
teichmann@5831: import org.dive4elements.river.artifacts.model.sq.SQFractionResult;
teichmann@5831: import org.dive4elements.river.artifacts.model.sq.SQResult;
andre@8541: import org.dive4elements.river.artifacts.model.sq.SQ;
aheinecke@6172: import org.dive4elements.river.artifacts.model.sq.SQRelationJRDataSource;
andre@8578: import org.dive4elements.river.artifacts.model.sq.SQMeasurementsJRDataSource;
teichmann@5831: import org.dive4elements.river.artifacts.model.Parameters;
aheinecke@6172: import org.dive4elements.river.artifacts.model.DateRange;
aheinecke@6172: import org.dive4elements.river.artifacts.access.SQRelationAccess;
aheinecke@6172:
aheinecke@6172: import org.dive4elements.river.artifacts.resources.Resources;
aheinecke@6172:
aheinecke@6172: import org.dive4elements.river.artifacts.D4EArtifact;
teichmann@5831:
teichmann@5831: import org.dive4elements.river.exports.AbstractExporter;
ingo@3077:
aheinecke@6172: import org.dive4elements.river.utils.RiverUtils;
aheinecke@6172: import org.dive4elements.river.utils.Formatter;
aheinecke@6172:
aheinecke@6172: import org.dive4elements.artifacts.common.utils.Config;
aheinecke@6172:
sascha@3392: import org.apache.log4j.Logger;
ingo@3077:
ingo@3077: /**
ingo@3077: * @author Ingo Weinzierl
ingo@3077: */
ingo@3077: public class SQRelationExporter extends AbstractExporter {
ingo@3077:
teichmann@8202: /** Private log. */
teichmann@8202: private static final Logger log =
ingo@3077: Logger.getLogger(SQRelationExporter.class);
ingo@3077:
tom@7937: public static final String INFO_COEFF_A =
tom@7937: "export.sqrelation.csv.info.coeff.a";
tom@7937:
tom@7937: public static final String INFO_COEFF_B =
tom@7937: "export.sqrelation.csv.info.coeff.b";
tom@7937:
tom@7937: public static final String INFO_QMAX =
tom@7937: "export.sqrelation.csv.info.qmax";
tom@7937:
tom@7965: public static final String INFO_STDERR =
tom@7965: "export.sqrelation.csv.info.stderr";
tom@7965:
tom@7937: public static final String INFO_R2 =
tom@7937: "export.sqrelation.csv.info.r2";
tom@7937:
tom@7937: public static final String INFO_NTOT =
tom@7937: "export.sqrelation.csv.info.ntot";
tom@7937:
tom@7937: public static final String INFO_NOUTL =
tom@7937: "export.sqrelation.csv.info.noutl";
tom@7937:
tom@7937: public static final String INFO_CFERGUSON =
tom@7937: "export.sqrelation.csv.info.cferguson";
tom@7937:
tom@7937: public static final String INFO_CDUAN =
tom@7937: "export.sqrelation.csv.info.cduan";
tom@7937:
tom@7937: public static final String INFO_PARAM_A =
tom@7937: "export.sqrelation.csv.info.param.a";
tom@7937:
tom@7937: public static final String INFO_PARAM_B =
tom@7937: "export.sqrelation.csv.info.param.b";
tom@7937:
tom@7937: public static final String INFO_PARAM_C =
tom@7937: "export.sqrelation.csv.info.param.c";
tom@7937:
tom@7937: public static final String INFO_PARAM_D =
tom@7937: "export.sqrelation.csv.info.param.d";
tom@7937:
tom@7937: public static final String INFO_PARAM_E =
tom@7937: "export.sqrelation.csv.info.param.e";
tom@7937:
tom@7937: public static final String INFO_PARAM_F =
tom@7937: "export.sqrelation.csv.info.param.f";
ingo@3077:
andre@8541: public static final String INFO_Q =
andre@8541: "export.sqrelation.csv.info.q";
andre@8541:
andre@8541: public static final String INFO_S_KG =
andre@8541: "export.sqrelation.csv.info.s_kg";
andre@8541:
andre@8541: public static final String INFO_DATE =
andre@8541: "export.sqrelation.csv.info.date";
andre@8541:
ingo@3077: public static final String CSV_PARAMETER =
ingo@3077: "export.sqrelation.csv.header.parameter";
ingo@3077:
ingo@3077: public static final String CSV_STATION =
ingo@3077: "export.sqrelation.csv.header.station";
ingo@3077:
ingo@3077: public static final String CSV_KM =
ingo@3077: "export.sqrelation.csv.header.km";
ingo@3077:
ingo@3077: public static final String CSV_FUNCTION =
ingo@3077: "export.sqrelation.csv.header.function";
ingo@3077:
ingo@3077: public static final String CSV_GAUGE =
ingo@3077: "export.sqrelation.csv.header.gauge";
ingo@3077:
ingo@3077: public static final String CSV_COEFF_A =
ingo@3077: "export.sqrelation.csv.header.coeff.a";
ingo@3077:
ingo@3077: public static final String CSV_COEFF_B =
ingo@3077: "export.sqrelation.csv.header.coeff.b";
ingo@3077:
ingo@3077: public static final String CSV_COEFF_Q =
ingo@3077: "export.sqrelation.csv.header.coeff.q";
ingo@3077:
ingo@3077: public static final String CSV_COEFF_R =
ingo@3077: "export.sqrelation.csv.header.coeff.r";
ingo@3077:
ingo@3077: public static final String CSV_N_TOTAL =
ingo@3077: "export.sqrelation.csv.header.n.total";
ingo@3077:
ingo@3077: public static final String CSV_N_OUTLIERS =
ingo@3077: "export.sqrelation.csv.header.n.outliers";
ingo@3077:
ingo@3077: public static final String CSV_C_DUAN =
ingo@3077: "export.sqrelation.csv.header.c.duan";
ingo@3077:
ingo@3077: public static final String CSV_C_FERGUSON =
ingo@3077: "export.sqrelation.csv.header.c.ferguson";
ingo@3077:
aheinecke@6828: public static final String CSV_QMAX =
aheinecke@6828: "export.sqrelation.csv.header.qmax";
aheinecke@6828:
aheinecke@6828: public static final String CSV_SD =
aheinecke@6828: "export.sqrelation.csv.header.sd";
ingo@3077:
andre@8541: public static final String CSV_S_KG =
andre@8541: "export.sqrelation.csv.header.s_kg";
andre@8541:
andre@8541: public static final String CSV_Q =
andre@8541: "export.sqrelation.csv.header.q";
andre@8541:
andre@8541: public static final String CSV_DATE =
andre@8541: "export.sqrelation.csv.header.date";
andre@8541:
aheinecke@6172: public static final String PDF_TITLE=
aheinecke@6172: "export.sqrelation.pdf.title";
aheinecke@6172:
aheinecke@6172: public static final String PDF_HEADER_MODE =
aheinecke@6172: "export.sqrelation.pdf.mode";
aheinecke@6172:
aheinecke@6172: public static final String JASPER_FILE =
aheinecke@6172: "export.sqrelation.pdf.file";
ingo@3077:
andre@8578: public static final String JASPER_MEASUREMENTS_FILE =
andre@8578: "export.sqrelation.measurements.pdf.file";
andre@8578:
sascha@3392: protected List data;
ingo@3077:
teichmann@7077: public SQRelationExporter() {
sascha@3392: data = new ArrayList();
ingo@3077: }
ingo@3077:
ingo@3077: @Override
ingo@3077: protected void addData(Object d) {
ingo@3077: if (d instanceof CalculationResult) {
sascha@3392: d = ((CalculationResult)d).getData();
sascha@3392: if (d instanceof SQResult []) {
sascha@3392: data.add((SQResult [])d);
ingo@3077: }
ingo@3077: }
ingo@3077: }
ingo@3077:
sascha@3392: protected void writeCSVHeader(CSVWriter writer) {
sascha@3392: writer.writeNext(new String[] {
tom@7936: msg(CSV_KM),
tom@7936: msg(CSV_PARAMETER),
tom@7936: msg(CSV_COEFF_A),
tom@7936: msg(CSV_COEFF_B),
tom@7936: msg(CSV_SD),
tom@7936: msg(CSV_QMAX),
tom@7936: msg(CSV_COEFF_R),
tom@7936: msg(CSV_N_TOTAL),
tom@7936: msg(CSV_N_OUTLIERS),
tom@7936: msg(CSV_C_DUAN),
andre@8541: msg(CSV_C_FERGUSON),
andre@8541: msg(CSV_S_KG),
andre@8541: msg(CSV_Q),
andre@8541: msg(CSV_DATE)
sascha@3392: });
sascha@3392: }
ingo@3077:
ingo@3077: @Override
ingo@3077: protected void writeCSVData(CSVWriter writer) {
teichmann@8202: log.debug("writeCSVData");
ingo@3077:
tom@7937: writeCSVInfo(writer, new String[] {
tom@7937: msg(INFO_COEFF_A),
tom@7937: msg(INFO_COEFF_B),
tom@7937: msg(INFO_QMAX),
tom@7965: msg(INFO_STDERR),
tom@7937: msg(INFO_R2),
tom@7937: msg(INFO_NTOT),
tom@7937: msg(INFO_NOUTL),
tom@7937: msg(INFO_CFERGUSON),
tom@7937: msg(INFO_CDUAN),
tom@7937: msg(INFO_PARAM_A),
tom@7937: msg(INFO_PARAM_B),
tom@7937: msg(INFO_PARAM_C),
tom@7937: msg(INFO_PARAM_D),
tom@7937: msg(INFO_PARAM_E),
andre@8541: msg(INFO_PARAM_F),
andre@8541: msg(INFO_S_KG),
andre@8541: msg(INFO_Q),
andre@8541: msg(INFO_DATE)
tom@7937: });
tom@7937:
ingo@3077: writeCSVHeader(writer);
ingo@3077:
sascha@3392: for (SQResult [] results: data) {
sascha@3392: for (SQResult result: results) {
andre@8578: writer.writeAll(data2StringArrays(result, true));
sascha@3392: }
ingo@3077: }
ingo@3077: }
ingo@3077:
andre@8578: protected List data2StringArrays(SQResult result, boolean includeMeasurements) {
aheinecke@6322: String km = Formatter.getSQRelationKM(context
aheinecke@6322: ).format(result.getKm());
aheinecke@6172: List retval = new ArrayList();
ingo@3077:
aheinecke@6828: NumberFormat sqAFormatter = Formatter.getSQRelationA(context);
aheinecke@6828: NumberFormat sqBFormatter = Formatter.getSQRelationB(context);
aheinecke@6828: NumberFormat fThreeFormatter = Formatter.getFormatter(context, 3, 3);
aheinecke@6828: NumberFormat fTwoFormatter = Formatter.getFormatter(context, 2, 2);
aheinecke@6828: NumberFormat fZeroFormatter = Formatter.getFormatter(context, 0, 0);
andre@8541: DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT,
andre@8541: Resources.getLocale(context.getMeta()));
aheinecke@6828:
sascha@3392: for (int i = 0; i < SQResult.NUMBER_FRACTIONS; ++i) {
sascha@3392: SQFractionResult fraction = result.getFraction(i);
sascha@3552:
sascha@3552: String name = result.getFractionName(i);
sascha@3552:
sascha@3552: Parameters parameters = fraction.getParameters();
sascha@3552:
sascha@3552: if (parameters == null) {
sascha@3392: continue;
sascha@3392: }
sascha@3552:
aheinecke@6828: String a, b, sd, o, t, max_q, c_ferguson, c_duan, r2;
aheinecke@6828: a = sqAFormatter.format(parameters.getValue(0, "a"));
aheinecke@6828: b = sqBFormatter.format(parameters.getValue(0, "b"));
aheinecke@6828:
aheinecke@6828: /* The std_dev parameter contains the standard error actually */
aheinecke@6828: sd = fThreeFormatter.format(parameters.getValue(0, "std_dev"));
aheinecke@6828: max_q = fZeroFormatter.format(parameters.getValue(0, "max_q"));
aheinecke@6828: c_ferguson = fTwoFormatter.format(parameters.getValue(0, "c_ferguson"));
aheinecke@6828: c_duan = fTwoFormatter.format(parameters.getValue(0, "c_duan"));
aheinecke@6828: r2 = fTwoFormatter.format(parameters.getValue(0, "r2"));
aheinecke@6828:
sascha@3552:
aheinecke@6172: o = String.valueOf(fraction.totalNumOutliers());
teichmann@7640: t = String.valueOf(fraction.numMeasurements());
aheinecke@6172:
andre@8578: if (includeMeasurements) {
andre@8578: for (SQ sq: fraction.getMeasurements()) {
andre@8578: retval.add(new String[] {
andre@8578: km,
andre@8578: name,
andre@8578: a,
andre@8578: b,
andre@8578: sd, // 4
andre@8578: max_q, // 5
andre@8578: r2, // 6
andre@8578: t, // 7
andre@8578: o, // 8
andre@8578: c_duan, // 9
andre@8578: c_ferguson, // 10
andre@8578: sqAFormatter.format(sq.getS()),
andre@8578: fZeroFormatter.format(sq.getQ()),
andre@8578: df.format(sq.getDate())
andre@8578: });
andre@8578: }
andre@8578: } else {
andre@8541: retval.add(new String[] {
andre@8541: km,
andre@8541: name,
andre@8541: a,
andre@8541: b,
andre@8541: sd, // 4
andre@8541: max_q, // 5
andre@8541: r2, // 6
andre@8541: t, // 7
andre@8541: o, // 8
andre@8541: c_duan, // 9
andre@8578: c_ferguson // 10
andre@8541: });
andre@8541: }
andre@8541:
sascha@3392: }
aheinecke@6172: return retval;
ingo@3077: }
ingo@3077:
ingo@3077:
aheinecke@6172: protected SQRelationJRDataSource createJRData() {
aheinecke@6172: SQRelationJRDataSource source = new SQRelationJRDataSource();
aheinecke@6172:
aheinecke@6172: addMetaData(source);
aheinecke@6172: for (SQResult [] results: data) {
aheinecke@6172: for (SQResult result: results) {
andre@8578: for (String[] res: data2StringArrays(result, false)) {
aheinecke@6172: source.addData(res);
aheinecke@6172: }
aheinecke@6172: }
aheinecke@6172: }
aheinecke@6172: return source;
aheinecke@6172: }
aheinecke@6172:
andre@8578: protected SQMeasurementsJRDataSource createMeasurementJRData() {
andre@8578: SQMeasurementsJRDataSource source = new SQMeasurementsJRDataSource();
andre@8578: NumberFormat fZeroFormatter = Formatter.getFormatter(context, 0, 0);
andre@8578: NumberFormat fEightFormatter = Formatter.getFormatter(context, 0, 8);
andre@8578: DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT,
andre@8578: Resources.getLocale(context.getMeta()));
andre@8578:
andre@8578: for (SQResult [] results: data) {
andre@8578: for (SQResult result: results) {
andre@8578: for (int i = 0; i < SQResult.NUMBER_FRACTIONS; ++i) {
andre@8578: String name = result.getFractionName(i);
andre@8578: SQFractionResult fraction = result.getFraction(i);
andre@8578: for (SQ sq: fraction.getMeasurements()) {
andre@8578: source.addData(new String[] {
andre@8578: name,
andre@8578: fEightFormatter.format(sq.getS()),
andre@8578: fZeroFormatter.format(sq.getQ()),
andre@8578: df.format(sq.getDate()),
andre@8578: null
andre@8578: });
andre@8578: }
andre@8578: for (int j = 0; j < fraction.numIterations(); j++) {
andre@8578: for (SQ sq: fraction.getOutliers(j)) {
andre@8578: source.addData(new String[] {
andre@8578: name,
andre@8578: fEightFormatter.format(sq.getS()),
andre@8578: fZeroFormatter.format(sq.getQ()),
andre@8578: df.format(sq.getDate()),
andre@8578: Integer.toString(j + 1)
andre@8578: });
andre@8578: }
andre@8578: }
andre@8578: }
andre@8578: }
andre@8578: }
andre@8578: return source;
andre@8578: }
andre@8578:
aheinecke@6172: protected void addMetaData(SQRelationJRDataSource source) {
aheinecke@6172: CallMeta meta = context.getMeta();
aheinecke@6172:
aheinecke@6172: D4EArtifact arti = (D4EArtifact) master;
aheinecke@6172:
aheinecke@6172: source.addMetaData ("river", RiverUtils.getRivername(arti));
aheinecke@6172:
aheinecke@6172: Locale locale = Resources.getLocale(meta);
aheinecke@6172: DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
aheinecke@6172:
aheinecke@6172: source.addMetaData("date", df.format(new Date()));
aheinecke@6172:
aheinecke@6172: SQRelationAccess access = new SQRelationAccess(arti);
aheinecke@6175: source.addMetaData("location", "KM " + getKmFormatter().format(access.getLocation()));
aheinecke@6172:
aheinecke@6172: DateRange period = access.getPeriod();
aheinecke@6172: source.addMetaData("periods", df.format(period.getFrom()) + " - " +
aheinecke@6172: df.format(period.getTo()));
aheinecke@6172:
aheinecke@6175: source.addMetaData("outliertest", Resources.getMsg(meta,
aheinecke@6175: access.getOutlierMethod(),
aheinecke@6175: access.getOutlierMethod()));
aheinecke@6830: source.addMetaData("outliers", Formatter.getRawFormatter(context).format(
aheinecke@6830: access.getOutliers()));
aheinecke@6172:
aheinecke@6172: source.addMetaData("calculation", Resources.getMsg(
aheinecke@6172: locale,
aheinecke@6172: PDF_HEADER_MODE,
aheinecke@6172: "SQRelation"));
aheinecke@6859:
aheinecke@6859: String measurementStationName = access.getMeasurementStationName();
aheinecke@6859:
aheinecke@6859: if (measurementStationName != null) {
aheinecke@6859: source.addMetaData("msName", measurementStationName);
aheinecke@7380: } else {
aheinecke@7380: source.addMetaData("msName", "");
aheinecke@6859: }
aheinecke@6859:
aheinecke@6859: String measurementStationGaugeName = access.getMeasurementStationGaugeName();
aheinecke@6859:
aheinecke@6859: if (measurementStationGaugeName != null) {
aheinecke@6859: source.addMetaData("msGauge", measurementStationGaugeName);
aheinecke@7380: } else {
aheinecke@7380: source.addMetaData("msGauge", "");
aheinecke@6859: }
aheinecke@6859:
aheinecke@6172: }
aheinecke@6172:
ingo@3077: @Override
ingo@3077: protected void writePDF(OutputStream out) {
teichmann@8202: log.debug("write PDF");
aheinecke@6172: SQRelationJRDataSource source = createJRData();
andre@8578: SQMeasurementsJRDataSource measureSource = createMeasurementJRData();
aheinecke@6172:
aheinecke@6172: String jasperFile = Resources.getMsg(
andre@8578: context.getMeta(),
andre@8578: JASPER_FILE,
andre@8578: "/jasper/sqrelation_en.jasper");
andre@8578: String jasperMeasurementsFile = Resources.getMsg(
andre@8578: context.getMeta(),
andre@8578: JASPER_MEASUREMENTS_FILE,
andre@8578: "/jasper/sqmeasurements_en.jasper");
aheinecke@6172: String confPath = Config.getConfigDirectory().toString();
aheinecke@6172:
aheinecke@6172:
aheinecke@6172: Map parameters = new HashMap();
aheinecke@6172: parameters.put("ReportTitle", Resources.getMsg(
aheinecke@6172: context.getMeta(), PDF_TITLE, "Exported Data"));
aheinecke@6172: try {
andre@8578: /* Page numbers start have a built in offset of 1 so this
andre@8578: * is fine. */
andre@8578: JasperPrint p2 = JasperFillManager.fillReport(
andre@8578: confPath + jasperMeasurementsFile,
andre@8578: parameters,
andre@8578: measureSource);
andre@8578: parameters.put("MEASUREMENT_PAGE_NUM", p2.getPages().size());
andre@8578: JasperPrint p1 = JasperFillManager.fillReport(
aheinecke@6172: confPath + jasperFile,
aheinecke@6172: parameters,
aheinecke@6172: source);
andre@8578: for (Object page: p2.getPages()) {
andre@8578: JRPrintPage object = (JRPrintPage)page;
andre@8578: p1.addPage(object);
andre@8578: }
andre@8578: JasperExportManager.exportReportToPdfStream(p1, out);
aheinecke@6172: }
aheinecke@6172: catch(JRException je) {
teichmann@8202: log.warn("Error generating PDF Report!", je);
aheinecke@6172: }
ingo@3077: }
ingo@3077: }
ingo@3077: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :