Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/services/DischargeTablesOverview.java @ 9312:740d65e4aa14
Q [m³/s] one message
author | gernotbelger |
---|---|
date | Thu, 26 Jul 2018 15:54:20 +0200 |
parents | 5e38e2924c07 |
children |
comparison
equal
deleted
inserted
replaced
9311:7c7f73e5e01e | 9312:740d65e4aa14 |
---|---|
16 import java.util.Date; | 16 import java.util.Date; |
17 import java.util.List; | 17 import java.util.List; |
18 import java.util.Locale; | 18 import java.util.Locale; |
19 | 19 |
20 import org.apache.log4j.Logger; | 20 import org.apache.log4j.Logger; |
21 import org.dive4elements.artifacts.CallMeta; | |
22 import org.dive4elements.artifacts.GlobalContext; | |
23 import org.dive4elements.river.artifacts.model.DischargeTables; | |
24 import org.dive4elements.river.artifacts.model.GaugesFactory; | |
25 import org.dive4elements.river.artifacts.resources.Resources; | |
26 import org.dive4elements.river.backend.SessionHolder; | |
27 import org.dive4elements.river.model.DischargeTable; | |
28 import org.dive4elements.river.model.Gauge; | |
29 import org.dive4elements.river.model.MainValue; | |
30 import org.dive4elements.river.model.TimeInterval; | |
21 import org.jfree.chart.ChartFactory; | 31 import org.jfree.chart.ChartFactory; |
22 import org.jfree.chart.JFreeChart; | 32 import org.jfree.chart.JFreeChart; |
23 import org.jfree.chart.plot.Marker; | 33 import org.jfree.chart.plot.Marker; |
24 import org.jfree.chart.plot.PlotOrientation; | 34 import org.jfree.chart.plot.PlotOrientation; |
25 import org.jfree.chart.plot.XYPlot; | 35 import org.jfree.chart.plot.XYPlot; |
27 import org.jfree.data.xy.XYSeriesCollection; | 37 import org.jfree.data.xy.XYSeriesCollection; |
28 import org.w3c.dom.Document; | 38 import org.w3c.dom.Document; |
29 import org.w3c.dom.Element; | 39 import org.w3c.dom.Element; |
30 import org.w3c.dom.NodeList; | 40 import org.w3c.dom.NodeList; |
31 | 41 |
32 import org.dive4elements.artifacts.CallMeta; | |
33 import org.dive4elements.artifacts.GlobalContext; | |
34 import org.dive4elements.river.artifacts.model.DischargeTables; | |
35 import org.dive4elements.river.artifacts.model.GaugesFactory; | |
36 import org.dive4elements.river.artifacts.resources.Resources; | |
37 import org.dive4elements.river.backend.SessionHolder; | |
38 import org.dive4elements.river.model.DischargeTable; | |
39 import org.dive4elements.river.model.Gauge; | |
40 import org.dive4elements.river.model.MainValue; | |
41 import org.dive4elements.river.model.TimeInterval; | |
42 | |
43 | |
44 /** Generate Discharge Table chart. */ | 42 /** Generate Discharge Table chart. */ |
45 public class DischargeTablesOverview extends AbstractChartService { | 43 public class DischargeTablesOverview extends AbstractChartService { |
46 | 44 |
47 private static final Logger log = Logger | 45 private static final Logger log = Logger.getLogger(DischargeTablesOverview.class); |
48 .getLogger(DischargeTablesOverview.class); | |
49 | 46 |
50 private static final long serialVersionUID = 1L; | 47 private static final long serialVersionUID = 1L; |
51 | 48 |
52 public static final String I18N_CHART_TITLE = | 49 public static final String I18N_CHART_TITLE = "gauge.discharge.service.chart.title"; |
53 "gauge.discharge.service.chart.title"; | |
54 public static final String DEFAULT_CHART_TITLE = "Pegel: XXX"; | 50 public static final String DEFAULT_CHART_TITLE = "Pegel: XXX"; |
55 | 51 |
56 public static final String I18N_CHART_X_AXIS_TITLE = | 52 public static final String I18N_CHART_X_AXIS_TITLE = "common.export.csv.header.q"; |
57 "gauge.discharge.service.chart.x.title"; | |
58 public static final String DEFAULT_X_AXIS_TITLE = "Q [m^3/s]"; | 53 public static final String DEFAULT_X_AXIS_TITLE = "Q [m^3/s]"; |
59 | 54 |
60 public static final String I18N_CHART_Y_AXIS_TITLE = | 55 public static final String I18N_CHART_Y_AXIS_TITLE = "gauge.discharge.service.chart.y.title"; |
61 "gauge.discharge.service.chart.y.title"; | |
62 public static final String DEFAULT_Y_AXIS_TITLE = "W [cm]"; | 56 public static final String DEFAULT_Y_AXIS_TITLE = "W [cm]"; |
63 | 57 |
64 public static final String I18N_CHART_SERIES_TITLE = | 58 public static final String I18N_CHART_SERIES_TITLE = "gauge.discharge.service.chart.series.title"; |
65 "gauge.discharge.service.chart.series.title"; | |
66 public static final String DEFAULT_CHART_SERIES_TITLE = "Abflusskurve"; | 59 public static final String DEFAULT_CHART_SERIES_TITLE = "Abflusskurve"; |
67 | 60 |
68 public static final String I18N_CHART_SERIES_TITLE_MASTER = | 61 public static final String I18N_CHART_SERIES_TITLE_MASTER = "gauge.discharge.service.chart.series.title.master"; |
69 "gauge.discharge.service.chart.series.title.master"; | 62 public static final String DEFAULT_CHART_SERIES_TITLE_MASTER = "Aktuelle Abflusskurve"; |
70 public static final String DEFAULT_CHART_SERIES_TITLE_MASTER = | 63 |
71 "Aktuelle Abflusskurve"; | 64 public static final DateFormat DATE_FORMAT = DateFormat.getDateInstance(DateFormat.SHORT, Locale.GERMANY); |
72 | |
73 public static final DateFormat DATE_FORMAT = DateFormat.getDateInstance( | |
74 DateFormat.SHORT, Locale.GERMANY); | |
75 | |
76 | 65 |
77 @Override | 66 @Override |
78 protected void init() { | 67 protected void init() { |
79 SessionHolder.acquire(); | 68 SessionHolder.acquire(); |
80 } | 69 } |
82 @Override | 71 @Override |
83 protected void finish() { | 72 protected void finish() { |
84 SessionHolder.release(); | 73 SessionHolder.release(); |
85 } | 74 } |
86 | 75 |
87 protected JFreeChart createChart(Document data, | 76 @Override |
88 GlobalContext globalContext, CallMeta callMeta) { | 77 protected JFreeChart createChart(final Document data, final GlobalContext globalContext, final CallMeta callMeta) { |
89 | 78 |
90 Gauge gauge = extractGauge(data); | 79 final Gauge gauge = extractGauge(data); |
91 | 80 |
92 if (gauge == null) { | 81 if (gauge == null) { |
93 log.warn("Could not determine Gauge from request!"); | 82 log.warn("Could not determine Gauge from request!"); |
94 return null; | 83 return null; |
95 } | 84 } |
96 | 85 |
97 log.info("create discharge chart for gauge '" + gauge.getName() + "'"); | 86 log.info("create discharge chart for gauge '" + gauge.getName() + "'"); |
98 TimeInterval timerange = extractTimeInterval(data); | 87 final TimeInterval timerange = extractTimeInterval(data); |
99 | 88 |
100 List<DischargeTable> dts = getDischargeTables(gauge, timerange); | 89 final List<DischargeTable> dts = getDischargeTables(gauge, timerange); |
101 XYSeriesCollection dataset = new XYSeriesCollection(); | 90 final XYSeriesCollection dataset = new XYSeriesCollection(); |
102 | 91 |
103 for (DischargeTable dt : dts) { | 92 for (final DischargeTable dt : dts) { |
104 try { | 93 try { |
105 XYSeries series = createSeries(callMeta, dt); | 94 final XYSeries series = createSeries(callMeta, dt); |
106 if (series != null) { | 95 if (series != null) { |
107 dataset.addSeries(series); | 96 dataset.addSeries(series); |
108 } | 97 } |
109 } | 98 } |
110 catch (IllegalArgumentException iae) { | 99 catch (final IllegalArgumentException iae) { |
111 log.warn("unable to create discharge curve: " | 100 log.warn("unable to create discharge curve: " + iae.getMessage()); |
112 + iae.getMessage()); | 101 } |
113 } | 102 } |
114 } | 103 |
115 | 104 final String title = Resources.format(callMeta, I18N_CHART_TITLE, DEFAULT_CHART_TITLE, gauge.getName()); |
116 String title = Resources.format(callMeta, I18N_CHART_TITLE, | 105 |
117 DEFAULT_CHART_TITLE, gauge.getName()); | 106 final String xAxis = Resources.getMsg(callMeta, I18N_CHART_X_AXIS_TITLE, DEFAULT_X_AXIS_TITLE); |
118 | 107 |
119 String xAxis = Resources.getMsg(callMeta, I18N_CHART_X_AXIS_TITLE, | 108 final String yAxis = Resources.format(callMeta, I18N_CHART_Y_AXIS_TITLE, DEFAULT_Y_AXIS_TITLE); |
120 DEFAULT_X_AXIS_TITLE); | 109 |
121 | 110 final JFreeChart chart = ChartFactory.createXYLineChart(title, xAxis, yAxis, null, PlotOrientation.VERTICAL, true, true, false); |
122 String yAxis = Resources.format(callMeta, I18N_CHART_Y_AXIS_TITLE, | |
123 DEFAULT_Y_AXIS_TITLE); | |
124 | |
125 JFreeChart chart = ChartFactory.createXYLineChart(title, xAxis, yAxis, | |
126 null, PlotOrientation.VERTICAL, true, true, false); | |
127 | 111 |
128 chart.setBackgroundPaint(Color.white); | 112 chart.setBackgroundPaint(Color.white); |
129 | 113 |
130 XYPlot plot = (XYPlot) chart.getPlot(); | 114 final XYPlot plot = (XYPlot) chart.getPlot(); |
131 plot.setDataset(0, dataset); | 115 plot.setDataset(0, dataset); |
132 plot.setBackgroundPaint(Color.white); | 116 plot.setBackgroundPaint(Color.white); |
133 plot.setDomainGridlinePaint(Color.gray); | 117 plot.setDomainGridlinePaint(Color.gray); |
134 plot.setRangeGridlinePaint(Color.gray); | 118 plot.setRangeGridlinePaint(Color.gray); |
135 plot.setDomainGridlinesVisible(true); | 119 plot.setDomainGridlinesVisible(true); |
136 plot.setRangeGridlinesVisible(true); | 120 plot.setRangeGridlinesVisible(true); |
137 | 121 |
138 applyMainValueMarkers( | 122 applyMainValueMarkers(plot, gauge, callMeta); |
139 plot, | |
140 gauge, | |
141 callMeta); | |
142 | 123 |
143 return chart; | 124 return chart; |
144 } | 125 } |
145 | 126 |
146 protected XYSeries createSeries(CallMeta callMeta, DischargeTable dt) | 127 protected XYSeries createSeries(final CallMeta callMeta, final DischargeTable dt) throws IllegalArgumentException { |
147 throws IllegalArgumentException { | |
148 | 128 |
149 double[][] xy = null; | 129 double[][] xy = null; |
150 | 130 |
151 xy = DischargeTables.loadDischargeTableValues(dt); | 131 xy = DischargeTables.loadDischargeTableValues(dt); |
152 | 132 |
153 XYSeries series = new XYSeries(createSeriesTitle(callMeta, dt), false); | 133 final XYSeries series = new XYSeries(createSeriesTitle(callMeta, dt), false); |
154 for (int i = 0, n = xy[0].length; i < n; i++) { | 134 for (int i = 0, n = xy[0].length; i < n; i++) { |
155 series.add(xy[0][i], xy[1][i]); | 135 series.add(xy[0][i], xy[1][i]); |
156 } | 136 } |
157 | 137 |
158 return series; | 138 return series; |
159 } | 139 } |
160 | 140 |
161 | |
162 /** Add domain markers to plot that indicate mainvalues. */ | 141 /** Add domain markers to plot that indicate mainvalues. */ |
163 protected static void applyMainValueMarkers( | 142 protected static void applyMainValueMarkers(final XYPlot plot, final Gauge gauge, final CallMeta meta) { |
164 XYPlot plot, | 143 final String river = gauge.getRiver().getName(); |
165 Gauge gauge, | 144 final double km = gauge.getStation().doubleValue(); |
166 CallMeta meta | |
167 ) { | |
168 String river = gauge.getRiver().getName(); | |
169 double km = gauge.getStation().doubleValue(); | |
170 | 145 |
171 // Get Gauge s mainvalues. | 146 // Get Gauge s mainvalues. |
172 List<MainValue> mainValues = gauge.getMainValues(); | 147 final List<MainValue> mainValues = gauge.getMainValues(); |
173 for (MainValue mainValue : mainValues) { | 148 for (final MainValue mainValue : mainValues) { |
174 if (mainValue.getMainValue().getType().getName().equals("Q")) { | 149 if (mainValue.getMainValue().getType().getName().equals("Q")) { |
175 // Its a Q main value. | 150 // Its a Q main value. |
176 Marker m = FixingsKMChartService.createQSectorMarker( | 151 final Marker m = FixingsKMChartService.createQSectorMarker(mainValue.getValue().doubleValue(), mainValue.getMainValue().getName()); |
177 mainValue.getValue().doubleValue(), | |
178 mainValue.getMainValue().getName()); | |
179 plot.addDomainMarker(m); | 152 plot.addDomainMarker(m); |
180 } | 153 } else if (mainValue.getMainValue().getType().getName().equals("W")) { |
181 else if ( | |
182 mainValue.getMainValue().getType().getName().equals("W") | |
183 ) { | |
184 // Its a W main value. | 154 // Its a W main value. |
185 Marker m = FixingsKMChartService.createQSectorMarker( | 155 final Marker m = FixingsKMChartService.createQSectorMarker(mainValue.getValue().doubleValue(), mainValue.getMainValue().getName()); |
186 mainValue.getValue().doubleValue(), | |
187 mainValue.getMainValue().getName()); | |
188 plot.addRangeMarker(m); | 156 plot.addRangeMarker(m); |
189 } | 157 } |
190 } | 158 } |
191 } | 159 } |
192 | 160 |
193 protected String createSeriesTitle(CallMeta callMeta, DischargeTable dt) | 161 protected String createSeriesTitle(final CallMeta callMeta, final DischargeTable dt) throws IllegalArgumentException { |
194 throws IllegalArgumentException { | 162 final TimeInterval timeInterval = dt.getTimeInterval(); |
195 TimeInterval timeInterval = dt.getTimeInterval(); | |
196 | 163 |
197 if (timeInterval == null) { | 164 if (timeInterval == null) { |
198 return Resources.format(callMeta, DEFAULT_CHART_SERIES_TITLE); | 165 return Resources.format(callMeta, DEFAULT_CHART_SERIES_TITLE); |
199 } | 166 } |
200 | 167 |
201 Date start = timeInterval.getStartTime(); | 168 final Date start = timeInterval.getStartTime(); |
202 Date end = timeInterval.getStopTime(); | 169 final Date end = timeInterval.getStopTime(); |
203 | 170 |
204 if (start != null && end != null) { | 171 if (start != null && end != null) { |
205 return Resources.format(callMeta, I18N_CHART_SERIES_TITLE, | 172 return Resources.format(callMeta, I18N_CHART_SERIES_TITLE, DEFAULT_CHART_SERIES_TITLE, start, end); |
206 DEFAULT_CHART_SERIES_TITLE, start, end); | 173 } else if (start != null) { |
207 } | 174 return Resources.format(callMeta, I18N_CHART_SERIES_TITLE_MASTER, DEFAULT_CHART_SERIES_TITLE, start); |
208 else if (start != null) { | 175 } else { |
209 return Resources.format(callMeta, I18N_CHART_SERIES_TITLE_MASTER, | 176 throw new IllegalArgumentException("Missing start date of DischargeTable " + dt.getId()); |
210 DEFAULT_CHART_SERIES_TITLE, start); | 177 } |
211 } | 178 } |
212 else { | 179 |
213 throw new IllegalArgumentException( | 180 protected Gauge extractGauge(final Document data) { |
214 "Missing start date of DischargeTable " + dt.getId()); | 181 final NodeList gauges = data.getElementsByTagName("gauge"); |
215 } | |
216 } | |
217 | |
218 protected Gauge extractGauge(Document data) { | |
219 NodeList gauges = data.getElementsByTagName("gauge"); | |
220 | 182 |
221 if (gauges.getLength() > 0) { | 183 if (gauges.getLength() > 0) { |
222 String name = ((Element) gauges.item(0)).getAttribute("name"); | 184 final String name = ((Element) gauges.item(0)).getAttribute("name"); |
223 | 185 |
224 try { | 186 try { |
225 long officialNumber = Long.valueOf(name); | 187 final long officialNumber = Long.valueOf(name); |
226 return Gauge.getGaugeByOfficialNumber(officialNumber); | 188 return Gauge.getGaugeByOfficialNumber(officialNumber); |
227 } | 189 } |
228 catch (NumberFormatException nfe) { | 190 catch (final NumberFormatException nfe) { |
229 // it seems, that the client uses the name of the gauge instead | 191 // it seems, that the client uses the name of the gauge instead |
230 // of its official number | 192 // of its official number |
231 } | 193 } |
232 | 194 |
233 if (name != null && name.length() > 0) { | 195 if (name != null && name.length() > 0) { |
236 } | 198 } |
237 | 199 |
238 return null; | 200 return null; |
239 } | 201 } |
240 | 202 |
241 protected TimeInterval extractTimeInterval(Document data) { | 203 protected TimeInterval extractTimeInterval(final Document data) { |
242 NodeList timeranges = data.getElementsByTagName("timerange"); | 204 final NodeList timeranges = data.getElementsByTagName("timerange"); |
243 | 205 |
244 if (timeranges != null && timeranges.getLength() > 0) { | 206 if (timeranges != null && timeranges.getLength() > 0) { |
245 Element timerange = (Element) timeranges.item(0); | 207 final Element timerange = (Element) timeranges.item(0); |
246 | 208 |
247 String lower = timerange.getAttribute("lower"); | 209 final String lower = timerange.getAttribute("lower"); |
248 String upper = timerange.getAttribute("upper"); | 210 final String upper = timerange.getAttribute("upper"); |
249 | 211 |
250 if (lower != null && upper != null) { | 212 if (lower != null && upper != null) { |
251 try { | 213 try { |
252 Date d1 = DATE_FORMAT.parse(lower); | 214 final Date d1 = DATE_FORMAT.parse(lower); |
253 Date d2 = DATE_FORMAT.parse(upper); | 215 final Date d2 = DATE_FORMAT.parse(upper); |
254 | 216 |
255 return new TimeInterval(d1, d2); | 217 return new TimeInterval(d1, d2); |
256 } | 218 } |
257 catch (ParseException pe) { | 219 catch (final ParseException pe) { |
258 log.warn("Wrong time format: " + pe.getMessage()); | 220 log.warn("Wrong time format: " + pe.getMessage()); |
259 } | 221 } |
260 } | 222 } |
261 } | 223 } |
262 | 224 |
263 return null; | 225 return null; |
264 } | 226 } |
265 | 227 |
266 protected List<DischargeTable> getDischargeTables(Gauge gauge, | 228 protected List<DischargeTable> getDischargeTables(final Gauge gauge, final TimeInterval timerange) { |
267 TimeInterval timerange) { | 229 final List<DischargeTable> all = gauge.getDischargeTables(); |
268 List<DischargeTable> all = gauge.getDischargeTables(); | |
269 Collections.sort(all); | 230 Collections.sort(all); |
270 | 231 |
271 if (timerange == null) { | 232 if (timerange == null) { |
272 return all; | 233 return all; |
273 } | 234 } |
274 | 235 |
275 List<DischargeTable> dts = new ArrayList<DischargeTable>(all.size()); | 236 final List<DischargeTable> dts = new ArrayList<>(all.size()); |
276 long startDate = timerange.getStartTime().getTime(); | 237 final long startDate = timerange.getStartTime().getTime(); |
277 long stopDate = timerange.getStopTime().getTime(); | 238 final long stopDate = timerange.getStopTime().getTime(); |
278 | 239 |
279 for (DischargeTable dt : all) { | 240 for (final DischargeTable dt : all) { |
280 TimeInterval tmp = dt.getTimeInterval(); | 241 final TimeInterval tmp = dt.getTimeInterval(); |
281 if (tmp == null) { | 242 if (tmp == null) { |
282 // this should never happen because all discharge tables should | 243 // this should never happen because all discharge tables should |
283 // have a time interval set! | 244 // have a time interval set! |
284 continue; | 245 continue; |
285 } | 246 } |
286 | 247 |
287 Date start = tmp.getStartTime(); | 248 final Date start = tmp.getStartTime(); |
288 Date stop = tmp.getStartTime(); | 249 final Date stop = tmp.getStartTime(); |
289 | 250 |
290 if (start.getTime() > startDate && start.getTime() < stopDate) { | 251 if (start.getTime() > startDate && start.getTime() < stopDate) { |
291 dts.add(dt); | 252 dts.add(dt); |
292 continue; | 253 continue; |
293 } | 254 } else if (stop != null && stop.getTime() < stopDate && stop.getTime() > startDate) { |
294 else if (stop != null && stop.getTime() < stopDate | |
295 && stop.getTime() > startDate) { | |
296 dts.add(dt); | 255 dts.add(dt); |
297 continue; | 256 continue; |
298 } | 257 } |
299 } | 258 } |
300 | 259 |