package org.gcube.dataanalysis.geo.matrixmodel; import java.util.ArrayList; import java.util.List; import java.util.UUID; import org.gcube.contentmanagement.lexicalmatcher.utils.AnalysisLogger; import org.gcube.contentmanagement.lexicalmatcher.utils.DatabaseFactory; import org.gcube.dataanalysis.ecoengine.configuration.AlgorithmConfiguration; import org.gcube.dataanalysis.ecoengine.utils.DatabaseUtils; import org.gcube.dataanalysis.ecoengine.utils.Tuple; import org.gcube.dataanalysis.geo.utils.CSquareCodesConverter; import org.gcube.dataanalysis.geo.utils.VectorOperations; import org.hibernate.SessionFactory; /** * transforms a raster map into a table * * @author coro * */ public class RasterTable { private double valuesMatrix[][]; double x1; double x2; double y1; double y2; double z; double time; double xResolution; double yResolution; List> coordinates; private AlgorithmConfiguration configuration; private String tablename = "rstr" + ("" + UUID.randomUUID()).replace("-", ""); static String createTableStatement = "CREATE TABLE %1$s (id serial, csquarecode character varying, x real, y real, z real, t real, fvalue real)"; static String columnsnames = "csquarecode, x , y , z , t, fvalue"; public static String csquareColumn = "csquarecode"; public static String valuesColumn = "fvalue"; public static String idColumn = "id"; public String getTablename() { return tablename; } public void setTablename(String tablename) { this.tablename = tablename; } public List> getCoordinates(){ return coordinates; } public void setCoordinates(List> coordinates) { this.coordinates=coordinates; } public RasterTable(double x1, double x2, double y1, double y2, double z, double xResolution, double yResolution, double[][] values, AlgorithmConfiguration configuration) { init(x1, x2, y1, y2, z, 0, xResolution, yResolution, values, configuration); } public RasterTable(double x1, double x2, double y1, double y2, double z, double time, double xResolution, double yResolution, double[][] values, AlgorithmConfiguration configuration) { init(x1, x2, y1, y2, z, time, xResolution, yResolution, values, configuration); } public void init(double x1, double x2, double y1, double y2, double z, double time, double xResolution, double yResolution, double[][] values, AlgorithmConfiguration configuration){ this.valuesMatrix = values; this.configuration = configuration; this.x1 = x1; this.x2 = x2; this.y1 = y1; this.y2 = y2; this.z = z; this.time = time; this.xResolution = xResolution; this.yResolution = yResolution; } public void dumpGeoTable() { // open the connection to the db SessionFactory dbconnection = DatabaseUtils.initDBSession(configuration); try { AnalysisLogger.getLogger().debug("Database Initialized"); // create a table DatabaseFactory.executeSQLUpdate(String.format(createTableStatement, tablename), dbconnection); AnalysisLogger.getLogger().debug("Table " + tablename + " created"); if (coordinates==null) coordinates = VectorOperations.generateCoordinateTripletsInBoundingBox(x1, x2, y1, y2, z, xResolution, yResolution); int triplets = coordinates.size(); AnalysisLogger.getLogger().debug("Generated " + triplets + " coordinates triples"); List values = associateValueToCoordinates(coordinates, valuesMatrix); AnalysisLogger.getLogger().debug("Association to values completed - fulfilling buffer"); // for each element in the matrix, build the corresponding csquare code StringBuffer sb = new StringBuffer(); for (int i = 0; i < triplets; i++) { // save the string in a buffer Tuple cset = coordinates.get(i); double x = cset.getElements().get(0); double y = cset.getElements().get(1); String csquare = CSquareCodesConverter.convertAtResolution(y,x, xResolution); Double value = values.get(i); //we do not use NaNs in this case every value will be filled if (value.isNaN()) value = 0d; double zVal = z; if (cset.getElements().size()>2) zVal = cset.getElements().get(2); String tVal = ""+time; if (cset.getElements().size()>3){ tVal = ""+cset.getElements().get(3); if (Double.isNaN(cset.getElements().get(3)) || (Double.isInfinite(cset.getElements().get(3)))) tVal="NULL"; } sb.append("('" + csquare + "'," + x + "," + y + "," + zVal + "," + tVal +",'" + value + "')"); if (i % 5000 == 0) { // AnalysisLogger.getLogger().debug("Partial Inserting Buffer of " + sb.length() + " Values"); String insertStatement = DatabaseUtils.insertFromBuffer(tablename, columnsnames, sb); DatabaseFactory.executeSQLUpdate(insertStatement, dbconnection); // AnalysisLogger.getLogger().debug("Partial Insertion completed with Success!"); sb = new StringBuffer(); } else if (i < triplets - 1) sb.append(","); } AnalysisLogger.getLogger().debug("Inserting Final Buffer of " + sb.length() + " Values"); // AnalysisLogger.getLogger().debug("Inserting Final Buffer " + sb); // save all the strings on the table if (sb.length() > 0) { String insertStatement = DatabaseUtils.insertFromBuffer(tablename, columnsnames, sb); DatabaseFactory.executeSQLUpdate(insertStatement, dbconnection); AnalysisLogger.getLogger().debug("Insertion completed with Success!"); } } catch (Exception e) { e.printStackTrace(); AnalysisLogger.getLogger().debug("Error in dumping table: " + e.getLocalizedMessage()); } finally { // close the connection DatabaseUtils.closeDBConnection(dbconnection); AnalysisLogger.getLogger().debug("Raster Geo Table DB closed!"); } } public void deleteTable() { SessionFactory dbconnection = null; try { dbconnection = DatabaseUtils.initDBSession(configuration); DatabaseFactory.executeSQLUpdate(DatabaseUtils.dropTableStatement(tablename), dbconnection); } catch (Exception e) { // e.printStackTrace(); AnalysisLogger.getLogger().debug("Impossible to delete table "+tablename+" : "+e.getLocalizedMessage()); } finally { DatabaseUtils.closeDBConnection(dbconnection); } } public static List associateValueToCoordinates(List> coordinates, double[][] data){ List values = new ArrayList(); int k = 0; int g = 0; int ntriplets = coordinates.size(); int xsteps = data[0].length-1; for (int t = 0; t < ntriplets; t++) { values.add(data[k][g]); if (g == xsteps) { g = 0; k++; } else g++; } return values; } }