Mercurial > dive4elements > river
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 : |