view artifacts/src/main/java/org/dive4elements/river/exports/WaterlevelDescriptionBuilder.java @ 9040:5294114b1df4

Fixed/changed some FIXMEs/TODOs
author gernotbelger
date Wed, 02 May 2018 12:19:31 +0200
parents 05b5588bdd94
children 86d2cbfe7f7f
line wrap: on
line source
/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
 * Software engineering by
 *  Björnsen Beratende Ingenieure GmbH
 *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */
package org.dive4elements.river.exports;

import java.text.NumberFormat;

import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.WINFOArtifact;
import org.dive4elements.river.artifacts.model.WQKms;
import org.dive4elements.river.artifacts.resources.Resources;
import org.dive4elements.river.utils.Formatter;
import org.dive4elements.river.utils.RiverUtils;
import org.dive4elements.river.utils.RiverUtils.WQ_MODE;

/**
 * Helper that encapsulates the logic how the 'description' column in waterlevel exporting is generated.
 * TODO: this class should also be used in WaterlevelExport (all code is copied from there), but this would involve
 * heavy testing and we leave this to the one who is responsible to clean up this mess.
 *
 * @author Gernot Belger
 */
public final class WaterlevelDescriptionBuilder {

    private static final String CSV_META_Q = "export.waterlevel.csv.meta.q";

    // FIXME: unit 'NN + m' is wrong:
    // - use river-elevation system in case of absolute heights
    // - use 'cm am Pegel' in other cases
    private static final String CSV_META_W = "export.waterlevel.csv.meta.w";

    private static final String CSV_Q_DESC_HEADER = "export.waterlevel.csv.header.q.desc";

    // FIXME: missing in resource-files! hence always the default is used...
    private static final String CSV_W_DESC_HEADER = "export.waterlevel.csv.header.w.desc";

    private static final String DEFAULT_CSV_Q_DESC_HEADER = "Bezeichnung";

    private static final String DEFAULT_CSV_W_DESC_HEADER = "W/Pegel [cm]";

    private final boolean isQ;

    private final boolean atGauge;

    private final CallContext context;

    private final WQ_MODE mode;

    private final D4EArtifact artifact;

    public WaterlevelDescriptionBuilder(final D4EArtifact artifact, final CallContext context) {
        this.context = context;

        // REMARK: taken from WaterlevelExporter, should be moved into WInfoArtifact
        this.mode = RiverUtils.getWQMode(artifact);
        this.atGauge = this.mode == WQ_MODE.QGAUGE || this.mode == WQ_MODE.WGAUGE;
        this.isQ = this.mode == WQ_MODE.QGAUGE || this.mode == WQ_MODE.QFREE;

        this.artifact = artifact;
    }

    public boolean isAtGauge() {
        return this.atGauge;
    }

    public String getMetadata() {

        switch (this.mode) {
        case QFREE:
        case QGAUGE: {
            final String data = getMetadataQ();
            if (data == null)
                return null;

            return Resources.getMsg(this.context.getMeta(), CSV_META_Q, CSV_META_Q, data);
        }

        // TODO: probably none, default is wrong here, but this how it was implemented in WaterlevelExporter.
        case WFREE:
        case WGAUGE:
        case NONE:
        default:
            final double[] ws = RiverUtils.getWs(this.artifact);

            if (ws == null || ws.length <= 0)
                return null;

            // FIXME: we also have here a case single?!

            // FIXME: use correct wst unit!

            // FIXME: bad formatting ofd values. Use the correct Formatter!
            final String lower = String.valueOf(ws[0]);
            final String upper = String.valueOf(ws[ws.length - 1]);

            return Resources.getMsg(this.context.getMeta(), CSV_META_W, CSV_META_W, lower, upper);
        }
    }

    private String getMetadataQ() {

        final double[] qs = RiverUtils.getQs(this.artifact);
        if (qs == null || qs.length == 0)
            return null;

        final RiverUtils.WQ_INPUT input = RiverUtils.getWQInputMode(this.artifact);

        switch (input) {
        case ADAPTED:
        case RANGE:
            return String.valueOf(qs[0]) + " - " + String.valueOf(qs[qs.length - 1]);

        case SINGLE:
            String data = String.valueOf(qs[0]);
            for (int i = 1; i < qs.length; i++)
                data += ", " + String.valueOf(qs[i]);
            return data;

        default:
            return null;
        }
    }

    public String getColumnHeader() {

        if (!this.atGauge)
            return null;

        // REMARK: bad inter-dependency to WaterlevelExporter, but we want to really copy the logic from WInfo
        if (this.isQ)
            return Resources.getMsg(this.context.getMeta(), CSV_Q_DESC_HEADER, DEFAULT_CSV_Q_DESC_HEADER);

        return Resources.getMsg(this.context.getMeta(), CSV_W_DESC_HEADER, DEFAULT_CSV_W_DESC_HEADER);
    }

    public String getDesc(final WQKms wqkms) {
        return getDesc(wqkms, this.isQ);
    }

    public String getDesc(final WQKms wqkms, final boolean isQoverride) {
        String colDesc = "";

        if (this.artifact instanceof WINFOArtifact && isQoverride) {
            colDesc = getCSVRowTitle((WINFOArtifact) this.artifact, wqkms);
        } else if (!isQoverride) {
            final Double value = RiverUtils.getValueFromWQ(wqkms);
            colDesc = (value != null) ? Formatter.getWaterlevelW(this.context).format(value) : null;
        }

        if (this.artifact instanceof WINFOArtifact) {
            if (wqkms != null && wqkms.getRawValue() != null) {
                final WINFOArtifact winfo = (WINFOArtifact) this.artifact;
                colDesc = RiverUtils.getNamedMainValue(winfo, wqkms.getRawValue());
                // For 'W am Pegel' s
                if (colDesc == null) {
                    final Double value = RiverUtils.getValueFromWQ(wqkms);
                    colDesc = (value != null) ? Formatter.getWaterlevelW(this.context).format(value) : null;
                }
            }
        }

        if (colDesc == null)
            return "";

        /*
         * Quick hack. Can be removed when database strings are
         * adapted or left in here as it should never be harmful.
         */
        return colDesc.replace("Amtl.Festlegung_", "Amtl. ");
    }

    private String getCSVRowTitle(final WINFOArtifact winfo, final WQKms wqkms) {

        if (this.mode == WQ_MODE.WFREE || this.mode == WQ_MODE.QGAUGE)
            return localizeWQKms(wqkms);

        final Double v = wqkms.getRawValue();

        final String nmv = RiverUtils.getNamedMainValue(winfo, v);

        if (nmv != null && nmv.length() > 0) {
            return RiverUtils.stripNamedMainValue(nmv);
        }

        return localizeWQKms(wqkms);
    }

    /**
     * Get a string like 'W=' or 'Q=' with a number following in localized
     * format.
     */
    private String localizeWQKms(final WQKms wqkms) {
        final Double rawValue = wqkms.getRawValue();

        if (rawValue == null) {
            return wqkms.getName();
        }

        final NumberFormat nf = Formatter.getRawFormatter(this.context);

        if (this.mode == WQ_MODE.WFREE || this.mode == WQ_MODE.WGAUGE)
            return "W=" + nf.format(rawValue);

        return "Q=" + nf.format(rawValue);
    }
}

http://dive4elements.wald.intevation.org