ingo@927: package de.intevation.flys.artifacts.states;
ingo@927: 
ingo@1091: import java.io.File;
ingo@1118: import java.io.FileNotFoundException;
ingo@1118: import java.io.FileOutputStream;
ingo@1091: import java.io.IOException;
ingo@1123: import java.util.ArrayList;
ingo@935: import java.util.List;
ingo@935: 
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@1110: import com.vividsolutions.jts.geom.MultiPolygon;
ingo@1106: import com.vividsolutions.jts.geom.Polygon;
ingo@1106: 
ingo@927: import org.apache.log4j.Logger;
ingo@927: 
ingo@1106: import org.opengis.feature.simple.SimpleFeature;
ingo@1106: import org.opengis.feature.simple.SimpleFeatureType;
ingo@1106: 
ingo@1106: import org.geotools.feature.FeatureCollection;
ingo@1106: import org.geotools.feature.FeatureCollections;
ingo@1108: import org.geotools.feature.simple.SimpleFeatureBuilder;
ingo@1106: 
ingo@1091: import de.intevation.artifacts.Artifact;
ingo@935: import de.intevation.artifacts.CallContext;
ingo@935: 
ingo@1091: import de.intevation.artifacts.common.utils.FileTools;
ingo@1091: 
ingo@935: import de.intevation.artifactdatabase.state.Facet;
ingo@935: 
ingo@1108: import de.intevation.flys.model.CrossSectionTrack;
ingo@1109: import de.intevation.flys.model.DGM;
ingo@1110: import de.intevation.flys.model.Floodplain;
ingo@1108: import de.intevation.flys.model.RiverAxis;
ingo@1108: 
ingo@935: import de.intevation.flys.artifacts.FLYSArtifact;
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;
ingo@1118: import de.intevation.flys.artifacts.model.WQKms;
ingo@1149: import de.intevation.flys.artifacts.model.WSPLGENCalculation;
ingo@1091: import de.intevation.flys.artifacts.model.WSPLGENJob;
ingo@1149: import de.intevation.flys.artifacts.model.WSPLGENReportFacet;
ingo@1165: import de.intevation.flys.artifacts.resources.Resources;
ingo@1118: import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
ingo@1118: import de.intevation.flys.exports.WstWriter;
ingo@1096: import de.intevation.flys.utils.FLYSUtils;
ingo@1106: import de.intevation.flys.utils.GeometryUtils;
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: 
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@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";
ingo@1091: 
ingo@1096:     public static final int WSPLGEN_DEFAULT_OUTPUT = 0;
ingo@1096: 
ingo@1091: 
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<Facet>  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@1649:         Scheduler scheduler = Scheduler.getInstance();
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(
ingo@1129:             FLYSUtils.XPATH_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(
ingo@1129:             FLYSUtils.XPATH_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());
ingo@1091:             boolean success = FileTools.deleteRecursive(artifactDir);
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@1091:         removeDirectory(flys);
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");
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@1164:         setLine(artifact, facetCreator, artifactDir, job);
ingo@1108:         setAxis(artifact, artifactDir, job);
ingo@1108:         setPro(artifact, artifactDir, job);
ingo@1109:         setDgm(artifact, job);
ingo@1110:         setArea(artifact, artifactDir, job);
ingo@1118:         setOutFile(artifact, job);
ingo@1118:         setWsp(artifact, context, artifactDir, job);    // WSP
ingo@1096: 
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: 
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) {
ingo@1096:         double[] range = FLYSUtils.getKmRange(artifact);
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@1096:         String gel = artifact.getDataAsString("use_floodplain");
ingo@1096: 
ingo@1096:         if (gel != null && gel.length() > 0) {
ingo@1096:             boolean use = Boolean.parseBoolean(gel);
ingo@1096: 
ingo@1096:             if (use) {
ingo@1096:                 job.setGel(WSPLGENJob.GEL_SPERRE);
ingo@1096:             }
ingo@1096:             else {
ingo@1096:                 job.setGel(WSPLGENJob.GEL_NOSPERRE);
ingo@1096:             }
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:     ) {
ingo@1106:         String geoJSON = artifact.getDataAsString("uesk.barriers");
ingo@1106:         String srid    = FLYSUtils.getRiverSrid(artifact);
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<SimpleFeature> features = GeometryUtils.parseGeoJSON(geoJSON, ft);
ingo@1107:         if (features == null || features.size() == 0) {
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@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.");
ingo@1121:             job.addLin(shapeLines.getAbsolutePath());
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: 
ingo@1121:         if (p) {
ingo@1123:             logger.debug(
ingo@1123:                 "Successfully created barrier polygon shapefile. " +
ingo@1123:                 "Write shapefile path into WSPLGEN job.");
ingo@1106:             job.addLin(shapePolys.getAbsolutePath());
ingo@1106:         }
ingo@1164: 
ingo@1164:         if (p || l) {
ingo@1164:             facetCreator.createBarrierFacet();
ingo@1164:         }
ingo@1107:     }
ingo@1107: 
ingo@1107: 
ingo@1123:     protected SimpleFeatureType getBarriersFeatureType(
ingo@1123:         String name,
ingo@1123:         String srs,
ingo@1123:         Class  type
ingo@1123:     ) {
ingo@1123:         Object[][] attrs = new Object[2][];
ingo@1123:         attrs[0] = new Object[] { "typ", String.class };
ingo@1123:         attrs[1] = new Object[] { "elevation", Double.class };
ingo@1107: 
ingo@1123:         return GeometryUtils.buildFeatureType(name, srs, type, attrs);
ingo@1106:     }
ingo@1106: 
ingo@1106: 
ingo@1106:     protected FeatureCollection[] splitLinesAndPolygons(List<SimpleFeature> 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) {
ingo@1123:                 geom = applyElevationAttribute(feature, (LineString) geom);
ingo@1106:                 lines.add(feature);
ingo@1106:             }
ingo@1106:             else if (geom instanceof Polygon) {
ingo@1123:                 geom = applyElevationAttribute(feature, (Polygon) 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<Double> 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<Double> 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<Double> list = new ArrayList<Double>(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");
ingo@1108:         String srid    = FLYSUtils.getRiverSrid(artifact);
ingo@1108:         String srs     = "EPSG:" + srid;
ingo@1108: 
ingo@1108:         RiverAxis axis = RiverAxis.getRiverAxis(river);
ingo@1108:         if (axis == null) {
ingo@1108:             logger.warn("Could not find river axis for: '" + river + "'");
ingo@1108:             return;
ingo@1108:         }
ingo@1108: 
ingo@1108:         Geometry geom = axis.getGeom();
ingo@1108: 
ingo@1108:         SimpleFeatureType ft = GeometryUtils.buildFeatureType(
ingo@1108:             "axis", srs, LineString.class);
ingo@1108: 
ingo@1108:         SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft);
ingo@1108:         builder.add(geom);
ingo@1108: 
ingo@1108:         FeatureCollection collection = FeatureCollections.newCollection();
ingo@1108:         collection.add(builder.buildFeature("0"));
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");
ingo@1108:         String srid    = FLYSUtils.getRiverSrid(artifact);
ingo@1108:         String srs     = "EPSG:" + srid;
ingo@1108: 
ingo@1108:         List<CrossSectionTrack> cst =
ingo@1108:             CrossSectionTrack.getCrossSectionTrack(river);
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: 
ingo@1109:     protected void setDgm(FLYSArtifact artifact, WSPLGENJob job) {
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: 
ingo@1109:         job.setDgm(dgm.getPath());
ingo@1109:     }
ingo@1110: 
ingo@1110: 
ingo@1110:     protected void setArea(FLYSArtifact artifact, File dir, WSPLGENJob job) {
ingo@1110:         String river = artifact.getDataAsString("river");
ingo@1110:         String srid  = FLYSUtils.getRiverSrid(artifact);
ingo@1110:         String srs   = "EPSG:" + srid;
ingo@1110: 
ingo@1110:         Floodplain plain = Floodplain.getFloodplain(river);
ingo@1110: 
ingo@1110:         SimpleFeatureType ft = GeometryUtils.buildFeatureType(
ingo@1110:             "talaue", srs, MultiPolygon.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@1121:             GeometryUtils.buildFeatureType("talaue", srs, MultiPolygon.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);
ingo@1178:         String[] parts     = wspString.split(";");
ingo@1178: 
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:     }
ingo@927: }
ingo@927: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :