view artifacts/src/main/java/org/dive4elements/river/exports/FlowVelocityGenerator.java @ 7076:7f600001c807 generator-refactoring

Add LTR inversion code to diagram generator. This code is used in serveral diagrams and as it modifies a whole diagram it should be central. (This should also make maintenance easier). This function can be called by processors to make sure that their data is plotted with an LTR waterflow.
author Andre Heinecke <aheinecke@intevation.de>
date Fri, 20 Sep 2013 16:33:22 +0200
parents e0311aa32efb
children c453f7ecf479
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * 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.util.Arrays;

import org.apache.log4j.Logger;

import org.jfree.data.xy.XYSeries;

import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
import org.dive4elements.artifactdatabase.state.Facet;

import org.dive4elements.river.artifacts.D4EArtifact;

import org.dive4elements.river.artifacts.access.FlowVelocityAccess;
import org.dive4elements.river.artifacts.model.FacetTypes;
import org.dive4elements.river.artifacts.model.FlowVelocityData;
import org.dive4elements.river.artifacts.model.minfo.BedDiameterResult;
import org.dive4elements.river.artifacts.model.minfo.BedloadDiameterResult;
import org.dive4elements.river.model.FlowVelocityMeasurementValue;

import org.dive4elements.river.jfree.Bounds;
import org.dive4elements.river.jfree.DoubleBounds;
import org.dive4elements.river.jfree.RiverAnnotation;
import org.dive4elements.river.jfree.StyledXYSeries;

import org.dive4elements.river.themes.ThemeDocument;
import org.dive4elements.river.utils.RiverUtils;


/**
 * An OutGenerator that generates flow velocity curves.
 *
 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
 */
