2013-11-15 19:11:40 +01:00
package org.gcube.dataanalysis.geo.algorithms ;
import it.cnr.aquamaps.CSquare ;
import java.util.ArrayList ;
import java.util.List ;
import java.util.UUID ;
2013-11-19 12:32:56 +01:00
import org.gcube.common.scope.api.ScopeProvider ;
2013-11-15 19:11:40 +01:00
import org.gcube.dataanalysis.ecoengine.configuration.AlgorithmConfiguration ;
2016-09-27 18:00:11 +02:00
import org.gcube.dataanalysis.ecoengine.interfaces.StandardLocalInfraAlgorithm ;
2013-11-15 19:11:40 +01:00
import org.gcube.dataanalysis.ecoengine.utils.DatabaseFactory ;
import org.gcube.dataanalysis.ecoengine.utils.DatabaseUtils ;
2013-11-18 19:25:01 +01:00
import org.gcube.dataanalysis.geo.meta.PolyMapMetadata ;
2016-06-14 12:47:46 +02:00
import org.gcube.dataanalysis.geo.utils.GeospatialDataPublicationLevel ;
2013-11-15 19:11:40 +01:00
import org.gcube.spatial.data.gis.model.report.PublishResponse ;
2017-05-25 16:50:11 +02:00
import org.gcube.spatial.data.gis.model.report.Report.OperationState ;
2013-11-15 19:11:40 +01:00
import org.hibernate.SessionFactory ;
import scala.collection.Iterator ;
2016-09-27 18:00:11 +02:00
public abstract class MapsCreator extends StandardLocalInfraAlgorithm {
2013-11-15 19:11:40 +01:00
2013-11-18 19:25:01 +01:00
static String databaseParameterName = " TimeSeriesDataStore " ;
2013-11-15 19:11:40 +01:00
static String dbuserParameterName = " user " ;
static String dbpasswordParameterName = " password " ;
2013-11-18 19:25:01 +01:00
static String dburlParameterName = " STOREURL " ;
2013-11-15 19:11:40 +01:00
static String inputTableParameter = " InputTable " ;
static String outputTableParameter = " OutputTable " ;
static String xParameter = " xDimension " ;
static String yParameter = " yDimension " ;
static String csquareParameter = " csquaresDimension " ;
static String probabilityParameter = " Probability " ;
2013-11-18 19:25:01 +01:00
static String infoParameter = " Info " ;
2013-11-15 19:11:40 +01:00
static String resolutionParameter = " Resolution " ;
static String layerNameParameter = " MapName " ;
2016-06-14 12:47:46 +02:00
static String publicationLevel = " PublicationLevel " ;
2013-11-18 19:25:01 +01:00
static int maxNPoints = 259000 ;
2013-11-15 19:11:40 +01:00
SessionFactory gisdbconnection = null ;
SessionFactory smdbconnection = null ;
2013-11-18 19:25:01 +01:00
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 " ;
2013-11-15 19:11:40 +01:00
private static String addGeometryColumn = " Select AddGeometryColumn('%1$s','the_geom',4326,'POLYGON',2); " ;
2014-09-29 17:04:38 +02:00
private static String addPointsColumn = " Select AddGeometryColumn('%1$s','the_geom',4326,'POINT',2); " ;
2013-11-18 19:25:01 +01:00
static String makeSquare = " ST_GeomFromText('POLYGON((%1$s ,%2$s, %3$s, %4$s, %1$s))',4326) " ;
2014-09-29 17:04:38 +02:00
static String makePoint = " ST_GeomFromText('POINT(%1$s %2$s)',4326) " ;
// static String makePoint = "ST_SetSRID(ST_MakePoint((%1$s,%2$s),4326)";
2013-11-18 19:25:01 +01:00
//changeable parameters for application purposes
String datastore = " " ;
String defaultStyle = " " ;
String workspace = " " ;
String username = " " ;
String purpose = " " ;
String credits = " " ;
String keyword = " " ;
@Override
2013-11-15 19:11:40 +01:00
public String getDescription ( ) {
2013-11-19 14:26:33 +01:00
return " A transducer algorithm to produce a GIS map from a probability distribution or from a set of points. A maximum of " + maxNPoints + " is allowed " ;
2013-11-15 19:11:40 +01:00
}
@Override
2013-11-18 19:25:01 +01:00
public abstract void init ( ) throws Exception ;
2013-11-15 19:11:40 +01:00
@Override
protected void process ( ) throws Exception {
try {
2013-11-19 14:26:33 +01:00
status = 0 ;
2013-11-15 19:11:40 +01:00
log ( " Beginning process " ) ;
2013-11-19 12:32:56 +01:00
log ( " Set scope from outside: " + config . getGcubeScope ( ) ) ;
String scope = config . getGcubeScope ( ) ;
if ( scope = = null )
scope = ScopeProvider . instance . get ( ) ;
log ( " Using scope: " + scope ) ;
2016-06-14 12:47:46 +02:00
String publicationLevelValue = getInputParameter ( publicationLevel ) ;
log ( " Publication Level: " + publicationLevelValue ) ;
boolean isprivate = false ;
if ( GeospatialDataPublicationLevel . valueOf ( publicationLevelValue ) = = GeospatialDataPublicationLevel . PRIVATE )
isprivate = true ;
2013-11-18 19:25:01 +01:00
//initialize Gis DB parameters
2013-11-15 19:11:40 +01:00
String databaseJdbc = getInputParameter ( dburlParameterName ) ;
String databaseUser = getInputParameter ( dbuserParameterName ) ;
String databasePwd = getInputParameter ( dbpasswordParameterName ) ;
log ( " GIS Database Parameters to use: " + databaseJdbc + " , " + databaseUser ) ;
2013-11-18 19:25:01 +01:00
//getting resolution
String res$ = config . getParam ( resolutionParameter ) ;
double resolution = res$ ! = null ? Double . parseDouble ( res$ ) : 0 ;
//connection to the GIS DB
2013-11-15 19:11:40 +01:00
log ( " Connecting to gisDB... " ) ;
AlgorithmConfiguration gisconfig = new AlgorithmConfiguration ( ) ;
gisconfig . setParam ( " DatabaseDriver " , " org.postgresql.Driver " ) ;
2013-11-19 16:20:44 +01:00
/ *
2013-11-15 19:11:40 +01:00
gisconfig . setParam ( " DatabaseURL " , " jdbc:postgresql://geoserver-test.d4science-ii.research-infrastructures.eu/timeseriesgisdb " ) ;
gisconfig . setParam ( " DatabaseUserName " , databaseUser ) ;
gisconfig . setParam ( " DatabasePassword " , databasePwd ) ;
2013-11-19 16:20:44 +01:00
* /
gisconfig . setParam ( " DatabaseURL " , databaseJdbc ) ;
gisconfig . setParam ( " DatabaseUserName " , databaseUser ) ;
gisconfig . setParam ( " DatabasePassword " , databasePwd ) ;
2013-11-15 19:11:40 +01:00
gisconfig . setConfigPath ( config . getConfigPath ( ) ) ;
gisdbconnection = DatabaseUtils . initDBSession ( gisconfig ) ;
log ( " Initialized gisDBConnection! " ) ;
2013-11-19 14:26:33 +01:00
status = 10 ;
2013-11-15 19:11:40 +01:00
// connect to the SM DB
smdbconnection = DatabaseUtils . initDBSession ( config ) ;
log ( " Initialized SMDBConnection! " ) ;
2013-11-18 19:25:01 +01:00
//select info to attach
String infoPar = config . getParam ( probabilityParameter ) ;
if ( infoPar = = null )
infoPar = config . getParam ( infoParameter ) ;
2013-11-15 19:11:40 +01:00
// 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
2014-09-29 17:04:38 +02:00
String q = " select " + config . getParam ( xParameter ) + " , " + config . getParam ( yParameter ) + " , " + infoPar + " from " + config . getParam ( inputTableParameter ) + " limit " + maxNPoints ;
points = DatabaseFactory . executeSQLQuery ( q , smdbconnection ) ;
2013-11-15 19:11:40 +01:00
}
2013-11-18 19:25:01 +01:00
//points from csquares
2013-11-15 19:11:40 +01:00
else if ( config . getParam ( csquareParameter ) ! = null ) {
log ( " ..from csquares " ) ;
2013-11-18 19:25:01 +01:00
String queryCsquare = " select " + config . getParam ( csquareParameter ) + " , " + infoPar + " from " + config . getParam ( inputTableParameter ) + " limit " + maxNPoints ;
List < Object > csquares = DatabaseFactory . executeSQLQuery ( queryCsquare , smdbconnection ) ;
2013-11-15 19:11:40 +01:00
points = new ArrayList < Object > ( ) ;
//build points from csquares
for ( Object csquare : csquares ) {
2013-11-18 19:25:01 +01:00
Object [ ] csquareandprob = ( Object [ ] ) csquare ;
CSquare c = it . cnr . aquamaps . CSquare . apply ( " " + csquareandprob [ 0 ] ) ;
if ( resolution = = 0 )
resolution = c . size ( ) ;
2013-11-15 19:11:40 +01:00
// x,y
Iterator < Object > iterator = c . center ( ) . valuesIterator ( ) ;
2013-11-18 19:25:01 +01:00
String x = " " + iterator . next ( ) ;
String y = " " + iterator . next ( ) ;
String prob = " " + csquareandprob [ 1 ] ;
Object [ ] pair = { x , y , prob } ;
2013-11-15 19:11:40 +01:00
points . add ( pair ) ;
}
log ( " Points built from csquares! " ) ;
}
2013-11-18 19:25:01 +01:00
//GIS Table creation
2014-09-29 17:04:38 +02:00
2013-11-15 19:11:40 +01:00
String gisTableName = " stat " + UUID . randomUUID ( ) . toString ( ) . replace ( " - " , " " ) ;
2014-09-29 17:04:38 +02:00
log ( " Creating GIS table " + gisTableName ) ;
2013-11-19 14:26:33 +01:00
status = 30 ;
2013-11-18 19:25:01 +01:00
String createTable$ = String . format ( createProbTable , gisTableName ) ;
String columnNames$ = columnsProbNames ;
if ( config . getParam ( probabilityParameter ) = = null ) {
createTable$ = String . format ( createInfoTable , gisTableName ) ;
columnNames$ = columnsInfoNames ;
}
2013-11-15 19:11:40 +01:00
log ( createTable$ ) ;
2013-11-18 19:25:01 +01:00
//drop previous table
2013-11-15 19:11:40 +01:00
try {
DatabaseFactory . executeSQLUpdate ( DatabaseUtils . dropTableStatement ( gisTableName ) , gisdbconnection ) ;
} catch ( Exception e ) {
log ( " Impossible to drop table: " + e . getLocalizedMessage ( ) ) ;
}
2013-11-18 19:25:01 +01:00
//table creation
DatabaseFactory . executeSQLUpdate ( createTable$ , gisdbconnection ) ;
2014-09-29 17:04:38 +02:00
if ( resolution > 0 )
DatabaseFactory . executeSQLQuery ( String . format ( addGeometryColumn , gisTableName ) , gisdbconnection ) ;
else
DatabaseFactory . executeSQLQuery ( String . format ( addPointsColumn , gisTableName ) , gisdbconnection ) ;
2013-11-15 19:11:40 +01:00
log ( " Fulfilling elements " ) ;
2013-11-18 19:25:01 +01:00
log ( " Resolution: " + resolution ) ;
//points fulfilling
2013-11-15 19:11:40 +01:00
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 ] ;
2013-11-18 19:25:01 +01:00
double x1 = x - resolution ;
double x2 = x + resolution ;
2014-09-29 17:04:38 +02:00
double y1 = ( y ) - resolution ;
double y2 = ( y ) + resolution ;
String geom = " " ;
if ( resolution = = 0 )
geom = String . format ( makePoint , x , y ) ;
else
geom = String . format ( makeSquare , " " + x1 + " " + y1 , x1 + " " + y2 , x2 + " " + y2 , x2 + " " + y1 ) ;
2013-11-18 19:25:01 +01:00
// System.out.println(square);
2014-09-29 17:04:38 +02:00
String [ ] selements = { " " + i , " " + x , " " + y , probS , geom } ;
2013-11-15 19:11:40 +01:00
values . add ( selements ) ;
i + + ;
}
2013-11-19 14:26:33 +01:00
status = 50 ;
2013-11-15 19:11:40 +01:00
log ( " Writing chunks " ) ;
// write chunks into the DB
2013-11-18 19:25:01 +01:00
insertGeoChunksIntoTable ( gisTableName , columnNames$ , values , 5000 , gisdbconnection ) ;
2013-11-15 19:11:40 +01:00
log ( " Publishing Table " ) ;
2013-11-18 19:25:01 +01:00
String usernameP = config . getParam ( " ServiceUserName " ) ;
if ( usernameP ! = null )
username = usernameP ;
2013-11-15 19:11:40 +01:00
String layerName = config . getParam ( layerNameParameter ) ;
2016-06-14 12:47:46 +02:00
PublishResponse response = PolyMapMetadata . publishTable ( scope , gisTableName , resolution , username , layerName , defaultStyle , workspace , datastore , purpose , credits , keyword , isprivate ) ;
2013-11-19 14:26:33 +01:00
status = 80 ;
2013-11-18 19:25:01 +01:00
//analyzing response
2017-05-25 16:50:11 +02:00
if ( response . getMetaOperationResult ( ) ! = OperationState . COMPLETE & & response . getDataOperationResult ( ) ! = OperationState . COMPLETE ) {
log ( " Error in generating map - dropping gis table - error on data are " + response . getDataOperationMessages ( ) + " erorre on metadata are " + response . getMetaOperationMessages ( ) ) ;
2013-11-15 19:11:40 +01:00
try {
DatabaseFactory . executeSQLUpdate ( DatabaseUtils . dropTableStatement ( gisTableName ) , gisdbconnection ) ;
log ( " gis table dropped " ) ;
} catch ( Exception e ) {
log ( " Impossible to drop table: " + e . getLocalizedMessage ( ) ) ;
}
2017-05-25 16:50:11 +02:00
throw new Exception ( " Impossible to publish on GeoNetwork or GeoServer table: " + gisTableName + " (error on data are " + response . getDataOperationMessages ( ) + " erorre on metadata are " + response . getMetaOperationMessages ( ) + " ) " ) ;
2013-11-15 19:11:40 +01:00
} else {
2013-11-18 19:25:01 +01:00
//writing output
2013-11-15 19:11:40 +01:00
addOutputString ( " GIS map title " , layerName ) ;
addOutputString ( " GIS map UUID " , " " + response . getPublishedMetadata ( ) . getFileIdentifier ( ) ) ;
addOutputString ( " Associated Geospatial Table " , gisTableName ) ;
addOutputString ( " Generated by " , username ) ;
addOutputString ( " Resolution " , " " + resolution ) ;
2013-11-18 19:25:01 +01:00
addOutputString ( " Style " , " " + defaultStyle ) ;
addOutputString ( " Keyword " , " " + keyword ) ;
2013-11-15 19:11:40 +01:00
}
2013-11-18 19:25:01 +01:00
log ( " Output: " + outputParameters ) ;
2013-11-15 19:11:40 +01:00
log ( " All Done! " ) ;
2013-11-19 14:26:33 +01:00
status = 100 ;
2013-11-15 19:11:40 +01:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
throw e ;
} finally {
if ( smdbconnection ! = null )
DatabaseUtils . closeDBConnection ( smdbconnection ) ;
if ( gisdbconnection ! = null )
DatabaseUtils . closeDBConnection ( gisdbconnection ) ;
}
}
2013-11-18 19:25:01 +01:00
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 ;
}
}
}
2013-11-15 19:11:40 +01:00
}
2013-11-18 19:25:01 +01:00
2013-11-15 19:11:40 +01:00
@Override
public void shutdown ( ) {
2013-11-18 19:25:01 +01:00
log ( " shutdown invoked! " ) ;
2013-11-15 19:11:40 +01:00
}
@Override
2013-11-18 19:25:01 +01:00
protected abstract void setInputParameters ( ) ;
2013-11-15 19:11:40 +01:00
2013-11-18 19:25:01 +01:00
2013-11-15 19:11:40 +01:00
}