# HG changeset patch # User Sascha L. Teichmann # Date 1260892738 0 # Node ID ee760729f6b8a2771b65618d2a71e59947086d15 # Parent 59ad8f37a59010a4ef2a2c7841150c56b463ed20 Added mapping from linear diagram space to 2D map coordinates. gnv-artifacts/trunk@434 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 59ad8f37a590 -r ee760729f6b8 gnv-artifacts/ChangeLog --- a/gnv-artifacts/ChangeLog Tue Dec 15 15:50:39 2009 +0000 +++ b/gnv-artifacts/ChangeLog Tue Dec 15 15:58:58 2009 +0000 @@ -1,6 +1,16 @@ +2009-12-15 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/LinearToMap.java: Map linear + coordinates (from, to) to world coordinates (x, y) along a line string + given by a set of java.awt.geom.Point2D points. + + * src/main/java/de/intevation/gnv/math/LinearMetrics.java: Implements + Euclidean metric used by LinearToMap. TODO: Do same for WGS84 to + be more precise. + 2009-12-15 Tim Englich - * src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java (calculateStatistics): + * src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java (calculateStatistics): Issue96 Resloved big that one entry is missiing in the Statitic. The last row of the ResultSet was never used. diff -r 59ad8f37a590 -r ee760729f6b8 gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearMetrics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearMetrics.java Tue Dec 15 15:58:58 2009 +0000 @@ -0,0 +1,63 @@ +package de.intevation.gnv.math; + +import java.awt.geom.Point2D; + +import de.intevation.gnv.math.LinearToMap.Metrics; +import de.intevation.gnv.math.LinearToMap.Interpolator; + +/** + * @author Sascha L. Teichmann + */ +public final class LinearMetrics +implements Metrics +{ + public static final Metrics INSTANCE = + new LinearMetrics(); + + public static final class LinearInterpolator + implements Interpolator + { + private double mx; + private double bx; + private double my; + private double by; + + public LinearInterpolator(Point2D p1, Point2D p2) { + + /* + I) p1.x = 0*m + bx + II) p2.x = 1*m + bx + + bx = p1.x + + p2.x = m + p1.x + + mx = p2.x - p1.x + */ + + bx = p1.getX(); + mx = p2.getX() - bx; + + by = p1.getY(); + my = p2.getY() - by; + } + + public void interpolate(double t, Point2D v) { + double x = t*mx + bx; + double y = t*my + by; + v.setLocation(x, y); + } + } // class LinearInterpolator + + private LinearMetrics() { + } + + public double distance(Point2D p1, Point2D p2) { + return p1.distance(p2); + } + + public Interpolator getInterpolator(Point2D p1, Point2D p2) { + return new LinearInterpolator(p1, p2); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: diff -r 59ad8f37a590 -r ee760729f6b8 gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearToMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearToMap.java Tue Dec 15 15:58:58 2009 +0000 @@ -0,0 +1,195 @@ +package de.intevation.gnv.math; + +import java.awt.geom.Point2D; + +import java.util.List; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * @author Sascha L. Teichmann + */ +public class LinearToMap +{ + public interface Interpolator { + + void interpolate(double t, Point2D v); + + } // interface Interpolator + + public interface Metrics { + + double distance(Point2D p1, Point2D p2); + + Interpolator getInterpolator(Point2D p1, Point2D p2); + + } // interface Metrics + + public static final class Range { + private Range next; + + private double from; + private double to; + private double b; + + private Point2D p1; + private Point2D p2; + + private Interpolator interpolator; + + public Range() { + } + + public Range( + double from, + double to, + Interpolator interpolator, + Point2D p1, + Point2D 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, Point2D v) { + interpolator.interpolate((x - from)*b, v); + } + + public boolean inside(double x) { + return x >= from && x <= to; + } + + public Point2D startPoint() { + return p1; + } + + public Point2D endPoint() { + return p2; + } + } // class Range + + protected Range head; + protected Range last; + + public LinearToMap() { + } + + public LinearToMap( + List 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) { + Point2D p1 = (Point2D)path.get(i-1); + Point2D p2 = (Point2D)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, Point2D v) { + Range range = locateRange(diagramX); + if (range == null) { + return false; + } + range.eval(diagramX, v); + return true; + } + + public static double length(List path, Metrics metrics) { + double sum = 0d; + for (int i = path.size()-1; i >= 1; --i) { + Point2D p1 = (Point2D)path.get(i); + Point2D p2 = (Point2D)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: