view flys-artifacts/src/main/java/de/intevation/flys/artifacts/WQKmsInterpolArtifact.java @ 2716:150dcdefeb7d

Only offer soundings that fit to the current km range in MINFO bed height workflow. flys-artifacts/trunk@4444 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Fri, 18 May 2012 12:44:20 +0000
parents c553d4fa3957
children 64dc2997b2dd
line wrap: on
line source
package de.intevation.flys.artifacts;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import org.w3c.dom.Document;

import de.intevation.artifactdatabase.state.Facet;
import de.intevation.artifactdatabase.state.DefaultOutput;
import de.intevation.artifactdatabase.state.State;

import de.intevation.artifacts.Artifact;
import de.intevation.artifacts.ArtifactFactory;
import de.intevation.artifacts.ArtifactNamespaceContext;
import de.intevation.artifacts.CallMeta;

import de.intevation.flys.artifacts.model.FacetTypes;
import de.intevation.flys.artifacts.model.WQKms;
import de.intevation.flys.artifacts.model.WQFacet;
import de.intevation.flys.artifacts.model.WKmsFactory;
import de.intevation.flys.artifacts.model.WQKmsFactory;
import de.intevation.flys.artifacts.model.WstValueTable;
import de.intevation.flys.artifacts.model.WstValueTableFactory;

import de.intevation.flys.artifacts.states.StaticState;
import de.intevation.flys.artifacts.resources.Resources;

import de.intevation.artifacts.common.utils.XMLUtils;

/**
 * Artifact to access additional "waterlevel/discharge"-type of data, like
 * fixation measurements, but doing so with costy interpolation.
 *
 * This artifact neglects (Static)FLYSArtifacts capabilities of interaction
 * with the StateEngine by overriding the getState*-methods.
 */
