Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java @ 362:1ab23cd66870
Added result set handling. Needs some testing.
gnv-artifacts/trunk@436 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 16 Dec 2009 01:32:19 +0000 |
parents | aec85d00d82c |
children | f66088a43ecc |
comparison
equal
deleted
inserted
replaced
361:aec85d00d82c | 362:1ab23cd66870 |
---|---|
10 | 10 |
11 import org.apache.log4j.Logger; | 11 import org.apache.log4j.Logger; |
12 import org.w3c.dom.Node; | 12 import org.w3c.dom.Node; |
13 | 13 |
14 import com.vividsolutions.jts.geom.Coordinate; | 14 import com.vividsolutions.jts.geom.Coordinate; |
15 import com.vividsolutions.jts.geom.Point; | |
15 import com.vividsolutions.jts.geom.LineString; | 16 import com.vividsolutions.jts.geom.LineString; |
17 | |
16 import com.vividsolutions.jts.io.ParseException; | 18 import com.vividsolutions.jts.io.ParseException; |
17 import com.vividsolutions.jts.io.WKTReader; | 19 import com.vividsolutions.jts.io.WKTReader; |
18 | 20 |
19 import de.intevation.artifactdatabase.Config; | 21 import de.intevation.artifactdatabase.Config; |
20 | 22 |
21 import de.intevation.gnv.artifacts.cache.CacheFactory; | 23 import de.intevation.gnv.artifacts.cache.CacheFactory; |
22 | 24 |
25 import de.intevation.gnv.geobackend.base.DefaultResultDescriptor; | |
26 import de.intevation.gnv.geobackend.base.ResultDescriptor; | |
27 import de.intevation.gnv.geobackend.base.DefaultResult; | |
23 import de.intevation.gnv.geobackend.base.Result; | 28 import de.intevation.gnv.geobackend.base.Result; |
29 | |
30 import de.intevation.gnv.math.Point2d; | |
31 import de.intevation.gnv.math.Interpolation2D; | |
32 | |
24 import de.intevation.gnv.geobackend.base.query.QueryExecutor; | 33 import de.intevation.gnv.geobackend.base.query.QueryExecutor; |
25 import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; | 34 import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; |
26 import de.intevation.gnv.geobackend.base.query.exception.QueryException; | 35 import de.intevation.gnv.geobackend.base.query.exception.QueryException; |
27 import de.intevation.gnv.geobackend.sde.datasources.ResultSet; | 36 import de.intevation.gnv.geobackend.sde.datasources.ResultSet; |
28 | 37 |
38 | |
29 import de.intevation.gnv.utils.IndexBuffer; | 39 import de.intevation.gnv.utils.IndexBuffer; |
40 import de.intevation.gnv.utils.DistanceCalculator; | |
30 | 41 |
31 import de.intevation.gnv.math.LinearFunction; | 42 import de.intevation.gnv.math.LinearFunction; |
43 import de.intevation.gnv.math.LinearMetrics; | |
32 | 44 |
33 import org.apache.commons.math.optimization.fitting.CurveFitter; | 45 import org.apache.commons.math.optimization.fitting.CurveFitter; |
34 | 46 |
35 import org.apache.commons.math.optimization.general.GaussNewtonOptimizer; | 47 import org.apache.commons.math.optimization.general.GaussNewtonOptimizer; |
36 import org.apache.commons.math.optimization.OptimizationException; | 48 import org.apache.commons.math.optimization.OptimizationException; |
192 String[] addedFilterValues = new String[filterValues.length+1]; | 204 String[] addedFilterValues = new String[filterValues.length+1]; |
193 System.arraycopy(filterValues, 0, addedFilterValues, 0, filterValues.length); | 205 System.arraycopy(filterValues, 0, addedFilterValues, 0, filterValues.length); |
194 addedFilterValues[filterValues.length] = additionWhere; | 206 addedFilterValues[filterValues.length] = additionWhere; |
195 | 207 |
196 result = process( | 208 result = process( |
209 Arrays.asList(coords), | |
197 queryExecutor.executeQuery( | 210 queryExecutor.executeQuery( |
198 this.queryID, | 211 this.queryID, |
199 addedFilterValues)); | 212 addedFilterValues)); |
200 | 213 |
201 } catch (ParseException e) { | 214 } catch (ParseException e) { |
214 } | 227 } |
215 } | 228 } |
216 return result; | 229 return result; |
217 } | 230 } |
218 | 231 |
219 protected Collection<Result> process(Collection<Result> input) { | 232 private static final String [] COLUMN_BLACKLIST = { |
220 // TODO: split by additional parameters, interpolate the | 233 "MEDIAN.MESHPOINT.JPOSITION", |
221 // values, and create a new dummy result set. | 234 "MEDIAN.MESHPOINT.IPOSITION" |
222 | 235 }; |
223 return input; | 236 |
224 | 237 private static final boolean blacklisted(String column) { |
238 for (int i = 0; i < COLUMN_BLACKLIST.length; ++i) { | |
239 if (COLUMN_BLACKLIST.equals(column)) { | |
240 return true; | |
241 } | |
242 } | |
243 return false; | |
244 } | |
245 | |
246 private static boolean different(Result a, Result b, int [] indices) { | |
247 for (int i = 0; i < indices.length; ++i) { | |
248 Object oa = a.getObject(indices[i]); | |
249 Object ob = b.getObject(indices[i]); | |
250 if ((oa == null && ob != null) | |
251 || (oa != null && ob == null) | |
252 || (oa != null && !oa.equals(ob))) { | |
253 return true; | |
254 } | |
255 } | |
256 return false; | |
257 } | |
258 | |
259 private static final String [] DIFF_COLUMS = { | |
260 "GROUP1", | |
261 "GROUP2", | |
262 "GROUP3" | |
263 }; | |
264 | |
265 public static final class SectionHandler | |
266 implements Interpolation2D.Consumer | |
267 { | |
268 private ArrayList<Point2d> points; | |
269 private List<Coordinate> path; | |
270 private Collection<Result> output; | |
271 private Result prototyp; | |
272 private ResultDescriptor descriptor; | |
273 | |
274 public SectionHandler() { | |
275 } | |
276 | |
277 public SectionHandler( | |
278 List<Coordinate> path, | |
279 Collection<Result> output, | |
280 ResultDescriptor descriptor | |
281 ) { | |
282 this.path = path; | |
283 this.output = output; | |
284 this.descriptor = descriptor; | |
285 } | |
286 | |
287 public void finish() { | |
288 if (!points.isEmpty()) { | |
289 double distance = toKM( | |
290 DistanceCalculator.calculateDistance(path)); | |
291 | |
292 Interpolation2D.interpolate( | |
293 path, | |
294 points, | |
295 0d, | |
296 distance, | |
297 steps(distance), | |
298 LinearMetrics.INSTANCE, // XXX: This wrong!!! | |
299 this); | |
300 | |
301 points.clear(); | |
302 } | |
303 } | |
304 | |
305 public void setPrototyp(Result prototyp) { | |
306 this.prototyp = prototyp; | |
307 } | |
308 | |
309 public void handle(Result result) { | |
310 Coordinate coordinate = | |
311 toCoordinate(result.getString("SHAPE")); | |
312 double value = result.getDouble("YORDINATE"); | |
313 int iPos = result.getInteger("MEDIAN.MESHPOINT.JPOSITION"); | |
314 int jPos = result.getInteger("MEDIAN.MESHPOINT.JPOSITION"); | |
315 Point2d p = new Point2d( | |
316 coordinate.x, | |
317 coordinate.y, | |
318 value, | |
319 iPos, jPos); | |
320 points.add(p); | |
321 } | |
322 | |
323 public void interpolated(Coordinate coordinate) { | |
324 DefaultResult result = new DefaultResult(descriptor); | |
325 ResultDescriptor pd = prototyp.getResultDescriptor(); | |
326 | |
327 int pcolums = pd.getColumnCount(); | |
328 for (int i = 0, j = 0; i < pcolums; ++i) { | |
329 String colname = pd.getColumnName(i); | |
330 if (blacklisted(colname)) { | |
331 continue; | |
332 } | |
333 if (colname.equals("SHAPE")) { | |
334 result.addColumnValue(j, toWKT(coordinate)); | |
335 } | |
336 else if (colname.equals("YORDINATE")) { | |
337 result.addColumnValue(j, Double.valueOf(coordinate.z)); | |
338 } | |
339 ++j; | |
340 } | |
341 output.add(result); | |
342 } | |
343 } // class SectionHandler | |
344 | |
345 public static final double NAUTICAL_MILE = 1852.216d; | |
346 public static final double KILOMETER = 1000d; | |
347 | |
348 public static final double toKM(double distance) { | |
349 return (distance * NAUTICAL_MILE) / KILOMETER; | |
350 } | |
351 | |
352 public static final double INTERPOLATION_STEP_WIDTH = | |
353 Double.parseDouble(System.getProperty( | |
354 "interpolation.step.width", "100")); | |
355 | |
356 public static int steps(double km) { | |
357 return (int)Math.ceil( | |
358 Math.max(1d, (km * KILOMETER)/INTERPOLATION_STEP_WIDTH)); | |
359 } | |
360 | |
361 public static Coordinate toCoordinate(String shape) { | |
362 try { | |
363 return ((Point)(new WKTReader().read(shape))).getCoordinate(); | |
364 } | |
365 catch (ParseException pe) { | |
366 log.error(pe); | |
367 } | |
368 return null; | |
369 } | |
370 | |
371 public static String toWKT(Coordinate coordinate) { | |
372 StringBuilder sb = new StringBuilder("POINT("); | |
373 sb.append(coordinate.x) | |
374 .append(' ') | |
375 .append(coordinate.y) | |
376 .append(')'); | |
377 return sb.toString(); | |
378 } | |
379 | |
380 protected Collection<Result> process( | |
381 List<Coordinate> path, | |
382 Collection<Result> input | |
383 ) { | |
384 ArrayList<Result> output = new ArrayList<Result>(); | |
385 | |
386 | |
387 Result last = null; | |
388 | |
389 int [] diffColums = null; | |
390 | |
391 SectionHandler sectionHandler = null; | |
392 | |
393 for (Result result: input) { | |
394 | |
395 if (sectionHandler == null) { | |
396 | |
397 ResultDescriptor rd = result.getResultDescriptor(); | |
398 diffColums = rd.getColumnIndices(DIFF_COLUMS); | |
399 int columns = rd.getColumnCount(); | |
400 | |
401 DefaultResultDescriptor resultDescriptor = | |
402 new DefaultResultDescriptor(); | |
403 | |
404 for (int j = 0; j < columns; ++j) { | |
405 String columnName = rd.getColumnName(j); | |
406 if (!blacklisted(columnName)) { | |
407 resultDescriptor.addColumn( | |
408 columnName, | |
409 rd.getColumnClassName(j)); | |
410 } | |
411 } | |
412 | |
413 sectionHandler = new SectionHandler( | |
414 path, | |
415 output, | |
416 resultDescriptor); | |
417 | |
418 sectionHandler.setPrototyp(result); | |
419 } | |
420 | |
421 if (last != null && different(last, result, diffColums)) { | |
422 sectionHandler.finish(); | |
423 sectionHandler.setPrototyp(result); | |
424 } | |
425 | |
426 sectionHandler.handle(result); | |
427 | |
428 last = result; | |
429 } | |
430 | |
431 if (sectionHandler != null) { | |
432 sectionHandler.finish(); | |
433 } | |
434 | |
435 return output; | |
225 } | 436 } |
226 } | 437 } |