package org.gcube.dataanalysis.geo.algorithms; import java.io.File; import java.sql.Connection; import java.sql.DriverManager; import java.util.List; import java.util.UUID; import org.gcube.dataanalysis.ecoengine.configuration.AlgorithmConfiguration; import org.gcube.dataanalysis.ecoengine.datatypes.PrimitiveType; import org.gcube.dataanalysis.ecoengine.datatypes.PrimitiveTypesList; import org.gcube.dataanalysis.ecoengine.datatypes.ServiceType; import org.gcube.dataanalysis.ecoengine.datatypes.enumtypes.PrimitiveTypes; import org.gcube.dataanalysis.ecoengine.datatypes.enumtypes.ServiceParameters; import org.gcube.dataanalysis.ecoengine.interfaces.StandardLocalInfraAlgorithm; import org.gcube.dataanalysis.ecoengine.utils.ZipTools; import org.gcube.dataanalysis.geo.meta.PolyMapMetadata; import org.gcube.dataanalysis.geo.utils.GdalConverter; import org.gcube.dataanalysis.geo.utils.GeospatialDataPublicationLevel; import org.gcube.spatial.data.gis.model.report.PublishResponse; public class ShapefilePublisher extends StandardLocalInfraAlgorithm{ private static String layerTitleParam = "MapTitle"; private static String layerAbstractParam = "MapAbstract"; private static String FileParam = "ShapeFileZip"; private static String ShapeFileParam = "ShapeFileName"; private static String TopicsParam = "Topics"; private static String DBUserParam = "DBUser"; private static String DBPasswordParam = "DBPassword"; private static String DBUrlParameter = "DBUrl"; static String publicationLevel= "PublicationLevel"; @Override public void init() throws Exception { log("ShapefilePublisher->initialised"); } @Override public String getDescription() { String description = "An algorithm to publish shapefiles under WMS and WFS standards in the e-Infrastructure. The produced WMS, WFS links are reported as output of this process. The map will be available in the VRE for consultation."; return description; } //static String shapeImporting = "shp2pgsql -g the_geom -d shapefile2.shp | PGPASSWORD=d4science2 psql -h geoserver-test.d4science-ii.research-infrastructures.eu -p 5432 -U postgres timeseriesgisdb"; //static String shapeImporting = "shp2pgsql -g the_geom -d %1$s | PGPASSWORD=%2$s psql -h %3$s -p 5432 -U %4$s %5$s"; static String shapeImporting = "shp2pgsql -s 4326 -g the_geom -d %1$s public.%6$s | PGPASSWORD=%2$s psql -h %3$s -p 5432 -U %4$s %5$s"; @Override protected void process() throws Exception { status = 10; //collect information String databaseJdbc = getInputParameter(DBUrlParameter); String databaseUser = getInputParameter(DBUserParam); String databasePwd = getInputParameter(DBPasswordParam); //get the shapefile and extract the zip file String zipFile = getInputParameter(FileParam); String shapeFileName = getInputParameter(ShapeFileParam); String layerName = getInputParameter(layerTitleParam); String layerAbstract = getInputParameter(layerAbstractParam); String topics = getInputParameter(TopicsParam); String username = getInputParameter("ServiceUserName"); String publicationLevelValue = getInputParameter(publicationLevel); log("ShapefilePublisher->"+databasePwd); log("ShapefilePublisher->Parameters:"); log("ShapefilePublisher->zipFile:"+zipFile); log("ShapefilePublisher->shapeFileName:"+shapeFileName); log("ShapefilePublisher->layerName:"+layerName); log("ShapefilePublisher->layerAbstract:"+layerAbstract); log("ShapefilePublisher->topics:"+topics); log("ShapefilePublisher->databaseJdbc:"+databaseJdbc); log("ShapefilePublisher->databaseUser:"+databaseUser); log("ShapefilePublisher->service user name:"+username); if (topics == null || topics.trim().length()==0) throw new Exception("Error topics missing!"); File tempFolder = new File(config.getConfigPath(),""+UUID.randomUUID()); log("ShapefilePublisher->Creating temp folder "+tempFolder); boolean created = tempFolder.mkdir(); log("ShapefilePublisher->Temp Folder creation check "+created); log("ShapefilePublisher->unzipping file :"+zipFile+" in folder "+tempFolder.getAbsolutePath()); ZipTools.unZip(zipFile, tempFolder.getAbsolutePath()); // parse a string like this: // jdbc:postgresql://geoserver-test.d4science-ii.research-infrastructures.eu:5432/timeseriesgisdb String databaseName = databaseJdbc.substring(databaseJdbc.lastIndexOf("/")+1); String databaseAddress = databaseJdbc.substring(databaseJdbc.indexOf("//")+2,databaseJdbc.lastIndexOf(":")); log("ShapefilePublisher->Parsed database Info:"+databaseName+" ["+databaseAddress+"]"); String shapefile = new File (tempFolder,shapeFileName).getAbsolutePath(); log("ShapefilePublisher->Shape file to search for:"+shapefile); String gisTableName = shapeFileName; String gisRandomTableName = ("shp_"+UUID.randomUUID()).replace("-", ""); try{ gisTableName = shapeFileName.substring(0,shapeFileName.lastIndexOf(".")); }catch(Exception e){ throw new Exception("Error - Wrong file name "+shapeFileName); } log("ShapefilePublisher->Original table name :"+gisTableName); log("ShapefilePublisher->Table name to produce :"+gisRandomTableName); String shapeImportCommand = String.format(shapeImporting, shapefile, databasePwd, databaseAddress, databaseUser, databaseName,gisRandomTableName); log("ShapefilePublisher->Shape file command:"+shapeImportCommand); //run the importer status = 50; List commandsExecuted = GdalConverter.command(shapeImportCommand, tempFolder.getAbsolutePath()); String commandExecuted = commandsExecuted.toString(); log("ShapefilePublisher->Command executed output:"+commandExecuted); //check for the import to be success if (!commandExecuted.contains("COMMIT")){ throw new Exception("An error occurred when importing the file "+commandExecuted); } log("ShapefilePublisher->Publishing the table "+gisRandomTableName); String scope = config.getGcubeScope(); double resolution = 0; String datastore = "timeseriesws"; String defaultStyle = "polygon"; String workspace = "aquamaps"; String purpose = "To Publish Geometric Layers for user-provided Vector Maps"; String credits = "Generated via the DataMiner Service"; String keywords = topics.replace(AlgorithmConfiguration.listSeparator, ","); boolean isprivate = false; if (GeospatialDataPublicationLevel.valueOf(publicationLevelValue)==GeospatialDataPublicationLevel.PRIVATE) isprivate=true; PublishResponse response = null; try{ response = PolyMapMetadata.publishTable(scope, gisRandomTableName, resolution, username, layerName, defaultStyle, workspace, datastore, purpose, credits, keywords, isprivate); }catch(Exception e){ e.printStackTrace(); log ("ShapefilePublisher->Error during table publication: "+e.getLocalizedMessage()); throw new Exception("Error during the publication of the shapefile on the SDI"); } log("ShapefilePublisher->Finished publishing the table"); if (response == null) { log("ShapefilePublisher->Error in generating map"); throw new Exception("Impossible to publish on GeoNetwork or GeoServer this table: " + gisRandomTableName+" possibly it is already present!"); } else { //writing output addOutputString("GIS map title", layerName); addOutputString("GIS map UUID", "" + response.getPublishedMetadata().getFileIdentifier()); addOutputString("GIS Table ", gisRandomTableName); addOutputString("Generated by ", username); addOutputString("Resolution", "" + resolution); addOutputString("Style", "" + defaultStyle); addOutputString("Keyword", "" + topics); } log("ShapefilePublisher->Output produced:"+outputParameters); log("ShapefilePublisher->All done!"); status = 100; } @Override protected void setInputParameters() { try { PrimitiveType e = new PrimitiveType(Enum.class.getName(), GeospatialDataPublicationLevel.values(), PrimitiveTypes.ENUMERATED, publicationLevel, "The visibility level of the produced map",""+GeospatialDataPublicationLevel.PRIVATE); inputs.add(e); addStringInput(layerTitleParam, "Title of the geospatial dataset to be shown on GeoExplorer", "Generic Vector Layer"); addStringInput(ShapeFileParam, "Name of the shape file inside the zip", "shapefile.shp"); addStringInput(layerAbstractParam, "Abstract defining the content, the references and usage policies", "Abstract"); inputs.add(new PrimitiveType(File.class.getName(), null, PrimitiveTypes.FILE, FileParam, "Shapefile zip file to process")); inputs.add(new PrimitiveTypesList(String.class.getName(), PrimitiveTypes.STRING, TopicsParam, "Topics to be attached to the published dataset. E.g. Biodiversity, D4Science, Environment, Weather", false)); inputs.add(new ServiceType(ServiceParameters.USERNAME,"ServiceUserName","The final user Name")); addRemoteDatabaseInput("UsersGisTablesDB", DBUrlParameter,DBUserParam,DBPasswordParam, "driver", "dialect"); } catch (Throwable e) { e.printStackTrace(); } } @Override public void shutdown() { } }