teichmann@5831: package org.dive4elements.river.artifacts.states; rrenkert@5310: rrenkert@5310: import java.io.File; rrenkert@5310: import java.io.FileNotFoundException; rrenkert@5310: import java.io.IOException; teichmann@5313: rrenkert@5310: import java.util.ArrayList; rrenkert@5310: import java.util.Arrays; rrenkert@5310: import java.util.List; rrenkert@5310: rrenkert@5310: import org.apache.log4j.Logger; teichmann@5313: rrenkert@5310: import org.apache.velocity.Template; teichmann@5313: rrenkert@5310: import org.geotools.data.shapefile.ShapefileDataStore; teichmann@5313: rrenkert@5310: import org.geotools.feature.FeatureCollection; rrenkert@5310: import org.geotools.feature.FeatureCollections; teichmann@5313: rrenkert@5310: import org.opengis.feature.simple.SimpleFeatureType; teichmann@5313: rrenkert@5310: import org.opengis.feature.type.GeometryDescriptor; teichmann@5313: rrenkert@5310: import org.w3c.dom.Element; rrenkert@5310: teichmann@5831: import org.dive4elements.artifactdatabase.state.Facet; teichmann@5313: teichmann@5831: import org.dive4elements.artifacts.Artifact; teichmann@5831: import org.dive4elements.artifacts.CallContext; teichmann@5313: teichmann@5831: import org.dive4elements.artifacts.common.utils.FileTools; teichmann@5313: teichmann@5831: import org.dive4elements.artifacts.common.utils.XMLUtils.ElementCreator; teichmann@5831: teichmann@5831: import org.dive4elements.river.artifacts.FLYSArtifact; teichmann@5831: teichmann@5831: import org.dive4elements.river.artifacts.access.MapAccess; teichmann@5831: teichmann@5831: import org.dive4elements.river.artifacts.model.LayerInfo; teichmann@5831: teichmann@5831: import org.dive4elements.river.artifacts.model.map.HWS; teichmann@5831: import org.dive4elements.river.artifacts.model.map.HWSContainer; teichmann@5831: import org.dive4elements.river.artifacts.model.map.HWSFactory; teichmann@5831: teichmann@5831: import org.dive4elements.river.utils.ArtifactMapfileGenerator; teichmann@5831: import org.dive4elements.river.utils.FLYSUtils; teichmann@5831: import org.dive4elements.river.utils.GeometryUtils; teichmann@5831: import org.dive4elements.river.utils.MapfileGenerator; rrenkert@5310: rrenkert@5310: public class HWSBarriersState rrenkert@5310: extends DefaultState rrenkert@5310: { rrenkert@5310: rrenkert@5310: /** The logger that is used in this class.*/ rrenkert@5310: private static Logger logger = Logger.getLogger(HWSBarriersState.class); rrenkert@5310: private static final String HWS_SHAPEFILE_LINES = "hws-lines.shp"; rrenkert@5310: private static final String HWS_SHAPEFILE_POINTS = "hws-points.shp"; rrenkert@5310: private static final String USER_RGD_SHAPE = "user-rgd.shp"; rrenkert@5310: private static final String USER_RGD_ZIP = "user-rgd.zip"; rrenkert@5310: private static final String USER_RGD_FILENAME = "user-rgd"; rrenkert@5310: @Override rrenkert@5310: protected String getUIProvider() { rrenkert@5310: return "map_digitize"; rrenkert@5310: } rrenkert@5310: rrenkert@5310: rrenkert@5310: @Override rrenkert@5310: protected Element createStaticData( rrenkert@5310: FLYSArtifact flys, rrenkert@5310: ElementCreator creator, rrenkert@5310: CallContext cc, rrenkert@5310: String name, rrenkert@5310: String value, rrenkert@5310: String type rrenkert@5310: ) { rrenkert@5310: Element dataElement = creator.create("data"); rrenkert@5310: creator.addAttr(dataElement, "name", name, true); rrenkert@5310: creator.addAttr(dataElement, "type", type, true); rrenkert@5310: rrenkert@5310: Element itemElement = creator.create("item"); rrenkert@5310: creator.addAttr(itemElement, "value", value, true); rrenkert@5310: rrenkert@5310: creator.addAttr(itemElement, "label", "", true); rrenkert@5310: dataElement.appendChild(itemElement); rrenkert@5310: rrenkert@5310: return dataElement; rrenkert@5310: } rrenkert@5310: rrenkert@5310: rrenkert@5310: @Override rrenkert@5310: public Object computeAdvance( rrenkert@5310: FLYSArtifact artifact, rrenkert@5310: String hash, rrenkert@5310: CallContext context, rrenkert@5310: List facets, rrenkert@5310: Object old rrenkert@5310: ) { rrenkert@5310: File artifactDir = getDirectory(artifact); rrenkert@5310: rrenkert@5310: if (artifactDir == null) { rrenkert@5310: logger.error("Could not create directory for HWS shapefile!"); rrenkert@5310: return null; rrenkert@5310: } rrenkert@5310: rrenkert@5310: MapAccess access = new MapAccess(artifact, context); rrenkert@5310: String river = access.getRiver(); rrenkert@5310: HWSContainer hwsLines = HWSFactory.getHWSLines(river); rrenkert@5310: HWSContainer hwsPoints = HWSFactory.getHWSPoints(river); rrenkert@5310: List selected = access.getHWS(); rrenkert@5310: rrenkert@5310: List selectedLines = hwsLines.getHws(selected); rrenkert@5310: List selectedPoints = hwsPoints.getHws(selected); rrenkert@5310: rrenkert@5310: FeatureCollection collectionLines = FeatureCollections.newCollection(); rrenkert@5310: SimpleFeatureType lineType = null; rrenkert@5310: for (HWS h : selectedLines) { rrenkert@5310: lineType = h.getFeatureType(); rrenkert@5310: collectionLines.add(h.getFeature()); rrenkert@5310: } rrenkert@5310: boolean successLines = false; rrenkert@5310: if (lineType != null && collectionLines.size() > 0) { rrenkert@5310: File shapeLines = new File(artifactDir, HWS_SHAPEFILE_LINES); rrenkert@5310: successLines = GeometryUtils.writeShapefile( rrenkert@5310: shapeLines, lineType, collectionLines); rrenkert@5310: } rrenkert@5310: rrenkert@5310: FeatureCollection collectionPoints = FeatureCollections.newCollection(); rrenkert@5310: SimpleFeatureType pointType = null; rrenkert@5310: for (HWS h : selectedPoints) { rrenkert@5310: pointType = h.getFeatureType(); rrenkert@5310: collectionPoints.add(h.getFeature()); rrenkert@5310: } rrenkert@5310: boolean successPoints = false; rrenkert@5310: if (pointType != null && collectionPoints.size() > 0) { rrenkert@5310: File shapePoints = new File(artifactDir, HWS_SHAPEFILE_POINTS); rrenkert@5310: successPoints =GeometryUtils.writeShapefile( rrenkert@5310: shapePoints, pointType, collectionPoints); rrenkert@5310: } rrenkert@5310: rrenkert@5310: if (successLines) { rrenkert@5310: createMapfile( rrenkert@5310: artifact, rrenkert@5310: artifactDir, rrenkert@5310: MapfileGenerator.MS_LAYER_PREFIX + "hws-lines", rrenkert@5310: HWS_SHAPEFILE_LINES, rrenkert@5310: "LINE", rrenkert@5310: "31467", rrenkert@5310: "hws"); rrenkert@5310: } rrenkert@5310: if (successPoints) { rrenkert@5310: createMapfile( rrenkert@5310: artifact, rrenkert@5310: artifactDir, rrenkert@5310: MapfileGenerator.MS_LAYER_PREFIX + "hws-points", rrenkert@5310: HWS_SHAPEFILE_POINTS, rrenkert@5310: "POINT", rrenkert@5310: "31467", rrenkert@5310: "hws"); rrenkert@5310: } rrenkert@5310: rrenkert@5310: String userRgd = artifact.getDataAsString("uesk.user-rgd"); rrenkert@5310: if (!userRgd.equals("none")) { rrenkert@5310: if (extractUserShp(artifactDir)) { rrenkert@5310: try { rrenkert@5310: ShapefileDataStore store = new ShapefileDataStore( rrenkert@5310: new File(artifactDir.getCanonicalPath() + rrenkert@5310: "/" + USER_RGD_SHAPE) rrenkert@5310: .toURI().toURL()); rrenkert@5310: GeometryDescriptor desc = rrenkert@5310: store.getSchema().getGeometryDescriptor(); rrenkert@5310: String type = desc.getType().getName().toString(); rrenkert@5310: String proj = rrenkert@5310: desc.getCoordinateReferenceSystem(). rrenkert@5310: getCoordinateSystem().toString(); rrenkert@5310: int pos1 = proj.indexOf("EPSG\",\""); rrenkert@5310: int pos2 = proj.indexOf("\"]]"); rrenkert@5310: String epsg = ""; rrenkert@5310: if (pos1 >= 0 && pos2 >= 0) { rrenkert@5310: epsg = rrenkert@5310: proj.substring(proj.indexOf("EPSG\",\"") + 7, rrenkert@5310: proj.indexOf("\"]]")); rrenkert@5310: } rrenkert@5310: else { rrenkert@5310: logger.warn("Could not read EPSG code from shapefile."); rrenkert@5310: return null; rrenkert@5310: } rrenkert@5310: if (type.contains("Line")) { rrenkert@5310: type = "LINE"; rrenkert@5310: } rrenkert@5310: else if (type.contains("Poly")) { aheinecke@5394: type = "POLYGON"; rrenkert@5310: } rrenkert@5310: else { rrenkert@5310: type = "POINT"; rrenkert@5310: } rrenkert@5310: createMapfile( rrenkert@5310: artifact, rrenkert@5310: artifactDir, rrenkert@5310: MapfileGenerator.MS_LAYER_PREFIX + USER_RGD_FILENAME, rrenkert@5310: USER_RGD_SHAPE, rrenkert@5310: type, rrenkert@5310: epsg, rrenkert@5310: "user-rgd"); rrenkert@5310: } rrenkert@5310: catch (IOException e) { rrenkert@5310: logger.warn("No mapfile for user-rgd created!"); rrenkert@5310: } rrenkert@5310: } rrenkert@5310: } rrenkert@5310: return null; rrenkert@5310: } rrenkert@5310: rrenkert@5310: private boolean extractUserShp(File dir) { rrenkert@5310: // TODO Auto-generated method stub rrenkert@5310: File archive = new File(dir, USER_RGD_ZIP); rrenkert@5310: boolean exists = archive.exists(); rrenkert@5310: logger.debug("Zip file exists: " + exists); rrenkert@5310: if (exists) { rrenkert@5310: try { rrenkert@5310: File tmpDir = new File(dir, "usr_tmp"); rrenkert@5310: FileTools.extractArchive(archive, tmpDir); rrenkert@5310: moveFiles(tmpDir, dir); rrenkert@5310: return true; rrenkert@5310: } rrenkert@5310: catch (IOException ioe) { rrenkert@5310: logger.warn("Zip archive " + dir + "/" rrenkert@5310: + USER_RGD_ZIP + " could not be extracted."); rrenkert@5310: return false; rrenkert@5310: } rrenkert@5310: } rrenkert@5310: return false; rrenkert@5310: } rrenkert@5310: rrenkert@5310: private void moveFiles(File source, final File target) rrenkert@5310: throws IOException rrenkert@5310: { rrenkert@5310: if (!source.exists()) { rrenkert@5310: return; rrenkert@5310: } rrenkert@5310: if (!target.exists()) { rrenkert@5310: target.mkdir(); rrenkert@5310: } rrenkert@5310: FileTools.walkTree(source, new FileTools.FileVisitor() { rrenkert@5310: @Override rrenkert@5310: public boolean visit(File file) { rrenkert@5310: if (!file.isDirectory()) { rrenkert@5310: String name = file.getName(); rrenkert@5310: String suffix = ""; rrenkert@5310: int pos = name.lastIndexOf('.'); rrenkert@5310: if (pos > 0 && pos < name.length() - 1) { rrenkert@5310: suffix = name.substring(pos + 1); rrenkert@5310: } rrenkert@5310: else { rrenkert@5310: return true; rrenkert@5310: } rrenkert@5310: try { rrenkert@5310: FileTools.copyFile(file, new File(target, USER_RGD_FILENAME + "." + suffix)); rrenkert@5310: } rrenkert@5310: catch (IOException ioe) { rrenkert@5310: logger.warn ("Error while copying file " + file.getName()); rrenkert@5310: return true; rrenkert@5310: } rrenkert@5310: } rrenkert@5310: return true; rrenkert@5310: } rrenkert@5310: }); rrenkert@5310: rrenkert@5310: FileTools.deleteRecursive(source); rrenkert@5310: } rrenkert@5310: rrenkert@5310: private void createMapfile( rrenkert@5310: FLYSArtifact artifact, rrenkert@5310: File artifactDir, rrenkert@5310: String name, rrenkert@5310: String hwsShapefile, rrenkert@5310: String type, rrenkert@5310: String srid, rrenkert@5310: String group rrenkert@5310: ) { rrenkert@5310: LayerInfo info = new LayerInfo(); rrenkert@5310: info.setName(name + artifact.identifier()); rrenkert@5310: info.setType(type); rrenkert@5310: info.setDirectory(artifact.identifier()); rrenkert@5310: info.setTitle(name); rrenkert@5310: info.setData(hwsShapefile); rrenkert@5310: info.setSrid(srid); rrenkert@5310: info.setGroupTitle(group); rrenkert@5310: MapfileGenerator generator = new ArtifactMapfileGenerator(); rrenkert@5310: Template tpl = generator.getTemplateByName(MapfileGenerator.SHP_LAYER_TEMPLATE); rrenkert@5310: try { rrenkert@5310: File layer = new File(artifactDir.getCanonicalPath() + "/" + name); rrenkert@5310: generator.writeLayer(info, layer, tpl); rrenkert@5310: List layers = new ArrayList(); rrenkert@5310: layers.add(layer.getAbsolutePath()); rrenkert@5310: generator.generate(); rrenkert@5310: } rrenkert@5310: catch(FileNotFoundException fnfe) { rrenkert@5310: logger.warn("Could not find mapfile for hws layer"); rrenkert@5310: } rrenkert@5310: catch (Exception ioe) { rrenkert@5310: logger.warn("Could not create mapfile for hws layer"); rrenkert@5310: logger.warn(Arrays.toString(ioe.getStackTrace())); rrenkert@5310: } rrenkert@5310: } rrenkert@5310: rrenkert@5310: rrenkert@5310: @Override rrenkert@5310: public void endOfLife(Artifact artifact, Object callContext) { rrenkert@5310: super.endOfLife(artifact, callContext); rrenkert@5310: logger.info("ScenarioSelect.endOfLife: " + artifact.identifier()); rrenkert@5310: rrenkert@5310: FLYSArtifact flys = (FLYSArtifact) artifact; rrenkert@5310: removeDirectory(flys); rrenkert@5310: } rrenkert@5310: rrenkert@5310: rrenkert@5310: /** rrenkert@5310: * Removes the directory and all its content where the required data and the rrenkert@5310: * results of WSPLGEN are stored. Should be called in endOfLife(). rrenkert@5310: */ rrenkert@5310: // FIXME: I've seen this code somewhere else... rrenkert@5310: protected void removeDirectory(FLYSArtifact artifact) { rrenkert@5310: String shapePath = FLYSUtils.getXPathString( rrenkert@5310: FLYSUtils.XPATH_FLOODMAP_SHAPEFILE_DIR); rrenkert@5310: rrenkert@5310: File artifactDir = new File(shapePath, artifact.identifier()); rrenkert@5310: rrenkert@5310: if (artifactDir.exists()) { rrenkert@5310: logger.debug("Delete directory: " + artifactDir.getAbsolutePath()); rrenkert@5310: boolean success = FileTools.deleteRecursive(artifactDir); rrenkert@5310: if (!success) { rrenkert@5310: logger.warn("could not remove dir '" + artifactDir + "'"); rrenkert@5310: } rrenkert@5310: } rrenkert@5310: else { rrenkert@5310: logger.debug("There is no directory to remove."); rrenkert@5310: } rrenkert@5310: } rrenkert@5310: rrenkert@5310: /** rrenkert@5310: * Returns (and creates if not existing) the directory for storing WSPLEN rrenkert@5310: * data for the owner artifact. rrenkert@5310: * rrenkert@5310: * @param artifact The owner Artifact. rrenkert@5310: * rrenkert@5310: * @return the directory for WSPLEN data. rrenkert@5310: */ rrenkert@5310: protected File getDirectory(FLYSArtifact artifact) { rrenkert@5310: String shapePath = FLYSUtils.getXPathString( rrenkert@5310: FLYSUtils.XPATH_FLOODMAP_SHAPEFILE_DIR); rrenkert@5310: rrenkert@5310: File artifactDir = FileTools.getDirectory( rrenkert@5310: shapePath, artifact.identifier()); rrenkert@5310: rrenkert@5310: return artifactDir; rrenkert@5310: } rrenkert@5310: rrenkert@5310: } teichmann@5313: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :