ingo@927: package de.intevation.flys.artifacts.states; ingo@927: teichmann@5281: import java.io.File; teichmann@5281: import java.io.FileNotFoundException; teichmann@5281: import java.io.FileOutputStream; teichmann@5281: import java.io.IOException; teichmann@5281: teichmann@5281: import java.util.ArrayList; teichmann@5313: import java.util.Arrays; teichmann@5281: import java.util.List; teichmann@5281: teichmann@5281: import org.apache.log4j.Logger; teichmann@5281: teichmann@5313: import org.apache.velocity.Template; teichmann@5313: teichmann@5281: import org.geotools.feature.FeatureCollection; teichmann@5281: import org.geotools.feature.FeatureCollections; teichmann@5281: teichmann@5281: import org.geotools.feature.simple.SimpleFeatureBuilder; teichmann@5281: teichmann@5281: import org.hibernate.HibernateException; teichmann@5281: teichmann@5281: import org.opengis.feature.simple.SimpleFeature; teichmann@5281: import org.opengis.feature.simple.SimpleFeatureType; teichmann@5281: ingo@1123: import com.vividsolutions.jts.geom.Coordinate; ingo@1107: import com.vividsolutions.jts.geom.Geometry; ingo@1106: import com.vividsolutions.jts.geom.LineString; ingo@1106: import com.vividsolutions.jts.geom.Polygon; ingo@1106: ingo@3302: import de.intevation.artifactdatabase.state.Facet; teichmann@5281: ingo@1091: import de.intevation.artifacts.Artifact; ingo@935: import de.intevation.artifacts.CallContext; ingo@2093: import de.intevation.artifacts.CallMeta; ingo@1970: import de.intevation.artifacts.GlobalContext; teichmann@5281: ingo@1091: import de.intevation.artifacts.common.utils.FileTools; teichmann@5281: teichmann@5281: import de.intevation.flys.artifacts.FLYSArtifact; teichmann@5281: felix@4854: import de.intevation.flys.artifacts.access.RangeAccess; teichmann@5281: ingo@1970: import de.intevation.flys.artifacts.context.FLYSContext; teichmann@5281: ingo@1165: import de.intevation.flys.artifacts.model.CalculationMessage; ingo@1118: import de.intevation.flys.artifacts.model.CalculationResult; ingo@927: import de.intevation.flys.artifacts.model.FacetTypes; rrenkert@5312: import de.intevation.flys.artifacts.model.LayerInfo; ingo@1118: import de.intevation.flys.artifacts.model.WQKms; teichmann@5313: rrenkert@5312: import de.intevation.flys.artifacts.model.map.HWS; rrenkert@5312: import de.intevation.flys.artifacts.model.map.HWSContainer; rrenkert@5312: import de.intevation.flys.artifacts.model.map.HWSFactory; ingo@3302: import de.intevation.flys.artifacts.model.map.WMSLayerFacet; ingo@3302: import de.intevation.flys.artifacts.model.map.WSPLGENCalculation; ingo@3302: import de.intevation.flys.artifacts.model.map.WSPLGENJob; ingo@3302: import de.intevation.flys.artifacts.model.map.WSPLGENReportFacet; teichmann@5281: ingo@1165: import de.intevation.flys.artifacts.resources.Resources; teichmann@5281: ingo@1118: import de.intevation.flys.exports.WstWriter; teichmann@5281: ingo@3302: import de.intevation.flys.model.CrossSectionTrack; ingo@3302: import de.intevation.flys.model.DGM; ingo@3302: import de.intevation.flys.model.Floodplain; ingo@3302: import de.intevation.flys.model.RiverAxis; teichmann@5281: christian@4864: import de.intevation.flys.utils.ArtifactMapfileGenerator; ingo@1096: import de.intevation.flys.utils.FLYSUtils; ingo@3302: import de.intevation.flys.utils.GeometryUtils; ingo@1782: import de.intevation.flys.utils.MapfileGenerator; teichmann@5281: ingo@1650: import de.intevation.flys.wsplgen.FacetCreator; ingo@1165: import de.intevation.flys.wsplgen.JobObserver; ingo@1127: import de.intevation.flys.wsplgen.Scheduler; ingo@927: ingo@927: public class FloodMapState ingo@927: extends DefaultState ingo@927: implements FacetTypes ingo@927: { felix@1160: /** The logger that is used in this state. */ ingo@927: private static Logger logger = Logger.getLogger(FloodMapState.class); ingo@927: ingo@935: ingo@1107: public static final String KEEP_ARTIFACT_DIR = ingo@1107: System.getProperty("flys.uesk.keep.artifactsdir", "false"); ingo@1107: ingo@1107: ingo@2095: public static final String OUTPUT_NAME = "floodmap"; ingo@2095: ingo@1178: public static final String WSP_ARTIFACT = "wsp"; ingo@1118: ingo@1118: public static final String WINFO_WSP_STATE_ID = "state.winfo.waterlevel"; ingo@1118: ingo@1091: public static final String WSPLGEN_PARAMETER_FILE = "wsplgen.par"; ingo@1106: public static final String WSPLGEN_BARRIERS_LINES = "barrier_lines.shp"; ingo@1106: public static final String WSPLGEN_BARRIERS_POLY = "barrier_polygons.shp"; ingo@1108: public static final String WSPLGEN_AXIS = "axis.shp"; ingo@1108: public static final String WSPLGEN_QPS = "qps.shp"; ingo@1110: public static final String WSPLGEN_FLOODPLAIN = "talaue.shp"; ingo@1120: public static final String WSPLGEN_WSP_FILE = "waterlevel.wst"; ingo@1118: public static final String WSPLGEN_OUTPUT_FILE = "wsplgen.shp"; raimund@2639: public static final String WSPLGEN_USER_SHAPE = "user-rgd.shp"; raimund@2639: public static final String WSPLGEN_USER_ZIP = "user-rgd.zip"; raimund@2639: public static final String WSPLGEN_USER_FILENAME = "user-rgd"; ingo@1091: ingo@3070: public static final String WSPLGEN_QPS_NAME = "qps"; ingo@3070: ingo@1096: public static final int WSPLGEN_DEFAULT_OUTPUT = 0; ingo@1096: rrenkert@5312: private static final String HWS_LINES_SHAPE = "hws-lines.shp"; rrenkert@5312: aheinecke@5580: private static final String I18N_HWS_POINTS_OFFICIAL = "floodmap.hws.points.official"; aheinecke@5580: private static final String I18N_HWS_LINES_OFFICIAL = "floodmap.hws.lines.official"; rrenkert@5312: private static final String HWS_LINES = "hws-lines"; rrenkert@5312: private static final String HWS_POINT_SHAPE = "hws-points.shp"; rrenkert@5312: private static final String HWS_POINTS = "hws-points"; ingo@1091: ingo@2095: /** ingo@2095: * @param orig ingo@2095: * @param owner ingo@2095: * @param context ingo@2095: * @param callMeta ingo@2095: */ ingo@2093: @Override ingo@2095: public void initialize( ingo@2095: Artifact orig, ingo@2095: Artifact owner, ingo@2095: Object context, ingo@2095: CallMeta callMeta ingo@2095: ) { ingo@2093: logger.info("Initialize State with Artifact: " + orig.identifier()); ingo@2095: ingo@2095: copyShapeDir(orig, owner); ingo@2095: modifyFacets(orig, owner, context, callMeta); christian@4864: christian@4864: ArtifactMapfileGenerator amfg = new ArtifactMapfileGenerator(); christian@4864: try { christian@4864: amfg.generate(); christian@4864: } christian@4864: catch (IOException e) { christian@4864: logger.error(e.getMessage(), e); christian@4864: } ingo@2093: } ingo@2093: ingo@2093: ingo@2095: protected void copyShapeDir(Artifact orig, Artifact owner) { ingo@2095: File origDir = getDirectory((FLYSArtifact) orig); ingo@2095: File thisDir = getDirectory((FLYSArtifact) owner); ingo@2095: ingo@2095: FileTools.copyDirectory(origDir, thisDir); ingo@2095: } ingo@2095: ingo@2095: ingo@2095: protected void modifyFacets( ingo@2095: Artifact orig, ingo@2095: Artifact owner, ingo@2095: Object context, ingo@2095: CallMeta callMeta ingo@2095: ) { ingo@2095: FLYSArtifact flys = (FLYSArtifact) owner; ingo@2095: List facets = flys.getFacets(); sascha@3555: if (facets == null || facets.isEmpty()) { ingo@2095: logger.warn("No facets for '" + OUTPUT_NAME + "' given!"); ingo@2095: return; ingo@2095: } ingo@2095: ingo@2095: for (Facet facet: facets) { ingo@2095: if (facet instanceof WMSLayerFacet) { ingo@2095: WMSLayerFacet wms = (WMSLayerFacet) facet; ingo@2095: ingo@2095: List layers = wms.getLayers(); ingo@2095: ingo@2095: for (String layer: layers) { ingo@2095: if (layer.startsWith(MapfileGenerator.MS_WSPLGEN_PREFIX)) { ingo@2095: wms.removeLayer(layer); ingo@2095: ingo@2095: String newLayer = MapfileGenerator.MS_WSPLGEN_PREFIX + ingo@2095: owner.identifier(); ingo@2095: ingo@2095: wms.addLayer(newLayer); ingo@2095: ingo@2095: logger.debug( ingo@2095: "Replaced layer: " + layer + " with " + newLayer); ingo@2095: } ingo@2095: } ingo@2095: } ingo@2095: } ingo@2095: } ingo@2095: ingo@1053: ingo@1053: @Override ingo@935: public Object computeAdvance( ingo@935: FLYSArtifact artifact, ingo@935: String hash, ingo@935: CallContext context, ingo@935: List facets, ingo@935: Object old ingo@935: ) { ingo@1091: logger.debug("FloodMapState.computeAdvance"); ingo@1091: ingo@1091: File artifactDir = getDirectory(artifact); ingo@1091: ingo@1091: if (artifactDir == null) { ingo@1091: logger.error("Could not create directory for WSPLGEN results!"); ingo@1091: return null; ingo@1091: } ingo@1091: ingo@1149: WSPLGENCalculation calculation = new WSPLGENCalculation(); ingo@1149: ingo@1638: FacetCreator facetCreator = new FacetCreator( ingo@1650: artifact, context, hash, getID(), facets); ingo@1164: ingo@1149: WSPLGENJob job = prepareWSPLGENJob( ingo@1149: artifact, ingo@1164: facetCreator, ingo@1149: artifactDir, ingo@1149: context, ingo@1149: calculation); ingo@1091: ingo@1168: CalculationResult res = new CalculationResult(null, calculation); ingo@1168: WSPLGENReportFacet report= new WSPLGENReportFacet( ingo@1168: ComputeType.ADVANCE, hash, getID(), res); ingo@1168: ingo@1168: facets.add(report); ingo@1168: ingo@1091: if (job == null) { ingo@1107: if (KEEP_ARTIFACT_DIR.equals("false")) { ingo@1107: removeDirectory(artifact); ingo@1107: } ingo@1091: ingo@1168: calculation.addError(-1, Resources.getMsg( ingo@1168: context.getMeta(), ingo@1168: "wsplgen.job.error", ingo@1168: "wsplgen.job.error")); ingo@1168: ingo@1091: logger.error("No WSPLGEN processing has been started!"); ingo@1091: ingo@1091: return null; ingo@1091: } ingo@1091: ingo@1128: context.afterCall(CallContext.BACKGROUND); ingo@1165: context.addBackgroundMessage(new CalculationMessage( ingo@1165: JobObserver.STEPS.length, ingo@1165: 0, ingo@1165: Resources.getMsg( ingo@1165: context.getMeta(), ingo@1165: "wsplgen.job.queued", ingo@1165: "wsplgen.job.queued") ingo@1165: )); ingo@1091: ingo@1970: GlobalContext gc = (GlobalContext) context.globalContext(); ingo@1970: Scheduler scheduler = (Scheduler) gc.get(FLYSContext.SCHEDULER); ingo@1649: scheduler.addJob(job); ingo@1649: ingo@1091: return null; ingo@1091: } ingo@1091: ingo@1091: ingo@1091: /** ingo@1091: * Returns (and creates if not existing) the directory for storing WSPLEN ingo@1091: * data for the owner artifact. ingo@1091: * ingo@1091: * @param artifact The owner Artifact. ingo@1091: * ingo@1091: * @return the directory for WSPLEN data. ingo@1091: */ ingo@1091: protected File getDirectory(FLYSArtifact artifact) { ingo@1129: String shapePath = FLYSUtils.getXPathString( christian@4656: FLYSUtils.XPATH_FLOODMAP_SHAPEFILE_DIR); ingo@1091: ingo@1091: File artifactDir = FileTools.getDirectory( ingo@1091: shapePath, artifact.identifier()); ingo@1091: ingo@1091: return artifactDir; ingo@1091: } ingo@1091: ingo@1091: ingo@1091: /** ingo@1091: * Removes the directory and all its content where the required data and the ingo@1091: * results of WSPLGEN are stored. Should be called in endOfLife(). ingo@1091: */ ingo@1091: protected void removeDirectory(FLYSArtifact artifact) { ingo@1129: String shapePath = FLYSUtils.getXPathString( christian@4656: FLYSUtils.XPATH_FLOODMAP_SHAPEFILE_DIR); ingo@1129: ingo@1129: File artifactDir = new File(shapePath, artifact.identifier()); ingo@1091: ingo@1091: if (artifactDir.exists()) { ingo@1091: logger.info("Delete directory: " + artifactDir.getAbsolutePath()); christian@4656: if (!FileTools.deleteRecursive(artifactDir)) { christian@4656: logger.warn("Could not delete directory: " christian@4656: + artifactDir.getAbsolutePath()); christian@4656: } ingo@1091: } ingo@1091: else { ingo@1091: logger.debug("There is no directory to remove."); ingo@1091: } ingo@1091: } ingo@1091: ingo@1091: ingo@1091: @Override ingo@1091: public void endOfLife(Artifact artifact, Object callContext) { ingo@1091: logger.info("FloodMapState.endOfLife: " + artifact.identifier()); ingo@1091: ingo@1091: FLYSArtifact flys = (FLYSArtifact) artifact; ingo@1782: ingo@1970: Scheduler scheduler = Scheduler.getInstance(); ingo@1970: scheduler.cancelJob(flys.identifier()); ingo@1091: } ingo@1091: ingo@1091: ingo@1091: protected WSPLGENJob prepareWSPLGENJob( ingo@1149: FLYSArtifact artifact, ingo@1164: FacetCreator facetCreator, ingo@1149: File artifactDir, ingo@1149: CallContext context, ingo@1149: WSPLGENCalculation calculation ingo@1091: ) { ingo@1091: logger.debug("FloodMapState.prepareWSPLGENJob"); rrenkert@5312: String scenario = artifact.getDataAsString("scenario"); ingo@1091: ingo@1149: WSPLGENJob job = new WSPLGENJob( ingo@1149: artifact, ingo@1149: artifactDir, ingo@1650: facetCreator, ingo@1149: context, ingo@1149: calculation); ingo@1149: ingo@1149: File paraFile = new File(artifactDir, WSPLGEN_PARAMETER_FILE); ingo@1091: ingo@1096: setOut(artifact, job); ingo@1096: setRange(artifact, job); ingo@1096: setDelta(artifact, job); ingo@1096: setGel(artifact, job); ingo@1096: setDist(artifact, job); ingo@1108: setAxis(artifact, artifactDir, job); ingo@1108: setPro(artifact, artifactDir, job); rrenkert@5152: setDgm(artifact, job, context); ingo@1110: setArea(artifact, artifactDir, job); ingo@1118: setOutFile(artifact, job); ingo@1118: setWsp(artifact, context, artifactDir, job); // WSP rrenkert@5312: if (scenario.equals("scenario.current")) { rrenkert@5312: setOfficialHWS(artifact, facetCreator, artifactDir, job); rrenkert@5312: } rrenkert@5312: else if (scenario.equals("scenario.scenario")) { rrenkert@5312: setAdditionalHWS(artifact, facetCreator, artifactDir, job); rrenkert@5312: setLine(artifact, facetCreator, artifactDir, job); rrenkert@5312: setUserShape(artifact, facetCreator, artifactDir, job); rrenkert@5312: } ingo@1096: // TODO ingo@1096: // setWspTag(artifact, job); ingo@1096: ingo@1091: try { ingo@1091: job.toFile(paraFile); ingo@1091: ingo@1091: return job; ingo@1091: } ingo@1091: catch (IOException ioe) { ingo@1091: logger.warn("Cannot write PAR file: " + ioe.getMessage()); ingo@1091: } ingo@1091: catch (IllegalArgumentException iae) { ingo@1091: logger.warn("Cannot write PAR file: " + iae.getMessage()); ingo@1091: } ingo@1091: ingo@935: return null; ingo@935: } ingo@1096: ingo@1096: rrenkert@5312: private void setAdditionalHWS( rrenkert@5312: FLYSArtifact artifact, rrenkert@5312: FacetCreator facetCreator, rrenkert@5312: File dir, rrenkert@5312: WSPLGENJob job) { rrenkert@5312: File line = new File(dir, HWS_LINES_SHAPE); rrenkert@5312: boolean lines = line.exists(); rrenkert@5312: logger.debug("shp file exists: " + lines); rrenkert@5312: if (lines) { rrenkert@5312: job.addLin(dir + "/" + HWS_LINES_SHAPE); aheinecke@5580: facetCreator.createShapeFacet(I18N_HWS_LINES_OFFICIAL, rrenkert@5312: MapfileGenerator.MS_LAYER_PREFIX + HWS_LINES, rrenkert@5312: FLOODMAP_LINES, 2); rrenkert@5312: } rrenkert@5312: File point = new File(dir, HWS_POINT_SHAPE); rrenkert@5312: boolean points = point.exists(); rrenkert@5312: logger.debug("shp file exists: " + points); rrenkert@5312: if (points) { aheinecke@5580: facetCreator.createShapeFacet(I18N_HWS_POINTS_OFFICIAL, rrenkert@5312: MapfileGenerator.MS_LAYER_PREFIX + HWS_POINTS, rrenkert@5312: FLOODMAP_FIXPOINTS, 3); rrenkert@5312: } rrenkert@5312: } rrenkert@5312: rrenkert@5312: rrenkert@5312: private void setOfficialHWS( rrenkert@5312: FLYSArtifact artifact, rrenkert@5312: FacetCreator facetCreator, rrenkert@5312: File artifactDir, rrenkert@5312: WSPLGENJob job) { rrenkert@5312: String river = artifact.getDataAsString("river"); rrenkert@5312: rrenkert@5312: HWSContainer hwsLines = HWSFactory.getHWSLines(river); rrenkert@5312: List selectedLines = hwsLines.getOfficialHWS(); rrenkert@5312: rrenkert@5312: FeatureCollection collectionLines = FeatureCollections.newCollection(); rrenkert@5312: SimpleFeatureType lineType = null; rrenkert@5312: for (HWS h : selectedLines) { rrenkert@5312: lineType = h.getFeatureType(); rrenkert@5312: collectionLines.add(h.getFeature()); rrenkert@5312: } rrenkert@5312: boolean successLines = false; rrenkert@5312: if (lineType != null && collectionLines.size() > 0) { rrenkert@5312: File shapeLines = new File(artifactDir, HWS_LINES_SHAPE); rrenkert@5312: successLines = GeometryUtils.writeShapefile( rrenkert@5312: shapeLines, lineType, collectionLines); rrenkert@5312: } rrenkert@5312: if (successLines) { rrenkert@5312: createMapfile( rrenkert@5312: artifact, rrenkert@5312: artifactDir, rrenkert@5312: MapfileGenerator.MS_LAYER_PREFIX + "hws-lines", rrenkert@5312: HWS_LINES_SHAPE, rrenkert@5312: "LINE", rrenkert@5312: "31467", rrenkert@5312: "hws"); rrenkert@5312: job.addLin(artifactDir + "/" + HWS_LINES_SHAPE); aheinecke@5580: facetCreator.createShapeFacet(I18N_HWS_LINES_OFFICIAL, rrenkert@5312: MapfileGenerator.MS_LAYER_PREFIX + HWS_LINES, aheinecke@5349: FLOODMAP_HWS_LINES,2); rrenkert@5312: } rrenkert@5312: } rrenkert@5312: rrenkert@5312: rrenkert@5312: private void createMapfile( rrenkert@5312: FLYSArtifact artifact, rrenkert@5312: File artifactDir, rrenkert@5312: String name, rrenkert@5312: String hwsShapefile, rrenkert@5312: String type, rrenkert@5312: String srid, rrenkert@5312: String group rrenkert@5312: ) { rrenkert@5312: LayerInfo info = new LayerInfo(); rrenkert@5312: info.setName(name + artifact.identifier()); rrenkert@5312: info.setType(type); rrenkert@5312: info.setDirectory(artifact.identifier()); rrenkert@5312: info.setTitle(name); rrenkert@5312: info.setData(hwsShapefile); rrenkert@5312: info.setSrid(srid); rrenkert@5312: info.setGroupTitle(group); rrenkert@5312: MapfileGenerator generator = new ArtifactMapfileGenerator(); rrenkert@5312: Template tpl = generator.getTemplateByName(MapfileGenerator.SHP_LAYER_TEMPLATE); rrenkert@5312: try { rrenkert@5312: File layer = new File(artifactDir.getCanonicalPath() + "/" + name); rrenkert@5312: generator.writeLayer(info, layer, tpl); rrenkert@5312: List layers = new ArrayList(); rrenkert@5312: layers.add(layer.getAbsolutePath()); rrenkert@5312: generator.generate(); rrenkert@5312: } rrenkert@5312: catch(FileNotFoundException fnfe) { rrenkert@5312: logger.warn("Could not find mapfile for hws layer"); rrenkert@5312: } rrenkert@5312: catch (Exception ioe) { rrenkert@5312: logger.warn("Could not create mapfile for hws layer"); rrenkert@5312: logger.warn(Arrays.toString(ioe.getStackTrace())); rrenkert@5312: } rrenkert@5312: } rrenkert@5312: rrenkert@5312: ingo@1096: protected void setOut(FLYSArtifact artifact, WSPLGENJob job) { ingo@1096: job.setOut(WSPLGEN_DEFAULT_OUTPUT); ingo@1096: } ingo@1096: ingo@1096: ingo@1096: protected void setRange(FLYSArtifact artifact, WSPLGENJob job) { felix@4854: RangeAccess rangeAccess = new RangeAccess(artifact, null); felix@4854: double[] range = rangeAccess.getKmRange(); ingo@1096: ingo@1096: job.setStart(range[0]); ingo@1096: job.setEnd(range[1]); ingo@1096: } ingo@1096: ingo@1096: ingo@1096: protected void setDelta(FLYSArtifact artifact, WSPLGENJob job) { ingo@1096: String from = artifact.getDataAsString("diff_from"); ingo@1096: String to = artifact.getDataAsString("diff_to"); ingo@1096: String diff = artifact.getDataAsString("diff_diff"); ingo@1096: ingo@1096: try { ingo@1096: job.setFrom(Double.parseDouble(from)); ingo@1096: } ingo@1096: catch (NumberFormatException nfe) { ingo@1096: } ingo@1096: ingo@1096: try { ingo@1096: job.setTo(Double.parseDouble(to)); ingo@1096: } ingo@1096: catch (NumberFormatException nfe) { ingo@1096: } ingo@1096: ingo@1096: try { ingo@1096: job.setDiff(Double.parseDouble(diff)); ingo@1096: } ingo@1096: catch (NumberFormatException nfe) { ingo@1096: } ingo@1096: } ingo@1096: ingo@1096: ingo@1096: protected void setGel(FLYSArtifact artifact, WSPLGENJob job) { ingo@1955: String gel = artifact.getDataAsString("scenario"); ingo@1096: ingo@1955: logger.debug("Selected gel = '" + gel + "'"); ingo@1955: ingo@1955: if (gel == null || gel.length() == 0) { ingo@1955: job.setGel(WSPLGENJob.GEL_NOSPERRE); ingo@1955: } ingo@1955: else if (gel.equals("scenario.current")) { ingo@1955: job.setGel(WSPLGENJob.GEL_SPERRE); ingo@1955: } ingo@1955: else if (gel.equals("scenario.scenario")) { ingo@1955: job.setGel(WSPLGENJob.GEL_SPERRE); ingo@1955: } ingo@1955: else { ingo@1955: job.setGel(WSPLGENJob.GEL_NOSPERRE); ingo@1096: } ingo@1096: } ingo@1096: ingo@1096: ingo@1096: protected void setDist(FLYSArtifact artifact, WSPLGENJob job) { ingo@1096: String dist = artifact.getDataAsString("profile_distance"); ingo@1096: ingo@1096: try { ingo@1096: job.setDist(Double.parseDouble(dist)); ingo@1096: } ingo@1096: catch (NumberFormatException nfe) { ingo@1096: // nothing to do here ingo@1096: } ingo@1096: } ingo@1106: ingo@1106: ingo@1164: protected void setLine( ingo@1164: FLYSArtifact artifact, ingo@1164: FacetCreator facetCreator, ingo@1164: File dir, ingo@1164: WSPLGENJob job ingo@1164: ) { rrenkert@5031: String river = artifact.getDataAsString("river"); ingo@1106: String geoJSON = artifact.getDataAsString("uesk.barriers"); rrenkert@5031: String srid = FLYSUtils.getRiverDGMSrid(river); ingo@1106: String srs = "EPSG:" + srid; ingo@1106: ingo@1164: if (geoJSON == null || geoJSON.length() == 0) { ingo@1164: logger.debug("No barrier features in parameterization existing."); ingo@1164: return; ingo@1164: } ingo@1164: ingo@1123: SimpleFeatureType ft = getBarriersFeatureType( ingo@1123: "barriers", srs, Geometry.class); ingo@1123: ingo@1123: List features = GeometryUtils.parseGeoJSON(geoJSON, ft); sascha@3555: if (features == null || features.isEmpty()) { ingo@1107: logger.debug("No barrier features extracted."); ingo@1107: return; ingo@1107: } ingo@1106: ingo@1106: FeatureCollection[] fcs = splitLinesAndPolygons(features); ingo@1106: ingo@1106: File shapeLines = new File(dir, WSPLGEN_BARRIERS_LINES); ingo@1106: File shapePolys = new File(dir, WSPLGEN_BARRIERS_POLY); ingo@1106: ingo@1124: Object[][] obj = new Object[][] { ingo@1124: new Object[] { "typ", String.class } ingo@1124: }; ingo@1124: ingo@1955: String scenario = job.getGel(); ingo@1955: ingo@1121: boolean l = GeometryUtils.writeShapefile( ingo@1121: shapeLines, ingo@1124: GeometryUtils.buildFeatureType("lines", srs, LineString.class, obj), ingo@1121: fcs[0]); ingo@1106: ingo@1121: if (l) { ingo@1123: logger.debug( ingo@1123: "Successfully created barrier line shapefile. " + ingo@1123: "Write shapefile path into WSPLGEN job."); rrenkert@5312: createMapfile( rrenkert@5312: artifact, rrenkert@5312: dir, rrenkert@5312: MapfileGenerator.MS_LAYER_PREFIX + "barriers-lines", rrenkert@5312: WSPLGEN_BARRIERS_LINES, rrenkert@5312: "LINE", rrenkert@5312: srid, rrenkert@5312: "barriers"); ingo@1955: ingo@1955: if (scenario.equals(WSPLGENJob.GEL_NOSPERRE)) { ingo@1955: logger.debug("WSPLGEN will not use barrier features."); ingo@1955: } ingo@1955: else { ingo@1955: job.addLin(shapeLines.getAbsolutePath()); ingo@1955: } ingo@1121: } ingo@1121: ingo@1121: boolean p = GeometryUtils.writeShapefile( ingo@1121: shapePolys, ingo@1124: GeometryUtils.buildFeatureType("polygons", srs, Polygon.class, obj), ingo@1121: fcs[1]); ingo@1121: rrenkert@5312: ingo@1121: if (p) { ingo@1123: logger.debug( ingo@1123: "Successfully created barrier polygon shapefile. " + ingo@1123: "Write shapefile path into WSPLGEN job."); rrenkert@5312: createMapfile( rrenkert@5312: artifact, rrenkert@5312: dir, rrenkert@5312: MapfileGenerator.MS_LAYER_PREFIX + "barriers-poly", rrenkert@5312: shapePolys.getAbsolutePath(), rrenkert@5312: "POLYGON", rrenkert@5312: srid, rrenkert@5312: "barriers"); ingo@1955: ingo@1955: if (scenario.equals(WSPLGENJob.GEL_NOSPERRE)) { ingo@1955: logger.debug("WSPLGEN will not use barrier features."); ingo@1955: } ingo@1955: else { ingo@1955: job.addLin(shapePolys.getAbsolutePath()); ingo@1955: } ingo@1106: } ingo@1164: ingo@1164: if (p || l) { ingo@1164: facetCreator.createBarrierFacet(); ingo@1164: } ingo@1107: } ingo@1107: ingo@1107: raimund@2639: protected void setUserShape( raimund@2639: FLYSArtifact artifact, raimund@2639: FacetCreator facetCreator, raimund@2639: File dir, raimund@2639: WSPLGENJob job raimund@2639: ) { rrenkert@5312: File archive = new File(dir, WSPLGEN_USER_SHAPE); raimund@2639: boolean exists = archive.exists(); rrenkert@5312: logger.debug("shp file exists: " + exists); raimund@2639: if (exists) { raimund@2639: job.addLin(dir + "/" + WSPLGEN_USER_SHAPE); rrenkert@5312: facetCreator.createShapeFacet(FacetCreator.I18N_USERSHAPE, rrenkert@5312: MapfileGenerator.MS_LAYER_PREFIX + "user-rgd", rrenkert@5312: FLOODMAP_USERSHAPE, rrenkert@5312: 4); raimund@2639: } raimund@2639: } raimund@2639: ingo@1123: protected SimpleFeatureType getBarriersFeatureType( ingo@1123: String name, ingo@1123: String srs, ingo@1123: Class type ingo@1123: ) { ingo@1707: Object[][] attrs = new Object[3][]; ingo@1123: attrs[0] = new Object[] { "typ", String.class }; ingo@1123: attrs[1] = new Object[] { "elevation", Double.class }; ingo@1707: attrs[2] = new Object[] { "mark.selected", Integer.class }; ingo@1107: ingo@1123: return GeometryUtils.buildFeatureType(name, srs, type, attrs); ingo@1106: } ingo@1106: ingo@1106: ingo@1106: protected FeatureCollection[] splitLinesAndPolygons(List f) { ingo@1106: FeatureCollection lines = FeatureCollections.newCollection(); ingo@1106: FeatureCollection polygons = FeatureCollections.newCollection(); ingo@1106: ingo@1106: for (SimpleFeature feature: f) { ingo@1119: Geometry geom = (Geometry) feature.getDefaultGeometry(); ingo@1106: ingo@1123: ingo@1106: if (geom instanceof LineString) { christian@4569: geom = applyElevationAttribute(feature, geom); ingo@1106: lines.add(feature); ingo@1106: } ingo@1106: else if (geom instanceof Polygon) { christian@4569: geom = applyElevationAttribute(feature, geom); ingo@1106: polygons.add(feature); ingo@1106: } ingo@1106: else { ingo@1106: logger.warn("Feature not supported: " + geom.getClass()); ingo@1106: } ingo@1106: } ingo@1106: ingo@1106: logger.debug("Found " + lines.size() + " barrier lines."); ingo@1106: logger.debug("Found " + polygons.size() + " barrier polygons."); ingo@1106: ingo@1106: return new FeatureCollection[] { lines, polygons }; ingo@1106: } ingo@1108: ingo@1108: ingo@1123: protected static Geometry applyElevationAttribute( ingo@1123: SimpleFeature feature, ingo@1123: Geometry geom ingo@1123: ) { ingo@1123: logger.debug("Apply elevations for: " + geom.getClass()); ingo@1123: ingo@1123: List elevations = extractElevations(feature); ingo@1123: int numPoints = geom.getNumPoints(); ingo@1123: int numElevation = elevations.size(); ingo@1123: ingo@1123: String typ = (String) feature.getAttribute("typ"); ingo@1123: ingo@1123: if (numPoints > numElevation) { ingo@1123: logger.warn("More vertices in Geometry than elevations given."); ingo@1123: } ingo@1123: ingo@1123: Coordinate[] c = geom.getCoordinates(); ingo@1123: for (int i = 0; i < numPoints; i++) { ingo@1123: if (i < numElevation) { ingo@1123: c[i].z = elevations.get(i); ingo@1123: } ingo@1123: else if (typ != null && typ.equals("Graben")) { ingo@1123: c[i].z = -9999d; ingo@1123: } ingo@1123: else { ingo@1123: c[i].z = 9999d; ingo@1123: } ingo@1123: } ingo@1123: ingo@1123: return geom; ingo@1123: } ingo@1123: ingo@1123: ingo@1123: protected static List extractElevations(SimpleFeature feature) { ingo@1123: String tmp = (String) feature.getAttribute("elevation"); ingo@1123: String typ = (String) feature.getAttribute("typ"); ingo@1123: ingo@1123: String[] elevations = tmp == null ? null : tmp.split(" "); ingo@1123: ingo@1123: int num = elevations != null ? elevations.length : 0; ingo@1123: ingo@1123: List list = new ArrayList(num); ingo@1123: ingo@1123: for (int i = 0; i < num; i++) { ingo@1123: try { ingo@1123: list.add(Double.parseDouble(elevations[i])); ingo@1123: } ingo@1123: catch (NumberFormatException nfe) { ingo@1123: logger.warn("Error while parsing elevation at pos: " + i); ingo@1123: if (typ != null && typ.equals("Graben")) { ingo@1123: list.add(new Double(-9999.0)); ingo@1123: } ingo@1123: else { ingo@1123: list.add(new Double(9999.0)); ingo@1123: } ingo@1123: } ingo@1123: } ingo@1123: ingo@1123: return list; ingo@1123: } ingo@1123: ingo@1123: ingo@1108: protected void setAxis(FLYSArtifact artifact, File dir, WSPLGENJob job) { ingo@1108: String river = artifact.getDataAsString("river"); rrenkert@4994: String srid = FLYSUtils.getRiverDGMSrid(river); ingo@1108: String srs = "EPSG:" + srid; rrenkert@5170: rrenkert@5170: List axes = null; rrenkert@5170: try { rrenkert@5170: axes = RiverAxis.getRiverAxis(river); rrenkert@5170: } rrenkert@5181: catch (HibernateException iae) { rrenkert@5173: logger.warn("No valid river axis found for " + river); rrenkert@5170: return; rrenkert@5170: } sascha@3555: if (axes == null || axes.isEmpty()) { ingo@1108: logger.warn("Could not find river axis for: '" + river + "'"); ingo@1108: return; ingo@1108: } ingo@1108: ingo@1108: SimpleFeatureType ft = GeometryUtils.buildFeatureType( ingo@1108: "axis", srs, LineString.class); ingo@1108: ingo@1108: SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft); ingo@2078: FeatureCollection collection = FeatureCollections.newCollection(); ingo@1108: ingo@2078: for (int i = 0, n = axes.size(); i < n; i++) { ingo@2078: RiverAxis axis = axes.get(i); ingo@2078: ingo@2078: builder.add(axis.getGeom()); ingo@2078: collection.add(builder.buildFeature(String.valueOf(i))); ingo@2078: ingo@2078: builder.reset(); ingo@2078: } ingo@1108: ingo@1108: File axisShape = new File(dir, WSPLGEN_AXIS); ingo@1108: ingo@1121: boolean a = GeometryUtils.writeShapefile( ingo@1121: axisShape, ingo@1121: GeometryUtils.buildFeatureType("axis", srs, LineString.class), ingo@1121: collection); ingo@1121: ingo@1121: if (a) { ingo@1108: job.setAxis(axisShape.getAbsolutePath()); ingo@1108: } ingo@1108: } ingo@1108: ingo@1108: ingo@1108: protected void setPro(FLYSArtifact artifact, File dir, WSPLGENJob job) { ingo@1108: String river = artifact.getDataAsString("river"); rrenkert@4994: String srid = FLYSUtils.getRiverDGMSrid(river); ingo@1108: String srs = "EPSG:" + srid; ingo@1108: ingo@1108: List cst = ingo@3070: CrossSectionTrack.getCrossSectionTrack(river, WSPLGEN_QPS_NAME); ingo@1108: ingo@1108: logger.debug("Found " + cst.size() + " CrossSectionTracks."); ingo@1108: ingo@1119: Object[][] attrs = new Object[2][]; ingo@1119: attrs[0] = new Object[] { "ELEVATION", Double.class }; ingo@1119: attrs[1] = new Object[] { "KILOMETER", Double.class }; ingo@1119: ingo@1108: SimpleFeatureType ft = GeometryUtils.buildFeatureType( ingo@1119: "qps", srs, LineString.class, attrs); ingo@1108: ingo@1108: SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft); ingo@1108: FeatureCollection collection = FeatureCollections.newCollection(); ingo@1108: ingo@1108: int i = 0; ingo@1108: for (CrossSectionTrack track: cst) { ingo@1108: builder.reset(); ingo@1108: builder.add(track.getGeom()); ingo@1119: builder.add(track.getZ().doubleValue()); ingo@1119: builder.add(track.getKm().doubleValue()); ingo@1108: ingo@1108: collection.add(builder.buildFeature(String.valueOf(i++))); ingo@1108: } ingo@1108: ingo@1108: File qpsShape = new File(dir, WSPLGEN_QPS); ingo@1108: ingo@1121: boolean q = GeometryUtils.writeShapefile( ingo@1121: qpsShape, ingo@1121: GeometryUtils.buildFeatureType("qps", srs, LineString.class, attrs), ingo@1121: collection); ingo@1121: ingo@1121: if (q) { ingo@1108: job.setPro(qpsShape.getAbsolutePath()); ingo@1108: } ingo@1108: } ingo@1109: ingo@1109: rrenkert@5152: protected void setDgm( rrenkert@5152: FLYSArtifact artifact, rrenkert@5152: WSPLGENJob job, rrenkert@5152: CallContext context rrenkert@5152: ) { ingo@1186: String dgm_id = artifact.getDataAsString("dgm"); ingo@1109: ingo@1186: int id = -1; ingo@1186: try { ingo@1186: id = Integer.parseInt(dgm_id); ingo@1186: } ingo@1186: catch (NumberFormatException nfe) { /* do nothing */ } ingo@1186: ingo@1186: DGM dgm = DGM.getDGM(id); ingo@1109: ingo@1109: if (dgm == null) { ingo@1186: logger.warn("Could not find specified DGM."); ingo@1109: ingo@1109: return; ingo@1109: } ingo@1109: rrenkert@5152: File dgmPath = new File (dgm.getPath()); rrenkert@5152: if (dgmPath.isAbsolute()) { rrenkert@5152: job.setDgm(dgm.getPath()); rrenkert@5152: } rrenkert@5152: else { rrenkert@5152: FLYSContext fc = (FLYSContext)context.globalContext(); rrenkert@5152: String prefix = (String) fc.get("dgm-path"); rrenkert@5152: job.setDgm(prefix.trim() + dgm.getPath().trim()); rrenkert@5152: } ingo@1109: } ingo@1110: ingo@1110: ingo@1110: protected void setArea(FLYSArtifact artifact, File dir, WSPLGENJob job) { ingo@1955: String useFloodplain = artifact.getDataAsString("use_floodplain"); ingo@1955: if (!Boolean.valueOf(useFloodplain)) { ingo@1955: logger.debug("WSPLGEN will not use floodplain."); ingo@1955: return; ingo@1955: } ingo@1955: ingo@1110: String river = artifact.getDataAsString("river"); rrenkert@5031: String srid = FLYSUtils.getRiverDGMSrid(river); ingo@1110: String srs = "EPSG:" + srid; ingo@1110: ingo@1110: Floodplain plain = Floodplain.getFloodplain(river); ingo@1110: ingo@1110: SimpleFeatureType ft = GeometryUtils.buildFeatureType( ingo@1845: "talaue", srs, Polygon.class); ingo@1110: ingo@1110: SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft); ingo@1110: builder.add(plain.getGeom()); ingo@1110: ingo@1110: FeatureCollection collection = FeatureCollections.newCollection(); ingo@1110: collection.add(builder.buildFeature("0")); ingo@1110: ingo@1110: File talaueShape = new File(dir, WSPLGEN_FLOODPLAIN); ingo@1110: ingo@1121: boolean t = GeometryUtils.writeShapefile( ingo@1121: talaueShape, ingo@1845: GeometryUtils.buildFeatureType("talaue", srs, Polygon.class), ingo@1121: collection); ingo@1121: ingo@1121: if (t) { ingo@1110: job.setArea(talaueShape.getAbsolutePath()); ingo@1110: } ingo@1110: } ingo@1118: ingo@1118: ingo@1118: protected void setOutFile(FLYSArtifact artifact, WSPLGENJob job) { ingo@1118: job.setOutFile(WSPLGEN_OUTPUT_FILE); ingo@1118: } ingo@1118: ingo@1118: ingo@1178: protected WQKms getWQKms(FLYSArtifact flys, CallContext cc) { ingo@1178: String wspString = flys.getDataAsString(WSP_ARTIFACT); christian@4569: if (wspString == null) { christian@4569: logger.debug("getWQKms(): wspString == null"); christian@4569: return null; christian@4569: } christian@4569: String[] parts = wspString.split(";"); ingo@1178: String otherArtifact = parts[0]; ingo@1178: ingo@1178: int idx = -1; ingo@1178: try { ingo@1178: idx = Integer.parseInt(parts[2]); ingo@1178: } ingo@1178: catch (NumberFormatException nfe) { /* do nothing */ } ingo@1178: ingo@1178: FLYSArtifact src = otherArtifact != null ingo@1178: ? FLYSUtils.getArtifact(otherArtifact, cc) ingo@1178: : flys; ingo@1178: ingo@1178: logger.debug("Use waterlevel provided by Artifact: " + src.identifier()); ingo@1178: ingo@1178: CalculationResult rawData = (CalculationResult) src.compute( ingo@1178: cc, ingo@1178: null, ingo@1178: WINFO_WSP_STATE_ID, ingo@1178: ComputeType.ADVANCE, ingo@1178: false); ingo@1178: ingo@1178: WQKms[] wqkms = (WQKms[]) rawData.getData(); ingo@1178: ingo@1178: return wqkms == null || idx == -1 || idx >= wqkms.length ingo@1178: ? null ingo@1178: : wqkms[idx]; ingo@1178: } ingo@1178: ingo@1178: ingo@1118: protected void setWsp( ingo@1118: FLYSArtifact artifact, ingo@1118: CallContext context, ingo@1118: File dir, ingo@1118: WSPLGENJob job) ingo@1118: { ingo@1118: logger.debug("FloodMapState.setWsp"); ingo@1118: ingo@1178: WQKms data = getWQKms(artifact, context); ingo@1118: ingo@1178: if (data == null) { ingo@1118: logger.warn("No WST data found!"); ingo@1118: return; ingo@1118: } ingo@1118: ingo@1178: WstWriter writer = new WstWriter(1); ingo@1118: ingo@1118: // TODO REMOVE job.setWspTag(...) This is only used until the user is ingo@1118: // able to select the WSP column himself! ingo@1118: boolean writeWspTag = true; ingo@1118: ingo@1118: double[] buf = new double[4]; ingo@1178: logger.debug("Add WST column: " + data.getName()); ingo@1178: writer.addColumn(data.getName()); ingo@1118: ingo@1178: if (writeWspTag) { ingo@1178: job.setWspTag(data.getName()); ingo@1178: writeWspTag = false; ingo@1178: } ingo@1118: ingo@1178: for (int i = 0, num = data.size(); i < num; i++) { ingo@1178: data.get(i, buf); ingo@1178: writer.add(buf); ingo@1118: } ingo@1118: ingo@1118: FileOutputStream fout = null; ingo@1118: ingo@1118: try { ingo@1118: File wspFile = new File(dir, WSPLGEN_WSP_FILE); ingo@1118: fout = new FileOutputStream(wspFile); ingo@1118: ingo@1118: writer.write(fout); ingo@1118: ingo@1118: job.setWsp(wspFile.getAbsolutePath()); ingo@1118: } ingo@1118: catch (FileNotFoundException fnfe) { ingo@1118: logger.warn("Error while writing wsp file: " + fnfe.getMessage()); ingo@1118: } ingo@1118: finally { ingo@1118: if (fout != null) { ingo@1118: try { ingo@1118: fout.close(); ingo@1118: } ingo@1118: catch (IOException ioe) { /* do nothing */ } ingo@1118: } ingo@1118: } ingo@1118: } raimund@2639: raimund@2639: raimund@2639: ingo@927: } ingo@927: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :