view artifacts/src/main/java/org/dive4elements/river/artifacts/states/HWSBarriersState.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/HWSBarriersState.java@bd047b71ab37
children 4897a58c8746
line wrap: on
line source
package org.dive4elements.river.artifacts.states;

import java.io.File;
import java.io.FileNotFoundException;
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.data.shapefile.ShapefileDataStore;

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

import org.opengis.feature.simple.SimpleFeatureType;

import org.opengis.feature.type.GeometryDescriptor;

import org.w3c.dom.Element;

import org.dive4elements.artifactdatabase.state.Facet;

import org.dive4elements.artifacts.Artifact;
import org.dive4elements.artifacts.CallContext;

import org.dive4elements.artifacts.common.utils.FileTools;

import org.dive4elements.artifacts.common.utils.XMLUtils.ElementCreator;

import org.dive4elements.river.artifacts.FLYSArtifact;

import org.dive4elements.river.artifacts.access.MapAccess;

import org.dive4elements.river.artifacts.model.LayerInfo;

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.utils.ArtifactMapfileGenerator;
import org.dive4elements.river.utils.FLYSUtils;
import org.dive4elements.river.utils.GeometryUtils;
import org.dive4elements.river.utils.MapfileGenerator;

public class HWSBarriersState
extends DefaultState
{

    /** The logger that is used in this class.*/
    private static Logger logger = Logger.getLogger(HWSBarriersState.class);
    private static final String HWS_SHAPEFILE_LINES = "hws-lines.shp";
    private static final String HWS_SHAPEFILE_POINTS = "hws-points.shp";
    private static final String USER_RGD_SHAPE     = "user-rgd.shp";
    private static final String USER_RGD_ZIP       = "user-rgd.zip";
    private static final String USER_RGD_FILENAME  = "user-rgd";
    @Override
    protected String getUIProvider() {
        return "map_digitize";
    }


    @Override
    protected Element createStaticData(
        FLYSArtifact   flys,
        ElementCreator creator,
        CallContext    cc,
        String         name,
        String         value,
        String         type
    ) {
        Element dataElement = creator.create("data");
        creator.addAttr(dataElement, "name", name, true);
        creator.addAttr(dataElement, "type", type, true);

        Element itemElement = creator.create("item");
        creator.addAttr(itemElement, "value", value, true);

        creator.addAttr(itemElement, "label", "", true);
        dataElement.appendChild(itemElement);

        return dataElement;
    }


    @Override
    public Object computeAdvance(
        FLYSArtifact artifact,
        String hash,
        CallContext context,
        List<Facet> facets,
        Object old
    ) {
        File artifactDir = getDirectory(artifact);

        if (artifactDir == null) {
            logger.error("Could not create directory for HWS shapefile!");
            return null;
        }

        MapAccess access = new MapAccess(artifact, context);
        String river = access.getRiver();
        HWSContainer hwsLines = HWSFactory.getHWSLines(river);
        HWSContainer hwsPoints = HWSFactory.getHWSPoints(river);
        List<String> selected = access.getHWS();

        List<HWS> selectedLines = hwsLines.getHws(selected);
        List<HWS> selectedPoints = hwsPoints.getHws(selected);

        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_SHAPEFILE_LINES);
            successLines = GeometryUtils.writeShapefile(
                shapeLines, lineType, collectionLines);
        }

        FeatureCollection collectionPoints = FeatureCollections.newCollection();
        SimpleFeatureType pointType = null;
        for (HWS h : selectedPoints) {
            pointType = h.getFeatureType();
            collectionPoints.add(h.getFeature());
        }
        boolean successPoints = false;
        if (pointType != null && collectionPoints.size() > 0) {
            File shapePoints = new File(artifactDir, HWS_SHAPEFILE_POINTS);
            successPoints =GeometryUtils.writeShapefile(
                shapePoints, pointType, collectionPoints);
        }

        if (successLines) {
            createMapfile(
                artifact,
                artifactDir,
                MapfileGenerator.MS_LAYER_PREFIX + "hws-lines",
                HWS_SHAPEFILE_LINES,
                "LINE",
                "31467",
                "hws");
        }
        if (successPoints) {
            createMapfile(
                artifact,
                artifactDir,
                MapfileGenerator.MS_LAYER_PREFIX + "hws-points",
                HWS_SHAPEFILE_POINTS,
                "POINT",
                "31467",
                "hws");
        }

        String userRgd = artifact.getDataAsString("uesk.user-rgd");
        if (!userRgd.equals("none")) {
            if (extractUserShp(artifactDir)) {
                try {
                    ShapefileDataStore store = new ShapefileDataStore(
                    new File(artifactDir.getCanonicalPath() +
                        "/" + USER_RGD_SHAPE)
                            .toURI().toURL());
                    GeometryDescriptor desc =
                        store.getSchema().getGeometryDescriptor();
                    String type = desc.getType().getName().toString();
                    String proj =
                        desc.getCoordinateReferenceSystem().
                            getCoordinateSystem().toString();
                    int pos1 = proj.indexOf("EPSG\",\"");
                    int pos2 = proj.indexOf("\"]]");
                    String epsg = "";
                    if (pos1 >= 0 && pos2 >= 0) {
                        epsg =
                            proj.substring(proj.indexOf("EPSG\",\"") + 7,
                                proj.indexOf("\"]]"));
                    }
                    else {
                        logger.warn("Could not read EPSG code from shapefile.");
                        return null;
                    }
                    if (type.contains("Line")) {
                        type = "LINE";
                    }
                    else if (type.contains("Poly")) {
                        type = "POLYGON";
                    }
                    else {
                        type = "POINT";
                    }
                    createMapfile(
                        artifact,
                        artifactDir,
                        MapfileGenerator.MS_LAYER_PREFIX + USER_RGD_FILENAME,
                        USER_RGD_SHAPE,
                        type,
                        epsg,
                        "user-rgd");
                }
                catch (IOException e) {
                    logger.warn("No mapfile for user-rgd created!");
                }
            }
        }
        return null;
    }

    private boolean extractUserShp(File dir) {
        // TODO Auto-generated method stub
        File archive = new File(dir, USER_RGD_ZIP);
        boolean exists = archive.exists();
        logger.debug("Zip file exists: " + exists);
        if (exists) {
            try {
                File tmpDir = new File(dir, "usr_tmp");
                FileTools.extractArchive(archive, tmpDir);
                moveFiles(tmpDir, dir);
                return true;
            }
            catch (IOException ioe) {
                logger.warn("Zip archive " + dir + "/"
                    + USER_RGD_ZIP + " could not be extracted.");
                return false;
            }
        }
        return false;
    }

    private void moveFiles(File source, final File target)
    throws IOException
    {
        if (!source.exists()) {
            return;
        }
        if (!target.exists()) {
            target.mkdir();
        }
        FileTools.walkTree(source, new FileTools.FileVisitor() {
            @Override
            public boolean visit(File file) {
                if (!file.isDirectory()) {
                    String name = file.getName();
                    String suffix = "";
                    int pos = name.lastIndexOf('.');
                    if (pos > 0 && pos < name.length() - 1) {
                        suffix = name.substring(pos + 1);
                    }
                    else {
                        return true;
                    }
                    try {
                        FileTools.copyFile(file, new File(target, USER_RGD_FILENAME + "." + suffix));
                    }
                    catch (IOException ioe) {
                        logger.warn ("Error while copying file " + file.getName());
                        return true;
                    }
                }
                return true;
            }
        });

        FileTools.deleteRecursive(source);
    }

    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()));
        }
    }


    @Override
    public void endOfLife(Artifact artifact, Object callContext) {
        super.endOfLife(artifact, callContext);
        logger.info("ScenarioSelect.endOfLife: " + artifact.identifier());

        FLYSArtifact flys = (FLYSArtifact) artifact;
        removeDirectory(flys);
    }


    /**
     * Removes the directory and all its content where the required data and the
     * results of WSPLGEN are stored. Should be called in endOfLife().
     */
    // FIXME: I've seen this code somewhere else...
    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.debug("Delete directory: " + artifactDir.getAbsolutePath());
            boolean success = FileTools.deleteRecursive(artifactDir);
            if (!success) {
                logger.warn("could not remove dir '" + artifactDir + "'");
            }
        }
        else {
            logger.debug("There is no directory to remove.");
        }
    }

    /**
     * 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;
    }

}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org