comparison artifacts/src/main/java/org/dive4elements/river/artifacts/services/SQKMChartService.java @ 5838:5aa05a7a34b7

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

http://dive4elements.wald.intevation.org