public class FlowVelocityGenerator
extends      XYChartGenerator
implements   FacetTypes
{
    public enum YAXIS {
        V(0),
        T(1),
        Q(2),
        D(3);
        /* TODO Q and Density will come as 4th and 3rd axis. */
        protected int idx;
        private YAXIS(int c) {
           idx = c;
        }
    }

    /** The logger that is used in this generator. */
    private static Logger logger = Logger.getLogger(FlowVelocityGenerator.class);

    /** Key to look up internationalized String for annotations label. */
    public static final String I18N_ANNOTATIONS_LABEL =
        "chart.flow_velocity.annotations.label";

    /**
     * Key to look up internationalized String for LongitudinalSection diagrams
     * titles.
     */
    public static final String I18N_CHART_TITLE =
        "chart.flow_velocity.section.title";

    /**
     * Key to look up internationalized String for LongitudinalSection diagrams
     * subtitles.
     */
    public static final String I18N_CHART_SUBTITLE =
        "chart.flow_velocity.section.subtitle";

    /**
     * Key to look up internationalized String for LongitudinalSection diagrams
     * short subtitles.
     */
    public static final String I18N_CHART_SHORT_SUBTITLE =
        "chart.flow_velocity.section.shortsubtitle";

    public static final String I18N_XAXIS_LABEL =
        "chart.flow_velocity.section.xaxis.label";

    public static final String I18N_YAXIS_LABEL =
        "chart.flow_velocity.section.yaxis.label";

    public static final String I18N_2YAXIS_LABEL =
        "chart.flow_velocity.section.yaxis.second.label";

    public static final String I18N_3YAXIS_LABEL =
        "chart.flow_velocity.section.yaxis.third.label";
    public static final String I18N_4YAXIS_LABEL = "chart.bedquality.yaxis.label.diameter";

    public static final String I18N_CHART_TITLE_DEFAULT  = "Geschwindigkeit- und Schubspannung";
    public static final String I18N_XAXIS_LABEL_DEFAULT  = "km";
    public static final String I18N_YAXIS_LABEL_DEFAULT  = "Geschwindigkeit v [m/s]";
    public static final String I18N_2YAXIS_LABEL_DEFAULT = "Schubspannung Tau [N]";
    public static final String I18N_3YAXIS_LABEL_DEFAULT = "Q [m³/s]";
    public static final String I18N_4YAXIS_LABEL_DEFAULT = "Durchmesser [mm]";

    @Override
    protected YAxisWalker getYAxisWalker() {
        return new YAxisWalker() {
            @Override
            public int length() {
                return YAXIS.values().length;
            }

            @Override
            public String getId(int idx) {
                YAXIS[] yaxes = YAXIS.values();
                return yaxes[idx].toString();
            }
        };
    }


    /**
     * Returns the default title for this chart.
     *
     * @return the default title for this chart.
     */
    @Override
    public String getDefaultChartTitle() {
        Object[] args = new Object[] {
            getRiverName()
        };

        return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT, args);
    }


    /**
     * Get internationalized label for the x axis.
     */
    @Override
    protected String getDefaultXAxisLabel() {
        D4EArtifact flys = (D4EArtifact) master;

        return msg(
            I18N_XAXIS_LABEL,
            I18N_XAXIS_LABEL_DEFAULT,
            new Object[] { RiverUtils.getRiver(flys).getName() });
    }


    @Override
    protected String getDefaultYAxisLabel(int index) {
        String label = "default";

        if (index == YAXIS.V.idx) {
            label = getVAxisLabel();
        }
        else if (index == YAXIS.T.idx) {
            label = getTAxisLabel();
        }
        else if (index == YAXIS.Q.idx) {
            label = getQAxisLabel();
        }
        else if (index == YAXIS.D.idx) {
            label = getDAxisLabel();
        }

        return label;
    }


    /**
     * Get internationalized label for the y axis.
     */
    protected String getVAxisLabel() {
        return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
    }


    /**
     * Get internationalized label for the y axis.
     */
    protected String getQAxisLabel() {
        return msg(I18N_3YAXIS_LABEL, I18N_3YAXIS_LABEL_DEFAULT);
    }

    /**
     * Get internationalized label for the y axis.
     */
    protected String getTAxisLabel() {
        return msg(I18N_2YAXIS_LABEL, I18N_2YAXIS_LABEL_DEFAULT);
    }

    /**
     * Get internationalized label for the y axis.
     */
    protected String getDAxisLabel() {
        return msg(I18N_4YAXIS_LABEL, I18N_4YAXIS_LABEL_DEFAULT);
    }

    /**
     * Produce output.
     * @param artifactAndFacet current facet.
     * @param attr  theme for facet
     * @param visible Whether this facets data is actually visible or not.
     */
    public void doOut(
        ArtifactAndFacet artifactAndFacet,
        ThemeDocument    attr,
        boolean          visible
    ) {
        String name = artifactAndFacet.getFacetName();

        logger.debug("FlowVelocityGenerator.doOut: " + name);

        if (name == null) {
            logger.error("No facet name for doOut(). No output generated!");
            return;
        }

        Facet facet = artifactAndFacet.getFacet();

        if (facet == null) {
            return;
        }

        if (getXBounds(0) != null && getDomainAxisRange() != null) {
            logger.debug(Arrays.toString(getDomainAxisRangeFromRequest()));
            Bounds bounds =
                calculateZoom(getXBounds(0), getDomainAxisRange());
            context.putContextValue("startkm", bounds.getLower());
            context.putContextValue("endkm", bounds.getUpper());
        }
        else if (getXBounds(0) != null && getDomainAxisRange() == null) {
            context.putContextValue("startkm", getXBounds(0).getLower());
            context.putContextValue("endkm", getXBounds(0).getUpper());
        }
        else if (getXBounds(0) == null && getDomainAxisRange() == null) {
            D4EArtifact artifact = (D4EArtifact)artifactAndFacet.getArtifact();
            FlowVelocityAccess access = new FlowVelocityAccess(artifact);
            context.putContextValue("startkm", access.getLowerKM());
            context.putContextValue("endkm", access.getUpperKM());
        }
        else if (getXBounds(0) == null && getDomainAxisRange() != null){
            D4EArtifact artifact = (D4EArtifact)artifactAndFacet.getArtifact();
            FlowVelocityAccess access = new FlowVelocityAccess(artifact);
            Bounds b = new DoubleBounds(access.getLowerKM(), access.getUpperKM());
            Bounds bounds =
                calculateZoom(b, getDomainAxisRange());
            context.putContextValue("startkm", bounds.getLower());
            context.putContextValue("endkm", bounds.getUpper());
        }
        if (name.equals(FLOW_VELOCITY_MAINCHANNEL)) {
            doMainChannelOut(
                (FlowVelocityData) artifactAndFacet.getData(context),
                artifactAndFacet,
                attr,
                visible);
        }
        else if (name.equals(FLOW_VELOCITY_TOTALCHANNEL)) {
            doTotalChannelOut(
                (FlowVelocityData) artifactAndFacet.getData(context),
                artifactAndFacet,
                attr,
                visible);
        }
        else if (name.equals(FLOW_VELOCITY_MAINCHANNEL_FILTERED)) {
            doMainChannelOut(
                (FlowVelocityData) artifactAndFacet.getData(context),
                artifactAndFacet,
                attr,
                visible);
        }
        else if (name.equals(FLOW_VELOCITY_TOTALCHANNEL_FILTERED)) {
            doTotalChannelOut(
                (FlowVelocityData) artifactAndFacet.getData(context),
                artifactAndFacet,
                attr,
                visible);
        }
        else if (name.equals(FLOW_VELOCITY_DISCHARGE)) {
            doQOut(
                (FlowVelocityData) artifactAndFacet.getData(context),
                artifactAndFacet,
                attr,
                visible);
        }
        else if (name.equals(FLOW_VELOCITY_TAU)) {
            doTauOut(
                (FlowVelocityData) artifactAndFacet.getData(context),
                artifactAndFacet,
                attr,
                visible);
        }
        else if (name.equals(FLOW_VELOCITY_TAU_FILTERED)) {
            doTauOut(
                (FlowVelocityData) artifactAndFacet.getData(context),
                artifactAndFacet,
                attr,
                visible);
        }

        else if (name.equals(FLOW_VELOCITY_ANNOTATION)) {
            doAnnotations(
                (RiverAnnotation) artifactAndFacet.getData(context),
                 artifactAndFacet,
                 attr,
                 visible);
        }
        else if (FacetTypes.IS.AREA(name)) {
            doArea(
                artifactAndFacet.getData(context),
                artifactAndFacet,
                attr,
                visible);
        }
        else if (FacetTypes.IS.MANUALPOINTS(name)) {
            doPoints(
                artifactAndFacet.getData(context),
                artifactAndFacet,
                attr,
                visible,
                YAXIS.V.idx);
        }
        else if (name.equals(LONGITUDINAL_ANNOTATION)) {
            doAnnotations(
                (RiverAnnotation) artifactAndFacet.getData(context),
                 artifactAndFacet,
                 attr,
                 visible);
        }
        else if (name.equals(FLOW_VELOCITY_MEASUREMENT)) {
            doVPointOut(
                 artifactAndFacet.getData(context),
                 artifactAndFacet,
                 attr,
                 visible);
        }
        else if (name.equals(BED_QUALITY_BED_DIAMETER_SUBLAYER)) {
            doBedQualitySubLayerOut(
                (BedDiameterResult)artifactAndFacet.getData(context),
                artifactAndFacet,
                attr,
                visible);
        }
        else if (name.equals(BED_QUALITY_BED_DIAMETER_TOPLAYER)) {
            doBedQualityTopLayerOut(
                (BedDiameterResult)artifactAndFacet.getData(context),
                artifactAndFacet,
                attr,
                visible);
        }
        else if (name.equals(BED_QUALITY_BEDLOAD_DIAMETER)) {
            doBedQualityLoadDiameter(
                (BedloadDiameterResult)artifactAndFacet.getData(context),
                artifactAndFacet,
                attr,
                visible);
        }
        else {
            logger.warn("Unknown facet name: " + name);
            return;
        }
    }


    private void doBedQualityLoadDiameter(
        BedloadDiameterResult data,
        ArtifactAndFacet aandf,
        ThemeDocument attr,
        boolean visible) {
        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), attr);
        StyledSeriesBuilder.addPoints(series, data.getDiameterData(), true);

        addAxisSeries(series, YAXIS.D.idx, visible);
    }


    private void doBedQualityTopLayerOut(
        BedDiameterResult data,
        ArtifactAndFacet aandf,
        ThemeDocument attr,
        boolean visible) {
        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), attr);
        StyledSeriesBuilder.addPoints(series, data.getDiameterSubData(), true);
        addAxisSeries(series, YAXIS.D.idx, visible);
    }


    private void doBedQualitySubLayerOut(
        BedDiameterResult data,
        ArtifactAndFacet aandf,
        ThemeDocument attr,
        boolean visible
    ) {
        logger.debug("Do beddiametersubout");
        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), attr);
        StyledSeriesBuilder.addPoints(series, data.getDiameterSubData(), true);
        addAxisSeries(series, YAXIS.D.idx, visible);
    }


    /**
     * Process the output for W facets in a longitudinal section curve.
     *
     * @param data A FlowVelocityData object
     * @param aandf The facet. This facet does NOT support any data objects. Use
     * D4EArtifact.getNativeFacet() instead to retrieve a Facet which supports
     * data.
     * @param theme The theme that contains styling information.
     * @param visible The visibility of the curve.
     */
    protected void doMainChannelOut(
        FlowVelocityData data,
        ArtifactAndFacet aandf,
        ThemeDocument    theme,
        boolean          visible
    ) {
        logger.debug("FlowVelocityGenerator.doMainChannelOut");

        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);

        StyledSeriesBuilder.addPoints(series, data.getMainChannelPoints(), true);

        addAxisSeries(series, YAXIS.V.idx, visible);
    }


    /** Handle VWQKms. */
    protected void doVPointOut (
        Object data,
        ArtifactAndFacet aandf,
        ThemeDocument    theme,
        boolean          visible
    ) {
        logger.debug("FlowVelocityGenerator.doVPointOut");

        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);

        FlowVelocityMeasurementValue.FastFlowVelocityMeasurementValue
            value = (FlowVelocityMeasurementValue.FastFlowVelocityMeasurementValue)
                data;

        StyledSeriesBuilder.addPoints(series, new double[][] {{value.getStation()},{value.getV()}}, true);

        addAxisSeries(series, YAXIS.V.idx, visible);
    }


    /**
     * Add items to dataseries which describes the differences.
     */
    protected void doTotalChannelOut(
        FlowVelocityData data,
        ArtifactAndFacet aandf,
        ThemeDocument    theme,
        boolean          visible
    ) {
        logger.debug("FlowVelocityGenerator.doTotalChannelOut");

        if (data == null) {
            logger.warn("No data to add to FlowVelocity chart.");
            return;
         }

        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);

        StyledSeriesBuilder.addPoints(series, data.getTotalChannelPoints(), true);

        addAxisSeries(series, YAXIS.V.idx, visible);
    }



    /**
     * @param data A FlowVelocityData object
     * @param aandf The facet. This facet does NOT support any data objects. Use
     * D4EArtifact.getNativeFacet() instead to retrieve a Facet which supports
     * data.
     * @param theme The theme that contains styling information.
     * @param visible The visibility of the curve.
     */
    protected void doQOut(
        FlowVelocityData data,
        ArtifactAndFacet aandf,
        ThemeDocument    theme,
        boolean          visible
    ) {
        logger.debug("FlowVelocityGenerator.doQOut");

        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);

        StyledSeriesBuilder.addPoints(series, data.getQPoints(), true);

        addAxisSeries(series, YAXIS.Q.idx, visible);
    }

    /**
     * @param data A FlowVelocityData object
     * @param aandf The facet. This facet does NOT support any data objects. Use
     * D4EArtifact.getNativeFacet() instead to retrieve a Facet which supports
     * data.
     * @param theme The theme that contains styling information.
     * @param visible The visibility of the curve.
     */
    protected void doTauOut(
        FlowVelocityData data,
        ArtifactAndFacet aandf,
        ThemeDocument    theme,
        boolean          visible
    ) {
        logger.debug("FlowVelocityGenerator.doTauOut");

        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);

        StyledSeriesBuilder.addPoints(series, data.getTauPoints(), true);

        addAxisSeries(series, YAXIS.T.idx, visible);
    }


    /** Look up the axis identifier for a given facet type. */
    public int axisIdxForFacet(String facetName) {
        if (FacetTypes.IS.V(facetName)) {
            return YAXIS.V.idx;
        }
        else if (FacetTypes.IS.T(facetName)) {
            return YAXIS.T.idx;
        }
        else {
            logger.warn("Could not find axis for facet " + facetName);
            return YAXIS.V.idx;
        }
    }


    /**
     * Do Area out.
     * @param theme styling information.
     * @param visible whether or not visible.
     */
    protected void doArea(
        Object           o,
        ArtifactAndFacet aandf,
        ThemeDocument    theme,
        boolean          visible
    ) {
        logger.debug("FlowVelocityGenerator.doArea");
        logger.warn("TODO: Implement FlowVelocityGenerator.doArea");
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org