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