Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/exports/process/MiscDischargeProcessor.java @ 8181:209f8a9e8a75
Added new processor to plot misc discharge data, e.g. from datacage or recommendations.
author | Raimund Renkert <rrenkert@intevation.de> |
---|---|
date | Thu, 04 Sep 2014 11:10:37 +0200 |
parents | |
children | 407c9598352f |
comparison
equal
deleted
inserted
replaced
8171:bb770daccd1d | 8181:209f8a9e8a75 |
---|---|
1 /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde | |
2 * Software engineering by Intevation GmbH | |
3 * | |
4 * This file is Free Software under the GNU AGPL (>=v3) | |
5 * and comes with ABSOLUTELY NO WARRANTY! Check out the | |
6 * documentation coming with Dive4Elements River for details. | |
7 */ | |
8 | |
9 package org.dive4elements.river.exports.process; | |
10 | |
11 import java.util.ArrayList; | |
12 import java.util.List; | |
13 | |
14 import org.apache.log4j.Logger; | |
15 import org.jfree.data.xy.XYSeries; | |
16 | |
17 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; | |
18 import org.dive4elements.artifacts.CallContext; | |
19 import org.dive4elements.river.artifacts.model.FacetTypes; | |
20 import org.dive4elements.river.artifacts.model.WQKms; | |
21 import org.dive4elements.river.exports.DiagramGenerator; | |
22 import org.dive4elements.river.exports.DischargeCurveGenerator; | |
23 import org.dive4elements.river.exports.StyledSeriesBuilder; | |
24 import org.dive4elements.river.exports.XYChartGenerator; | |
25 import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation; | |
26 import org.dive4elements.river.jfree.RiverAnnotation; | |
27 import org.dive4elements.river.jfree.StickyAxisAnnotation; | |
28 import org.dive4elements.river.jfree.StyledXYSeries; | |
29 import org.dive4elements.river.themes.ThemeDocument; | |
30 | |
31 import org.jfree.chart.annotations.XYTextAnnotation; | |
32 | |
33 | |
34 /** Helper for data handling in discharge diagrams. */ | |
35 public class MiscDischargeProcessor | |
36 extends DefaultProcessor implements FacetTypes { | |
37 | |
38 private final static Logger logger = | |
39 Logger.getLogger(MiscDischargeProcessor.class); | |
40 | |
41 /** Station for which the diagram is shown. */ | |
42 private double km; | |
43 | |
44 /** Tolerance for comparison of kilometers. */ | |
45 public static final double KM_EPSILON = 0.001d; | |
46 | |
47 | |
48 /** This processor needs to be constructed with a given km. */ | |
49 public MiscDischargeProcessor() { | |
50 km = Double.NaN; | |
51 } | |
52 | |
53 | |
54 public MiscDischargeProcessor(double km) { | |
55 this.km = km; | |
56 } | |
57 | |
58 public void doOut( | |
59 DiagramGenerator generator, | |
60 ArtifactAndFacet bundle, | |
61 ThemeDocument theme, | |
62 boolean visible) { | |
63 CallContext context = generator.getCallContext(); | |
64 Object data = bundle.getData(context); | |
65 if (data instanceof WQKms) { | |
66 doWQKmsPointOut( | |
67 generator, (WQKms) data, bundle, theme, visible); | |
68 return; | |
69 } | |
70 else if (data instanceof RiverAnnotation) { | |
71 doRiverAnnotationOut( | |
72 generator, (RiverAnnotation)data, bundle, theme, visible); | |
73 return; | |
74 } | |
75 else if (data instanceof double[][]) { | |
76 doPointsOut(generator, (double[][])data, bundle, theme, visible); | |
77 } | |
78 else { | |
79 logger.error("Can't process " | |
80 + data.getClass().getName() + " objects of facet " | |
81 + bundle.getFacetName()); | |
82 } | |
83 } | |
84 | |
85 /** Process data, add it to plot. */ | |
86 @Override | |
87 public void doOut( | |
88 XYChartGenerator generator, | |
89 ArtifactAndFacet bundle, | |
90 ThemeDocument theme, | |
91 boolean visible, | |
92 int axisIndex | |
93 ) { | |
94 CallContext context = generator.getCallContext(); | |
95 Object data = bundle.getData(context); | |
96 /* TODO: Remove the first case.*/ | |
97 if (bundle.getFacetName().equals(STATIC_WQ)) { | |
98 doPointOut( | |
99 generator, bundle, theme, visible, axisIndex); | |
100 } | |
101 else if (data instanceof WQKms) { | |
102 doWQKmsPointOut( | |
103 generator, (WQKms) data, bundle, theme, visible, axisIndex); | |
104 return; | |
105 } | |
106 else if (data instanceof RiverAnnotation) { | |
107 doRiverAnnotationOut( | |
108 generator, (RiverAnnotation) data, bundle, theme, visible); | |
109 return; | |
110 } | |
111 else if (data instanceof double[][]) { | |
112 doMarksOut( | |
113 generator, (double[][]) data, bundle, theme, visible); | |
114 return; | |
115 } | |
116 else { | |
117 logger.error("Can't process " | |
118 + data.getClass().getName() + " objects of facet " | |
119 + bundle.getFacetName()); | |
120 } | |
121 } | |
122 | |
123 private void doPointOut(XYChartGenerator generator, | |
124 ArtifactAndFacet bundle, | |
125 ThemeDocument theme, | |
126 boolean visible, | |
127 int axisIndex | |
128 ) { | |
129 XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme); | |
130 Object wq = bundle.getData(generator.getCallContext()); | |
131 if (wq instanceof double[][]) { | |
132 double [][] data = (double [][]) wq; | |
133 StyledSeriesBuilder.addPoints(series, data, true); | |
134 } else if (wq instanceof WQKms) { | |
135 WQKms wqkms = (WQKms) wq; | |
136 StyledSeriesBuilder.addPointsQW(series, (WQKms) wq); | |
137 } | |
138 | |
139 generator.addAxisSeries(series, axisIndex, visible); | |
140 } | |
141 | |
142 /** Handle WQKms data by finding w/q values at given km. */ | |
143 protected void doWQKmsPointOut(XYChartGenerator generator, | |
144 WQKms wqkms, | |
145 ArtifactAndFacet bundle, | |
146 ThemeDocument theme, | |
147 boolean visible, | |
148 int axidx | |
149 ) { | |
150 logger.debug("doWQKmsPointOut"); | |
151 String title = bundle.getFacetDescription(); | |
152 XYSeries series = new StyledXYSeries( | |
153 title, | |
154 theme); | |
155 | |
156 double[] kms = wqkms.getKms(); | |
157 | |
158 for (int i = 0 ; i< kms.length; i++) { | |
159 if (Math.abs(kms[i] - getKm()) <= KM_EPSILON) { | |
160 series.add(wqkms.getQ(i), wqkms.getW(i)); | |
161 generator.addAxisSeries(series, axidx, visible); | |
162 if(visible && theme.parseShowPointLabel()) { | |
163 List<XYTextAnnotation> textAnnos = new ArrayList<XYTextAnnotation>(); | |
164 XYTextAnnotation anno = new CollisionFreeXYTextAnnotation( | |
165 title, | |
166 wqkms.getQ(i), | |
167 // TODO add a percentage to the extend of W axis | |
168 wqkms.getW(i)); | |
169 textAnnos.add(anno); | |
170 RiverAnnotation flysAnno = new RiverAnnotation(null, null, null, theme); | |
171 flysAnno.setTextAnnotations(textAnnos); | |
172 generator.addAnnotations(flysAnno); | |
173 } | |
174 return; | |
175 } | |
176 } | |
177 | |
178 logger.warn("No WQ found for km " + getKm()); | |
179 } | |
180 | |
181 protected void doRiverAnnotationOut(XYChartGenerator generator, | |
182 RiverAnnotation annotations, | |
183 ArtifactAndFacet bundle, | |
184 ThemeDocument theme, | |
185 boolean visible | |
186 ) { | |
187 if (!(generator instanceof DischargeCurveGenerator)) { | |
188 logger.error("DischargeProcessor can only be used in " + | |
189 " in DischargeCurveGenerator-classes."); | |
190 return; | |
191 } | |
192 logger.debug("doRiverAnnotationOut"); | |
193 DischargeCurveGenerator dGenerator = | |
194 (DischargeCurveGenerator) generator; | |
195 | |
196 dGenerator.translateRiverAnnotation(annotations); | |
197 dGenerator.doAnnotations( | |
198 annotations, | |
199 bundle, theme, visible); | |
200 } | |
201 | |
202 | |
203 /** | |
204 * Put Sticky Axis Markers to Y-axis for each value. | |
205 * @param data [[-,y1],[-,y2],...] ('x'-coordinates ignored) | |
206 */ | |
207 protected void doMarksOut(XYChartGenerator generator, | |
208 double[][] data, | |
209 ArtifactAndFacet bundle, | |
210 ThemeDocument theme, | |
211 boolean visible | |
212 ) { | |
213 logger.debug("doMarksOut"); | |
214 | |
215 if (!visible) { | |
216 return; | |
217 } | |
218 | |
219 // TODO subtract gauge null point if at gauge. | |
220 String title = bundle.getFacetDescription(); | |
221 List<StickyAxisAnnotation> yMarks = new ArrayList<StickyAxisAnnotation>(); | |
222 | |
223 for (double yPos: data[1]) { | |
224 yMarks.add(new StickyAxisAnnotation( | |
225 title, | |
226 (float) yPos, | |
227 StickyAxisAnnotation.SimpleAxis.Y_AXIS)); | |
228 } | |
229 | |
230 generator.doAnnotations(new RiverAnnotation(title, yMarks), | |
231 bundle, theme, visible); | |
232 } | |
233 | |
234 /** True if this processor knows how to deal with facetType. */ | |
235 @Override | |
236 public boolean canHandle(String facetType) { | |
237 return STATIC_WQKMS_W.equals(facetType) | |
238 || COMPUTED_DISCHARGE_MAINVALUES_Q.equals(facetType) | |
239 || MAINVALUES_Q.equals(facetType) | |
240 || COMPUTED_DISCHARGE_MAINVALUES_W.equals(facetType) | |
241 || MAINVALUES_W.equals(facetType) | |
242 || STATIC_W_INTERPOL.equals(facetType) | |
243 || STATIC_WQ.equals(facetType) | |
244 || STATIC_WQ_ANNOTATIONS.equals(facetType); | |
245 } | |
246 | |
247 | |
248 /** The station of the current calculation/view. */ | |
249 protected double getKm() { | |
250 return km; | |
251 } | |
252 | |
253 private void doPointsOut( | |
254 DiagramGenerator generator, | |
255 double[][] data, | |
256 ArtifactAndFacet bundle, | |
257 ThemeDocument theme, | |
258 boolean visible | |
259 ) { | |
260 XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme); | |
261 StyledSeriesBuilder.addPoints(series, data, true); | |
262 generator.addAxisSeries(series, axisName, visible); | |
263 } | |
264 | |
265 /** Handle WQKms data by finding w/q values at given km. */ | |
266 protected void doWQKmsPointOut( | |
267 DiagramGenerator generator, | |
268 WQKms wqkms, | |
269 ArtifactAndFacet bundle, | |
270 ThemeDocument theme, | |
271 boolean visible | |
272 ) { | |
273 logger.debug("doWQKmsPointOut"); | |
274 String title = bundle.getFacetDescription(); | |
275 XYSeries series = new StyledXYSeries( | |
276 title, | |
277 theme); | |
278 | |
279 double[] kms = wqkms.getKms(); | |
280 | |
281 for (int i = 0 ; i< kms.length; i++) { | |
282 if (Math.abs(kms[i] - getKm()) <= KM_EPSILON) { | |
283 series.add(wqkms.getQ(i), wqkms.getW(i)); | |
284 generator.addAxisSeries(series, axisName, visible); | |
285 if(visible && theme.parseShowPointLabel()) { | |
286 List<XYTextAnnotation> textAnnos = new ArrayList<XYTextAnnotation>(); | |
287 XYTextAnnotation anno = new CollisionFreeXYTextAnnotation( | |
288 title, | |
289 wqkms.getQ(i), | |
290 // TODO add a percentage to the extend of W axis | |
291 wqkms.getW(i)); | |
292 textAnnos.add(anno); | |
293 RiverAnnotation flysAnno = new RiverAnnotation(null, null, null, theme); | |
294 flysAnno.setTextAnnotations(textAnnos); | |
295 generator.addAnnotations(flysAnno); | |
296 } | |
297 return; | |
298 } | |
299 } | |
300 | |
301 logger.warn("No WQ found for km " + getKm()); | |
302 } | |
303 | |
304 protected void doRiverAnnotationOut(DiagramGenerator generator, | |
305 RiverAnnotation annotations, | |
306 ArtifactAndFacet bundle, | |
307 ThemeDocument theme, | |
308 boolean visible | |
309 ) { | |
310 if (visible) { | |
311 annotations.setTheme(theme); | |
312 generator.addAnnotations(annotations); | |
313 } | |
314 } | |
315 } | |
316 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |