view flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticWKmsArtifact.java @ 2089:0da8874bd378

Added initial state to map artifact to be able to advance and step back. The map artifact overrides describe() to have the complete UI information in the describe response document. flys-artifacts/trunk@3613 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Raimund Renkert <raimund.renkert@intevation.de>
date Fri, 06 Jan 2012 12:02:10 +0000
parents 701658081f4f
children f021080cb409
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 java.awt.geom.Point2D;

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.CrossSectionWaterLineFacet;
import de.intevation.flys.artifacts.model.FacetTypes;
import de.intevation.flys.artifacts.model.WKms;
import de.intevation.flys.artifacts.model.WKmsFacet;
import de.intevation.flys.artifacts.model.WKmsFactory;

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

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

import de.intevation.flys.geom.Lines;
import de.intevation.flys.model.CrossSectionLine;

/**
 * Artifact to access additional "waterlevel"-type of data, like the height
 * of protective measures (dikes).
 *
 * This artifact neglects (Static)FLYSArtifacts capabilities of interaction
 * with the StateEngine by overriding the getState*-methods.
 */
public class StaticWKmsArtifact
extends      StaticFLYSArtifact
implements   FacetTypes, WaterLineArtifact
{
    /** The logger for this class. */
    private static Logger logger =
        Logger.getLogger(StaticWKmsArtifact.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_wkms.static";

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


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


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

        state = new StaticState(STATIC_STATE_NAME);

        List<Facet> fs = new ArrayList<Facet>();
        logger.debug(XMLUtils.toString(data));
        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 col = -1;
                int wst = Integer.valueOf(parts[3]);

                if (!parts[2].equals("A")) {
                    col = Integer.valueOf(parts[2]);
                }

                addStringData("col_pos", parts[2]);
                addStringData("wst_id",  parts[3]);

                String wkmsName;
                if (col >= 0) {
                    wkmsName = WKmsFactory.getWKmsName(col, wst);
                }
                else {
                    wkmsName = WKmsFactory.getWKmsName(wst);
                }

                String name;
                if (parts[0].equals(HEIGHTMARKS_POINTS)) {
                    name = HEIGHTMARKS_POINTS;
                }
                else {
                    name = STATIC_WKMS;
                }

                String facetDescription = Resources.getMsg(
                    callMeta, wkmsName, wkmsName);
                Facet wKmsFacet = new WKmsFacet(
                    name,
                    facetDescription);
                Facet csFacet = new CrossSectionWaterLineFacet(0,
                    facetDescription);
                fs.add(wKmsFacet);
                fs.add(csFacet);
                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("StaticWKmsArtifact.initialize");
        WINFOArtifact winfo = (WINFOArtifact) artifact;
        // TODO: The river is of no interest, so far.
        addData("river", winfo.getData("river"));
    }


    /**
     * 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 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 WKms from factory.
     * @param TODO idx param is not needed
     * @return WKms according to parameterization (can be null);
     */
    public WKms getWKms(int idx) {
        logger.debug("StaticWKmsArtifact.getWKms");

        return WKmsFactory.getWKms(
            Integer.valueOf(getDataAsString("col_pos")),
            Integer.valueOf(getDataAsString("wst_id")));
    }


    /**
     * Returns W at Km of WKms, searching linearly.
     * Returns -1 if not found.
     */
    public double getWAtKm(WKms wkms, double km) {
        // Uninformed search.
        int size = wkms.size();
        for (int i = 0; i < size; i++) {
            if (wkms.getKm(i) == km) {
                return wkms.getW(i);
            }
        }

        return -1;
    }


    /**
     * Get points of line describing the surface of water at cross section.
     *
     * @return an array holding coordinates of points of surface of water (
     *         in the form {{x1, x2} {y1, y2}} ).
     */
    public double [][] getWaterLines(int idx, CrossSectionLine csl) {
        logger.debug("getWaterLines(" + idx + ")");

        List<Point2D> points = csl.fetchCrossSectionLinesPoints();

        WKms wkms = getWKms(0);

        double km = csl.getKm().doubleValue();

        // Find W at km.
        double wAtKm = getWAtKm(wkms, km);
        if (wAtKm == -1) {
            logger.warn("Waterlevel at km " + km + " unknown.");
            return new double[][] {{}};
        }

        return Lines.createWaterLines(points, wAtKm);
    }


    /**
     * 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