view flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java @ 1109:ba9fa72dd6f5

Write file path of DMGs into the WSPLGEN job while preparing WSPLGEN. flys-artifacts/trunk@2614 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 31 Aug 2011 07:50:01 +0000
parents 5b1198c27d43
children 563e015f0f22
line wrap: on
line source
package de.intevation.flys.artifacts.states;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;

import javax.xml.xpath.XPathConstants;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Polygon;

import org.apache.log4j.Logger;

import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureCollections;
import org.geotools.feature.simple.SimpleFeatureBuilder;

import de.intevation.artifacts.Artifact;
import de.intevation.artifacts.CallContext;

import de.intevation.artifacts.common.utils.Config;
import de.intevation.artifacts.common.utils.FileTools;

import de.intevation.artifactdatabase.state.Facet;

import de.intevation.flys.model.CrossSectionTrack;
import de.intevation.flys.model.DGM;
import de.intevation.flys.model.RiverAxis;

import de.intevation.flys.artifacts.FLYSArtifact;
import de.intevation.flys.artifacts.model.FacetTypes;
import de.intevation.flys.artifacts.model.WSPLGENFacet;
import de.intevation.flys.artifacts.model.WSPLGENJob;
import de.intevation.flys.utils.FLYSUtils;
import de.intevation.flys.utils.GeometryUtils;


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 XPATH_SHAPEFILE_DIR =
        "/artifact-database/floodmap/shapefile-path/@value";

    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 int WSPLGEN_DEFAULT_OUTPUT = 0;



    @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;
        }

        WSPLGENJob job = prepareWSPLGENJob(artifact, artifactDir);

        if (job == null) {
            if (KEEP_ARTIFACT_DIR.equals("false")) {
                removeDirectory(artifact);
            }

            logger.error("No WSPLGEN processing has been started!");

            return null;
        }

        facets.add(new WSPLGENFacet(0, FLOODMAP_WSPLGEN, "WSPLGEN"));

        //context.afterCall(CallContext.BACKGROUND);

        return null;
    }


    /**
     * Returns the shapefile path defined in the configuration.
     *
     * @return the shapefile path.
     */
    protected String getShapefilePath() {
        String shapePath = (String) Config.getXPath(
            XPATH_SHAPEFILE_DIR, XPathConstants.STRING);
        shapePath = Config.replaceConfigDir(shapePath);

        return shapePath;
    }


    /**
     * 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 = getShapefilePath();

        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    = getShapefilePath();
        File   artifactDir = new File(shapePath, artifact.identifier());

        if (artifactDir.exists()) {
            logger.info("Delete directory: " + artifactDir.getAbsolutePath());
            boolean success = FileTools.deleteRecursive(artifactDir);
        }
        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;
        removeDirectory(flys);
    }


    protected WSPLGENJob prepareWSPLGENJob(
        FLYSArtifact artifact,
        File         artifactDir
    ) {
        logger.debug("FloodMapState.prepareWSPLGENJob");

        WSPLGENJob job = new WSPLGENJob();
        File  paraFile = new File(artifactDir, WSPLGEN_PARAMETER_FILE);

        setOut(artifact, job);
        setRange(artifact, job);
        setDelta(artifact, job);
        setGel(artifact, job);
        setDist(artifact, job);
        setLine(artifact, artifactDir, job);
        setAxis(artifact, artifactDir, job);
        setPro(artifact, artifactDir, job);
        setDgm(artifact, job);

        // TODO
        // setWsp(artifact, job);    // WSP
        // setWspTag(artifact, job);
        // setArea(artifact, job);   // SHP
        // setOutFile(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;
    }


    protected void setOut(FLYSArtifact artifact, WSPLGENJob job) {
        job.setOut(WSPLGEN_DEFAULT_OUTPUT);
    }


    protected void setRange(FLYSArtifact artifact, WSPLGENJob job) {
        double[] range = FLYSUtils.getKmRange(artifact);

        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("use_floodplain");

        if (gel != null && gel.length() > 0) {
            boolean use = Boolean.parseBoolean(gel);

            if (use) {
                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, File dir, WSPLGENJob job) {
        String geoJSON = artifact.getDataAsString("uesk.barriers");
        String srid    = FLYSUtils.getRiverSrid(artifact);
        String srs     = "EPSG:" + srid;

        List<SimpleFeature> features = getBarriersFeatures(geoJSON, srs);
        if (features == null || features.size() == 0) {
            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);

        try {
            GeometryUtils.writeShapefile(
                shapeLines,
                GeometryUtils.buildFeatureType("lines", srs, LineString.class),
                fcs[0]);
            job.addLin(shapeLines.getAbsolutePath());

            GeometryUtils.writeShapefile(
                shapePolys,
                GeometryUtils.buildFeatureType("polygons", srs, Polygon.class),
                fcs[1]);
            job.addLin(shapePolys.getAbsolutePath());
        }
        catch (MalformedURLException mue) {
            logger.error("Error while writing shapefile: " + mue.getMessage());
        }
        catch (IOException ioe) {
            logger.error("Error while writing shapefile: " + ioe.getMessage());
        }
    }


    protected List<SimpleFeature> getBarriersFeatures(String json, String srs) {
        SimpleFeatureType ft = GeometryUtils.buildFeatureType(
            "barriers", srs,Geometry.class);

        return GeometryUtils.parseGeoJSON(json, ft);
    }


    protected FeatureCollection[] splitLinesAndPolygons(List<SimpleFeature> f) {
        FeatureCollection lines    = FeatureCollections.newCollection();
        FeatureCollection polygons = FeatureCollections.newCollection();

        for (SimpleFeature feature: f) {
            Object geom = feature.getDefaultGeometry();

            if (geom instanceof LineString) {
                lines.add(feature);
            }
            else if (geom instanceof Polygon) {
                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 void setAxis(FLYSArtifact artifact, File dir, WSPLGENJob job) {
        String river = artifact.getDataAsString("river");
        String srid    = FLYSUtils.getRiverSrid(artifact);
        String srs     = "EPSG:" + srid;

        RiverAxis axis = RiverAxis.getRiverAxis(river);
        if (axis == null) {
            logger.warn("Could not find river axis for: '" + river + "'");
            return;
        }

        Geometry geom = axis.getGeom();

        SimpleFeatureType ft = GeometryUtils.buildFeatureType(
            "axis", srs, LineString.class);

        SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft);
        builder.add(geom);

        FeatureCollection collection = FeatureCollections.newCollection();
        collection.add(builder.buildFeature("0"));

        File axisShape = new File(dir, WSPLGEN_AXIS);

        try {
            GeometryUtils.writeShapefile(
                axisShape,
                GeometryUtils.buildFeatureType("axis", srs, LineString.class),
                collection);
            job.setAxis(axisShape.getAbsolutePath());
        }
        catch (MalformedURLException mue) {
            logger.error("Error while writing shapefile: " + mue.getMessage());
        }
        catch (IOException ioe) {
            logger.error("Error while writing shapefile: " + ioe.getMessage());
        }
    }


    protected void setPro(FLYSArtifact artifact, File dir, WSPLGENJob job) {
        String river = artifact.getDataAsString("river");
        String srid    = FLYSUtils.getRiverSrid(artifact);
        String srs     = "EPSG:" + srid;

        List<CrossSectionTrack> cst =
            CrossSectionTrack.getCrossSectionTrack(river);

        logger.debug("Found " + cst.size() + " CrossSectionTracks.");

        SimpleFeatureType ft = GeometryUtils.buildFeatureType(
            "qps", srs, LineString.class);

        SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft);
        FeatureCollection collection = FeatureCollections.newCollection();

        int i = 0;
        for (CrossSectionTrack track: cst) {
            builder.reset();
            builder.add(track.getGeom());

            collection.add(builder.buildFeature(String.valueOf(i++)));
        }

        File qpsShape = new File(dir, WSPLGEN_QPS);

        try {
            GeometryUtils.writeShapefile(
                qpsShape,
                GeometryUtils.buildFeatureType("qps", srs, LineString.class),
                collection);
            job.setPro(qpsShape.getAbsolutePath());
        }
        catch (MalformedURLException mue) {
            logger.error("Error while writing shapefile: " + mue.getMessage());
        }
        catch (IOException ioe) {
            logger.error("Error while writing shapefile: " + ioe.getMessage());
        }
    }


    protected void setDgm(FLYSArtifact artifact, WSPLGENJob job) {
        String   river = artifact.getDataAsString("river");
        double[] range = FLYSUtils.getKmRange(artifact);

        DGM dgm = DGM.getDGM(river, range[0], range[1]);

        if (dgm == null) {
            logger.warn(
                "Could not find a DGM for river '" + river + "'" +
                "(" + range[0] + " - " + range[1] + ")");

            return;
        }

        job.setDgm(dgm.getPath());
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org