view artifacts/src/main/java/org/dive4elements/river/artifacts/model/CrossSectionWaterLineFacet.java @ 9499:853f2dafc16e

VegetationZones in CrossSectionsDiagram
author gernotbelger
date Thu, 27 Sep 2018 18:06:26 +0200
parents bd5f5d2220fa
children
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.artifacts.model;

import java.io.Serializable;
import java.util.List;

import org.apache.log4j.Logger;
import org.dive4elements.artifactdatabase.state.Facet;
import org.dive4elements.artifacts.Artifact;
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.artifacts.DataProvider;
import org.dive4elements.river.artifacts.WaterLineArtifact;
import org.dive4elements.river.artifacts.geom.Lines;
import org.dive4elements.river.artifacts.geom.Lines.LineData;
import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
import org.dive4elements.river.model.FastCrossSectionLine;

/**
 * Facet for Waterlines in Cross Sections.
 */
public class CrossSectionWaterLineFacet extends DataFacet implements FacetTypes {

    private static final LineData NO_LINE_DATA = new Lines.LineData(new double[][] {}, 0d, 0d);

    private static final long serialVersionUID = 1L;

    /** Private log to use. */
    private static Logger log = Logger.getLogger(CrossSectionWaterLineFacet.class);

    private final Serializable waterLineIndex;

    public CrossSectionWaterLineFacet(final int facetIndex, final String description, final ComputeType type, final String hash, final String stateId,
            final Serializable waterLineIndex) {
        this(facetIndex, CROSS_SECTION_WATER_LINE, description, type, hash, stateId, waterLineIndex);
    }

    /**
     * Trivial constructor, set (maybe localized) description.
     *
     * @param facetIndex
     *            Index of this facet.
     * @param waterLineIndex
     *            Determines which water-line the artifact will return. Depends on the implementation of the artifact.
     *            Is serializable because this class is, must be immutable because only the reference is copied in
     *            'deepCopy'
     * @param name
     *            'type' of this facet.
     * @param description
     *            (maybe) localized user-visible description.
     */
    public CrossSectionWaterLineFacet(final int facetIndex, final String name, final String description, final ComputeType type, final String hash,
            final String stateId, final Serializable waterLineIndex) {
        super(facetIndex, name, description, type, hash, stateId);

        this.waterLineIndex = waterLineIndex;
    }

    /**
     * Gets waterline (crossed with cross section) of waterlevel.
     * FIXME: the cross section facets delgate fetching the data to the artifact, which in turn (in most cases) re-calculate
     * the artifact on every call....
     * Instead this should work like other facets that rely on the hashed computation.
     */
    @Override
    public Object getData(final Artifact artifact, final CallContext context) {
        log.debug("Get data for cross section water line");

        final List<DataProvider> providers = context.getDataProvider(CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA);
        if (providers.size() < 1) {
            log.warn("Could not find Cross-Section data provider.");
            return NO_LINE_DATA;
        }

        final DataProvider dataProvider = providers.get(0);

        final FastCrossSectionLine crossSection = (FastCrossSectionLine) dataProvider.provideData(CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA, null, context);
        if (crossSection == null)
            return NO_LINE_DATA;

        Object nextKm = dataProvider.provideData(CrossSectionFacet.BLACKBOARD_CS_NEXT_KM, null, context);
        Object prevKm = dataProvider.provideData(CrossSectionFacet.BLACKBOARD_CS_PREV_KM, null, context);
        if (prevKm == null)
            prevKm = new Double(-1d);
        if (nextKm == null)
            nextKm = new Double(-1d);

        if (!(artifact instanceof WaterLineArtifact)) {
            log.error("CrossSectionWaterLineFacet needs WaterLineArtifact");
            return NO_LINE_DATA;
        }

        final WaterLineArtifact lineArtifact = (WaterLineArtifact) artifact;

        final double currentKm = crossSection.getKm();

        final double waterLevel = lineArtifact.getWaterLevel(this.type, this.hash, this.stateId, currentKm, this.waterLineIndex, (Double) nextKm,
                (Double) prevKm, context);
        if (Double.isNaN(waterLevel))
            return NO_LINE_DATA;

        return Lines.createWaterLines(crossSection.getPoints(), waterLevel);
    }

    /** Do a deep copy. */
    @Override
    public Facet deepCopy() {
        final CrossSectionWaterLineFacet copy = new CrossSectionWaterLineFacet(this.getIndex(), this.name, this.description, this.type, this.hash, this.stateId,
                this.waterLineIndex);
        copy.set(this);
        return copy;
    }
}

http://dive4elements.wald.intevation.org