Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java @ 540:80630520e25a
merged gnv-artifacts/0.4
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:49 +0200 |
parents | 061355435075 |
children | 24a85678bd39 |
comparison
equal
deleted
inserted
replaced
415:9f4a0b990d27 | 540:80630520e25a |
---|---|
1 package de.intevation.gnv.chart; | |
2 | |
3 import java.util.Collection; | |
4 import java.util.Locale; | |
5 | |
6 import com.vividsolutions.jts.geom.Point; | |
7 import com.vividsolutions.jts.io.WKTReader; | |
8 import com.vividsolutions.jts.io.ParseException; | |
9 | |
10 import org.apache.log4j.Logger; | |
11 | |
12 import org.jfree.chart.ChartTheme; | |
13 import org.jfree.chart.plot.PlotOrientation; | |
14 import org.jfree.data.general.Series; | |
15 import org.jfree.data.xy.XYSeries; | |
16 | |
17 import de.intevation.gnv.geobackend.base.Result; | |
18 import de.intevation.gnv.utils.DistanceCalculator; | |
19 | |
20 | |
21 /** | |
22 * @author Ingo Weinzierl <ingo.weinzierl@intevation.de> | |
23 */ | |
24 public class HorizontalProfileChart | |
25 extends VerticalProfileChart | |
26 { | |
27 private static Logger log = Logger.getLogger(HorizontalProfileChart.class); | |
28 | |
29 private static WKTReader wktReader = new WKTReader(); | |
30 private Point lastPoint; | |
31 private double distance; | |
32 | |
33 | |
34 public HorizontalProfileChart( | |
35 ChartLabels labels, | |
36 ChartTheme theme, | |
37 Collection parameters, | |
38 Collection measurements, | |
39 Collection dates, | |
40 Collection result, | |
41 Collection timeGaps, | |
42 Locale locale, | |
43 boolean linesVisible, | |
44 boolean shapesVisible | |
45 ) { | |
46 super( | |
47 labels, | |
48 theme, | |
49 parameters, | |
50 measurements, | |
51 dates, | |
52 result, | |
53 timeGaps, | |
54 locale, | |
55 linesVisible, | |
56 shapesVisible | |
57 ); | |
58 this.PLOT_ORIENTATION = PlotOrientation.VERTICAL; | |
59 this.distance = 0; | |
60 } | |
61 | |
62 | |
63 protected void gapDetection( | |
64 Result[] results, | |
65 Series series, | |
66 int startPos, | |
67 int endPos | |
68 ) { | |
69 log.debug("Start gap detection."); | |
70 try { | |
71 Point startValue = getPoint(results[startPos]); | |
72 Point endValue = getPoint(results[endPos-1]); | |
73 if (results[0].getInteger("DATAID") == 2) | |
74 addGapsOnGrid(results, series, startPos, endPos); | |
75 else | |
76 addGaps( | |
77 results, | |
78 series, | |
79 startValue, | |
80 endValue, | |
81 startPos, | |
82 endPos | |
83 ); | |
84 } | |
85 catch (ParseException pe) { | |
86 log.warn( | |
87 "Error while parsing points for gap detection. " + | |
88 "No gaps for current series will be detected." | |
89 ); | |
90 } | |
91 | |
92 log.debug("Gap detection finished."); | |
93 } | |
94 | |
95 | |
96 protected void addValue(Result row, Series series) { | |
97 try { | |
98 Point point = (Point) wktReader.read(row.getString("SHAPE")); | |
99 if (lastPoint != null) | |
100 distance = distance + DistanceCalculator.calculateDistance( | |
101 lastPoint, point | |
102 ); | |
103 lastPoint = point; | |
104 | |
105 ((XYSeries) series).add( | |
106 distance, | |
107 row.getDouble("YORDINATE") | |
108 ); | |
109 } | |
110 catch(ParseException pe) { | |
111 log.warn("No data found while parsing."); | |
112 } | |
113 } | |
114 | |
115 | |
116 protected void addSeries(Series series, String label, int idx) { | |
117 super.addSeries(series, label, idx); | |
118 | |
119 // reset values used by current series for next series | |
120 lastPoint = null; | |
121 distance = 0; | |
122 } | |
123 | |
124 | |
125 protected String createSeriesName( | |
126 String breakPoint1, | |
127 String breakPoint2, | |
128 String breakPoint3 | |
129 ) { | |
130 log.debug("create seriesname of horizontalprofile chart"); | |
131 return super.createSeriesName( | |
132 breakPoint1, | |
133 breakPoint2, | |
134 breakPoint3) + | |
135 " " + | |
136 findValueTitle(dates, breakPoint3); | |
137 } | |
138 | |
139 | |
140 protected void addGapsOnGrid( | |
141 Result[] results, | |
142 Series series, | |
143 int startPos, | |
144 int endPos | |
145 ) { | |
146 String axis = getDependendAxisName( | |
147 results[startPos], | |
148 results[startPos+1] | |
149 ); | |
150 | |
151 double range = 0; | |
152 double distance = 0; | |
153 int last = 0; | |
154 int current = 0; | |
155 Point lastPoint = null; | |
156 Point currentPoint = null; | |
157 | |
158 for (int i = startPos+1; i < endPos; i++) { | |
159 try { | |
160 last = results[i-1].getInteger(axis); | |
161 lastPoint = getPoint(results[i-1]); | |
162 current = results[i].getInteger(axis); | |
163 currentPoint = getPoint(results[i]); | |
164 distance = DistanceCalculator.calculateDistance( | |
165 lastPoint, | |
166 currentPoint | |
167 ); | |
168 | |
169 boolean detected = gridDetection(last, current); | |
170 | |
171 if (detected) { | |
172 log.debug( | |
173 "Gap detected on grid between " + range + | |
174 " and " + (range+distance) | |
175 ); | |
176 | |
177 ((XYSeries) series).add(range+0.0001, null); | |
178 } | |
179 | |
180 range += distance; | |
181 } | |
182 catch (ParseException pe) { | |
183 log.warn("Error while parsing point for gap detection.", pe); | |
184 } | |
185 } | |
186 } | |
187 | |
188 | |
189 protected void addGaps( | |
190 Result[] results, | |
191 Series series, | |
192 Point startValue, | |
193 Point endValue, | |
194 int startPos, | |
195 int endPos | |
196 ) { | |
197 double range = 0; | |
198 Point last = null; | |
199 Point now = null; | |
200 | |
201 for (int i = startPos+1; i < endPos; i++) { | |
202 boolean detected = false; | |
203 | |
204 try { | |
205 last = (Point) getPoint(results[i-1]); | |
206 now = (Point) getPoint(results[i]); | |
207 | |
208 // gap detection for more than GAP_MAX_VALUES values | |
209 if (results.length > GAP_MAX_VALUES) | |
210 detected = simpleDetection(startValue, endValue, last, now); | |
211 // gap detection for less than GAP_MAX_VALUES values | |
212 else | |
213 detected = specialDetection( | |
214 startValue, | |
215 endValue, | |
216 last, | |
217 now, | |
218 results.length | |
219 ); | |
220 | |
221 // gap detected, insert null value to break line | |
222 if (detected) { | |
223 log.info("Gap after " + range); | |
224 double x = range + 0.0001; | |
225 | |
226 ((XYSeries)series).add(x, null); | |
227 } | |
228 | |
229 range += DistanceCalculator.calculateDistance(last,now); | |
230 } | |
231 catch (ParseException pe) { | |
232 log.warn("Error while parsing point."); | |
233 } | |
234 | |
235 } | |
236 } | |
237 | |
238 | |
239 protected boolean simpleDetection( | |
240 Point start, | |
241 Point end, | |
242 Point last, | |
243 Point current | |
244 ) { | |
245 double delta = DistanceCalculator.calculateDistance(start, end); | |
246 double deltaSmall = DistanceCalculator.calculateDistance(last,current); | |
247 | |
248 return (deltaSmall > (delta / 100 * PERCENTAGE)); | |
249 } | |
250 | |
251 | |
252 protected boolean specialDetection( | |
253 Point start, | |
254 Point end, | |
255 Point last, | |
256 Point current, | |
257 int count | |
258 ) { | |
259 double delta = Math.abs( | |
260 DistanceCalculator.calculateDistance(end, start) | |
261 ); | |
262 double smallDelta = Math.abs( | |
263 DistanceCalculator.calculateDistance(current, last) | |
264 ); | |
265 | |
266 return (smallDelta > (3.0 / (count - 1) * delta)); | |
267 } | |
268 | |
269 @Override | |
270 protected String getDependendAxisName(Result first, Result second) { | |
271 if (first.getInteger("IPOSITION") == second.getInteger("IPOSITION")) | |
272 return "JPOSITION"; | |
273 | |
274 return "IPOSITION"; | |
275 } | |
276 | |
277 private Point getPoint(Result result) | |
278 throws ParseException | |
279 { | |
280 return (Point) wktReader.read(result.getString("SHAPE")); | |
281 } | |
282 } | |
283 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : |