comparison gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java @ 657:af3f56758f59

merged gnv-artifacts/0.5
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:13:53 +0200
parents b98d1adee7a6
children 79401c871da4
comparison
equal deleted inserted replaced
590:5f5f273c8566 657:af3f56758f59
1 package de.intevation.gnv.chart;
2
3 import java.util.Collection;
4 import java.util.Locale;
5 import java.util.Map;
6
7 import com.vividsolutions.jts.geom.Point;
8 import com.vividsolutions.jts.io.WKTReader;
9 import com.vividsolutions.jts.io.ParseException;
10
11 import org.apache.log4j.Logger;
12
13 import org.jfree.chart.ChartTheme;
14 import org.jfree.chart.plot.PlotOrientation;
15 import org.jfree.data.general.Series;
16 import org.jfree.data.xy.XYSeries;
17
18 import de.intevation.gnv.geobackend.base.Result;
19 import de.intevation.gnv.utils.DistanceCalculator;
20
21
22 /**
23 * @author Ingo Weinzierl <ingo.weinzierl@intevation.de>
24 */
25 public class HorizontalProfileChart
26 extends VerticalProfileChart
27 {
28 private static Logger log = Logger.getLogger(HorizontalProfileChart.class);
29
30 private static WKTReader wktReader = new WKTReader();
31 private Point firstPoint;
32
33 public HorizontalProfileChart(
34 ChartLabels labels,
35 ChartTheme theme,
36 Collection parameters,
37 Collection measurements,
38 Collection dates,
39 Collection result,
40 Collection timeGaps,
41 Locale locale,
42 boolean linesVisible,
43 boolean shapesVisible
44 ) {
45 super(
46 labels,
47 theme,
48 parameters,
49 measurements,
50 dates,
51 result,
52 timeGaps,
53 locale,
54 linesVisible,
55 shapesVisible
56 );
57 this.PLOT_ORIENTATION = PlotOrientation.VERTICAL;
58 }
59
60
61 @Override
62 protected Object getValue(Result row) {
63 try {
64 return (Point) wktReader.read(row.getString("SHAPE"));
65 }
66 catch(ParseException pe) {
67 log.warn("No data found while parsing.");
68 return null;
69 }
70 }
71
72
73 protected void gapDetection(
74 Result[] results,
75 Series series,
76 int startPos,
77 int endPos
78 ) {
79 log.debug("Start gap detection.");
80 try {
81 Point startValue = getPoint(results[startPos]);
82 Point endValue = getPoint(results[endPos-1]);
83 if (results[0].getInteger("DATAID") == 2)
84 addGapsOnGrid(results, series, startPos, endPos);
85 else
86 addGaps(
87 results,
88 series,
89 startValue,
90 endValue,
91 startPos,
92 endPos
93 );
94 }
95 catch (ParseException pe) {
96 log.warn(
97 "Error while parsing points for gap detection. " +
98 "No gaps for current series will be detected."
99 );
100 }
101
102 log.debug("Gap detection finished.");
103 }
104
105
106 protected void addValue(Result row, Series series) {
107 double distance = 0;
108
109 try {
110 Point point = (Point) wktReader.read(row.getString("SHAPE"));
111 if (firstPoint != null) {
112 distance = DistanceCalculator.calculateDistance(
113 firstPoint, point
114 );
115 }
116 else {
117 firstPoint = point;
118 }
119
120 ((XYSeries) series).add(
121 distance,
122 row.getDouble("YORDINATE")
123 );
124 }
125 catch(ParseException pe) {
126 log.warn("No data found while parsing.");
127 }
128 }
129
130
131 protected void addSeries(Series series, String label, int idx) {
132 super.addSeries(series, label, idx);
133
134 // reset firstPoint for next series
135 firstPoint = null;
136 }
137
138
139 @Override
140 protected void prepareRangeAxis(String seriesKey, int idx) {
141 return;
142 // do nothing here
143 }
144
145
146 @Override
147 protected void storeMaxValue(Map values, Object value, String parameter) {
148 return;
149 // do nothing here
150 }
151
152
153 protected String createSeriesName(
154 String breakPoint1,
155 String breakPoint2,
156 String breakPoint3
157 ) {
158 log.debug("create seriesname of horizontalprofile chart");
159 return super.createSeriesName(
160 breakPoint1,
161 breakPoint2,
162 breakPoint3) +
163 " " +
164 findValueTitle(dates, breakPoint3);
165 }
166
167
168 protected void addGapsOnGrid(
169 Result[] results,
170 Series series,
171 int startPos,
172 int endPos
173 ) {
174 String axis = getDependendAxisName(
175 results[startPos],
176 results[startPos+1]
177 );
178
179 int last = 0;
180 int current = 0;
181 Point lastPoint = null;
182 Point currentPoint = null;
183
184 try {
185 firstPoint = getPoint(results[0]);
186 }
187 catch (ParseException pe) {
188 log.error("Unable to parse start point for gap detection.");
189 return;
190 }
191
192 for (int i = startPos+1; i < endPos; i++) {
193 try {
194 last = results[i-1].getInteger(axis);
195 lastPoint = getPoint(results[i-1]);
196 current = results[i].getInteger(axis);
197 currentPoint = getPoint(results[i]);
198 double distance = DistanceCalculator.calculateDistance(
199 firstPoint,
200 currentPoint);
201 double distanceOld = DistanceCalculator.calculateDistance(
202 firstPoint,
203 lastPoint);
204
205 boolean detected = gridDetection(last, current);
206
207 if (log.isDebugEnabled()) {
208 log.debug("Last point: " + lastPoint.toString());
209 log.debug("Current point: " + currentPoint.toString());
210 log.debug("Current distance from start: " + distance);
211 }
212
213 if (detected) {
214 log.info(
215 "Gap detected on grid between " + distanceOld +
216 " and " + distance);
217
218 ((XYSeries) series).add(distance-1d, null);
219 ((XYSeries) series).add(distanceOld+1d, null);
220 }
221 }
222 catch (ParseException pe) {
223 log.warn("Error while parsing point for gap detection.", pe);
224 }
225 }
226 }
227
228
229 protected void addGaps(
230 Result[] results,
231 Series series,
232 Point startValue,
233 Point endValue,
234 int startPos,
235 int endPos
236 ) {
237 double range = 0;
238 Point last = null;
239 Point now = null;
240
241 for (int i = startPos+1; i < endPos; i++) {
242 boolean detected = false;
243
244 try {
245 last = (Point) getPoint(results[i-1]);
246 now = (Point) getPoint(results[i]);
247
248 // gap detection for more than GAP_MAX_VALUES values
249 if (results.length > GAP_MAX_VALUES)
250 detected = simpleDetection(startValue, endValue, last, now);
251 // gap detection for less than GAP_MAX_VALUES values
252 else
253 detected = specialDetection(
254 startValue,
255 endValue,
256 last,
257 now,
258 results.length
259 );
260
261 // gap detected, insert null value to break line
262 if (detected) {
263 log.info("Gap after " + range);
264 double x = range + 0.0001;
265
266 ((XYSeries)series).add(x, null);
267 }
268
269 range += DistanceCalculator.calculateDistance(last,now);
270 }
271 catch (ParseException pe) {
272 log.warn("Error while parsing point.");
273 }
274
275 }
276 }
277
278
279 protected boolean simpleDetection(
280 Point start,
281 Point end,
282 Point last,
283 Point current
284 ) {
285 double delta = DistanceCalculator.calculateDistance(start, end);
286 double deltaSmall = DistanceCalculator.calculateDistance(last,current);
287
288 return (deltaSmall > (delta / 100 * PERCENTAGE));
289 }
290
291
292 protected boolean specialDetection(
293 Point start,
294 Point end,
295 Point last,
296 Point current,
297 int count
298 ) {
299 double delta = Math.abs(
300 DistanceCalculator.calculateDistance(end, start)
301 );
302 double smallDelta = Math.abs(
303 DistanceCalculator.calculateDistance(current, last)
304 );
305
306 return (smallDelta > (3.0 / (count - 1) * delta));
307 }
308
309 @Override
310 protected String getDependendAxisName(Result first, Result second) {
311 if (first.getInteger("IPOSITION") == second.getInteger("IPOSITION"))
312 return "JPOSITION";
313
314 return "IPOSITION";
315 }
316
317 private Point getPoint(Result result)
318 throws ParseException
319 {
320 return (Point) wktReader.read(result.getString("SHAPE"));
321 }
322 }
323 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org