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

http://dive4elements.wald.intevation.org