view flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffCalculation.java @ 4241:49cb65d5932d

Improved the historical discharge calculation. The calculation now creates new HistoricalWQKms (new subclass of WQKms). Those WQKms are used to create new facets from (new) type 'HistoricalDischargeCurveFacet'. The chart generator is improved to support those facets.
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 24 Oct 2012 14:34:35 +0200
parents 95d699c769fb
children
line wrap: on
line source
package de.intevation.flys.artifacts.model.minfo;

import gnu.trove.TDoubleArrayList;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;

import de.intevation.flys.artifacts.FLYSArtifact;
import de.intevation.flys.artifacts.access.BedDifferencesAccess;
import de.intevation.flys.artifacts.model.Calculation;
import de.intevation.flys.artifacts.model.CalculationResult;


public class BedDiffCalculation
extends Calculation
{

    private static final Logger logger = Logger
        .getLogger(BedDiffCalculation.class);

    protected String river;
    protected String yearEpoch;
    protected FLYSArtifact[][] artifacts;

    public BedDiffCalculation() {
    }

    public CalculationResult calculate(BedDifferencesAccess access) {
        logger.info("BedDiffCalculation.calculate");

        String river = access.getRiver();
        String yearEpoch = access.getYearEpoch();
        FLYSArtifact[][] artifacts = access.getDifferenceArtifacts();

        logger.debug("got artifacts: " + artifacts.length + "; " + artifacts[0].length);
        if (river == null) {
            // TODO: i18n
            addProblem("minfo.missing.river");
        }

        if (yearEpoch == null) {
            addProblem("minfo.missing.year_epoch");
        }

        if (artifacts == null) {
            addProblem("minfo.missing.differences");
        }

        if (!hasProblems()) {
            this.river = river;
            this.yearEpoch = yearEpoch;
            this.artifacts = artifacts;
            return internalCalculate();
        }

        return new CalculationResult();
    }

    private CalculationResult internalCalculate() {

        if (yearEpoch.equals("year")) {
            List<BedDiffYearResult> results =
                new LinkedList<BedDiffYearResult>();

            for (int i = 0; i < artifacts.length; i++) {
                BedHeight[] pair =
                    getHeightPair(artifacts[i][0], artifacts[i][1], "single");
                BedDiffYearResult res = calculateYearDifference(pair);
                results.add(res);
            }
            return new CalculationResult(
                results.toArray(new BedDiffYearResult[results.size()]), this);
        }
        if (yearEpoch.equals("epoch")) {
            List<BedDiffEpochResult> results =
                new LinkedList<BedDiffEpochResult>();
            for (int i = 0; i < artifacts.length; i++) {
                BedHeight[] pair =
                    getHeightPair(artifacts[i][0], artifacts[i][1], "epoch");
                BedDiffEpochResult res = calculateEpochDifference(pair);
                results.add(res);
            }
            return new CalculationResult(
                results.toArray(new BedDiffEpochResult[results.size()]), this);
        }

       return new CalculationResult();
    }

    private BedHeight[] getHeightPair(
        FLYSArtifact art1,
        FLYSArtifact art2,
        String type
    ) {
        int id1 = BedDifferencesAccess.getHeightId(art1);
        int id2 = BedDifferencesAccess.getHeightId(art2);

        BedHeight[] heights = new BedHeight[2];
        heights[0] = BedHeightFactory.getHeight(type, id1, 0);
        heights[1] = BedHeightFactory.getHeight(type, id2, 0);
        return heights;
    }

    private BedDiffEpochResult calculateEpochDifference(BedHeight[] pair) {

        TDoubleArrayList stations = pair[0].getStations();
        TDoubleArrayList diffRes = new TDoubleArrayList();
        TDoubleArrayList kms = new TDoubleArrayList();
        TDoubleArrayList heights1 = new TDoubleArrayList();
        TDoubleArrayList heights2 = new TDoubleArrayList();

        for (int i = 0; i < stations.size(); i++) {
            if (!Double.isNaN(pair[0].getHeight(stations.get(i))) &&
                !Double.isNaN(pair[1].getHeight(stations.get(i)))) {
                double hDiff =
                    pair[0].getHeight(stations.get(i)) -
                    pair[1].getHeight(stations.get(i));
                diffRes.add(hDiff);
                kms.add(stations.get(i));
                heights1.add(pair[0].getHeight(stations.get(i)));
                heights2.add(pair[1].getHeight(stations.get(i)));
            }
        }
        Date start = ((BedHeightEpoch)pair[0]).getStart();
        Date end = ((BedHeightEpoch)pair[1]).getEnd();
        return new BedDiffEpochResult(kms, diffRes, heights1, heights2, start, end);
    }

    private BedDiffYearResult calculateYearDifference(BedHeight[] pair) {

        TDoubleArrayList stations = pair[0].getStations();
        TDoubleArrayList diffRes = new TDoubleArrayList();
        TDoubleArrayList kms = new TDoubleArrayList();
        TDoubleArrayList morphs = new TDoubleArrayList();
        TDoubleArrayList absolute = new TDoubleArrayList();
        TDoubleArrayList gap = new TDoubleArrayList();
        TDoubleArrayList heights1 = new TDoubleArrayList();
        TDoubleArrayList heights2 = new TDoubleArrayList();

        BedHeightSingle s1 = (BedHeightSingle)pair[0];
        BedHeightSingle s2 = (BedHeightSingle)pair[1];
        int range = s1.getYear() - s2.getYear();
        if (range  < 0) {
            range = range * -1;
        }
        for (int i = 0; i < stations.size(); i++) {
            if (!Double.isNaN(s1.getHeight(stations.get(i))) &&
                !Double.isNaN(s2.getHeight(stations.get(i)))) {
                double hDiff =
                    s1.getHeight(stations.get(i)) -
                    s2.getHeight(stations.get(i));
                diffRes.add(hDiff);
                double km = stations.get(i);
                kms.add(km);
                if (s1.getMorphWidth(km) >
                    s2.getMorphWidth(km)) {
                    morphs.add(s1.getMorphWidth(km));
                }
                else {
                    morphs.add(s2.getMorphWidth(km));
                }
                if (s1.getDataGap(km) > s2.getDataGap(km)) {
                    gap.add(s1.getDataGap(km));
                }
                else {
                    gap.add(s2.getDataGap(km));
                }
                absolute.add((hDiff / range) * 100);
                heights1.add(s1.getHeight(km));
                heights2.add(s2.getHeight(km));
            }
        }
        return new BedDiffYearResult(
            kms,
            diffRes,
            heights1,
            heights2,
            morphs,
            absolute,
            gap,
            s1.getYear(),
            s2.getYear());
    }
}

http://dive4elements.wald.intevation.org