Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java @ 3818:dc18457b1cef
merged flys-artifacts/pre2.7-2012-03-16
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:59 +0200 |
parents | 8cb679d4ec49 |
children | a78dafdd8590 |
comparison
equal
deleted
inserted
replaced
2456:60ab1054069d | 3818:dc18457b1cef |
---|---|
1 package de.intevation.flys.artifacts.states; | |
2 | |
3 import java.io.File; | |
4 import java.io.FileNotFoundException; | |
5 import java.io.FileOutputStream; | |
6 import java.io.IOException; | |
7 import java.util.ArrayList; | |
8 import java.util.List; | |
9 | |
10 import com.vividsolutions.jts.geom.Coordinate; | |
11 import com.vividsolutions.jts.geom.Geometry; | |
12 import com.vividsolutions.jts.geom.LineString; | |
13 import com.vividsolutions.jts.geom.Polygon; | |
14 | |
15 import org.apache.log4j.Logger; | |
16 | |
17 import org.opengis.feature.simple.SimpleFeature; | |
18 import org.opengis.feature.simple.SimpleFeatureType; | |
19 | |
20 import org.geotools.feature.FeatureCollection; | |
21 import org.geotools.feature.FeatureCollections; | |
22 import org.geotools.feature.simple.SimpleFeatureBuilder; | |
23 | |
24 import de.intevation.artifacts.Artifact; | |
25 import de.intevation.artifacts.CallContext; | |
26 import de.intevation.artifacts.CallMeta; | |
27 import de.intevation.artifacts.GlobalContext; | |
28 | |
29 import de.intevation.artifacts.common.utils.FileTools; | |
30 | |
31 import de.intevation.artifactdatabase.state.Facet; | |
32 | |
33 import de.intevation.flys.model.CrossSectionTrack; | |
34 import de.intevation.flys.model.DGM; | |
35 import de.intevation.flys.model.Floodplain; | |
36 import de.intevation.flys.model.RiverAxis; | |
37 | |
38 import de.intevation.flys.artifacts.FLYSArtifact; | |
39 import de.intevation.flys.artifacts.context.FLYSContext; | |
40 import de.intevation.flys.artifacts.model.CalculationMessage; | |
41 import de.intevation.flys.artifacts.model.CalculationResult; | |
42 import de.intevation.flys.artifacts.model.FacetTypes; | |
43 import de.intevation.flys.artifacts.model.WMSLayerFacet; | |
44 import de.intevation.flys.artifacts.model.WQKms; | |
45 import de.intevation.flys.artifacts.model.WSPLGENCalculation; | |
46 import de.intevation.flys.artifacts.model.WSPLGENJob; | |
47 import de.intevation.flys.artifacts.model.WSPLGENReportFacet; | |
48 import de.intevation.flys.artifacts.resources.Resources; | |
49 import de.intevation.flys.artifacts.states.DefaultState.ComputeType; | |
50 import de.intevation.flys.exports.WstWriter; | |
51 import de.intevation.flys.utils.FLYSUtils; | |
52 import de.intevation.flys.utils.MapfileGenerator; | |
53 import de.intevation.flys.utils.GeometryUtils; | |
54 import de.intevation.flys.wsplgen.FacetCreator; | |
55 import de.intevation.flys.wsplgen.JobObserver; | |
56 import de.intevation.flys.wsplgen.Scheduler; | |
57 | |
58 | |
59 public class FloodMapState | |
60 extends DefaultState | |
61 implements FacetTypes | |
62 { | |
63 /** The logger that is used in this state. */ | |
64 private static Logger logger = Logger.getLogger(FloodMapState.class); | |
65 | |
66 | |
67 public static final String KEEP_ARTIFACT_DIR = | |
68 System.getProperty("flys.uesk.keep.artifactsdir", "false"); | |
69 | |
70 | |
71 public static final String OUTPUT_NAME = "floodmap"; | |
72 | |
73 public static final String WSP_ARTIFACT = "wsp"; | |
74 | |
75 public static final String WINFO_WSP_STATE_ID = "state.winfo.waterlevel"; | |
76 | |
77 public static final String WSPLGEN_PARAMETER_FILE = "wsplgen.par"; | |
78 public static final String WSPLGEN_BARRIERS_LINES = "barrier_lines.shp"; | |
79 public static final String WSPLGEN_BARRIERS_POLY = "barrier_polygons.shp"; | |
80 public static final String WSPLGEN_AXIS = "axis.shp"; | |
81 public static final String WSPLGEN_QPS = "qps.shp"; | |
82 public static final String WSPLGEN_FLOODPLAIN = "talaue.shp"; | |
83 public static final String WSPLGEN_WSP_FILE = "waterlevel.wst"; | |
84 public static final String WSPLGEN_OUTPUT_FILE = "wsplgen.shp"; | |
85 | |
86 public static final int WSPLGEN_DEFAULT_OUTPUT = 0; | |
87 | |
88 | |
89 /** | |
90 * @param orig | |
91 * @param owner | |
92 * @param context | |
93 * @param callMeta | |
94 */ | |
95 @Override | |
96 public void initialize( | |
97 Artifact orig, | |
98 Artifact owner, | |
99 Object context, | |
100 CallMeta callMeta | |
101 ) { | |
102 logger.info("Initialize State with Artifact: " + orig.identifier()); | |
103 | |
104 copyShapeDir(orig, owner); | |
105 modifyFacets(orig, owner, context, callMeta); | |
106 | |
107 MapfileGenerator.getInstance().update(); | |
108 } | |
109 | |
110 | |
111 protected void copyShapeDir(Artifact orig, Artifact owner) { | |
112 File origDir = getDirectory((FLYSArtifact) orig); | |
113 File thisDir = getDirectory((FLYSArtifact) owner); | |
114 | |
115 FileTools.copyDirectory(origDir, thisDir); | |
116 } | |
117 | |
118 | |
119 protected void modifyFacets( | |
120 Artifact orig, | |
121 Artifact owner, | |
122 Object context, | |
123 CallMeta callMeta | |
124 ) { | |
125 FLYSArtifact flys = (FLYSArtifact) owner; | |
126 List<Facet> facets = flys.getFacets(); | |
127 if (facets == null || facets.size() == 0) { | |
128 logger.warn("No facets for '" + OUTPUT_NAME + "' given!"); | |
129 return; | |
130 } | |
131 | |
132 for (Facet facet: facets) { | |
133 if (facet instanceof WMSLayerFacet) { | |
134 WMSLayerFacet wms = (WMSLayerFacet) facet; | |
135 | |
136 List<String> layers = wms.getLayers(); | |
137 | |
138 for (String layer: layers) { | |
139 if (layer.startsWith(MapfileGenerator.MS_WSPLGEN_PREFIX)) { | |
140 wms.removeLayer(layer); | |
141 | |
142 String newLayer = MapfileGenerator.MS_WSPLGEN_PREFIX + | |
143 owner.identifier(); | |
144 | |
145 wms.addLayer(newLayer); | |
146 | |
147 logger.debug( | |
148 "Replaced layer: " + layer + " with " + newLayer); | |
149 } | |
150 } | |
151 } | |
152 } | |
153 } | |
154 | |
155 | |
156 @Override | |
157 public Object computeAdvance( | |
158 FLYSArtifact artifact, | |
159 String hash, | |
160 CallContext context, | |
161 List<Facet> facets, | |
162 Object old | |
163 ) { | |
164 logger.debug("FloodMapState.computeAdvance"); | |
165 | |
166 File artifactDir = getDirectory(artifact); | |
167 | |
168 if (artifactDir == null) { | |
169 logger.error("Could not create directory for WSPLGEN results!"); | |
170 return null; | |
171 } | |
172 | |
173 WSPLGENCalculation calculation = new WSPLGENCalculation(); | |
174 | |
175 FacetCreator facetCreator = new FacetCreator( | |
176 artifact, context, hash, getID(), facets); | |
177 | |
178 WSPLGENJob job = prepareWSPLGENJob( | |
179 artifact, | |
180 facetCreator, | |
181 artifactDir, | |
182 context, | |
183 calculation); | |
184 | |
185 CalculationResult res = new CalculationResult(null, calculation); | |
186 WSPLGENReportFacet report= new WSPLGENReportFacet( | |
187 ComputeType.ADVANCE, hash, getID(), res); | |
188 | |
189 facets.add(report); | |
190 | |
191 if (job == null) { | |
192 if (KEEP_ARTIFACT_DIR.equals("false")) { | |
193 removeDirectory(artifact); | |
194 } | |
195 | |
196 calculation.addError(-1, Resources.getMsg( | |
197 context.getMeta(), | |
198 "wsplgen.job.error", | |
199 "wsplgen.job.error")); | |
200 | |
201 logger.error("No WSPLGEN processing has been started!"); | |
202 | |
203 return null; | |
204 } | |
205 | |
206 context.afterCall(CallContext.BACKGROUND); | |
207 context.addBackgroundMessage(new CalculationMessage( | |
208 JobObserver.STEPS.length, | |
209 0, | |
210 Resources.getMsg( | |
211 context.getMeta(), | |
212 "wsplgen.job.queued", | |
213 "wsplgen.job.queued") | |
214 )); | |
215 | |
216 GlobalContext gc = (GlobalContext) context.globalContext(); | |
217 Scheduler scheduler = (Scheduler) gc.get(FLYSContext.SCHEDULER); | |
218 scheduler.addJob(job); | |
219 | |
220 return null; | |
221 } | |
222 | |
223 | |
224 /** | |
225 * Returns (and creates if not existing) the directory for storing WSPLEN | |
226 * data for the owner artifact. | |
227 * | |
228 * @param artifact The owner Artifact. | |
229 * | |
230 * @return the directory for WSPLEN data. | |
231 */ | |
232 protected File getDirectory(FLYSArtifact artifact) { | |
233 String shapePath = FLYSUtils.getXPathString( | |
234 FLYSUtils.XPATH_SHAPEFILE_DIR); | |
235 | |
236 File artifactDir = FileTools.getDirectory( | |
237 shapePath, artifact.identifier()); | |
238 | |
239 return artifactDir; | |
240 } | |
241 | |
242 | |
243 /** | |
244 * Removes the directory and all its content where the required data and the | |
245 * results of WSPLGEN are stored. Should be called in endOfLife(). | |
246 */ | |
247 protected void removeDirectory(FLYSArtifact artifact) { | |
248 String shapePath = FLYSUtils.getXPathString( | |
249 FLYSUtils.XPATH_SHAPEFILE_DIR); | |
250 | |
251 File artifactDir = new File(shapePath, artifact.identifier()); | |
252 | |
253 if (artifactDir.exists()) { | |
254 logger.info("Delete directory: " + artifactDir.getAbsolutePath()); | |
255 boolean success = FileTools.deleteRecursive(artifactDir); | |
256 } | |
257 else { | |
258 logger.debug("There is no directory to remove."); | |
259 } | |
260 } | |
261 | |
262 | |
263 @Override | |
264 public void endOfLife(Artifact artifact, Object callContext) { | |
265 logger.info("FloodMapState.endOfLife: " + artifact.identifier()); | |
266 | |
267 FLYSArtifact flys = (FLYSArtifact) artifact; | |
268 removeDirectory(flys); | |
269 | |
270 Scheduler scheduler = Scheduler.getInstance(); | |
271 scheduler.cancelJob(flys.identifier()); | |
272 | |
273 MapfileGenerator.getInstance().update(); | |
274 } | |
275 | |
276 | |
277 protected WSPLGENJob prepareWSPLGENJob( | |
278 FLYSArtifact artifact, | |
279 FacetCreator facetCreator, | |
280 File artifactDir, | |
281 CallContext context, | |
282 WSPLGENCalculation calculation | |
283 ) { | |
284 logger.debug("FloodMapState.prepareWSPLGENJob"); | |
285 | |
286 WSPLGENJob job = new WSPLGENJob( | |
287 artifact, | |
288 artifactDir, | |
289 facetCreator, | |
290 context, | |
291 calculation); | |
292 | |
293 File paraFile = new File(artifactDir, WSPLGEN_PARAMETER_FILE); | |
294 | |
295 setOut(artifact, job); | |
296 setRange(artifact, job); | |
297 setDelta(artifact, job); | |
298 setGel(artifact, job); | |
299 setDist(artifact, job); | |
300 setLine(artifact, facetCreator, artifactDir, job); | |
301 setAxis(artifact, artifactDir, job); | |
302 setPro(artifact, artifactDir, job); | |
303 setDgm(artifact, job); | |
304 setArea(artifact, artifactDir, job); | |
305 setOutFile(artifact, job); | |
306 setWsp(artifact, context, artifactDir, job); // WSP | |
307 | |
308 // TODO | |
309 // setWspTag(artifact, job); | |
310 | |
311 try { | |
312 job.toFile(paraFile); | |
313 | |
314 return job; | |
315 } | |
316 catch (IOException ioe) { | |
317 logger.warn("Cannot write PAR file: " + ioe.getMessage()); | |
318 } | |
319 catch (IllegalArgumentException iae) { | |
320 logger.warn("Cannot write PAR file: " + iae.getMessage()); | |
321 } | |
322 | |
323 return null; | |
324 } | |
325 | |
326 | |
327 protected void setOut(FLYSArtifact artifact, WSPLGENJob job) { | |
328 job.setOut(WSPLGEN_DEFAULT_OUTPUT); | |
329 } | |
330 | |
331 | |
332 protected void setRange(FLYSArtifact artifact, WSPLGENJob job) { | |
333 double[] range = FLYSUtils.getKmRange(artifact); | |
334 | |
335 job.setStart(range[0]); | |
336 job.setEnd(range[1]); | |
337 } | |
338 | |
339 | |
340 protected void setDelta(FLYSArtifact artifact, WSPLGENJob job) { | |
341 String from = artifact.getDataAsString("diff_from"); | |
342 String to = artifact.getDataAsString("diff_to"); | |
343 String diff = artifact.getDataAsString("diff_diff"); | |
344 | |
345 try { | |
346 job.setFrom(Double.parseDouble(from)); | |
347 } | |
348 catch (NumberFormatException nfe) { | |
349 } | |
350 | |
351 try { | |
352 job.setTo(Double.parseDouble(to)); | |
353 } | |
354 catch (NumberFormatException nfe) { | |
355 } | |
356 | |
357 try { | |
358 job.setDiff(Double.parseDouble(diff)); | |
359 } | |
360 catch (NumberFormatException nfe) { | |
361 } | |
362 } | |
363 | |
364 | |
365 protected void setGel(FLYSArtifact artifact, WSPLGENJob job) { | |
366 String gel = artifact.getDataAsString("scenario"); | |
367 | |
368 logger.debug("Selected gel = '" + gel + "'"); | |
369 | |
370 if (gel == null || gel.length() == 0) { | |
371 job.setGel(WSPLGENJob.GEL_NOSPERRE); | |
372 } | |
373 else if (gel.equals("scenario.current")) { | |
374 job.setGel(WSPLGENJob.GEL_SPERRE); | |
375 } | |
376 else if (gel.equals("scenario.scenario")) { | |
377 job.setGel(WSPLGENJob.GEL_SPERRE); | |
378 } | |
379 else { | |
380 job.setGel(WSPLGENJob.GEL_NOSPERRE); | |
381 } | |
382 } | |
383 | |
384 | |
385 protected void setDist(FLYSArtifact artifact, WSPLGENJob job) { | |
386 String dist = artifact.getDataAsString("profile_distance"); | |
387 | |
388 try { | |
389 job.setDist(Double.parseDouble(dist)); | |
390 } | |
391 catch (NumberFormatException nfe) { | |
392 // nothing to do here | |
393 } | |
394 } | |
395 | |
396 | |
397 protected void setLine( | |
398 FLYSArtifact artifact, | |
399 FacetCreator facetCreator, | |
400 File dir, | |
401 WSPLGENJob job | |
402 ) { | |
403 String geoJSON = artifact.getDataAsString("uesk.barriers"); | |
404 String srid = FLYSUtils.getRiverSrid(artifact); | |
405 String srs = "EPSG:" + srid; | |
406 | |
407 if (geoJSON == null || geoJSON.length() == 0) { | |
408 logger.debug("No barrier features in parameterization existing."); | |
409 return; | |
410 } | |
411 | |
412 SimpleFeatureType ft = getBarriersFeatureType( | |
413 "barriers", srs, Geometry.class); | |
414 | |
415 List<SimpleFeature> features = GeometryUtils.parseGeoJSON(geoJSON, ft); | |
416 if (features == null || features.size() == 0) { | |
417 logger.debug("No barrier features extracted."); | |
418 return; | |
419 } | |
420 | |
421 FeatureCollection[] fcs = splitLinesAndPolygons(features); | |
422 | |
423 File shapeLines = new File(dir, WSPLGEN_BARRIERS_LINES); | |
424 File shapePolys = new File(dir, WSPLGEN_BARRIERS_POLY); | |
425 | |
426 Object[][] obj = new Object[][] { | |
427 new Object[] { "typ", String.class } | |
428 }; | |
429 | |
430 String scenario = job.getGel(); | |
431 | |
432 boolean l = GeometryUtils.writeShapefile( | |
433 shapeLines, | |
434 GeometryUtils.buildFeatureType("lines", srs, LineString.class, obj), | |
435 fcs[0]); | |
436 | |
437 if (l) { | |
438 logger.debug( | |
439 "Successfully created barrier line shapefile. " + | |
440 "Write shapefile path into WSPLGEN job."); | |
441 | |
442 if (scenario.equals(WSPLGENJob.GEL_NOSPERRE)) { | |
443 logger.debug("WSPLGEN will not use barrier features."); | |
444 } | |
445 else { | |
446 job.addLin(shapeLines.getAbsolutePath()); | |
447 } | |
448 } | |
449 | |
450 boolean p = GeometryUtils.writeShapefile( | |
451 shapePolys, | |
452 GeometryUtils.buildFeatureType("polygons", srs, Polygon.class, obj), | |
453 fcs[1]); | |
454 | |
455 if (p) { | |
456 logger.debug( | |
457 "Successfully created barrier polygon shapefile. " + | |
458 "Write shapefile path into WSPLGEN job."); | |
459 | |
460 if (scenario.equals(WSPLGENJob.GEL_NOSPERRE)) { | |
461 logger.debug("WSPLGEN will not use barrier features."); | |
462 } | |
463 else { | |
464 job.addLin(shapePolys.getAbsolutePath()); | |
465 } | |
466 } | |
467 | |
468 if (p || l) { | |
469 facetCreator.createBarrierFacet(); | |
470 } | |
471 } | |
472 | |
473 | |
474 protected SimpleFeatureType getBarriersFeatureType( | |
475 String name, | |
476 String srs, | |
477 Class type | |
478 ) { | |
479 Object[][] attrs = new Object[3][]; | |
480 attrs[0] = new Object[] { "typ", String.class }; | |
481 attrs[1] = new Object[] { "elevation", Double.class }; | |
482 attrs[2] = new Object[] { "mark.selected", Integer.class }; | |
483 | |
484 return GeometryUtils.buildFeatureType(name, srs, type, attrs); | |
485 } | |
486 | |
487 | |
488 protected FeatureCollection[] splitLinesAndPolygons(List<SimpleFeature> f) { | |
489 FeatureCollection lines = FeatureCollections.newCollection(); | |
490 FeatureCollection polygons = FeatureCollections.newCollection(); | |
491 | |
492 for (SimpleFeature feature: f) { | |
493 Geometry geom = (Geometry) feature.getDefaultGeometry(); | |
494 | |
495 | |
496 if (geom instanceof LineString) { | |
497 geom = applyElevationAttribute(feature, (LineString) geom); | |
498 lines.add(feature); | |
499 } | |
500 else if (geom instanceof Polygon) { | |
501 geom = applyElevationAttribute(feature, (Polygon) geom); | |
502 polygons.add(feature); | |
503 } | |
504 else { | |
505 logger.warn("Feature not supported: " + geom.getClass()); | |
506 } | |
507 } | |
508 | |
509 logger.debug("Found " + lines.size() + " barrier lines."); | |
510 logger.debug("Found " + polygons.size() + " barrier polygons."); | |
511 | |
512 return new FeatureCollection[] { lines, polygons }; | |
513 } | |
514 | |
515 | |
516 protected static Geometry applyElevationAttribute( | |
517 SimpleFeature feature, | |
518 Geometry geom | |
519 ) { | |
520 logger.debug("Apply elevations for: " + geom.getClass()); | |
521 | |
522 List<Double> elevations = extractElevations(feature); | |
523 int numPoints = geom.getNumPoints(); | |
524 int numElevation = elevations.size(); | |
525 | |
526 String typ = (String) feature.getAttribute("typ"); | |
527 | |
528 if (numPoints > numElevation) { | |
529 logger.warn("More vertices in Geometry than elevations given."); | |
530 } | |
531 | |
532 Coordinate[] c = geom.getCoordinates(); | |
533 for (int i = 0; i < numPoints; i++) { | |
534 if (i < numElevation) { | |
535 c[i].z = elevations.get(i); | |
536 } | |
537 else if (typ != null && typ.equals("Graben")) { | |
538 c[i].z = -9999d; | |
539 } | |
540 else { | |
541 c[i].z = 9999d; | |
542 } | |
543 } | |
544 | |
545 return geom; | |
546 } | |
547 | |
548 | |
549 protected static List<Double> extractElevations(SimpleFeature feature) { | |
550 String tmp = (String) feature.getAttribute("elevation"); | |
551 String typ = (String) feature.getAttribute("typ"); | |
552 | |
553 String[] elevations = tmp == null ? null : tmp.split(" "); | |
554 | |
555 int num = elevations != null ? elevations.length : 0; | |
556 | |
557 List<Double> list = new ArrayList<Double>(num); | |
558 | |
559 for (int i = 0; i < num; i++) { | |
560 try { | |
561 list.add(Double.parseDouble(elevations[i])); | |
562 } | |
563 catch (NumberFormatException nfe) { | |
564 logger.warn("Error while parsing elevation at pos: " + i); | |
565 if (typ != null && typ.equals("Graben")) { | |
566 list.add(new Double(-9999.0)); | |
567 } | |
568 else { | |
569 list.add(new Double(9999.0)); | |
570 } | |
571 } | |
572 } | |
573 | |
574 return list; | |
575 } | |
576 | |
577 | |
578 protected void setAxis(FLYSArtifact artifact, File dir, WSPLGENJob job) { | |
579 String river = artifact.getDataAsString("river"); | |
580 String srid = FLYSUtils.getRiverSrid(artifact); | |
581 String srs = "EPSG:" + srid; | |
582 | |
583 List<RiverAxis> axes = RiverAxis.getRiverAxis(river); | |
584 if (axes == null || axes.size() == 0) { | |
585 logger.warn("Could not find river axis for: '" + river + "'"); | |
586 return; | |
587 } | |
588 | |
589 SimpleFeatureType ft = GeometryUtils.buildFeatureType( | |
590 "axis", srs, LineString.class); | |
591 | |
592 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft); | |
593 FeatureCollection collection = FeatureCollections.newCollection(); | |
594 | |
595 for (int i = 0, n = axes.size(); i < n; i++) { | |
596 RiverAxis axis = axes.get(i); | |
597 | |
598 builder.add(axis.getGeom()); | |
599 collection.add(builder.buildFeature(String.valueOf(i))); | |
600 | |
601 builder.reset(); | |
602 } | |
603 | |
604 File axisShape = new File(dir, WSPLGEN_AXIS); | |
605 | |
606 boolean a = GeometryUtils.writeShapefile( | |
607 axisShape, | |
608 GeometryUtils.buildFeatureType("axis", srs, LineString.class), | |
609 collection); | |
610 | |
611 if (a) { | |
612 job.setAxis(axisShape.getAbsolutePath()); | |
613 } | |
614 } | |
615 | |
616 | |
617 protected void setPro(FLYSArtifact artifact, File dir, WSPLGENJob job) { | |
618 String river = artifact.getDataAsString("river"); | |
619 String srid = FLYSUtils.getRiverSrid(artifact); | |
620 String srs = "EPSG:" + srid; | |
621 | |
622 List<CrossSectionTrack> cst = | |
623 CrossSectionTrack.getCrossSectionTrack(river); | |
624 | |
625 logger.debug("Found " + cst.size() + " CrossSectionTracks."); | |
626 | |
627 Object[][] attrs = new Object[2][]; | |
628 attrs[0] = new Object[] { "ELEVATION", Double.class }; | |
629 attrs[1] = new Object[] { "KILOMETER", Double.class }; | |
630 | |
631 SimpleFeatureType ft = GeometryUtils.buildFeatureType( | |
632 "qps", srs, LineString.class, attrs); | |
633 | |
634 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft); | |
635 FeatureCollection collection = FeatureCollections.newCollection(); | |
636 | |
637 int i = 0; | |
638 for (CrossSectionTrack track: cst) { | |
639 builder.reset(); | |
640 builder.add(track.getGeom()); | |
641 builder.add(track.getZ().doubleValue()); | |
642 builder.add(track.getKm().doubleValue()); | |
643 | |
644 collection.add(builder.buildFeature(String.valueOf(i++))); | |
645 } | |
646 | |
647 File qpsShape = new File(dir, WSPLGEN_QPS); | |
648 | |
649 boolean q = GeometryUtils.writeShapefile( | |
650 qpsShape, | |
651 GeometryUtils.buildFeatureType("qps", srs, LineString.class, attrs), | |
652 collection); | |
653 | |
654 if (q) { | |
655 job.setPro(qpsShape.getAbsolutePath()); | |
656 } | |
657 } | |
658 | |
659 | |
660 protected void setDgm(FLYSArtifact artifact, WSPLGENJob job) { | |
661 String dgm_id = artifact.getDataAsString("dgm"); | |
662 | |
663 int id = -1; | |
664 try { | |
665 id = Integer.parseInt(dgm_id); | |
666 } | |
667 catch (NumberFormatException nfe) { /* do nothing */ } | |
668 | |
669 DGM dgm = DGM.getDGM(id); | |
670 | |
671 if (dgm == null) { | |
672 logger.warn("Could not find specified DGM."); | |
673 | |
674 return; | |
675 } | |
676 | |
677 job.setDgm(dgm.getPath()); | |
678 } | |
679 | |
680 | |
681 protected void setArea(FLYSArtifact artifact, File dir, WSPLGENJob job) { | |
682 String useFloodplain = artifact.getDataAsString("use_floodplain"); | |
683 if (!Boolean.valueOf(useFloodplain)) { | |
684 logger.debug("WSPLGEN will not use floodplain."); | |
685 return; | |
686 } | |
687 | |
688 String river = artifact.getDataAsString("river"); | |
689 String srid = FLYSUtils.getRiverSrid(artifact); | |
690 String srs = "EPSG:" + srid; | |
691 | |
692 Floodplain plain = Floodplain.getFloodplain(river); | |
693 | |
694 SimpleFeatureType ft = GeometryUtils.buildFeatureType( | |
695 "talaue", srs, Polygon.class); | |
696 | |
697 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft); | |
698 builder.add(plain.getGeom()); | |
699 | |
700 FeatureCollection collection = FeatureCollections.newCollection(); | |
701 collection.add(builder.buildFeature("0")); | |
702 | |
703 File talaueShape = new File(dir, WSPLGEN_FLOODPLAIN); | |
704 | |
705 boolean t = GeometryUtils.writeShapefile( | |
706 talaueShape, | |
707 GeometryUtils.buildFeatureType("talaue", srs, Polygon.class), | |
708 collection); | |
709 | |
710 if (t) { | |
711 job.setArea(talaueShape.getAbsolutePath()); | |
712 } | |
713 } | |
714 | |
715 | |
716 protected void setOutFile(FLYSArtifact artifact, WSPLGENJob job) { | |
717 job.setOutFile(WSPLGEN_OUTPUT_FILE); | |
718 } | |
719 | |
720 | |
721 protected WQKms getWQKms(FLYSArtifact flys, CallContext cc) { | |
722 String wspString = flys.getDataAsString(WSP_ARTIFACT); | |
723 String[] parts = wspString.split(";"); | |
724 | |
725 String otherArtifact = parts[0]; | |
726 | |
727 int idx = -1; | |
728 try { | |
729 idx = Integer.parseInt(parts[2]); | |
730 } | |
731 catch (NumberFormatException nfe) { /* do nothing */ } | |
732 | |
733 FLYSArtifact src = otherArtifact != null | |
734 ? FLYSUtils.getArtifact(otherArtifact, cc) | |
735 : flys; | |
736 | |
737 logger.debug("Use waterlevel provided by Artifact: " + src.identifier()); | |
738 | |
739 CalculationResult rawData = (CalculationResult) src.compute( | |
740 cc, | |
741 null, | |
742 WINFO_WSP_STATE_ID, | |
743 ComputeType.ADVANCE, | |
744 false); | |
745 | |
746 WQKms[] wqkms = (WQKms[]) rawData.getData(); | |
747 | |
748 return wqkms == null || idx == -1 || idx >= wqkms.length | |
749 ? null | |
750 : wqkms[idx]; | |
751 } | |
752 | |
753 | |
754 protected void setWsp( | |
755 FLYSArtifact artifact, | |
756 CallContext context, | |
757 File dir, | |
758 WSPLGENJob job) | |
759 { | |
760 logger.debug("FloodMapState.setWsp"); | |
761 | |
762 WQKms data = getWQKms(artifact, context); | |
763 | |
764 if (data == null) { | |
765 logger.warn("No WST data found!"); | |
766 return; | |
767 } | |
768 | |
769 WstWriter writer = new WstWriter(1); | |
770 | |
771 // TODO REMOVE job.setWspTag(...) This is only used until the user is | |
772 // able to select the WSP column himself! | |
773 boolean writeWspTag = true; | |
774 | |
775 double[] buf = new double[4]; | |
776 logger.debug("Add WST column: " + data.getName()); | |
777 writer.addColumn(data.getName()); | |
778 | |
779 if (writeWspTag) { | |
780 job.setWspTag(data.getName()); | |
781 writeWspTag = false; | |
782 } | |
783 | |
784 for (int i = 0, num = data.size(); i < num; i++) { | |
785 data.get(i, buf); | |
786 writer.add(buf); | |
787 } | |
788 | |
789 FileOutputStream fout = null; | |
790 | |
791 try { | |
792 File wspFile = new File(dir, WSPLGEN_WSP_FILE); | |
793 fout = new FileOutputStream(wspFile); | |
794 | |
795 writer.write(fout); | |
796 | |
797 job.setWsp(wspFile.getAbsolutePath()); | |
798 } | |
799 catch (FileNotFoundException fnfe) { | |
800 logger.warn("Error while writing wsp file: " + fnfe.getMessage()); | |
801 } | |
802 finally { | |
803 if (fout != null) { | |
804 try { | |
805 fout.close(); | |
806 } | |
807 catch (IOException ioe) { /* do nothing */ } | |
808 } | |
809 } | |
810 } | |
811 } | |
812 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : |