view gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearToMap.java @ 522:c896282c2601

Issue 156 solved. Added width, height and points as parameter to svg and pdf output mode. Width and height have an effact on the width and height of the export, points is a boolean property which enables/disables the drawing of data points. gnv-artifacts/trunk@616 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Mon, 25 Jan 2010 09:18:31 +0000
parents aec85d00d82c
children 9a828e5a2390
line wrap: on
line source
package de.intevation.gnv.math;

import com.vividsolutions.jts.geom.Coordinate;

import java.util.List;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 *  @author Sascha L. Teichmann
 */
public class LinearToMap
{
    public static final class Range {
        private Range next;

        private double from;
        private double to;
        private double b;

        private Coordinate p1;
        private Coordinate p2;

        private Interpolator interpolator;

        public Range() {
        }

        public Range(
            double       from, 
            double       to,
            Interpolator interpolator,
            Coordinate   p1,
            Coordinate   p2
        ) {
            this.from         = from;
            this.to           = to;
            this.interpolator = interpolator;
            this.p1           = p1;
            this.p2           = p2;

            b = from == to
                ? 0d
                : 1.0d/(to - from);
        }

        public void eval(double x, Coordinate v) {
            interpolator.interpolate((x - from)*b, v);
        }

        public boolean inside(double x) {
            return x >= from && x <= to;
        }

        public Coordinate startPoint() {
            return p1;
        }

        public Coordinate endPoint() {
            return p2;
        }
    } // class Range

    protected Range head;
    protected Range last;

    public LinearToMap() {
    }

    public LinearToMap(
        List<? extends Coordinate> path, 
        double                     from, 
        double                     to,
        Metrics                    metrics
    ) {
        double diagramLength = Math.abs(to - from);

        double worldLength = length(path, metrics);

        double rangeStart = from;

        Range last = null;

        for (int i = 1, N = path.size(); i < N; ++i) {
            Coordinate p1 = path.get(i-1);
            Coordinate p2 = path.get(i);
            double segmentLength = metrics.distance(p1, p2);

            double relativeLength = segmentLength / worldLength;

            double rangeLength = diagramLength * relativeLength;

            double rangeEnd = rangeStart + rangeLength;

            Range range = new Range(
                rangeStart, rangeEnd,
                metrics.getInterpolator(p1, p2),
                p1, p2);

            if (last == null) {
                last = head = range;
            }
            else {
                last.next = range;
                last = range;
            }
            rangeStart = rangeEnd;
        }
    }

    protected Range locateRange(double diagramX) {

        if (last != null && last.inside(diagramX)) {
            return last;
        }

        Range current = head;
        while (current != null) {
            if (current.inside(diagramX)) {
                return last = current;
            }
            current = current.next;
        }

        return null;
    }

    public boolean locate(double diagramX, Coordinate v) {
        Range range = locateRange(diagramX);
        if (range == null) {
            return false;
        }
        range.eval(diagramX, v);
        return true;
    }

    public static double length(
        List<? extends Coordinate> path, 
        Metrics                    metrics
    ) {
        double sum = 0d;
        for (int i = path.size()-1; i >= 1; --i) {
            Coordinate p1 = path.get(i);
            Coordinate p2 = path.get(i-1);
            sum += metrics.distance(p1, p2);
        }
        return sum;
    }

    public int numRanges() {
        int count = 0;
        Range current = head;
        while (current != null) {
            ++count;
            current = current.next;
        }
        return count;
    }

    public Iterator ranges() {
        return new Iterator() {

            Range current = head;

            public boolean hasNext() {
                return current != null;
            }

            public Object next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                Range x = current;
                current = current.next;
                return x;
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:

http://dive4elements.wald.intevation.org