comparison gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearToMap.java @ 360:ee760729f6b8

Added mapping from linear diagram space to 2D map coordinates. gnv-artifacts/trunk@434 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 15 Dec 2009 15:58:58 +0000
parents
children aec85d00d82c
comparison
equal deleted inserted replaced
359:59ad8f37a590 360:ee760729f6b8
1 package de.intevation.gnv.math;
2
3 import java.awt.geom.Point2D;
4
5 import java.util.List;
6 import java.util.Iterator;
7 import java.util.NoSuchElementException;
8
9 /**
10 * @author Sascha L. Teichmann
11 */
12 public class LinearToMap
13 {
14 public interface Interpolator {
15
16 void interpolate(double t, Point2D v);
17
18 } // interface Interpolator
19
20 public interface Metrics {
21
22 double distance(Point2D p1, Point2D p2);
23
24 Interpolator getInterpolator(Point2D p1, Point2D p2);
25
26 } // interface Metrics
27
28 public static final class Range {
29 private Range next;
30
31 private double from;
32 private double to;
33 private double b;
34
35 private Point2D p1;
36 private Point2D p2;
37
38 private Interpolator interpolator;
39
40 public Range() {
41 }
42
43 public Range(
44 double from,
45 double to,
46 Interpolator interpolator,
47 Point2D p1,
48 Point2D p2
49 ) {
50 this.from = from;
51 this.to = to;
52 this.interpolator = interpolator;
53 this.p1 = p1;
54 this.p2 = p2;
55
56 b = from == to
57 ? 0d
58 : 1.0d/(to - from);
59 }
60
61 public void eval(double x, Point2D v) {
62 interpolator.interpolate((x - from)*b, v);
63 }
64
65 public boolean inside(double x) {
66 return x >= from && x <= to;
67 }
68
69 public Point2D startPoint() {
70 return p1;
71 }
72
73 public Point2D endPoint() {
74 return p2;
75 }
76 } // class Range
77
78 protected Range head;
79 protected Range last;
80
81 public LinearToMap() {
82 }
83
84 public LinearToMap(
85 List path,
86 double from,
87 double to,
88 Metrics metrics
89 ) {
90 double diagramLength = Math.abs(to - from);
91
92 double worldLength = length(path, metrics);
93
94 double rangeStart = from;
95
96 Range last = null;
97
98 for (int i = 1, N = path.size(); i < N; ++i) {
99 Point2D p1 = (Point2D)path.get(i-1);
100 Point2D p2 = (Point2D)path.get(i);
101 double segmentLength = metrics.distance(p1, p2);
102
103 double relativeLength = segmentLength / worldLength;
104
105 double rangeLength = diagramLength * relativeLength;
106
107 double rangeEnd = rangeStart + rangeLength;
108
109 Range range = new Range(
110 rangeStart, rangeEnd,
111 metrics.getInterpolator(p1, p2),
112 p1, p2);
113
114 if (last == null) {
115 last = head = range;
116 }
117 else {
118 last.next = range;
119 last = range;
120 }
121 rangeStart = rangeEnd;
122 }
123 }
124
125 protected Range locateRange(double diagramX) {
126
127 if (last != null && last.inside(diagramX)) {
128 return last;
129 }
130
131 Range current = head;
132 while (current != null) {
133 if (current.inside(diagramX)) {
134 return last = current;
135 }
136 current = current.next;
137 }
138
139 return null;
140 }
141
142 public boolean locate(double diagramX, Point2D v) {
143 Range range = locateRange(diagramX);
144 if (range == null) {
145 return false;
146 }
147 range.eval(diagramX, v);
148 return true;
149 }
150
151 public static double length(List path, Metrics metrics) {
152 double sum = 0d;
153 for (int i = path.size()-1; i >= 1; --i) {
154 Point2D p1 = (Point2D)path.get(i);
155 Point2D p2 = (Point2D)path.get(i-1);
156 sum += metrics.distance(p1, p2);
157 }
158 return sum;
159 }
160
161 public int numRanges() {
162 int count = 0;
163 Range current = head;
164 while (current != null) {
165 ++count;
166 current = current.next;
167 }
168 return count;
169 }
170
171 public Iterator ranges() {
172 return new Iterator() {
173
174 Range current = head;
175
176 public boolean hasNext() {
177 return current != null;
178 }
179
180 public Object next() {
181 if (!hasNext()) {
182 throw new NoSuchElementException();
183 }
184 Range x = current;
185 current = current.next;
186 return x;
187 }
188
189 public void remove() {
190 throw new UnsupportedOperationException();
191 }
192 };
193 }
194 }
195 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:

http://dive4elements.wald.intevation.org