comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/BedloadKMChartService.java @ 3751:ae598cf50682

Added new services to render overview charts in minfo bed quality calculation and implemented transition model for minfo bed quality. flys-artifacts/trunk@5441 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Raimund Renkert <raimund.renkert@intevation.de>
date Wed, 12 Sep 2012 14:08:59 +0000
parents
children 854666f70a80
comparison
equal deleted inserted replaced
3750:e560a9a10eb1 3751:ae598cf50682
1 package de.intevation.flys.artifacts.services;
2
3 import java.awt.Color;
4 import java.awt.Dimension;
5 import java.awt.Transparency;
6 import java.awt.image.BufferedImage;
7 import java.io.ByteArrayOutputStream;
8 import java.io.IOException;
9 import java.util.Date;
10 import java.util.List;
11
12 import javax.imageio.ImageIO;
13
14 import org.apache.log4j.Logger;
15 import org.jfree.chart.ChartFactory;
16 import org.jfree.chart.JFreeChart;
17 import org.jfree.chart.axis.DateAxis;
18 import org.jfree.chart.plot.PlotOrientation;
19 import org.jfree.chart.plot.XYPlot;
20 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
21 import org.jfree.data.xy.XYSeries;
22 import org.jfree.data.xy.XYSeriesCollection;
23 import org.w3c.dom.Document;
24 import org.w3c.dom.Element;
25 import org.w3c.dom.NodeList;
26
27 import de.intevation.artifactdatabase.DefaultService;
28 import de.intevation.artifacts.CallMeta;
29 import de.intevation.artifacts.GlobalContext;
30 import de.intevation.artifacts.Service;
31 import de.intevation.flys.artifacts.model.minfo.BedloadOverview;
32 import de.intevation.flys.artifacts.model.minfo.BedloadOverviewFactory;
33 import de.intevation.flys.artifacts.resources.Resources;
34 import de.intevation.flys.backend.SedDBSessionHolder;
35 import de.intevation.flys.utils.KMIndex;
36
37 public class BedloadKMChartService extends DefaultService {
38
39 /**
40 *
41 */
42 private static final long serialVersionUID = 4156704841305086495L;
43
44 private static final Logger log =
45 Logger.getLogger(BedloadKMChartService.class);
46
47 public static final int DEFAULT_WIDTH = 240;
48 public static final int DEFAULT_HEIGHT = 180;
49
50 public static final String I18N_CHART_LABEL =
51 "bedload.km.chart.label";
52
53 public static final String DEFAULT_CHART_LABEL =
54 "Measuring Points";
55
56 public static final String I18N_CHART_TITLE =
57 "bedload.km.chart.title";
58
59 public static final String DEFAULT_CHART_TITLE =
60 "Measuring points";
61
62 public static final String I18N_KM_AXIS =
63 "bedload.km.chart.km.axis";
64
65 public static final String DEFAULT_KM_AXIS =
66 "km";
67
68 public static final String I18N_DATE_AXIS =
69 "bedload.km.chart.date.axis";
70
71 public static final String DEFAULT_DATE_AXIS =
72 "Date";
73
74 public static final String DEFAULT_FORMAT = "png";
75
76 // TODO: Load fancy image from resources.
77 public static final byte [] EMPTY = {
78 (byte)0x89, (byte)0x50, (byte)0x4e, (byte)0x47,
79 (byte)0x0d, (byte)0x0a, (byte)0x1a, (byte)0x0a,
80 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0d,
81 (byte)0x49, (byte)0x48, (byte)0x44, (byte)0x52,
82 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
83 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
84 (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00,
85 (byte)0x00, (byte)0x3a, (byte)0x7e, (byte)0x9b,
86 (byte)0x55, (byte)0x00, (byte)0x00, (byte)0x00,
87 (byte)0x01, (byte)0x73, (byte)0x52, (byte)0x47,
88 (byte)0x42, (byte)0x00, (byte)0xae, (byte)0xce,
89 (byte)0x1c, (byte)0xe9, (byte)0x00, (byte)0x00,
90 (byte)0x00, (byte)0x09, (byte)0x70, (byte)0x48,
91 (byte)0x59, (byte)0x73, (byte)0x00, (byte)0x00,
92 (byte)0x0b, (byte)0x13, (byte)0x00, (byte)0x00,
93 (byte)0x0b, (byte)0x13, (byte)0x01, (byte)0x00,
94 (byte)0x9a, (byte)0x9c, (byte)0x18, (byte)0x00,
95 (byte)0x00, (byte)0x00, (byte)0x07, (byte)0x74,
96 (byte)0x49, (byte)0x4d, (byte)0x45, (byte)0x07,
97 (byte)0xdc, (byte)0x04, (byte)0x04, (byte)0x10,
98 (byte)0x30, (byte)0x15, (byte)0x7d, (byte)0x77,
99 (byte)0x36, (byte)0x0b, (byte)0x00, (byte)0x00,
100 (byte)0x00, (byte)0x08, (byte)0x74, (byte)0x45,
101 (byte)0x58, (byte)0x74, (byte)0x43, (byte)0x6f,
102 (byte)0x6d, (byte)0x6d, (byte)0x65, (byte)0x6e,
103 (byte)0x74, (byte)0x00, (byte)0xf6, (byte)0xcc,
104 (byte)0x96, (byte)0xbf, (byte)0x00, (byte)0x00,
105 (byte)0x00, (byte)0x0a, (byte)0x49, (byte)0x44,
106 (byte)0x41, (byte)0x54, (byte)0x08, (byte)0xd7,
107 (byte)0x63, (byte)0xf8, (byte)0x0f, (byte)0x00,
108 (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x00,
109 (byte)0x1b, (byte)0xb6, (byte)0xee, (byte)0x56,
110 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
111 (byte)0x49, (byte)0x45, (byte)0x4e, (byte)0x44,
112 (byte)0xae, (byte)0x42, (byte)0x60, (byte)0x82
113 };
114
115 private static final Output empty() {
116 return new Output(EMPTY, "image/png");
117 }
118
119 @Override
120 public Service.Output process(
121 Document data,
122 GlobalContext globalContext,
123 CallMeta callMeta
124 ) {
125 log.debug("SQKMChartService.process");
126
127 SedDBSessionHolder.acquire();
128 try {
129 return doProcess(data, globalContext, callMeta);
130 }
131 finally {
132 SedDBSessionHolder.HOLDER.get().close();
133 SedDBSessionHolder.release();
134 }
135 }
136
137 protected Service.Output doProcess(
138 Document input,
139 GlobalContext globalContext,
140 CallMeta callMeta
141 ) {
142 String river = getRiverName(input);
143 Dimension extent = getExtent(input);
144 String format = getFormat(input);
145
146 if (river == null) {
147 log.warn("River invalid.");
148 return empty();
149 }
150
151 BedloadOverview overview = BedloadOverviewFactory.getOverview(river);
152
153 if (overview == null) {
154 log.warn("No overview found for river '" + river + "'");
155 return empty();
156 }
157
158 KMIndex<List<Date>> entries = overview.filter(BedloadOverview.ACCEPT);
159
160 JFreeChart chart = createChart(entries, river, callMeta);
161
162 return encode(chart, extent, format);
163 }
164
165 protected static Output encode(
166 JFreeChart chart,
167 Dimension extent,
168 String format
169 ) {
170 BufferedImage image = chart.createBufferedImage(
171 extent.width, extent.height,
172 Transparency.BITMASK,
173 null);
174
175 ByteArrayOutputStream out = new ByteArrayOutputStream();
176
177 try {
178 ImageIO.write(image, format, out);
179 }
180 catch (IOException ioe) {
181 log.warn("writing image failed", ioe);
182 return empty();
183 }
184
185 return new Output(out.toByteArray(), "image/" + format);
186 }
187
188 protected static JFreeChart createChart(
189 KMIndex<List<Date>> entries,
190 String river,
191 CallMeta callMeta
192 ) {
193
194 XYSeriesCollection dataset = new XYSeriesCollection();
195 String key = Resources.format(
196 callMeta, I18N_CHART_LABEL, DEFAULT_CHART_LABEL, river);
197
198 XYSeries series = new XYSeries(key);
199 for (KMIndex.Entry<List<Date>> e: entries) {
200 double km = e.getKm();
201 List<Date> ds = e.getValue();
202 for (Date d: ds) {
203 series.add(km, d.getTime());
204 }
205 }
206
207 dataset.addSeries(series);
208 String title = Resources.format(
209 callMeta, I18N_CHART_TITLE, DEFAULT_CHART_TITLE, river);
210
211 String kmAxis = Resources.getMsg(
212 callMeta, I18N_KM_AXIS, DEFAULT_KM_AXIS);
213
214 String dateAxis = Resources.getMsg(
215 callMeta, I18N_DATE_AXIS, DEFAULT_DATE_AXIS);
216
217 JFreeChart chart = ChartFactory.createXYLineChart(
218 title,
219 kmAxis,
220 dateAxis,
221 null,
222 PlotOrientation.VERTICAL,
223 true,
224 true,
225 false);
226
227 XYPlot plot = (XYPlot)chart.getPlot();
228
229 DateAxis dA = new DateAxis();
230 plot.setRangeAxis(dA);
231 plot.setDataset(0, dataset);
232
233 chart.setBackgroundPaint(Color.white);
234 plot.setBackgroundPaint(Color.white);
235 plot.setDomainGridlinePaint(Color.gray);
236 plot.setRangeGridlinePaint(Color.gray);
237 plot.setDomainGridlinesVisible(true);
238 plot.setRangeGridlinesVisible(true);
239 XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();
240
241 renderer.setSeriesPaint(0, Color.gray);
242 renderer.setSeriesLinesVisible(0, false);
243 renderer.setSeriesShapesVisible(0, true);
244 renderer.setDrawOutlines(true);
245 return chart;
246 }
247
248
249 protected static String getRiverName(Document input) {
250 NodeList rivers = input.getElementsByTagName("river");
251
252 if (rivers.getLength() == 0) {
253 return null;
254 }
255
256 String river = ((Element)rivers.item(0)).getAttribute("name");
257
258 return river.length() > 0 ? river : null;
259 }
260
261 protected static Dimension getExtent(Document input) {
262
263 int width = DEFAULT_WIDTH;
264 int height = DEFAULT_HEIGHT;
265
266 NodeList extents = input.getElementsByTagName("extent");
267
268 if (extents.getLength() > 0) {
269 Element element = (Element)extents.item(0);
270 String w = element.getAttribute("width");
271 String h = element.getAttribute("height");
272
273 try {
274 width = Math.max(1, Integer.parseInt(w));
275 }
276 catch (NumberFormatException nfe) {
277 log.warn("width '" + w + "' is not a valid.");
278 }
279
280 try {
281 height = Math.max(1, Integer.parseInt(h));
282 }
283 catch (NumberFormatException nfe) {
284 log.warn("height '" + h + "' is not a valid");
285 }
286 }
287
288 return new Dimension(width, height);
289 }
290
291 protected static String getFormat(Document input) {
292 String format = DEFAULT_FORMAT;
293
294 NodeList formats = input.getElementsByTagName("format");
295
296 if (formats.getLength() > 0) {
297 String type = ((Element)formats.item(0)).getAttribute("type");
298 if (type.length() > 0) {
299 format = type;
300 }
301 }
302
303 return format;
304 }
305 }

http://dive4elements.wald.intevation.org