public class WQKmsInterpolArtifact
extends      StaticFLYSArtifact
implements   FacetTypes
{
    /** The logger for this class. */
    private static Logger logger =
        Logger.getLogger(WQKmsInterpolArtifact.class);

    /** XPath to access initial parameter. */
    public static final String XPATH_DATA =
        "/art:action/art:ids/@value";

    public static final String STATIC_STATE_NAME =
        "state.additional_wqkms.interpol.static";

    /** One and only state to be in. */
    protected transient State state = null;


    /**
     * Trivial Constructor.
     */
    public WQKmsInterpolArtifact() {
        logger.debug("WQKmsInterpolArtifact.WQKmsInterpolArtifact");
    }


    /**
     * Gets called from factory, to set things up.
     */
    @Override
    public void setup(
        String          identifier,
        ArtifactFactory factory,
        Object          context,
        CallMeta        callMeta,
        Document        data)
    {
        logger.debug("WQKmsInterpolArtifact.setup");

        state = new StaticState(STATIC_STATE_NAME);

        List<Facet> fs = new ArrayList<Facet>();
        String code = XMLUtils.xpathString(
            data, XPATH_DATA, ArtifactNamespaceContext.INSTANCE);

        // TODO Go for JSON, one day.
        //ex.: flood_protection-wstv-114-12
        if (code != null) {
            String [] parts = code.split("-");

            if (parts.length >= 4) {
                int wst = Integer.valueOf(parts[3]);
                int col = -1;
                String colpos = parts[2];
                // Are we interested in a single column or in all columns?
                if (colpos.equals("A")) {
                    ; // Take all.
                }
                else {
                    col = Integer.valueOf(colpos);
                    addStringData("col_pos", parts[2]);
                }
                addStringData("wst_id",  parts[3]);
                String wkmsName = (col > 0)
                                ? WKmsFactory.getWKmsName(col, wst)
                                : WKmsFactory.getWKmsName(wst);
                String name;
                if (parts[0].startsWith("height")){
                    name = STATIC_WQ_ANNOTATIONS;
                }
                else if (parts[0].startsWith("flood")) {
                    name = STATIC_WKMS_INTERPOL;
                }
                else {
                    name = STATIC_WQ;
                }

                Facet facet = new WQFacet(name,
                    Resources.getMsg(
                        callMeta,
                        wkmsName,
                        wkmsName));
                fs.add(facet);
                facets.put(state.getID(), fs);
            }
        }

        spawnState();
        super.setup(identifier, factory, context, callMeta, data);
    }


    /**
     * Initialize the static state with output.
     * @return static state
     */
    protected State spawnState() {
        state = new StaticState(STATIC_STATE_NAME);
        List<Facet> fs = facets.get(STATIC_STATE_NAME);
        DefaultOutput output = new DefaultOutput(
            "general",
            "general",
            "image/png",
            fs,
            "chart");

        state.getOutputs().add(output);

        return state;
    }


    /**
     * Called via setup.
     *
     * @param artifact The master-artifact.
     */
    @Override
    protected void initialize(
        Artifact artifact,
        Object context,
        CallMeta meta)
    {
        logger.debug("WQKmsInterpolArtifact.initialize");
        FLYSArtifact winfo = (FLYSArtifact) artifact;
        importData(winfo, "river");
        importData(winfo, "ld_locations");
    }


    /**
     * Get a list containing the one and only State.
     * @param  context ignored.
     * @return list with one and only state.
     */
    @Override
    protected List<State> getStates(Object context) {
        ArrayList<State> states = new ArrayList<State>();
        states.add(getState());
        return states;
    }


    /**
     * Get WQ at a given km.
     */
    public double [][] getWQAtKm(double km) {

        WstValueTable interpolator = null;
        // Get WstValueTable
        if (getDataAsString("col_pos") != null) {
            interpolator = WstValueTableFactory.getWstColumnTable(
                getDataAsInt("wst_id"), getDataAsInt("col_pos"));
        }
        else {
            interpolator = WstValueTableFactory.getTable(
                getDataAsInt("wst_id"));
        }

        Double tmp = getDataAsDouble("ld_locations");
        double [][] vs = interpolator.interpolateWQColumnwise(
            tmp != null ? tmp : 0);

        for (int x = 0; x < vs[1].length; x++) {
            logger.debug("getWQAtKm: Q/W " + vs[0][x] + " / " + vs[1][x]);
        }

        return vs;
    }


    /**
     * Get a DataItem casted to int (0 if fails).
     */
    public int getDataAsInt(String dataName) {
        String val = getDataAsString(dataName);
        try {
            return Integer.valueOf(val);
        }
        catch (NumberFormatException e) {
            logger.warn("Could not get data " + dataName + " as int", e);
            return 0;
        }
    }


    /**
     * Get the "current" state (there is but one).
     * @param cc ignored.
     * @return the "current" (only possible) state.
     */
    @Override
    public State getCurrentState(Object cc) {
        return getState();
    }


    /**
     * Get the only possible state.
     * @return the state.
     */
    protected State getState() {
        return getState(null, null);
    }


    /**
     * Get the state.
     * @param context ignored.
     * @param stateID ignored.
     * @return the state.
     */
    @Override
    protected State getState(Object context, String stateID) {
        return (state != null)
            ? state
            : spawnState();
    }


    /**
     * Get WQKms from factory.
     * @param TODO idx param is not needed
     * @return WQKms according to parameterization (can be null);
     */
    public WQKms getWQKms(int idx) {
        logger.debug("WQKmsInterpolArtifact.getWQKms");
        logger.warn("Stub, getWQKms not yet implemented.");

        return WQKmsFactory.getWQKms(
            Integer.valueOf(getDataAsString("col_pos")),
            Integer.valueOf(getDataAsString("wst_id")));
    }


    /**
     * Determines Facets initial disposition regarding activity (think of
     * selection in Client ThemeList GUI). This will be checked one time
     * when the facet enters a collections describe document.
     *
     * @param facetName name of the facet.
     * @param index     index of the facet.
     *
     * @return Always 0. Static Data will enter plots inactive.
     */
    @Override
    public int getInitialFacetActivity(
        String outputName,
        String facetName,
        int index)
    {
        return 0;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org