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