view gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java @ 605:e8ebdbc7f1e3

First step of removing the cache blob. The static part of the describe document will be created by using the input data stored at each state. Some TODOs left (see ChangeLog). gnv-artifacts/trunk@671 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Tue, 09 Feb 2010 14:27:55 +0000
parents 061355435075
children 24a85678bd39
line wrap: on
line source
package de.intevation.gnv.chart;

import java.util.Collection;
import java.util.Locale;

import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.io.WKTReader;
import com.vividsolutions.jts.io.ParseException;

import org.apache.log4j.Logger;

import org.jfree.chart.ChartTheme;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.general.Series;
import org.jfree.data.xy.XYSeries;

import de.intevation.gnv.geobackend.base.Result;
import de.intevation.gnv.utils.DistanceCalculator;


/**
 * @author Ingo Weinzierl <ingo.weinzierl@intevation.de>
 */
public class HorizontalProfileChart
extends      VerticalProfileChart
{
    private static Logger log = Logger.getLogger(HorizontalProfileChart.class);

    private static WKTReader wktReader = new WKTReader();
    private        Point     lastPoint;
    private        double    distance;


    public HorizontalProfileChart(
        ChartLabels labels,
        ChartTheme  theme,
        Collection  parameters,
        Collection  measurements,
        Collection  dates,
        Collection  result,
        Collection  timeGaps,
        Locale      locale,
        boolean     linesVisible,
        boolean     shapesVisible
    ) {
        super(
            labels,
            theme,
            parameters,
            measurements,
            dates,
            result,
            timeGaps,
            locale,
            linesVisible,
            shapesVisible
        );
        this.PLOT_ORIENTATION = PlotOrientation.VERTICAL;
        this.distance         = 0;
    }


    protected void gapDetection(
        Result[] results,
        Series   series,
        int      startPos,
        int      endPos
    ) {
        log.debug("Start gap detection.");
        try {
            Point startValue = getPoint(results[startPos]);
            Point endValue   = getPoint(results[endPos-1]);
            if (results[0].getInteger("DATAID") == 2)
                addGapsOnGrid(results, series, startPos, endPos);
            else
                addGaps(
                    results,
                    series,
                    startValue,
                    endValue,
                    startPos,
                    endPos
                );
        }
        catch (ParseException pe) {
            log.warn(
                "Error while parsing points for gap detection. " +
                "No gaps for current series will be detected."
            );
        }

        log.debug("Gap detection finished.");
    }


    protected void addValue(Result row, Series series) {
        try {
            Point point = (Point) wktReader.read(row.getString("SHAPE"));
            if (lastPoint != null)
                distance = distance + DistanceCalculator.calculateDistance(
                    lastPoint, point
                );
            lastPoint = point;

            ((XYSeries) series).add(
                distance,
                row.getDouble("YORDINATE")
            );
        }
        catch(ParseException pe) {
            log.warn("No data found while parsing.");
        }
    }


    protected void addSeries(Series series, String label, int idx) {
        super.addSeries(series, label, idx);

        // reset values used by current series for next series
        lastPoint = null;
        distance  = 0;
    }


    protected String createSeriesName(
        String breakPoint1,
        String breakPoint2,
        String breakPoint3
    ) {
        log.debug("create seriesname of horizontalprofile chart");
        return super.createSeriesName(
            breakPoint1,
            breakPoint2,
            breakPoint3) +
            " " +
            findValueTitle(dates, breakPoint3);
    }


    protected void addGapsOnGrid(
        Result[] results,
        Series   series,
        int      startPos,
        int      endPos
    ) {
        String axis = getDependendAxisName(
            results[startPos],
            results[startPos+1]
        );

        double range        = 0;
        double distance     = 0;
        int    last         = 0;
        int    current      = 0;
        Point  lastPoint    = null;
        Point  currentPoint = null;

        for (int i = startPos+1; i < endPos; i++) {
            try {
                last         = results[i-1].getInteger(axis);
                lastPoint    = getPoint(results[i-1]);
                current      = results[i].getInteger(axis);
                currentPoint = getPoint(results[i]);
                distance     = DistanceCalculator.calculateDistance(
                    lastPoint,
                    currentPoint
                );

                boolean detected = gridDetection(last, current);

                if (detected) {
                    log.debug(
                        "Gap detected on grid between " + range +
                        " and " + (range+distance)
                    );

                    ((XYSeries) series).add(range+0.0001, null);
                }

                range += distance;
            }
            catch (ParseException pe) {
                log.warn("Error while parsing point for gap detection.", pe);
            }
        }
    }


    protected void addGaps(
        Result[] results,
        Series   series,
        Point    startValue,
        Point    endValue,
        int      startPos,
        int      endPos
    ) {
        double range = 0;
        Point  last  = null;
        Point  now   = null;

        for (int i = startPos+1; i < endPos; i++) {
            boolean detected = false;

            try {
                last   = (Point) getPoint(results[i-1]);
                now    = (Point) getPoint(results[i]);

                // gap detection for more than GAP_MAX_VALUES values
                if (results.length > GAP_MAX_VALUES)
                    detected = simpleDetection(startValue, endValue, last, now);
                // gap detection for less than GAP_MAX_VALUES values
                else
                    detected = specialDetection(
                        startValue,
                        endValue,
                        last,
                        now,
                        results.length
                    );

                // gap detected, insert null value to break line
                if (detected) {
                    log.info("Gap after " + range);
                    double x = range + 0.0001;

                    ((XYSeries)series).add(x, null);
                }

                range += DistanceCalculator.calculateDistance(last,now);
            }
            catch (ParseException pe) {
                log.warn("Error while parsing point.");
            }

        }
    }


    protected boolean simpleDetection(
        Point start,
        Point end,
        Point last,
        Point current
    ) {
        double delta      = DistanceCalculator.calculateDistance(start, end);
        double deltaSmall = DistanceCalculator.calculateDistance(last,current);

        return (deltaSmall > (delta / 100 * PERCENTAGE));
    }


    protected boolean specialDetection(
        Point start,
        Point end,
        Point last,
        Point current,
        int   count
    ) {
        double delta      = Math.abs(
            DistanceCalculator.calculateDistance(end, start)
        );
        double smallDelta = Math.abs(
            DistanceCalculator.calculateDistance(current, last)
        );

        return (smallDelta > (3.0 / (count - 1) * delta));
    }

    @Override
    protected String getDependendAxisName(Result first, Result second) {
        if (first.getInteger("IPOSITION") == second.getInteger("IPOSITION"))
            return "JPOSITION";

        return "IPOSITION";
    }

    private Point getPoint(Result result)
    throws ParseException
    {
        return (Point) wktReader.read(result.getString("SHAPE"));
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org