comparison flys-backend/src/main/java/org/dive4elements/river/model/FastAnnotations.java @ 5828:dfb26b03b179

Moved directories to org.dive4elements.river
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 11:53:11 +0200
parents flys-backend/src/main/java/de/intevation/flys/model/FastAnnotations.java@20d249e1589f
children 18619c1e7c2a
comparison
equal deleted inserted replaced
5827:e308d4ecd35a 5828:dfb26b03b179
1 package de.intevation.flys.model;
2
3 import java.util.Comparator;
4 import java.util.ArrayList;
5 import java.util.List;
6 import java.util.Arrays;
7 import java.util.HashMap;
8 import java.util.Iterator;
9 import java.util.NoSuchElementException;
10
11 import java.io.Serializable;
12
13 import org.hibernate.Session;
14 import org.hibernate.SQLQuery;
15
16 import org.hibernate.type.StandardBasicTypes;
17
18 import de.intevation.flys.backend.SessionHolder;
19
20 public class FastAnnotations
21 implements Serializable
22 {
23 public static final String SQL_BY_RIVER_NAME =
24 "SELECT r.a AS a, r.b AS b, p.value AS position, " +
25 "at.value AS attribute, ant.name AS name, " +
26 "e.top AS top, e.bottom AS bottom " +
27 "FROM annotations an " +
28 "JOIN ranges r " +
29 "ON an.range_id = r.id " +
30 "JOIN attributes at " +
31 "ON an.attribute_id = at.id " +
32 "JOIN positions p " +
33 "ON an.position_id = p.id " +
34 "JOIN rivers riv " +
35 "ON r.river_id = riv.id " +
36 "LEFT JOIN annotation_types ant " +
37 "ON an.type_id = ant.id " +
38 "LEFT JOIN edges e " +
39 "ON an.edge_id = e.id " +
40 "WHERE riv.name = :river_name " +
41 "ORDER BY r.a";
42
43 public static final String SQL_BY_RIVER_ID =
44 "SELECT r.a AS a, r.b AS b, p.value AS position, " +
45 "at.value AS attribute, ant.name AS name, " +
46 "e.top AS top, e.bottom AS bottom " +
47 "FROM annotations an " +
48 "JOIN ranges r " +
49 "ON an.range_id = r.id " +
50 "JOIN attributes at " +
51 "ON an.attribute_id = at.id " +
52 "JOIN positions p " +
53 "ON an.position_id = p.id " +
54 "LEFT JOIN annotation_types ant " +
55 "ON an.type_id = ant.id " +
56 "LEFT JOIN edges e " +
57 "ON an.edge_id = e.id " +
58 "WHERE r.id = :river_id " +
59 "ORDER BY r.a";
60
61 public static final double EPSILON = 1e-5;
62
63 public static final Comparator<Annotation> KM_CMP =
64 new Comparator<Annotation>() {
65 @Override
66 public int compare(Annotation a, Annotation b) {
67 double diff = a.a - b.a;
68 if (diff < -EPSILON) return -1;
69 if (diff > +EPSILON) return +1;
70 return 0;
71 }
72 };
73
74 public static final class Annotation
75 implements Serializable
76 {
77 private double a;
78 private double b;
79 private String position;
80 private String attribute;
81 private String name;
82 private double top;
83 private double bottom;
84
85 public Annotation() {
86 }
87
88 public Annotation(double a) {
89 this.a = a;
90 }
91
92 public Annotation(
93 double a,
94 double b,
95 String position,
96 String attribute,
97 String name,
98 double top,
99 double bottom
100 ) {
101 this.a = a;
102 this.b = b;
103 this.position = position;
104 this.attribute = attribute;
105 this.name = name;
106 this.top = top;
107 this.bottom = bottom;
108 }
109
110 public double getA() {
111 return a;
112 }
113
114 public double getB() {
115 return b;
116 }
117
118 public String getPosition() {
119 return position;
120 }
121
122 public String getAttribute() {
123 return attribute;
124 }
125
126 public String getName() {
127 return name;
128 }
129
130 public double getTop() {
131 return top;
132 }
133
134 public double getBottom() {
135 return bottom;
136 }
137
138 @Override
139 public String toString() {
140 return "[a=" + a + ";b=" + b +
141 ";pos=" + position + ";attr=" + attribute +
142 ";name=" + name + ";top=" + top +
143 ";bot=" + bottom + "]";
144 }
145 } // class Annotation
146
147 public interface Filter {
148
149 boolean accept(Annotation annotation);
150
151 } // interface Filter
152
153 public static class NameFilter implements Filter {
154
155 private String name;
156
157 public NameFilter(String name) {
158 this.name = name;
159 }
160
161 @Override
162 public boolean accept(Annotation annotation) {
163 return annotation.getName().contains(name);
164 }
165 } // class NameFilter
166
167 public static final Filter ALL = new Filter() {
168 @Override
169 public boolean accept(Annotation annotation) {
170 return true;
171 }
172 };
173
174 public static final Filter IS_POINT = new Filter() {
175 @Override
176 public boolean accept(Annotation annotation) {
177 return Double.isNaN(annotation.getB());
178 }
179 };
180
181 public static final Filter IS_RANGE = new Filter() {
182 @Override
183 public boolean accept(Annotation annotation) {
184 return !Double.isNaN(annotation.getB());
185 }
186 };
187
188 private Annotation [] annotations;
189
190 public FastAnnotations() {
191 }
192
193 public FastAnnotations(Annotation [] annotations) {
194 this.annotations = annotations;
195 }
196
197 public FastAnnotations(String riverName) {
198 this(loadByRiverName(riverName));
199 }
200
201 public FastAnnotations(int riverId) {
202 this(loadByRiverId(riverId));
203 }
204
205 public FastAnnotations(Iterator<Annotation> iter) {
206 this(toArray(iter));
207 }
208
209 public int size() {
210 return annotations.length;
211 }
212
213 public Iterator<Annotation> filter(final Filter filter) {
214 return new Iterator<Annotation>() {
215
216 private int idx;
217 private Annotation current = findNext();
218
219 @Override
220 public boolean hasNext() {
221 return current != null;
222 }
223
224 @Override
225 public Annotation next() {
226 if (current == null) {
227 throw new NoSuchElementException();
228 }
229 Annotation result = current;
230 current = findNext();
231 return result;
232 }
233
234 private Annotation findNext() {
235
236 while (idx < annotations.length) {
237 Annotation annotation = annotations[idx++];
238 if (filter.accept(annotation)) {
239 return annotation;
240 }
241 }
242
243 return null;
244 }
245
246 @Override
247 public void remove() {
248 throw new UnsupportedOperationException();
249 }
250 };
251 }
252
253 public static Annotation [] toArray(Iterator<Annotation> iter) {
254
255 ArrayList<Annotation> list = new ArrayList<Annotation>();
256
257 while (iter.hasNext()) {
258 list.add(iter.next());
259 }
260
261 return list.toArray(new Annotation[list.size()]);
262 }
263
264 public Annotation findByKm(double km) {
265 Annotation key = new Annotation(km);
266 int idx = Arrays.binarySearch(annotations, key, KM_CMP);
267 return idx < 0 ? null : annotations[idx];
268 }
269
270 private static SQLQuery createQuery(String query) {
271 Session session = SessionHolder.HOLDER.get();
272
273 return session.createSQLQuery(query)
274 .addScalar("a", StandardBasicTypes.DOUBLE)
275 .addScalar("b", StandardBasicTypes.DOUBLE)
276 .addScalar("position", StandardBasicTypes.STRING)
277 .addScalar("attribute", StandardBasicTypes.STRING)
278 .addScalar("name", StandardBasicTypes.STRING)
279 .addScalar("top", StandardBasicTypes.DOUBLE)
280 .addScalar("bottom", StandardBasicTypes.DOUBLE);
281 }
282
283 private static Annotation [] buildAnnotations(List<Object []> list) {
284 Annotation [] anns = new Annotation[list.size()];
285
286 // Names are likely the same because they are a type
287 // like 'Pegel' or 'Hafen'.
288 HashMap<String, String> names = new HashMap<String, String>();
289
290 for (int i = 0; i < anns.length; ++i) {
291 Object [] data = list.get(i);
292 double a = ((Double)data[0]);
293 double b = data[1] != null ? (Double)data[1] : Double.NaN;
294 String position = (String)data[2];
295 String attribute = (String)data[3];
296 String name = (String)data[4];
297 double top = data[5] != null ? (Double)data[5] : Double.NaN;
298 double bottom = data[6] != null ? (Double)data[6] : Double.NaN;
299
300 if (name != null) {
301 String old = names.get(name);
302 if (old != null) {
303 name = old;
304 }
305 else {
306 names.put(name, name);
307 }
308 }
309
310 anns[i] = new Annotation(
311 a, b, position, attribute, name, top, bottom);
312 }
313
314 return anns;
315 }
316
317 public static Annotation [] loadByRiverName(String riverName) {
318
319 SQLQuery query = createQuery(SQL_BY_RIVER_NAME);
320
321 query.setString("river_name", riverName);
322
323 return buildAnnotations(query.list());
324 }
325
326 public static Annotation [] loadByRiverId(int riverId) {
327
328 SQLQuery query = createQuery(SQL_BY_RIVER_ID);
329
330 query.setInteger("river_id", riverId);
331
332 return buildAnnotations(query.list());
333 }
334 }
335 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org