Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java @ 376:d8f3ef441bf2
merged gnv-artifacts/0.3
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:47 +0200 |
parents | 061355435075 |
children | 04a242c67fe6 |
comparison
equal
deleted
inserted
replaced
293:6b0ef2324d02 | 376:d8f3ef441bf2 |
---|---|
1 package de.intevation.gnv.chart; | |
2 | |
3 import java.util.Collection; | |
4 import java.util.HashMap; | |
5 import java.util.Iterator; | |
6 import java.util.Locale; | |
7 | |
8 import org.apache.log4j.Logger; | |
9 | |
10 import org.jfree.chart.ChartTheme; | |
11 import org.jfree.chart.axis.Axis; | |
12 import org.jfree.chart.plot.XYPlot; | |
13 import org.jfree.chart.plot.PlotOrientation; | |
14 import org.jfree.data.xy.XYSeries; | |
15 import org.jfree.data.general.Series; | |
16 import org.jfree.data.xy.XYSeriesCollection; | |
17 | |
18 import de.intevation.gnv.geobackend.base.Result; | |
19 import de.intevation.gnv.state.describedata.KeyValueDescibeData; | |
20 | |
21 | |
22 /** | |
23 * @author Ingo Weinzierl <ingo.weinzierl@intevation.de> | |
24 */ | |
25 public class VerticalProfileChart | |
26 extends AbstractXYLineChart | |
27 { | |
28 private static Logger log = Logger.getLogger(VerticalProfileChart.class); | |
29 | |
30 protected final double PERCENTAGE = 5.0; | |
31 protected final double GAP_MAX_LEVEL = Math.sqrt(2.0); | |
32 protected final int GAP_MAX_VALUES = 60; | |
33 | |
34 | |
35 public VerticalProfileChart( | |
36 ChartLabels labels, | |
37 ChartTheme theme, | |
38 Collection parameters, | |
39 Collection measurements, | |
40 Collection dates, | |
41 Collection result, | |
42 Collection timeGaps, | |
43 Locale locale, | |
44 boolean linesVisible, | |
45 boolean shapesVisible | |
46 ) { | |
47 this.labels = labels; | |
48 this.theme = theme; | |
49 this.parameters = parameters; | |
50 this.measurements = measurements; | |
51 this.dates = dates; | |
52 this.resultSet = result; | |
53 this.timeGaps = timeGaps; | |
54 this.locale = locale; | |
55 this.PLOT_ORIENTATION = PlotOrientation.HORIZONTAL; | |
56 this.linesVisible = linesVisible; | |
57 this.shapesVisible = shapesVisible; | |
58 this.datasets = new HashMap(); | |
59 this.ranges = new HashMap(); | |
60 } | |
61 | |
62 | |
63 protected void initData() { | |
64 log.debug("init data for VerticalProfileChart"); | |
65 | |
66 String breakPoint1 = null; | |
67 String breakPoint2 = null; | |
68 String breakPoint3 = null; | |
69 | |
70 Iterator iter = resultSet.iterator(); | |
71 Result row = null; | |
72 String seriesName = null; | |
73 String parameter = null; | |
74 XYSeries series = null; | |
75 | |
76 int idx = 0; | |
77 int startPos = 0; | |
78 int endPos = 0; | |
79 double startValue = 0; | |
80 double endValue = 0; | |
81 | |
82 Result[] results = | |
83 (Result[]) resultSet.toArray(new Result[resultSet.size()]); | |
84 | |
85 while (iter.hasNext()) { | |
86 row = (Result) iter.next(); | |
87 | |
88 // add current data to plot and prepare for next one | |
89 if (!row.getString("GROUP1").equals(breakPoint1) || | |
90 !row.getString("GROUP2").equals(breakPoint2) || | |
91 !row.getString("GROUP3").equals(breakPoint3) | |
92 ) { | |
93 log.debug("prepare data/plot for next dataset"); | |
94 | |
95 if(series != null) { | |
96 gapDetection(results, series, startPos, endPos); | |
97 addSeries(series, parameter, idx); | |
98 | |
99 startPos = endPos +1; | |
100 } | |
101 | |
102 // prepare variables for next plot | |
103 breakPoint1 = row.getString("GROUP1"); | |
104 breakPoint2 = row.getString("GROUP2"); | |
105 breakPoint3 = row.getString("GROUP3"); | |
106 | |
107 seriesName = createSeriesName( | |
108 breakPoint1, | |
109 breakPoint2, | |
110 breakPoint3 | |
111 ); | |
112 parameter = findParameter(seriesName); | |
113 | |
114 log.debug("next dataset is '" + seriesName + "'"); | |
115 series = new XYSeries(seriesName); | |
116 } | |
117 | |
118 addValue(row, series); | |
119 storeMaxRange(row.getDouble("YORDINATE"), parameter); | |
120 endPos++; | |
121 } | |
122 | |
123 if (results.length == 0) | |
124 return; | |
125 | |
126 gapDetection(results, series, startPos, endPos); | |
127 addSeries(series, parameter, idx); | |
128 | |
129 addDatasets(); | |
130 } | |
131 | |
132 | |
133 protected void gapDetection( | |
134 Result[] results, | |
135 Series series, | |
136 int startPos, | |
137 int endPos | |
138 ) { | |
139 double startValue = results[startPos].getDouble("XORDINATE"); | |
140 double endValue = results[endPos-1].getDouble("XORDINATE"); | |
141 if (results[0].getInteger("DATAID") == 2) | |
142 addGapsOnGrid(results, series, startPos, endPos); | |
143 else | |
144 addGaps(results, series, startValue, endValue, startPos, endPos); | |
145 } | |
146 | |
147 | |
148 protected void addValue(Result row, Series series) { | |
149 ((XYSeries) series).add( | |
150 row.getDouble("XORDINATE"), | |
151 row.getDouble("YORDINATE") | |
152 ); | |
153 } | |
154 | |
155 | |
156 protected void addSeries(Series series, String parameter, int idx) { | |
157 log.debug("add series (" + parameter + ")to chart"); | |
158 | |
159 if (series == null) { | |
160 log.warn("no data to add"); | |
161 return; | |
162 } | |
163 | |
164 XYSeriesCollection xysc = null; | |
165 | |
166 if (datasets.containsKey(parameter)) | |
167 xysc = (XYSeriesCollection) datasets.get(parameter); | |
168 else | |
169 xysc = new XYSeriesCollection(); | |
170 | |
171 xysc.addSeries((XYSeries) series); | |
172 datasets.put(parameter, xysc); | |
173 } | |
174 | |
175 | |
176 protected void addDatasets() { | |
177 Iterator iter = parameters.iterator(); | |
178 XYPlot plot = chart.getXYPlot(); | |
179 int idx = 0; | |
180 | |
181 XYSeriesCollection xysc = null; | |
182 KeyValueDescibeData data = null; | |
183 String key = null; | |
184 while (iter.hasNext()) { | |
185 data = (KeyValueDescibeData) iter.next(); | |
186 key = data.getValue(); | |
187 | |
188 if (datasets.containsKey(key)) { | |
189 xysc = (XYSeriesCollection)datasets.get(key); | |
190 plot.setDataset(idx, xysc ); | |
191 log.debug("Added " + key + " parameter to plot."); | |
192 prepareAxis(key, idx); | |
193 adjustRenderer( | |
194 idx++, | |
195 xysc.getSeriesCount(), | |
196 linesVisible, | |
197 shapesVisible | |
198 ); | |
199 } | |
200 } | |
201 } | |
202 | |
203 | |
204 protected void localizeDomainAxis(Axis axis, Locale locale) { | |
205 // call localizeRangeAxis from superclass which formats NumberAxis | |
206 super.localizeRangeAxis(axis, locale); | |
207 } | |
208 | |
209 | |
210 protected String createSeriesName( | |
211 String breakPoint1, | |
212 String breakPoint2, | |
213 String breakPoint3 | |
214 ) { | |
215 log.debug("create seriesname of verticalprofile chart"); | |
216 return findValueTitle(parameters, breakPoint1) + | |
217 " " + | |
218 findValueTitle(measurements, breakPoint2) + | |
219 "m"; | |
220 } | |
221 | |
222 | |
223 protected void addGapsOnGrid( | |
224 Result[] results, | |
225 Series series, | |
226 int startPos, | |
227 int endPos | |
228 ) { | |
229 String axis = getDependendAxisName( | |
230 results[startPos], | |
231 results[startPos+1] | |
232 ); | |
233 double range = 0; | |
234 int last = 0; | |
235 int current = 0; | |
236 | |
237 for (int i = startPos+1; i < endPos; i++) { | |
238 last = results[i-1].getInteger(axis); | |
239 current = results[i].getInteger(axis); | |
240 | |
241 boolean detected = gridDetection(last, current); | |
242 | |
243 if (detected) { | |
244 double xOld = results[i-1].getDouble("XORDINATE"); | |
245 double xNow = results[i].getDouble("XORDINATE"); | |
246 log.debug("Gap detected on grid between "+ xOld +" and "+ xNow); | |
247 ((XYSeries) series).add(xOld+0.0001, null); | |
248 } | |
249 } | |
250 } | |
251 | |
252 | |
253 protected void addGaps( | |
254 Result[] results, | |
255 Series series, | |
256 double startValue, | |
257 double endValue, | |
258 int startPos, | |
259 int endPos | |
260 ) { | |
261 | |
262 double last = 0; | |
263 double current = 0; | |
264 int num = results.length; | |
265 | |
266 for (int i = startPos+1; i < endPos; i++) { | |
267 boolean detected = false; | |
268 | |
269 last = results[i-1].getDouble("YORDINATE"); | |
270 current = results[i].getDouble("YORDINATE"); | |
271 | |
272 // gap detection for more than GAP_MAX_VALUES values | |
273 if (num > GAP_MAX_VALUES) | |
274 detected = simpleDetection(startValue, endValue, last, current); | |
275 // gap detection for less than GAP_MAX_VALUES values | |
276 else | |
277 detected = specialDetection( | |
278 startValue, | |
279 endValue, | |
280 last, | |
281 current, | |
282 num | |
283 ); | |
284 | |
285 if (detected) { | |
286 log.info("Gap between " + last + " and " + current); | |
287 ((XYSeries) series).add((last+current)/2, null); | |
288 } | |
289 } | |
290 } | |
291 | |
292 | |
293 protected boolean simpleDetection( | |
294 double start, | |
295 double end, | |
296 double last, | |
297 double current | |
298 ) { | |
299 double delta = Math.abs(end - start); | |
300 double smallDelta = Math.abs(current - last); | |
301 | |
302 return (smallDelta > delta / 100 * PERCENTAGE); | |
303 } | |
304 | |
305 | |
306 protected boolean specialDetection( | |
307 double start, | |
308 double end, | |
309 double last, | |
310 double current, | |
311 int count | |
312 ) { | |
313 double delta = Math.abs(end - start); | |
314 double smallDelta = Math.abs(current - last); | |
315 | |
316 return (smallDelta > (3.0 / (count - 1) * delta)); | |
317 } | |
318 | |
319 | |
320 protected boolean gridDetection(double last, double current) { | |
321 return (Math.abs(current - last) > GAP_MAX_LEVEL); | |
322 } | |
323 | |
324 | |
325 protected String getDependendAxisName(Result first, Result second) { | |
326 return "KPOSITION"; | |
327 } | |
328 } | |
329 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : |