268 lines
10 KiB
Java
268 lines
10 KiB
Java
package org.gcube.dataanalysis.geo.algorithms;
|
|
|
|
import it.cnr.aquamaps.CSquare;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
|
|
import org.gcube.common.scope.api.ScopeProvider;
|
|
import org.gcube.dataanalysis.ecoengine.configuration.AlgorithmConfiguration;
|
|
import org.gcube.dataanalysis.ecoengine.interfaces.StandardLocalExternalAlgorithm;
|
|
import org.gcube.dataanalysis.ecoengine.utils.DatabaseFactory;
|
|
import org.gcube.dataanalysis.ecoengine.utils.DatabaseUtils;
|
|
import org.gcube.dataanalysis.geo.meta.PolyMapMetadata;
|
|
import org.gcube.spatial.data.gis.model.report.PublishResponse;
|
|
import org.hibernate.SessionFactory;
|
|
|
|
import scala.collection.Iterator;
|
|
|
|
public abstract class MapsCreator extends StandardLocalExternalAlgorithm {
|
|
|
|
static String databaseParameterName = "TimeSeriesDataStore";
|
|
static String dbuserParameterName = "user";
|
|
static String dbpasswordParameterName = "password";
|
|
static String dburlParameterName = "STOREURL";
|
|
|
|
static String inputTableParameter = "InputTable";
|
|
static String outputTableParameter = "OutputTable";
|
|
static String xParameter = "xDimension";
|
|
static String yParameter = "yDimension";
|
|
static String csquareParameter = "csquaresDimension";
|
|
|
|
static String probabilityParameter = "Probability";
|
|
static String infoParameter = "Info";
|
|
static String resolutionParameter = "Resolution";
|
|
static String layerNameParameter = "MapName";
|
|
static int maxNPoints = 259000;
|
|
SessionFactory gisdbconnection = null;
|
|
SessionFactory smdbconnection = null;
|
|
|
|
private static String createProbTable = "create table %1$s (geomid serial, x real, y real, probability real);";
|
|
private static String columnsProbNames = " geomid, x , y, probability, the_geom";
|
|
|
|
private static String createInfoTable = "create table %1$s (geomid serial, x real, y real, info character varying);";
|
|
private static String columnsInfoNames = " geomid, x , y, info, the_geom";
|
|
|
|
private static String addGeometryColumn = "Select AddGeometryColumn('%1$s','the_geom',4326,'POLYGON',2);";
|
|
static String makeSquare = "ST_GeomFromText('POLYGON((%1$s ,%2$s, %3$s, %4$s, %1$s))',4326)";
|
|
|
|
//changeable parameters for application purposes
|
|
String datastore = "";
|
|
String defaultStyle = "";
|
|
String workspace = "";
|
|
String username = "";
|
|
String purpose = "";
|
|
String credits = "";
|
|
String keyword = "";
|
|
|
|
@Override
|
|
public String getDescription() {
|
|
return "A transducer algorithm to produce a GIS map either from a probability distribution or from a set of points. A maximum of " + maxNPoints + " is allowed";
|
|
}
|
|
|
|
@Override
|
|
public abstract void init() throws Exception;
|
|
|
|
@Override
|
|
protected void process() throws Exception {
|
|
try {
|
|
log("Beginning process");
|
|
log("Set scope from outside:"+config.getGcubeScope());
|
|
String scope = config.getGcubeScope();
|
|
if (scope == null)
|
|
scope = ScopeProvider.instance.get();
|
|
log("Using scope:"+scope);
|
|
//initialize Gis DB parameters
|
|
String databaseJdbc = getInputParameter(dburlParameterName);
|
|
String databaseUser = getInputParameter(dbuserParameterName);
|
|
String databasePwd = getInputParameter(dbpasswordParameterName);
|
|
log("GIS Database Parameters to use: " + databaseJdbc + " , " + databaseUser);
|
|
//getting resolution
|
|
String res$ = config.getParam(resolutionParameter);
|
|
double resolution = res$!=null?Double.parseDouble(res$):0;
|
|
//connection to the GIS DB
|
|
log("Connecting to gisDB...");
|
|
AlgorithmConfiguration gisconfig = new AlgorithmConfiguration();
|
|
gisconfig.setParam("DatabaseDriver", "org.postgresql.Driver");
|
|
gisconfig.setParam("DatabaseURL", "jdbc:postgresql://geoserver-test.d4science-ii.research-infrastructures.eu/timeseriesgisdb");
|
|
gisconfig.setParam("DatabaseUserName", databaseUser);
|
|
gisconfig.setParam("DatabasePassword", databasePwd);
|
|
gisconfig.setConfigPath(config.getConfigPath());
|
|
gisdbconnection = DatabaseUtils.initDBSession(gisconfig);
|
|
log("Initialized gisDBConnection!");
|
|
|
|
// connect to the SM DB
|
|
smdbconnection = DatabaseUtils.initDBSession(config);
|
|
log("Initialized SMDBConnection!");
|
|
|
|
//select info to attach
|
|
String infoPar = config.getParam(probabilityParameter);
|
|
if (infoPar == null)
|
|
infoPar = config.getParam(infoParameter);
|
|
// points retrieval
|
|
List<Object> points = null;
|
|
log("Retrieving points..");
|
|
if (config.getParam(xParameter) != null && config.getParam(yParameter) != null) {
|
|
log("..from coordinates");
|
|
// select the points from the SM DB up to a maximum of 190000 points
|
|
points = DatabaseFactory.executeSQLQuery("select " + config.getParam(xParameter) + "," + config.getParam(yParameter) + "," +infoPar + " from " + config.getParam(inputTableParameter) + " limit " + maxNPoints, smdbconnection);
|
|
}
|
|
//points from csquares
|
|
else if (config.getParam(csquareParameter)!=null){
|
|
log("..from csquares");
|
|
String queryCsquare = "select " + config.getParam(csquareParameter) + "," + infoPar +" from " + config.getParam(inputTableParameter) + " limit " + maxNPoints;
|
|
List<Object> csquares= DatabaseFactory.executeSQLQuery(queryCsquare, smdbconnection);
|
|
points = new ArrayList<Object>();
|
|
//build points from csquares
|
|
for (Object csquare:csquares){
|
|
Object[] csquareandprob = (Object[]) csquare;
|
|
CSquare c = it.cnr.aquamaps.CSquare.apply(""+csquareandprob[0]);
|
|
if (resolution==0)
|
|
resolution=c.size();
|
|
// x,y
|
|
Iterator<Object> iterator = c.center().valuesIterator();
|
|
String x = ""+iterator.next();
|
|
String y = ""+iterator.next();
|
|
String prob = ""+csquareandprob[1];
|
|
Object[] pair = {x,y,prob};
|
|
points.add(pair);
|
|
}
|
|
log("Points built from csquares!");
|
|
}
|
|
//GIS Table creation
|
|
log("Creating GIS table");
|
|
String gisTableName = "stat" + UUID.randomUUID().toString().replace("-", "");
|
|
|
|
String createTable$ = String.format(createProbTable, gisTableName);
|
|
String columnNames$ = columnsProbNames;
|
|
if (config.getParam(probabilityParameter)==null){
|
|
createTable$ = String.format(createInfoTable, gisTableName);
|
|
columnNames$=columnsInfoNames;
|
|
}
|
|
log(createTable$);
|
|
//drop previous table
|
|
try {
|
|
DatabaseFactory.executeSQLUpdate(DatabaseUtils.dropTableStatement(gisTableName), gisdbconnection);
|
|
} catch (Exception e) {
|
|
log("Impossible to drop table:" + e.getLocalizedMessage());
|
|
}
|
|
//table creation
|
|
DatabaseFactory.executeSQLUpdate(createTable$, gisdbconnection);
|
|
DatabaseFactory.executeSQLQuery(String.format(addGeometryColumn, gisTableName), gisdbconnection);
|
|
log("Fulfilling elements");
|
|
log("Resolution:" + resolution);
|
|
//points fulfilling
|
|
List<String[]> values = new ArrayList<String[]>();
|
|
int i = 0;
|
|
for (Object point : points) {
|
|
Object[] elements = (Object[]) point;
|
|
double x = Double.parseDouble("" + elements[0]);
|
|
double y = Double.parseDouble("" + elements[1]);
|
|
String probS = "" + elements[2];
|
|
double x1 = x - resolution;
|
|
double x2 = x + resolution;
|
|
double y1 = y - resolution;
|
|
double y2 = y + resolution;
|
|
String square = String.format(makeSquare, "" + x1 + " " + y1, x1 + " " + y2, x2 + " " + y2, x2 + " " + y1);
|
|
// System.out.println(square);
|
|
String[] selements = { "" + i, "" + x, "" + y, probS,square };
|
|
values.add(selements);
|
|
i++;
|
|
}
|
|
log("Writing chunks");
|
|
// write chunks into the DB
|
|
insertGeoChunksIntoTable(gisTableName, columnNames$, values, 5000, gisdbconnection);
|
|
log("Publishing Table");
|
|
String usernameP = config.getParam("ServiceUserName");
|
|
if (usernameP != null)
|
|
username = usernameP;
|
|
|
|
String layerName = config.getParam(layerNameParameter);
|
|
PublishResponse response = PolyMapMetadata.publishTable(scope, gisTableName, resolution, username, layerName, defaultStyle, workspace, datastore, purpose, credits, keyword);
|
|
//analyzing response
|
|
if (response == null) {
|
|
log("Error in generating map - dropping gis table");
|
|
try {
|
|
DatabaseFactory.executeSQLUpdate(DatabaseUtils.dropTableStatement(gisTableName), gisdbconnection);
|
|
log("gis table dropped");
|
|
} catch (Exception e) {
|
|
log("Impossible to drop table:" + e.getLocalizedMessage());
|
|
}
|
|
throw new Exception("Impossible to publish on GeoNetwork or GeoServer: " + gisTableName);
|
|
} else {
|
|
//writing output
|
|
addOutputString("GIS map title", layerName);
|
|
addOutputString("GIS map UUID", "" + response.getPublishedMetadata().getFileIdentifier());
|
|
addOutputString("Associated Geospatial Table", gisTableName);
|
|
addOutputString("Generated by ", username);
|
|
addOutputString("Resolution", "" + resolution);
|
|
addOutputString("Style", "" + defaultStyle);
|
|
addOutputString("Keyword", "" + keyword);
|
|
}
|
|
log("Output:"+outputParameters);
|
|
log("All Done!");
|
|
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
throw e;
|
|
} finally {
|
|
if (smdbconnection != null)
|
|
DatabaseUtils.closeDBConnection(smdbconnection);
|
|
if (gisdbconnection != null)
|
|
DatabaseUtils.closeDBConnection(gisdbconnection);
|
|
}
|
|
|
|
}
|
|
|
|
public static void insertGeoChunksIntoTable(String table, String columnsNames, List<String[]> values, int chunkSize,SessionFactory dbconnection) throws Exception{
|
|
int valuesize = values.size();
|
|
StringBuffer sb = new StringBuffer();
|
|
int stopIndex =0;
|
|
for (int i=0;i<valuesize;i++){
|
|
String[] row = values.get(i);
|
|
sb.append("(");
|
|
for (int j=0;j<row.length-1;j++){
|
|
String preprow = row[j].replaceAll("^'", "").replaceAll("'$", "");
|
|
preprow=preprow.replace("'", ""+(char)96);
|
|
sb.append("'"+preprow+"'");
|
|
sb.append(",");
|
|
}
|
|
//append geometry
|
|
sb.append(row[row.length-1]);
|
|
sb.append(")");
|
|
if (stopIndex>0 && stopIndex%chunkSize==0){
|
|
DatabaseFactory.executeSQLUpdate(DatabaseUtils.insertFromBuffer(table, columnsNames, sb), dbconnection);
|
|
stopIndex=chunkSize;
|
|
sb = new StringBuffer();
|
|
}
|
|
else if (i<valuesize-1)
|
|
sb.append(",");
|
|
}
|
|
|
|
if (stopIndex<valuesize-1){
|
|
if (sb.length()>0){
|
|
try{
|
|
DatabaseFactory.executeSQLUpdate(DatabaseUtils.insertFromBuffer(table, columnsNames, sb), dbconnection);
|
|
}catch(Exception e){
|
|
System.out.println("Query:"+sb);
|
|
throw e;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
public void shutdown() {
|
|
log("shutdown invoked!");
|
|
}
|
|
|
|
@Override
|
|
protected abstract void setInputParameters();
|
|
|
|
|
|
|
|
}
|