Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearToMap.java @ 496:f14c5d1b5b71
Issue142. Paid attention on array length. Parameters without values resulted in ArrayIndexOutOfBoundsExceptions.
gnv-artifacts/trunk@576 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Tue, 19 Jan 2010 16:47:25 +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: