comparison artifacts/src/main/java/org/dive4elements/river/artifacts/states/FloodMapState.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/states/FloodMapState.java@bd047b71ab37
children 4897a58c8746
comparison
equal deleted inserted replaced
5837:d9901a08d0a6 5838:5aa05a7a34b7
1 package org.dive4elements.river.artifacts.states;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7
8 import java.util.ArrayList;
9 import java.util.Arrays;
10 import java.util.List;
11
12 import org.apache.log4j.Logger;
13
14 import org.apache.velocity.Template;
15
16 import org.geotools.feature.FeatureCollection;
17 import org.geotools.feature.FeatureCollections;
18
19 import org.geotools.feature.simple.SimpleFeatureBuilder;
20
21 import org.hibernate.HibernateException;
22
23 import org.opengis.feature.simple.SimpleFeature;
24 import org.opengis.feature.simple.SimpleFeatureType;
25
26 import com.vividsolutions.jts.geom.Coordinate;
27 import com.vividsolutions.jts.geom.Geometry;
28 import com.vividsolutions.jts.geom.LineString;
29 import com.vividsolutions.jts.geom.Polygon;
30
31 import org.dive4elements.artifactdatabase.state.Facet;
32
33 import org.dive4elements.artifacts.Artifact;
34 import org.dive4elements.artifacts.CallContext;
35 import org.dive4elements.artifacts.CallMeta;
36 import org.dive4elements.artifacts.GlobalContext;
37
38 import org.dive4elements.artifacts.common.utils.FileTools;
39
40 import org.dive4elements.river.artifacts.FLYSArtifact;
41
42 import org.dive4elements.river.artifacts.access.RangeAccess;
43
44 import org.dive4elements.river.artifacts.context.FLYSContext;
45
46 import org.dive4elements.river.artifacts.model.CalculationMessage;
47 import org.dive4elements.river.artifacts.model.CalculationResult;
48 import org.dive4elements.river.artifacts.model.FacetTypes;
49 import org.dive4elements.river.artifacts.model.LayerInfo;
50 import org.dive4elements.river.artifacts.model.WQKms;
51
52 import org.dive4elements.river.artifacts.model.map.HWS;
53 import org.dive4elements.river.artifacts.model.map.HWSContainer;
54 import org.dive4elements.river.artifacts.model.map.HWSFactory;
55 import org.dive4elements.river.artifacts.model.map.WMSLayerFacet;
56 import org.dive4elements.river.artifacts.model.map.WSPLGENCalculation;
57 import org.dive4elements.river.artifacts.model.map.WSPLGENJob;
58 import org.dive4elements.river.artifacts.model.map.WSPLGENReportFacet;
59
60 import org.dive4elements.river.artifacts.resources.Resources;
61
62 import org.dive4elements.river.exports.WstWriter;
63
64 import org.dive4elements.river.model.CrossSectionTrack;
65 import org.dive4elements.river.model.DGM;
66 import org.dive4elements.river.model.Floodplain;
67 import org.dive4elements.river.model.RiverAxis;
68
69 import org.dive4elements.river.utils.ArtifactMapfileGenerator;
70 import org.dive4elements.river.utils.FLYSUtils;
71 import org.dive4elements.river.utils.GeometryUtils;
72 import org.dive4elements.river.utils.MapfileGenerator;
73
74 import org.dive4elements.river.wsplgen.FacetCreator;
75 import org.dive4elements.river.wsplgen.JobObserver;
76 import org.dive4elements.river.wsplgen.Scheduler;
77
78 public class FloodMapState
79 extends DefaultState
80 implements FacetTypes
81 {
82 /** The logger that is used in this state. */
83 private static Logger logger = Logger.getLogger(FloodMapState.class);
84
85
86 public static final String KEEP_ARTIFACT_DIR =
87 System.getProperty("flys.uesk.keep.artifactsdir", "false");
88
89
90 public static final String OUTPUT_NAME = "floodmap";
91
92 public static final String WSP_ARTIFACT = "wsp";
93
94 public static final String WINFO_WSP_STATE_ID = "state.winfo.waterlevel";
95
96 public static final String WSPLGEN_PARAMETER_FILE = "wsplgen.par";
97 public static final String WSPLGEN_BARRIERS_LINES = "barrier_lines.shp";
98 public static final String WSPLGEN_BARRIERS_POLY = "barrier_polygons.shp";
99 public static final String WSPLGEN_AXIS = "axis.shp";
100 public static final String WSPLGEN_QPS = "qps.shp";
101 public static final String WSPLGEN_FLOODPLAIN = "talaue.shp";
102 public static final String WSPLGEN_WSP_FILE = "waterlevel.wst";
103 public static final String WSPLGEN_OUTPUT_FILE = "wsplgen.shp";
104 public static final String WSPLGEN_USER_SHAPE = "user-rgd.shp";
105 public static final String WSPLGEN_USER_ZIP = "user-rgd.zip";
106 public static final String WSPLGEN_USER_FILENAME = "user-rgd";
107
108 public static final String WSPLGEN_QPS_NAME = "qps";
109
110 public static final int WSPLGEN_DEFAULT_OUTPUT = 0;
111
112 private static final String HWS_LINES_SHAPE = "hws-lines.shp";
113
114 private static final String I18N_HWS_POINTS_OFFICIAL = "floodmap.hws.points.official";
115 private static final String I18N_HWS_LINES_OFFICIAL = "floodmap.hws.lines.official";
116 private static final String HWS_LINES = "hws-lines";
117 private static final String HWS_POINT_SHAPE = "hws-points.shp";
118 private static final String HWS_POINTS = "hws-points";
119
120 /**
121 * @param orig
122 * @param owner
123 * @param context
124 * @param callMeta
125 */
126 @Override
127 public void initialize(
128 Artifact orig,
129 Artifact owner,
130 Object context,
131 CallMeta callMeta
132 ) {
133 logger.info("Initialize State with Artifact: " + orig.identifier());
134
135 copyShapeDir(orig, owner);
136 modifyFacets(orig, owner, context, callMeta);
137
138 ArtifactMapfileGenerator amfg = new ArtifactMapfileGenerator();
139 try {
140 amfg.generate();
141 }
142 catch (IOException e) {
143 logger.error(e.getMessage(), e);
144 }
145 }
146
147
148 protected void copyShapeDir(Artifact orig, Artifact owner) {
149 File origDir = getDirectory((FLYSArtifact) orig);
150 File thisDir = getDirectory((FLYSArtifact) owner);
151
152 FileTools.copyDirectory(origDir, thisDir);
153 }
154
155
156 protected void modifyFacets(
157 Artifact orig,
158 Artifact owner,
159 Object context,
160 CallMeta callMeta
161 ) {
162 FLYSArtifact flys = (FLYSArtifact) owner;
163 List<Facet> facets = flys.getFacets();
164 if (facets == null || facets.isEmpty()) {
165 logger.warn("No facets for '" + OUTPUT_NAME + "' given!");
166 return;
167 }
168
169 for (Facet facet: facets) {
170 if (facet instanceof WMSLayerFacet) {
171 WMSLayerFacet wms = (WMSLayerFacet) facet;
172
173 List<String> layers = wms.getLayers();
174
175 for (String layer: layers) {
176 if (layer.startsWith(MapfileGenerator.MS_WSPLGEN_PREFIX)) {
177 wms.removeLayer(layer);
178
179 String newLayer = MapfileGenerator.MS_WSPLGEN_PREFIX +
180 owner.identifier();
181
182 wms.addLayer(newLayer);
183
184 logger.debug(
185 "Replaced layer: " + layer + " with " + newLayer);
186 }
187 }
188 }
189 }
190 }
191
192
193 @Override
194 public Object computeAdvance(
195 FLYSArtifact artifact,
196 String hash,
197 CallContext context,
198 List<Facet> facets,
199 Object old
200 ) {
201 logger.debug("FloodMapState.computeAdvance");
202
203 File artifactDir = getDirectory(artifact);
204
205 if (artifactDir == null) {
206 logger.error("Could not create directory for WSPLGEN results!");
207 return null;
208 }
209
210 WSPLGENCalculation calculation = new WSPLGENCalculation();
211
212 FacetCreator facetCreator = new FacetCreator(
213 artifact, context, hash, getID(), facets);
214
215 WSPLGENJob job = prepareWSPLGENJob(
216 artifact,
217 facetCreator,
218 artifactDir,
219 context,
220 calculation);
221
222 CalculationResult res = new CalculationResult(null, calculation);
223 WSPLGENReportFacet report= new WSPLGENReportFacet(
224 ComputeType.ADVANCE, hash, getID(), res);
225
226 facets.add(report);
227
228 if (job == null) {
229 if (KEEP_ARTIFACT_DIR.equals("false")) {
230 removeDirectory(artifact);
231 }
232
233 calculation.addError(-1, Resources.getMsg(
234 context.getMeta(),
235 "wsplgen.job.error",
236 "wsplgen.job.error"));
237
238 logger.error("No WSPLGEN processing has been started!");
239
240 return null;
241 }
242
243 context.afterCall(CallContext.BACKGROUND);
244 context.addBackgroundMessage(new CalculationMessage(
245 JobObserver.STEPS.length,
246 0,
247 Resources.getMsg(
248 context.getMeta(),
249 "wsplgen.job.queued",
250 "wsplgen.job.queued")
251 ));
252
253 GlobalContext gc = (GlobalContext) context.globalContext();
254 Scheduler scheduler = (Scheduler) gc.get(FLYSContext.SCHEDULER);
255 scheduler.addJob(job);
256
257 return null;
258 }
259
260
261 /**
262 * Returns (and creates if not existing) the directory for storing WSPLEN
263 * data for the owner artifact.
264 *
265 * @param artifact The owner Artifact.
266 *
267 * @return the directory for WSPLEN data.
268 */
269 protected File getDirectory(FLYSArtifact artifact) {
270 String shapePath = FLYSUtils.getXPathString(
271 FLYSUtils.XPATH_FLOODMAP_SHAPEFILE_DIR);
272
273 File artifactDir = FileTools.getDirectory(
274 shapePath, artifact.identifier());
275
276 return artifactDir;
277 }
278
279
280 /**
281 * Removes the directory and all its content where the required data and the
282 * results of WSPLGEN are stored. Should be called in endOfLife().
283 */
284 protected void removeDirectory(FLYSArtifact artifact) {
285 String shapePath = FLYSUtils.getXPathString(
286 FLYSUtils.XPATH_FLOODMAP_SHAPEFILE_DIR);
287
288 File artifactDir = new File(shapePath, artifact.identifier());
289
290 if (artifactDir.exists()) {
291 logger.info("Delete directory: " + artifactDir.getAbsolutePath());
292 if (!FileTools.deleteRecursive(artifactDir)) {
293 logger.warn("Could not delete directory: "
294 + artifactDir.getAbsolutePath());
295 }
296 }
297 else {
298 logger.debug("There is no directory to remove.");
299 }
300 }
301
302
303 @Override
304 public void endOfLife(Artifact artifact, Object callContext) {
305 logger.info("FloodMapState.endOfLife: " + artifact.identifier());
306
307 FLYSArtifact flys = (FLYSArtifact) artifact;
308
309 Scheduler scheduler = Scheduler.getInstance();
310 scheduler.cancelJob(flys.identifier());
311 }
312
313
314 protected WSPLGENJob prepareWSPLGENJob(
315 FLYSArtifact artifact,
316 FacetCreator facetCreator,
317 File artifactDir,
318 CallContext context,
319 WSPLGENCalculation calculation
320 ) {
321 logger.debug("FloodMapState.prepareWSPLGENJob");
322 String scenario = artifact.getDataAsString("scenario");
323
324 WSPLGENJob job = new WSPLGENJob(
325 artifact,
326 artifactDir,
327 facetCreator,
328 context,
329 calculation);
330
331 File paraFile = new File(artifactDir, WSPLGEN_PARAMETER_FILE);
332
333 setOut(artifact, job);
334 setRange(artifact, job);
335 setDelta(artifact, job);
336 setGel(artifact, job);
337 setDist(artifact, job);
338 setAxis(artifact, artifactDir, job);
339 setPro(artifact, artifactDir, job);
340 setDgm(artifact, job, context);
341 setArea(artifact, artifactDir, job);
342 setOutFile(artifact, job);
343 setWsp(artifact, context, artifactDir, job); // WSP
344 if (scenario.equals("scenario.current")) {
345 setOfficialHWS(artifact, facetCreator, artifactDir, job);
346 }
347 else if (scenario.equals("scenario.scenario")) {
348 setAdditionalHWS(artifact, facetCreator, artifactDir, job);
349 setLine(artifact, facetCreator, artifactDir, job);
350 setUserShape(artifact, facetCreator, artifactDir, job);
351 }
352 // TODO
353 // setWspTag(artifact, job);
354
355 try {
356 job.toFile(paraFile);
357
358 return job;
359 }
360 catch (IOException ioe) {
361 logger.warn("Cannot write PAR file: " + ioe.getMessage());
362 }
363 catch (IllegalArgumentException iae) {
364 logger.warn("Cannot write PAR file: " + iae.getMessage());
365 }
366
367 return null;
368 }
369
370
371 private void setAdditionalHWS(
372 FLYSArtifact artifact,
373 FacetCreator facetCreator,
374 File dir,
375 WSPLGENJob job) {
376 File line = new File(dir, HWS_LINES_SHAPE);
377 boolean lines = line.exists();
378 logger.debug("shp file exists: " + lines);
379 if (lines) {
380 job.addLin(dir + "/" + HWS_LINES_SHAPE);
381 facetCreator.createShapeFacet(I18N_HWS_LINES_OFFICIAL,
382 MapfileGenerator.MS_LAYER_PREFIX + HWS_LINES,
383 FLOODMAP_LINES, 2);
384 }
385 File point = new File(dir, HWS_POINT_SHAPE);
386 boolean points = point.exists();
387 logger.debug("shp file exists: " + points);
388 if (points) {
389 facetCreator.createShapeFacet(I18N_HWS_POINTS_OFFICIAL,
390 MapfileGenerator.MS_LAYER_PREFIX + HWS_POINTS,
391 FLOODMAP_FIXPOINTS, 3);
392 }
393 }
394
395
396 private void setOfficialHWS(
397 FLYSArtifact artifact,
398 FacetCreator facetCreator,
399 File artifactDir,
400 WSPLGENJob job) {
401 String river = artifact.getDataAsString("river");
402
403 HWSContainer hwsLines = HWSFactory.getHWSLines(river);
404 List<HWS> selectedLines = hwsLines.getOfficialHWS();
405
406 FeatureCollection collectionLines = FeatureCollections.newCollection();
407 SimpleFeatureType lineType = null;
408 for (HWS h : selectedLines) {
409 lineType = h.getFeatureType();
410 collectionLines.add(h.getFeature());
411 }
412 boolean successLines = false;
413 if (lineType != null && collectionLines.size() > 0) {
414 File shapeLines = new File(artifactDir, HWS_LINES_SHAPE);
415 successLines = GeometryUtils.writeShapefile(
416 shapeLines, lineType, collectionLines);
417 }
418 if (successLines) {
419 createMapfile(
420 artifact,
421 artifactDir,
422 MapfileGenerator.MS_LAYER_PREFIX + "hws-lines",
423 HWS_LINES_SHAPE,
424 "LINE",
425 "31467",
426 "hws");
427 job.addLin(artifactDir + "/" + HWS_LINES_SHAPE);
428 facetCreator.createShapeFacet(I18N_HWS_LINES_OFFICIAL,
429 MapfileGenerator.MS_LAYER_PREFIX + HWS_LINES,
430 FLOODMAP_HWS_LINES,2);
431 }
432 }
433
434
435 private void createMapfile(
436 FLYSArtifact artifact,
437 File artifactDir,
438 String name,
439 String hwsShapefile,
440 String type,
441 String srid,
442 String group
443 ) {
444 LayerInfo info = new LayerInfo();
445 info.setName(name + artifact.identifier());
446 info.setType(type);
447 info.setDirectory(artifact.identifier());
448 info.setTitle(name);
449 info.setData(hwsShapefile);
450 info.setSrid(srid);
451 info.setGroupTitle(group);
452 MapfileGenerator generator = new ArtifactMapfileGenerator();
453 Template tpl = generator.getTemplateByName(MapfileGenerator.SHP_LAYER_TEMPLATE);
454 try {
455 File layer = new File(artifactDir.getCanonicalPath() + "/" + name);
456 generator.writeLayer(info, layer, tpl);
457 List<String> layers = new ArrayList<String>();
458 layers.add(layer.getAbsolutePath());
459 generator.generate();
460 }
461 catch(FileNotFoundException fnfe) {
462 logger.warn("Could not find mapfile for hws layer");
463 }
464 catch (Exception ioe) {
465 logger.warn("Could not create mapfile for hws layer");
466 logger.warn(Arrays.toString(ioe.getStackTrace()));
467 }
468 }
469
470
471 protected void setOut(FLYSArtifact artifact, WSPLGENJob job) {
472 job.setOut(WSPLGEN_DEFAULT_OUTPUT);
473 }
474
475
476 protected void setRange(FLYSArtifact artifact, WSPLGENJob job) {
477 RangeAccess rangeAccess = new RangeAccess(artifact, null);
478 double[] range = rangeAccess.getKmRange();
479
480 job.setStart(range[0]);
481 job.setEnd(range[1]);
482 }
483
484
485 protected void setDelta(FLYSArtifact artifact, WSPLGENJob job) {
486 String from = artifact.getDataAsString("diff_from");
487 String to = artifact.getDataAsString("diff_to");
488 String diff = artifact.getDataAsString("diff_diff");
489
490 try {
491 job.setFrom(Double.parseDouble(from));
492 }
493 catch (NumberFormatException nfe) {
494 }
495
496 try {
497 job.setTo(Double.parseDouble(to));
498 }
499 catch (NumberFormatException nfe) {
500 }
501
502 try {
503 job.setDiff(Double.parseDouble(diff));
504 }
505 catch (NumberFormatException nfe) {
506 }
507 }
508
509
510 protected void setGel(FLYSArtifact artifact, WSPLGENJob job) {
511 String gel = artifact.getDataAsString("scenario");
512
513 logger.debug("Selected gel = '" + gel + "'");
514
515 if (gel == null || gel.length() == 0) {
516 job.setGel(WSPLGENJob.GEL_NOSPERRE);
517 }
518 else if (gel.equals("scenario.current")) {
519 job.setGel(WSPLGENJob.GEL_SPERRE);
520 }
521 else if (gel.equals("scenario.scenario")) {
522 job.setGel(WSPLGENJob.GEL_SPERRE);
523 }
524 else {
525 job.setGel(WSPLGENJob.GEL_NOSPERRE);
526 }
527 }
528
529
530 protected void setDist(FLYSArtifact artifact, WSPLGENJob job) {
531 String dist = artifact.getDataAsString("profile_distance");
532
533 try {
534 job.setDist(Double.parseDouble(dist));
535 }
536 catch (NumberFormatException nfe) {
537 // nothing to do here
538 }
539 }
540
541
542 protected void setLine(
543 FLYSArtifact artifact,
544 FacetCreator facetCreator,
545 File dir,
546 WSPLGENJob job
547 ) {
548 String river = artifact.getDataAsString("river");
549 String geoJSON = artifact.getDataAsString("uesk.barriers");
550 String srid = FLYSUtils.getRiverDGMSrid(river);
551 String srs = "EPSG:" + srid;
552
553 if (geoJSON == null || geoJSON.length() == 0) {
554 logger.debug("No barrier features in parameterization existing.");
555 return;
556 }
557
558 SimpleFeatureType ft = getBarriersFeatureType(
559 "barriers", srs, Geometry.class);
560
561 List<SimpleFeature> features = GeometryUtils.parseGeoJSON(geoJSON, ft);
562 if (features == null || features.isEmpty()) {
563 logger.debug("No barrier features extracted.");
564 return;
565 }
566
567 FeatureCollection[] fcs = splitLinesAndPolygons(features);
568
569 File shapeLines = new File(dir, WSPLGEN_BARRIERS_LINES);
570 File shapePolys = new File(dir, WSPLGEN_BARRIERS_POLY);
571
572 Object[][] obj = new Object[][] {
573 new Object[] { "typ", String.class }
574 };
575
576 String scenario = job.getGel();
577
578 boolean l = GeometryUtils.writeShapefile(
579 shapeLines,
580 GeometryUtils.buildFeatureType("lines", srs, LineString.class, obj),
581 fcs[0]);
582
583 if (l) {
584 logger.debug(
585 "Successfully created barrier line shapefile. " +
586 "Write shapefile path into WSPLGEN job.");
587 createMapfile(
588 artifact,
589 dir,
590 MapfileGenerator.MS_LAYER_PREFIX + "barriers-lines",
591 WSPLGEN_BARRIERS_LINES,
592 "LINE",
593 srid,
594 "barriers");
595
596 if (scenario.equals(WSPLGENJob.GEL_NOSPERRE)) {
597 logger.debug("WSPLGEN will not use barrier features.");
598 }
599 else {
600 job.addLin(shapeLines.getAbsolutePath());
601 }
602 }
603
604 boolean p = GeometryUtils.writeShapefile(
605 shapePolys,
606 GeometryUtils.buildFeatureType("polygons", srs, Polygon.class, obj),
607 fcs[1]);
608
609
610 if (p) {
611 logger.debug(
612 "Successfully created barrier polygon shapefile. " +
613 "Write shapefile path into WSPLGEN job.");
614 createMapfile(
615 artifact,
616 dir,
617 MapfileGenerator.MS_LAYER_PREFIX + "barriers-poly",
618 shapePolys.getAbsolutePath(),
619 "POLYGON",
620 srid,
621 "barriers");
622
623 if (scenario.equals(WSPLGENJob.GEL_NOSPERRE)) {
624 logger.debug("WSPLGEN will not use barrier features.");
625 }
626 else {
627 job.addLin(shapePolys.getAbsolutePath());
628 }
629 }
630
631 if (p || l) {
632 facetCreator.createBarrierFacet();
633 }
634 }
635
636
637 protected void setUserShape(
638 FLYSArtifact artifact,
639 FacetCreator facetCreator,
640 File dir,
641 WSPLGENJob job
642 ) {
643 File archive = new File(dir, WSPLGEN_USER_SHAPE);
644 boolean exists = archive.exists();
645 logger.debug("shp file exists: " + exists);
646 if (exists) {
647 job.addLin(dir + "/" + WSPLGEN_USER_SHAPE);
648 facetCreator.createShapeFacet(FacetCreator.I18N_USERSHAPE,
649 MapfileGenerator.MS_LAYER_PREFIX + "user-rgd",
650 FLOODMAP_USERSHAPE,
651 4);
652 }
653 }
654
655 protected SimpleFeatureType getBarriersFeatureType(
656 String name,
657 String srs,
658 Class type
659 ) {
660 Object[][] attrs = new Object[3][];
661 attrs[0] = new Object[] { "typ", String.class };
662 attrs[1] = new Object[] { "elevation", Double.class };
663 attrs[2] = new Object[] { "mark.selected", Integer.class };
664
665 return GeometryUtils.buildFeatureType(name, srs, type, attrs);
666 }
667
668
669 protected FeatureCollection[] splitLinesAndPolygons(List<SimpleFeature> f) {
670 FeatureCollection lines = FeatureCollections.newCollection();
671 FeatureCollection polygons = FeatureCollections.newCollection();
672
673 for (SimpleFeature feature: f) {
674 Geometry geom = (Geometry) feature.getDefaultGeometry();
675
676
677 if (geom instanceof LineString) {
678 geom = applyElevationAttribute(feature, geom);
679 lines.add(feature);
680 }
681 else if (geom instanceof Polygon) {
682 geom = applyElevationAttribute(feature, geom);
683 polygons.add(feature);
684 }
685 else {
686 logger.warn("Feature not supported: " + geom.getClass());
687 }
688 }
689
690 logger.debug("Found " + lines.size() + " barrier lines.");
691 logger.debug("Found " + polygons.size() + " barrier polygons.");
692
693 return new FeatureCollection[] { lines, polygons };
694 }
695
696
697 protected static Geometry applyElevationAttribute(
698 SimpleFeature feature,
699 Geometry geom
700 ) {
701 logger.debug("Apply elevations for: " + geom.getClass());
702
703 List<Double> elevations = extractElevations(feature);
704 int numPoints = geom.getNumPoints();
705 int numElevation = elevations.size();
706
707 String typ = (String) feature.getAttribute("typ");
708
709 if (numPoints > numElevation) {
710 logger.warn("More vertices in Geometry than elevations given.");
711 }
712
713 Coordinate[] c = geom.getCoordinates();
714 for (int i = 0; i < numPoints; i++) {
715 if (i < numElevation) {
716 c[i].z = elevations.get(i);
717 }
718 else if (typ != null && typ.equals("Graben")) {
719 c[i].z = -9999d;
720 }
721 else {
722 c[i].z = 9999d;
723 }
724 }
725
726 return geom;
727 }
728
729
730 protected static List<Double> extractElevations(SimpleFeature feature) {
731 String tmp = (String) feature.getAttribute("elevation");
732 String typ = (String) feature.getAttribute("typ");
733
734 String[] elevations = tmp == null ? null : tmp.split(" ");
735
736 int num = elevations != null ? elevations.length : 0;
737
738 List<Double> list = new ArrayList<Double>(num);
739
740 for (int i = 0; i < num; i++) {
741 try {
742 list.add(Double.parseDouble(elevations[i]));
743 }
744 catch (NumberFormatException nfe) {
745 logger.warn("Error while parsing elevation at pos: " + i);
746 if (typ != null && typ.equals("Graben")) {
747 list.add(new Double(-9999.0));
748 }
749 else {
750 list.add(new Double(9999.0));
751 }
752 }
753 }
754
755 return list;
756 }
757
758
759 protected void setAxis(FLYSArtifact artifact, File dir, WSPLGENJob job) {
760 String river = artifact.getDataAsString("river");
761 String srid = FLYSUtils.getRiverDGMSrid(river);
762 String srs = "EPSG:" + srid;
763
764 List<RiverAxis> axes = null;
765 try {
766 axes = RiverAxis.getRiverAxis(river);
767 }
768 catch (HibernateException iae) {
769 logger.warn("No valid river axis found for " + river);
770 return;
771 }
772 if (axes == null || axes.isEmpty()) {
773 logger.warn("Could not find river axis for: '" + river + "'");
774 return;
775 }
776
777 SimpleFeatureType ft = GeometryUtils.buildFeatureType(
778 "axis", srs, LineString.class);
779
780 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft);
781 FeatureCollection collection = FeatureCollections.newCollection();
782
783 for (int i = 0, n = axes.size(); i < n; i++) {
784 RiverAxis axis = axes.get(i);
785
786 builder.add(axis.getGeom());
787 collection.add(builder.buildFeature(String.valueOf(i)));
788
789 builder.reset();
790 }
791
792 File axisShape = new File(dir, WSPLGEN_AXIS);
793
794 boolean a = GeometryUtils.writeShapefile(
795 axisShape,
796 GeometryUtils.buildFeatureType("axis", srs, LineString.class),
797 collection);
798
799 if (a) {
800 job.setAxis(axisShape.getAbsolutePath());
801 }
802 }
803
804
805 protected void setPro(FLYSArtifact artifact, File dir, WSPLGENJob job) {
806 String river = artifact.getDataAsString("river");
807 String srid = FLYSUtils.getRiverDGMSrid(river);
808 String srs = "EPSG:" + srid;
809
810 List<CrossSectionTrack> cst =
811 CrossSectionTrack.getCrossSectionTrack(river, WSPLGEN_QPS_NAME);
812
813 logger.debug("Found " + cst.size() + " CrossSectionTracks.");
814
815 Object[][] attrs = new Object[2][];
816 attrs[0] = new Object[] { "ELEVATION", Double.class };
817 attrs[1] = new Object[] { "KILOMETER", Double.class };
818
819 SimpleFeatureType ft = GeometryUtils.buildFeatureType(
820 "qps", srs, LineString.class, attrs);
821
822 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft);
823 FeatureCollection collection = FeatureCollections.newCollection();
824
825 int i = 0;
826 for (CrossSectionTrack track: cst) {
827 builder.reset();
828 builder.add(track.getGeom());
829 builder.add(track.getZ().doubleValue());
830 builder.add(track.getKm().doubleValue());
831
832 collection.add(builder.buildFeature(String.valueOf(i++)));
833 }
834
835 File qpsShape = new File(dir, WSPLGEN_QPS);
836
837 boolean q = GeometryUtils.writeShapefile(
838 qpsShape,
839 GeometryUtils.buildFeatureType("qps", srs, LineString.class, attrs),
840 collection);
841
842 if (q) {
843 job.setPro(qpsShape.getAbsolutePath());
844 }
845 }
846
847
848 protected void setDgm(
849 FLYSArtifact artifact,
850 WSPLGENJob job,
851 CallContext context
852 ) {
853 String dgm_id = artifact.getDataAsString("dgm");
854
855 int id = -1;
856 try {
857 id = Integer.parseInt(dgm_id);
858 }
859 catch (NumberFormatException nfe) { /* do nothing */ }
860
861 DGM dgm = DGM.getDGM(id);
862
863 if (dgm == null) {
864 logger.warn("Could not find specified DGM.");
865
866 return;
867 }
868
869 File dgmPath = new File (dgm.getPath());
870 if (dgmPath.isAbsolute()) {
871 job.setDgm(dgm.getPath());
872 }
873 else {
874 FLYSContext fc = (FLYSContext)context.globalContext();
875 String prefix = (String) fc.get("dgm-path");
876 job.setDgm(prefix.trim() + dgm.getPath().trim());
877 }
878 }
879
880
881 protected void setArea(FLYSArtifact artifact, File dir, WSPLGENJob job) {
882 String useFloodplain = artifact.getDataAsString("use_floodplain");
883 if (!Boolean.valueOf(useFloodplain)) {
884 logger.debug("WSPLGEN will not use floodplain.");
885 return;
886 }
887
888 String river = artifact.getDataAsString("river");
889 String srid = FLYSUtils.getRiverDGMSrid(river);
890 String srs = "EPSG:" + srid;
891
892 Floodplain plain = Floodplain.getFloodplain(river);
893
894 SimpleFeatureType ft = GeometryUtils.buildFeatureType(
895 "talaue", srs, Polygon.class);
896
897 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft);
898 builder.add(plain.getGeom());
899
900 FeatureCollection collection = FeatureCollections.newCollection();
901 collection.add(builder.buildFeature("0"));
902
903 File talaueShape = new File(dir, WSPLGEN_FLOODPLAIN);
904
905 boolean t = GeometryUtils.writeShapefile(
906 talaueShape,
907 GeometryUtils.buildFeatureType("talaue", srs, Polygon.class),
908 collection);
909
910 if (t) {
911 job.setArea(talaueShape.getAbsolutePath());
912 }
913 }
914
915
916 protected void setOutFile(FLYSArtifact artifact, WSPLGENJob job) {
917 job.setOutFile(WSPLGEN_OUTPUT_FILE);
918 }
919
920
921 protected WQKms getWQKms(FLYSArtifact flys, CallContext cc) {
922 String wspString = flys.getDataAsString(WSP_ARTIFACT);
923 if (wspString == null) {
924 logger.debug("getWQKms(): wspString == null");
925 return null;
926 }
927 String[] parts = wspString.split(";");
928 String otherArtifact = parts[0];
929
930 int idx = -1;
931 try {
932 idx = Integer.parseInt(parts[2]);
933 }
934 catch (NumberFormatException nfe) { /* do nothing */ }
935
936 FLYSArtifact src = otherArtifact != null
937 ? FLYSUtils.getArtifact(otherArtifact, cc)
938 : flys;
939
940 logger.debug("Use waterlevel provided by Artifact: " + src.identifier());
941
942 CalculationResult rawData = (CalculationResult) src.compute(
943 cc,
944 null,
945 WINFO_WSP_STATE_ID,
946 ComputeType.ADVANCE,
947 false);
948
949 WQKms[] wqkms = (WQKms[]) rawData.getData();
950
951 return wqkms == null || idx == -1 || idx >= wqkms.length
952 ? null
953 : wqkms[idx];
954 }
955
956
957 protected void setWsp(
958 FLYSArtifact artifact,
959 CallContext context,
960 File dir,
961 WSPLGENJob job)
962 {
963 logger.debug("FloodMapState.setWsp");
964
965 WQKms data = getWQKms(artifact, context);
966
967 if (data == null) {
968 logger.warn("No WST data found!");
969 return;
970 }
971
972 WstWriter writer = new WstWriter(1);
973
974 // TODO REMOVE job.setWspTag(...) This is only used until the user is
975 // able to select the WSP column himself!
976 boolean writeWspTag = true;
977
978 double[] buf = new double[4];
979 logger.debug("Add WST column: " + data.getName());
980 writer.addColumn(data.getName());
981
982 if (writeWspTag) {
983 job.setWspTag(data.getName());
984 writeWspTag = false;
985 }
986
987 for (int i = 0, num = data.size(); i < num; i++) {
988 data.get(i, buf);
989 writer.add(buf);
990 }
991
992 FileOutputStream fout = null;
993
994 try {
995 File wspFile = new File(dir, WSPLGEN_WSP_FILE);
996 fout = new FileOutputStream(wspFile);
997
998 writer.write(fout);
999
1000 job.setWsp(wspFile.getAbsolutePath());
1001 }
1002 catch (FileNotFoundException fnfe) {
1003 logger.warn("Error while writing wsp file: " + fnfe.getMessage());
1004 }
1005 finally {
1006 if (fout != null) {
1007 try {
1008 fout.close();
1009 }
1010 catch (IOException ioe) { /* do nothing */ }
1011 }
1012 }
1013 }
1014
1015
1016
1017 }
1018 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org