sascha@360: package de.intevation.gnv.math; sascha@360: sascha@361: import com.vividsolutions.jts.geom.Coordinate; sascha@360: sascha@360: import java.util.List; sascha@360: import java.util.Iterator; sascha@360: import java.util.NoSuchElementException; sascha@360: sascha@360: /** sascha@360: * @author Sascha L. Teichmann sascha@360: */ sascha@360: public class LinearToMap sascha@360: { sascha@360: public static final class Range { sascha@360: private Range next; sascha@360: sascha@360: private double from; sascha@360: private double to; sascha@360: private double b; sascha@360: sascha@361: private Coordinate p1; sascha@361: private Coordinate p2; sascha@360: sascha@360: private Interpolator interpolator; sascha@360: sascha@360: public Range() { sascha@360: } sascha@360: sascha@360: public Range( sascha@360: double from, sascha@360: double to, sascha@360: Interpolator interpolator, sascha@361: Coordinate p1, sascha@361: Coordinate p2 sascha@360: ) { sascha@360: this.from = from; sascha@360: this.to = to; sascha@360: this.interpolator = interpolator; sascha@360: this.p1 = p1; sascha@360: this.p2 = p2; sascha@360: sascha@360: b = from == to sascha@360: ? 0d sascha@360: : 1.0d/(to - from); sascha@360: } sascha@360: sascha@361: public void eval(double x, Coordinate v) { sascha@360: interpolator.interpolate((x - from)*b, v); sascha@360: } sascha@360: sascha@360: public boolean inside(double x) { sascha@360: return x >= from && x <= to; sascha@360: } sascha@360: sascha@361: public Coordinate startPoint() { sascha@360: return p1; sascha@360: } sascha@360: sascha@361: public Coordinate endPoint() { sascha@360: return p2; sascha@360: } sascha@360: } // class Range sascha@360: sascha@360: protected Range head; sascha@360: protected Range last; sascha@360: sascha@360: public LinearToMap() { sascha@360: } sascha@360: sascha@360: public LinearToMap( sascha@361: List path, sascha@361: double from, sascha@361: double to, sascha@361: Metrics metrics sascha@360: ) { sascha@360: double diagramLength = Math.abs(to - from); sascha@360: sascha@360: double worldLength = length(path, metrics); sascha@360: sascha@360: double rangeStart = from; sascha@360: sascha@360: Range last = null; sascha@360: sascha@360: for (int i = 1, N = path.size(); i < N; ++i) { sascha@361: Coordinate p1 = path.get(i-1); sascha@361: Coordinate p2 = path.get(i); sascha@360: double segmentLength = metrics.distance(p1, p2); sascha@360: sascha@360: double relativeLength = segmentLength / worldLength; sascha@360: sascha@360: double rangeLength = diagramLength * relativeLength; sascha@360: sascha@360: double rangeEnd = rangeStart + rangeLength; sascha@360: sascha@360: Range range = new Range( sascha@360: rangeStart, rangeEnd, sascha@360: metrics.getInterpolator(p1, p2), sascha@360: p1, p2); sascha@360: sascha@360: if (last == null) { sascha@360: last = head = range; sascha@360: } sascha@360: else { sascha@360: last.next = range; sascha@360: last = range; sascha@360: } sascha@360: rangeStart = rangeEnd; sascha@360: } sascha@360: } sascha@360: sascha@360: protected Range locateRange(double diagramX) { sascha@360: sascha@360: if (last != null && last.inside(diagramX)) { sascha@360: return last; sascha@360: } sascha@360: sascha@360: Range current = head; sascha@360: while (current != null) { sascha@360: if (current.inside(diagramX)) { sascha@360: return last = current; sascha@360: } sascha@360: current = current.next; sascha@360: } sascha@360: sascha@360: return null; sascha@360: } sascha@360: sascha@361: public boolean locate(double diagramX, Coordinate v) { sascha@360: Range range = locateRange(diagramX); sascha@360: if (range == null) { sascha@360: return false; sascha@360: } sascha@360: range.eval(diagramX, v); sascha@360: return true; sascha@360: } sascha@360: sascha@361: public static double length( sascha@361: List path, sascha@361: Metrics metrics sascha@361: ) { sascha@360: double sum = 0d; sascha@360: for (int i = path.size()-1; i >= 1; --i) { sascha@361: Coordinate p1 = path.get(i); sascha@361: Coordinate p2 = path.get(i-1); sascha@360: sum += metrics.distance(p1, p2); sascha@360: } sascha@360: return sum; sascha@360: } sascha@360: sascha@360: public int numRanges() { sascha@360: int count = 0; sascha@360: Range current = head; sascha@360: while (current != null) { sascha@360: ++count; sascha@360: current = current.next; sascha@360: } sascha@360: return count; sascha@360: } sascha@360: sascha@360: public Iterator ranges() { sascha@360: return new Iterator() { sascha@360: sascha@360: Range current = head; sascha@360: sascha@360: public boolean hasNext() { sascha@360: return current != null; sascha@360: } sascha@360: sascha@360: public Object next() { sascha@360: if (!hasNext()) { sascha@360: throw new NoSuchElementException(); sascha@360: } sascha@360: Range x = current; sascha@360: current = current.next; sascha@360: return x; sascha@360: } sascha@360: sascha@360: public void remove() { sascha@360: throw new UnsupportedOperationException(); sascha@360: } sascha@360: }; sascha@360: } sascha@360: } sascha@360: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: