comparison gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java @ 540:80630520e25a

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

http://dive4elements.wald.intevation.org