git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-analysis/EcologicalEngineGeoSpatialExtension@120125 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
2d0d45a53d
commit
24ccb87501
|
@ -0,0 +1,60 @@
|
|||
package org.gcube.dataanalysis.geo.vti;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.contentmanagement.lexicalmatcher.utils.AnalysisLogger;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.ColumnType;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.DatabaseType;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.InputTable;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.enumtypes.TableTemplates;
|
||||
import org.gcube.dataanalysis.ecoengine.utils.IOHelper;
|
||||
import org.gcube.dataanalysis.geo.utils.CSquareCodesConverter;
|
||||
|
||||
public class CSquare2Coordinates extends GridCWP2Coordinates{
|
||||
|
||||
|
||||
@Override
|
||||
protected void setInputParameters() {
|
||||
|
||||
List<TableTemplates> templates = new ArrayList<TableTemplates>();
|
||||
templates.add(TableTemplates.GENERIC);
|
||||
InputTable tinput = new InputTable(templates, inputTableParameter, "The table to which the algorithm will add information");
|
||||
inputs.add(tinput);
|
||||
|
||||
ColumnType Dimension = new ColumnType(inputTableParameter, CodeColumn, "The column containing c-square codes", "GRID", false);
|
||||
|
||||
inputs.add(Dimension);
|
||||
|
||||
IOHelper.addStringInput(inputs, outputTableParameter, "The name of the output table", "csq_");
|
||||
DatabaseType.addDefaultDBPars(inputs);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "An algorithm that adds longitude, latitude and resolution columns analysing a column containing c-square codes.";
|
||||
}
|
||||
|
||||
public void rowToCoords (Object[] rowArray) {
|
||||
// take x and y
|
||||
Object grid = null;
|
||||
try{
|
||||
grid=rowArray[rowArray.length - 1];
|
||||
String gridValue = ""+ grid;
|
||||
// generate csquarecodes
|
||||
CSquareCodesConverter converter = new CSquareCodesConverter();
|
||||
converter.parse(gridValue);
|
||||
|
||||
currentLat= converter.getCurrentLat();
|
||||
currentLong=converter.getCurrentLong();
|
||||
currentRes=converter.getCurrentResolution();
|
||||
}catch(Exception e){
|
||||
AnalysisLogger.getLogger().debug("Error converting grid: "+grid+" - "+e.getLocalizedMessage());
|
||||
currentLat= 0;
|
||||
currentLong=0;
|
||||
currentRes=0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
package org.gcube.dataanalysis.geo.vti;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.gcube.contentmanagement.graphtools.utils.DateGuesser;
|
||||
import org.gcube.contentmanagement.lexicalmatcher.utils.AnalysisLogger;
|
||||
import org.gcube.dataanalysis.ecoengine.configuration.AlgorithmConfiguration;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.ColumnType;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.DatabaseType;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.InputTable;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.enumtypes.TableTemplates;
|
||||
import org.gcube.dataanalysis.ecoengine.utils.DatabaseFactory;
|
||||
import org.gcube.dataanalysis.ecoengine.utils.DatabaseUtils;
|
||||
import org.gcube.dataanalysis.ecoengine.utils.IOHelper;
|
||||
import org.gcube.dataanalysis.ecoengine.utils.Tuple;
|
||||
import org.gcube.dataanalysis.geo.vti.vesselsprocessing.Bathymetry;
|
||||
import org.gcube.dataanalysis.geo.vti.vesselsprocessing.FishingHoursCalculator;
|
||||
import org.gcube.dataanalysis.geo.vti.vesselsprocessing.VTIClassificator;
|
||||
|
||||
public class EstimateFishingActivity extends GridCWP2Coordinates{
|
||||
|
||||
static String VesselsIDColumn = "VesselsIDColumn";
|
||||
static String VesselsSpeedsColumn = "VesselsSpeedsColumn";
|
||||
static String VesselsTimestampsColumn = "VesselsTimestampsColumn";
|
||||
static String VesselsLatitudesColumn = "VesselsLatitudesColumn";
|
||||
static String VesselsLongitudesColumn = "VesselsLongitudesColumn";
|
||||
|
||||
@Override
|
||||
protected void setInputParameters() {
|
||||
|
||||
List<TableTemplates> templates = new ArrayList<TableTemplates>();
|
||||
templates.add(TableTemplates.GENERIC);
|
||||
InputTable tinput = new InputTable(templates, inputTableParameter, "The table to which the algorithm will add information");
|
||||
inputs.add(tinput);
|
||||
|
||||
ColumnType Dimension1 = new ColumnType(inputTableParameter, VesselsIDColumn, "A column containing (anonymised) unique vessels identifiers", "vessel_id", false);
|
||||
ColumnType Dimension2 = new ColumnType(inputTableParameter, VesselsSpeedsColumn, "The column containing vessels speeds", "speed", false);
|
||||
ColumnType Dimension3 = new ColumnType(inputTableParameter, VesselsTimestampsColumn, "The column containing the time stamp of the vessels transmitted information", "datetime", false);
|
||||
ColumnType Dimension4 = new ColumnType(inputTableParameter, VesselsLatitudesColumn, "The column containing vessels latitudes", "y", false);
|
||||
ColumnType Dimension5 = new ColumnType(inputTableParameter, VesselsLongitudesColumn, "The column containing vessels longitudes", "x", false);
|
||||
|
||||
inputs.add(Dimension1);
|
||||
inputs.add(Dimension2);
|
||||
inputs.add(Dimension3);
|
||||
inputs.add(Dimension4);
|
||||
inputs.add(Dimension5);
|
||||
|
||||
IOHelper.addStringInput(inputs, outputTableParameter, "The name of the output table", "fish_");
|
||||
DatabaseType.addDefaultDBPars(inputs);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "An algorithm that estimates activity hours (fishing or other) from vessels trajectories, " +
|
||||
"adds bathymetry information to the table and classifies (point-by-point) fishing activity of the involved vessels according to two algorithms: " +
|
||||
"one based on speed (activity_class_speed output column) and the other based on speed and bathymetry (activity_class_speed_bath output column). " +
|
||||
"The algorithm produces new columns containing this information. " +
|
||||
"This algorithm is based on the paper 'Deriving Fishing Monthly Effort and Caught Species' (Coro et al. 2013, in proc. of OCEANS - Bergen, 2013 MTS/IEEE). " +
|
||||
"Example of input table (NAFO anonymised data): http://goo.gl/3auJkM";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process() throws Exception {
|
||||
status = 0;
|
||||
AnalysisLogger.setLogger(config.getConfigPath() + AlgorithmConfiguration.defaultLoggerFile);
|
||||
|
||||
long t0 = System.currentTimeMillis();
|
||||
String table = IOHelper.getInputParameter(config, inputTableParameter);
|
||||
outTable = ("code_" + UUID.randomUUID()).replace("-", "");
|
||||
outTableLabel = IOHelper.getInputParameter(config, outputTableParameter);
|
||||
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: received parameters: " + config.getGeneralProperties());
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: input table: "+ table +" outputTable: " + outTable + " outLabel: " + outTableLabel);
|
||||
|
||||
status = 10;
|
||||
try{
|
||||
addInformationColumsToTable(table);
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: finished in "+(System.currentTimeMillis()-t0)+" ms");
|
||||
} catch (Throwable e) {
|
||||
throw new Exception(e.getMessage());
|
||||
} finally {
|
||||
status = 100;
|
||||
}
|
||||
}
|
||||
|
||||
public String selectInformationForTransformation (AlgorithmConfiguration config, String table, int limit, int offset){
|
||||
|
||||
String d = IOHelper.getInputParameter(config, CodeColumn);
|
||||
|
||||
String select = "select *," + d + " as loforcs01 from " + table + " limit " + limit + " offset " + offset;
|
||||
return select;
|
||||
}
|
||||
|
||||
public void addInformationColumsToTable(String table) throws Exception{
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: initializing connection");
|
||||
long t0 = System.currentTimeMillis();
|
||||
try {
|
||||
connection = DatabaseUtils.initDBSession(config);
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: database: " + config.getDatabaseURL());
|
||||
// create a new output table
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: dropping table " + outTable + " if exists");
|
||||
try {
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.dropTableStatement(outTable), connection);
|
||||
} catch (Exception e) {
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: table " + outTable + " does not exist yet");
|
||||
}
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: creating the new table " + outTable);
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.createBlankTableFromAnotherStatement(table, outTable), connection);
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: adding new columns to " + outTable);
|
||||
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.addColumnStatement(outTable, "activity_hours", "real"), connection);
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.addColumnStatement(outTable, "bathymetry", "real"), connection);
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.addColumnStatement(outTable, "activity_class_speed", "character varying"), connection);
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.addColumnStatement(outTable, "activity_class_speed_bath", "character varying"), connection);
|
||||
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: getting columns from " + outTable);
|
||||
// get columns names
|
||||
List<Object> names = DatabaseFactory.executeSQLQuery(DatabaseUtils.getColumnsNamesStatement(outTable), connection);
|
||||
StringBuffer colnames = new StringBuffer();
|
||||
int nnames = names.size();
|
||||
for (int i = 0; i < nnames; i++) {
|
||||
colnames.append(names.get(i));
|
||||
if (i < nnames - 1)
|
||||
colnames.append(",");
|
||||
}
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: columns are: " + colnames.toString());
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: taking chunks ... ");
|
||||
|
||||
List<Object> vessels = DatabaseFactory.executeSQLQuery("select distinct "+config.getParam(VesselsIDColumn)+" from "+table, connection);
|
||||
int nvessels = vessels.size();
|
||||
int k=0;
|
||||
|
||||
//error check
|
||||
if (config.getParam(VesselsIDColumn)==null || config.getParam(VesselsSpeedsColumn)==null || config.getParam(VesselsTimestampsColumn)==null || config.getParam(VesselsLongitudesColumn)==null || config.getParam(VesselsLatitudesColumn)==null)
|
||||
throw new Exception ("Error with input parameters, please check that all the required inputs have been provided.");
|
||||
for (Object vesselrow:vessels){
|
||||
String vesselID = ""+vesselrow;
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: Analysing vessel "+vesselID+" "+(k+1)+" of "+nvessels);
|
||||
//extract single vessel trajectory information
|
||||
String selectTrajectory = "select *, "+
|
||||
"\""+config.getParam(VesselsIDColumn)+"\""+" as fhv01,"+
|
||||
"\""+config.getParam(VesselsSpeedsColumn)+"\""+" as fhv02,"+
|
||||
"\""+config.getParam(VesselsTimestampsColumn)+"\""+" as fhv03,"+
|
||||
"\""+config.getParam(VesselsLongitudesColumn)+"\""+" as fhv04,"+
|
||||
"\""+config.getParam(VesselsLatitudesColumn)+"\""+" as fhv05 "+
|
||||
" from "+table+
|
||||
" where "+"\""+config.getParam(VesselsIDColumn)+"\""+" ="+vesselID+" order by CAST("+"\""+config.getParam(VesselsTimestampsColumn)+"\""+" as timestamp)";
|
||||
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: EstimateFishingActivity: Select trajectory: "+selectTrajectory);
|
||||
|
||||
List<Object> vesselTrajectory = DatabaseFactory.executeSQLQuery(selectTrajectory, connection);
|
||||
|
||||
int nvesselpoints = vesselTrajectory.size();
|
||||
String[] vesselIDs = new String[nvesselpoints];
|
||||
Date[] timeStamps = new Date[nvesselpoints];
|
||||
java.awt.geom.Point2D.Double [] coordinates = new java.awt.geom.Point2D.Double[nvesselpoints];
|
||||
Tuple<String>[] bathspeedpairs = new Tuple [nvesselpoints];
|
||||
String[] speeds = new String[nvesselpoints];
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: EstimateFishingActivity: building information: "+selectTrajectory);
|
||||
int i=0;
|
||||
for (Object trajectorrow:vesselTrajectory){
|
||||
Object[] trajectvector = (Object[]) trajectorrow;
|
||||
int lenvector = trajectvector.length;
|
||||
vesselIDs[i] = ""+trajectvector[lenvector-5];
|
||||
speeds[i] = ""+trajectvector[lenvector-4];
|
||||
timeStamps[i] = DateGuesser.convertDate(""+trajectvector[lenvector-3]).getTime();
|
||||
if (timeStamps[i]==null)
|
||||
throw new Exception ("Cannot parse time "+trajectvector[lenvector-3]+" for vessel "+vesselIDs[i]+". please try specifying time as MM/dd/yy KK:mm:ss a");
|
||||
if (i==0){
|
||||
String pattern = DateGuesser.getPattern(""+trajectvector[lenvector-3]);
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: sample time conversion: original "+trajectvector[lenvector-3]+" guessed: "+timeStamps[i]+" pattern: "+pattern);
|
||||
}
|
||||
try{
|
||||
coordinates [i] = new java.awt.geom.Point2D.Double(Double.parseDouble(""+trajectvector[lenvector-2]),Double.parseDouble(""+trajectvector[lenvector-1]));
|
||||
}catch(Exception e){
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: Warning - wrong coordinates: "+trajectvector[lenvector-2]+","+trajectvector[lenvector-1]);
|
||||
coordinates [i] = new java.awt.geom.Point2D.Double(0,0);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: estimating fishing hours");
|
||||
double [] hours = FishingHoursCalculator.calculateFishingHours(vesselIDs, timeStamps);
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: estimating bathymetry");
|
||||
|
||||
short [] bathymetry = null;
|
||||
try{
|
||||
Bathymetry bathymetryprocessor = new Bathymetry(config.getConfigPath()+"gebco_08.nc");
|
||||
bathymetry = bathymetryprocessor.compute(coordinates);
|
||||
}catch(Exception e){
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: Error - Bathymetry resource not available for the service "+e.getLocalizedMessage());
|
||||
throw new Exception("Error - Bathymetry resource not available for the service");
|
||||
}
|
||||
for (int g=0;g<nvesselpoints;g++){
|
||||
bathspeedpairs[g]=new Tuple<String>(""+speeds[g],""+bathymetry[g]);
|
||||
}
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: classifying routes");
|
||||
Tuple<Integer>[] classifications = VTIClassificator.classify(bathspeedpairs);
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity:building rows for the final table");
|
||||
List<String[]> stringrows = new ArrayList<String[]>();
|
||||
i=0;
|
||||
for (Object trajectorrow:vesselTrajectory){
|
||||
Object[] trajectvector = (Object[]) trajectorrow;
|
||||
String[] extendedrow = new String[nnames];
|
||||
for(int j=0;j<nnames-4;j++){
|
||||
extendedrow[j]=""+trajectvector[j];
|
||||
}
|
||||
extendedrow[nnames-4] = ""+hours[i];
|
||||
extendedrow[nnames-3] = ""+bathymetry[i];
|
||||
extendedrow[nnames-2] = ""+VTIClassificator.speedClassification(classifications[i].getElements().get(0));
|
||||
extendedrow[nnames-1] = ""+VTIClassificator.bathymetryClassification(classifications[i].getElements().get(1));
|
||||
stringrows.add(extendedrow);
|
||||
i++;
|
||||
}
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: inserting chunks into the table "+outTable);
|
||||
// write the vector into the table
|
||||
DatabaseUtils.insertChunksIntoTable(outTable, colnames.toString(), stringrows, nvesselpoints, connection, true);
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: inserting chunks done!");
|
||||
k++;
|
||||
}
|
||||
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: finished");
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity : ERROR!: " + e.getLocalizedMessage());
|
||||
try {
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: dropping " + outTable);
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.dropTableStatement(outTable), connection);
|
||||
} catch (Exception e1) {
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity: could not drop " + outTable);
|
||||
}
|
||||
throw new Exception(e.getMessage());
|
||||
} finally {
|
||||
shutdown();
|
||||
AnalysisLogger.getLogger().debug("EstimateFishingActivity finished in " + (System.currentTimeMillis() - t0) + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,232 @@
|
|||
package org.gcube.dataanalysis.geo.vti;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.gcube.contentmanagement.lexicalmatcher.utils.AnalysisLogger;
|
||||
import org.gcube.dataanalysis.ecoengine.configuration.AlgorithmConfiguration;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.ColumnType;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.DatabaseType;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.InputTable;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.OutputTable;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.StatisticalType;
|
||||
import org.gcube.dataanalysis.ecoengine.datatypes.enumtypes.TableTemplates;
|
||||
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.ecoengine.utils.IOHelper;
|
||||
import org.gcube.dataanalysis.geo.utils.GridCWPConverter;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
public class GridCWP2Coordinates extends StandardLocalExternalAlgorithm{
|
||||
|
||||
static String CodeColumn = "ColumnWithCodes";
|
||||
static String inputTableParameter = "InputTable";
|
||||
static String outputTableParameter = "OutputTableName";
|
||||
|
||||
String outTable = "";
|
||||
String outTableLabel = "";
|
||||
SessionFactory connection = null;
|
||||
|
||||
protected double currentLong;
|
||||
protected double currentLat;
|
||||
protected double currentRes;
|
||||
|
||||
public GridCWP2Coordinates(){
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setInputParameters() {
|
||||
|
||||
List<TableTemplates> templates = new ArrayList<TableTemplates>();
|
||||
templates.add(TableTemplates.GENERIC);
|
||||
InputTable tinput = new InputTable(templates, inputTableParameter, "The table to which the algorithm will add information");
|
||||
inputs.add(tinput);
|
||||
|
||||
ColumnType Dimension = new ColumnType(inputTableParameter, CodeColumn, "The column containing FAO Ocean Area codes in CWP format", "GRID", false);
|
||||
|
||||
inputs.add(Dimension);
|
||||
|
||||
IOHelper.addStringInput(inputs, outputTableParameter, "The name of the output table", "cwp_");
|
||||
DatabaseType.addDefaultDBPars(inputs);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatisticalType getOutput() {
|
||||
List<TableTemplates> template = new ArrayList<TableTemplates>();
|
||||
template.add(TableTemplates.GENERIC);
|
||||
OutputTable p = new OutputTable(template, outTableLabel, outTable, "Output table");
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "An algorithm that adds longitude, latitude and resolution columns analysing a column containing FAO Ocean Area codes (CWP format).";
|
||||
}
|
||||
|
||||
public String selectInformationForTransformation (AlgorithmConfiguration config, String table, int limit, int offset){
|
||||
|
||||
String d = IOHelper.getInputParameter(config, CodeColumn);
|
||||
|
||||
String select = "select *," + d + " as loforcs01 from " + table + " limit " + limit + " offset " + offset;
|
||||
return select;
|
||||
}
|
||||
|
||||
|
||||
public void rowToCoords (Object[] rowArray) {
|
||||
// take x and y
|
||||
Object grid = null;
|
||||
try{
|
||||
grid=rowArray[rowArray.length - 1];
|
||||
String gridValue = ""+(int)Double.parseDouble("" + grid);
|
||||
// generate csquarecodes
|
||||
GridCWPConverter gridder = null;
|
||||
gridder = new GridCWPConverter();
|
||||
gridder.gridCodeToPair(gridValue);
|
||||
|
||||
currentLat= gridder.outlat;
|
||||
currentLong=gridder.outlon;
|
||||
currentRes=gridder.gridresolution;
|
||||
}catch(Exception e){
|
||||
AnalysisLogger.getLogger().debug("Error converting grid: "+grid+" - "+e.getLocalizedMessage());
|
||||
currentLat= 0;
|
||||
currentLong=0;
|
||||
currentRes=0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process() throws Exception {
|
||||
status = 0;
|
||||
AnalysisLogger.setLogger(config.getConfigPath() + AlgorithmConfiguration.defaultLoggerFile);
|
||||
|
||||
long t0 = System.currentTimeMillis();
|
||||
String gridField = IOHelper.getInputParameter(config, CodeColumn);
|
||||
String table = IOHelper.getInputParameter(config, inputTableParameter);
|
||||
outTable = ("code_" + UUID.randomUUID()).replace("-", "");
|
||||
outTableLabel = IOHelper.getInputParameter(config, outputTableParameter);
|
||||
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: received parameters: code column " + gridField +", table " + table + ", outputTable " + outTable + " outLabel " + outTableLabel);
|
||||
|
||||
status = 10;
|
||||
if (gridField == null || gridField.trim().length() == 0 )
|
||||
throw new Exception("Error please provide information for the code column");
|
||||
try{
|
||||
addInformationColumsToTable(table);
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: finished in "+(System.currentTimeMillis()-t0)+" ms");
|
||||
|
||||
} catch (Throwable e) {
|
||||
throw new Exception(e.getMessage());
|
||||
} finally {
|
||||
status = 100;
|
||||
}
|
||||
}
|
||||
|
||||
public void addInformationColumsToTable(String table) throws Exception{
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: initializing connection");
|
||||
long t0 = System.currentTimeMillis();
|
||||
try {
|
||||
connection = DatabaseUtils.initDBSession(config);
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: database: " + config.getDatabaseURL());
|
||||
// create a new output table
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: dropping table " + outTable + " if exists");
|
||||
try {
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.dropTableStatement(outTable), connection);
|
||||
} catch (Exception e) {
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: table " + outTable + " does not exist yet");
|
||||
}
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: creating the new table " + outTable);
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.createBlankTableFromAnotherStatement(table, outTable), connection);
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: adding new columns to " + outTable);
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.addColumnStatement(outTable, "long_estim", "real"), connection);
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.addColumnStatement(outTable, "lat_estim", "real"), connection);
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.addColumnStatement(outTable, "res_estim", "real"), connection);
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: getting columns from " + outTable);
|
||||
// get columns names
|
||||
List<Object> names = DatabaseFactory.executeSQLQuery(DatabaseUtils.getColumnsNamesStatement(outTable), connection);
|
||||
StringBuffer colnames = new StringBuffer();
|
||||
int nnames = names.size();
|
||||
for (int i = 0; i < nnames; i++) {
|
||||
colnames.append(names.get(i));
|
||||
if (i < nnames - 1)
|
||||
colnames.append(",");
|
||||
}
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: columns are: " + colnames.toString());
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: taking chunks ... ");
|
||||
// take chunks of the table
|
||||
int initIdx = 0;
|
||||
int limit = 5000;
|
||||
|
||||
long maxRows = DatabaseUtils.estimateNumberofRows(table, connection);
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: estimated number of rows " + maxRows);
|
||||
status = 20;
|
||||
while (true) {
|
||||
|
||||
String select = selectInformationForTransformation(config, table, limit, initIdx);
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: executing query: "+select);
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: from " + initIdx + " to " + (initIdx + limit) + " limit "+limit);
|
||||
List<Object> rows = DatabaseFactory.executeSQLQuery(select, connection);
|
||||
|
||||
if (rows == null || rows.size() == 0) {
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: no more rows");
|
||||
break;
|
||||
}
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: transforming ");
|
||||
// take x and y
|
||||
List<String[]> stringrows = new ArrayList<String[]>();
|
||||
for (Object row : rows) {
|
||||
Object[] rowArray = (Object[]) row;
|
||||
// AnalysisLogger.getLogger().debug("ROW: "+Arrays.toString(rowArray));
|
||||
rowToCoords(rowArray);
|
||||
String[] stringArray = new String[nnames];
|
||||
// convert all the objects into Strings
|
||||
for (int k = 0; k < rowArray.length-1; k++) {
|
||||
stringArray[k] = "" + rowArray[k];
|
||||
}
|
||||
stringArray[nnames-3] = ""+currentLong;
|
||||
stringArray[nnames-2] = ""+currentLat;
|
||||
stringArray[nnames-1] = ""+currentRes;
|
||||
|
||||
stringrows.add(stringArray);
|
||||
}
|
||||
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: inserting chunks into the table");
|
||||
// write the vector into the table
|
||||
DatabaseUtils.insertChunksIntoTable(outTable, colnames.toString(), stringrows, limit, connection, true);
|
||||
initIdx = initIdx+limit;
|
||||
status = Math.min(90, 20 + (70 * initIdx / maxRows));
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: status " + status);
|
||||
}
|
||||
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: finished");
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates : ERROR!: " + e.getLocalizedMessage());
|
||||
try {
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: dropping " + outTable);
|
||||
DatabaseFactory.executeSQLUpdate(DatabaseUtils.dropTableStatement(outTable), connection);
|
||||
} catch (Exception e1) {
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates: could not drop " + outTable);
|
||||
}
|
||||
throw new Exception(e.getMessage());
|
||||
} finally {
|
||||
shutdown();
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates finished in " + (System.currentTimeMillis() - t0) + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
AnalysisLogger.getLogger().debug("GridCWP2Coordinates shutdown");
|
||||
DatabaseUtils.closeDBConnection(connection);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package org.gcube.dataanalysis.geo.vti.vesselsprocessing;
|
||||
|
||||
|
||||
public class Bathymetry {
|
||||
|
||||
private static VTIBathymetry bathymetryObj;
|
||||
|
||||
public static void init() throws Exception {
|
||||
bathymetryObj.open();
|
||||
}
|
||||
|
||||
public static void close() throws Exception {
|
||||
bathymetryObj.close();
|
||||
}
|
||||
|
||||
public static void initInstance(String bathfile ) throws Exception{
|
||||
if (bathymetryObj==null){
|
||||
bathymetryObj = new VTIBathymetry(bathfile);
|
||||
try {
|
||||
init();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
public Bathymetry(String bathfile) throws Exception {
|
||||
|
||||
initInstance(bathfile);
|
||||
}
|
||||
|
||||
public synchronized short[] compute(java.awt.geom.Point2D.Double [] points) throws Exception{
|
||||
|
||||
return bathymetryObj.getZ(points);
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
VTIBathymetry vti = new VTIBathymetry("./cfg/gebco_08.nc");
|
||||
try {
|
||||
long t0 = System.currentTimeMillis();
|
||||
vti.open();
|
||||
System.out.println("file open");
|
||||
|
||||
long t00 = System.currentTimeMillis();
|
||||
|
||||
// x = long
|
||||
// y = lat
|
||||
|
||||
double z = vti.getZ(1.75, 0.25);
|
||||
System.out.println("Z:" + z);
|
||||
long t01 = System.currentTimeMillis();
|
||||
System.out.println("computation elapsed " + (t01 - t00) + " ms");
|
||||
|
||||
t00 = System.currentTimeMillis();
|
||||
java.awt.geom.Point2D.Double[] pp = new java.awt.geom.Point2D.Double[9];
|
||||
|
||||
java.awt.geom.Point2D.Double point = new java.awt.geom.Point2D.Double(0.25f, 0.75f);
|
||||
pp[0] = point;
|
||||
point = new java.awt.geom.Point2D.Double(0.25f, 0.75f);
|
||||
pp[1] = point;
|
||||
point = new java.awt.geom.Point2D.Double(50f, 75f);
|
||||
pp[2] = point;
|
||||
point = new java.awt.geom.Point2D.Double(45f, 0.75f);
|
||||
pp[3] = point;
|
||||
point = new java.awt.geom.Point2D.Double(30f, 0.75f);
|
||||
pp[4] = point;
|
||||
point = new java.awt.geom.Point2D.Double(25f, 0.75f);
|
||||
pp[5] = point;
|
||||
point = new java.awt.geom.Point2D.Double(90f, 0.75f);
|
||||
pp[6] = point;
|
||||
point = new java.awt.geom.Point2D.Double(180f, 180f);
|
||||
pp[7] = point;
|
||||
point = new java.awt.geom.Point2D.Double(0.25f, 0.75f);
|
||||
pp[8] = point;
|
||||
|
||||
short[] zz = vti.getZ(pp);
|
||||
System.out.println("ZZ:" + zz);
|
||||
t01 = System.currentTimeMillis();
|
||||
System.out.println("computation elapsed " + (t01 - t00) + " ms");
|
||||
for (short z1 : zz)
|
||||
System.out.println("Zz:" + z1);
|
||||
|
||||
vti.close();
|
||||
System.out.println("file closed");
|
||||
long t1 = System.currentTimeMillis();
|
||||
System.out.println("elapsed " + (t1 - t0) + " ms");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package org.gcube.dataanalysis.geo.vti.vesselsprocessing;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.gcube.contentmanagement.graphtools.utils.MathFunctions;
|
||||
|
||||
public class FishingHoursCalculator {
|
||||
|
||||
|
||||
|
||||
|
||||
public static double[] calculateFishingHours(String [] vesselIDsField,Date[] timeStamps){
|
||||
int vNumber = vesselIDsField.length;
|
||||
double [] hours = new double[vNumber];
|
||||
Date previousDate = null;
|
||||
String previousVessel = null;
|
||||
for (int i=0;i<vNumber;i++){
|
||||
if ((previousVessel!= null)&&(!previousVessel.equals(vesselIDsField[i])))
|
||||
previousDate = null;
|
||||
|
||||
// System.out.print(timeStamps[i]+" vs "+previousDate+" ");
|
||||
|
||||
if (previousDate==null)
|
||||
hours [i] = 0.0f;
|
||||
else{
|
||||
long timediff = timeStamps[i].getTime()-previousDate.getTime();
|
||||
// System.out.print("time diff: "+timediff);
|
||||
//if time difference< 4 hours
|
||||
// if ((timediff>=0) && (timediff<=4*60*60*1000)){
|
||||
if ((timediff>=0) && (timediff<=14400000)){
|
||||
hours [i] = MathFunctions.roundDecimal((double)timediff/(double)(60*60*1000),2);
|
||||
}
|
||||
else
|
||||
hours [i] = 0.0f;
|
||||
}
|
||||
|
||||
// System.out.println(" hours:"+hours[i]);
|
||||
|
||||
previousDate = timeStamps[i];
|
||||
previousVessel = vesselIDsField[i];
|
||||
}
|
||||
|
||||
// System.exit(0);
|
||||
return hours;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package org.gcube.dataanalysis.geo.vti.vesselsprocessing;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.gcube.contentmanagement.graphtools.utils.MathFunctions;
|
||||
import org.gcube.dataanalysis.geo.utils.CSquareCodesConverter;
|
||||
|
||||
public class MonthlyFishingEffortCalculator {
|
||||
|
||||
private static int monthsDifference(Date minDate, Date maxDate) {
|
||||
Calendar min = Calendar.getInstance();
|
||||
min.setTime(minDate);
|
||||
Calendar max = Calendar.getInstance();
|
||||
max.setTime(maxDate);
|
||||
|
||||
int monthsDiff = (max.get(Calendar.YEAR) - min.get(Calendar.YEAR))*12 + (max.get(Calendar.MONTH) - min.get(Calendar.MONTH)) + ((max.get(Calendar.DAY_OF_MONTH) - min.get(Calendar.DAY_OF_MONTH)) / 27);
|
||||
|
||||
return monthsDiff;
|
||||
}
|
||||
|
||||
// positional Object: x,y,date,hours
|
||||
private double minEffort;
|
||||
private double maxEffort;
|
||||
|
||||
public Map<String, Double> calculateMonthlyFishingEffort(List<Object> rows, Date minDate, Date maxDate) {
|
||||
|
||||
HashMap<String, Double> csquare2month = new HashMap<String, Double>();
|
||||
HashMap<String, double[]> csquaremonths = new HashMap<String, double[]>();
|
||||
int numOfPoints = rows.size();
|
||||
int numOfMonths = monthsDifference(minDate, maxDate);
|
||||
System.out.println("min:"+minDate+" max "+maxDate+" months diffs "+numOfMonths);
|
||||
|
||||
for (int i = 0; i < numOfPoints; i++) {
|
||||
Object[] singleRow = (Object[]) rows.get(i);
|
||||
double x = Float.parseFloat(""+singleRow[0]);
|
||||
double y = Float.parseFloat(""+singleRow[1]);
|
||||
Date d = (Date) singleRow[2];
|
||||
double hours = (Float) singleRow[3];
|
||||
double speed = Double.parseDouble("" + singleRow[4]);
|
||||
|
||||
if ((speed >= 2) && (speed <= 6)) {
|
||||
String csquare = CSquareCodesConverter.convertHalfDegree(x, y);
|
||||
double[] csquaremontheffort = csquaremonths.get(csquare);
|
||||
|
||||
if (csquaremontheffort == null)
|
||||
csquaremontheffort = new double[numOfMonths + 1];
|
||||
|
||||
int index = monthsDifference(minDate, d);
|
||||
csquaremontheffort[index] = csquaremontheffort[index] + hours;
|
||||
// update the map
|
||||
csquaremonths.put(csquare, csquaremontheffort);
|
||||
}
|
||||
}
|
||||
|
||||
// calculate mean monthly effort
|
||||
for (String keySquare : csquaremonths.keySet()) {
|
||||
|
||||
double[] monthsEffort = csquaremonths.get(keySquare);
|
||||
|
||||
double sum = 0;
|
||||
for (int i = 0; i < numOfMonths + 1; i++) {
|
||||
sum += monthsEffort[i];
|
||||
}
|
||||
sum = sum / (double) (numOfMonths + 1);
|
||||
sum = MathFunctions.roundDecimal(sum, 2);
|
||||
if (sum > maxEffort)
|
||||
maxEffort = sum;
|
||||
if (sum < minEffort)
|
||||
minEffort = sum;
|
||||
|
||||
csquare2month.put(keySquare, sum);
|
||||
}
|
||||
|
||||
return csquare2month;
|
||||
}
|
||||
|
||||
public double getMinEffort() {
|
||||
return minEffort;
|
||||
}
|
||||
|
||||
public void setMinEffort(double minEffort) {
|
||||
this.minEffort = minEffort;
|
||||
}
|
||||
|
||||
public double getMaxEffort() {
|
||||
return maxEffort;
|
||||
}
|
||||
|
||||
public void setMaxEffort(double maxEffort) {
|
||||
this.maxEffort = maxEffort;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,290 @@
|
|||
package org.gcube.dataanalysis.geo.vti.vesselsprocessing;
|
||||
|
||||
import ucar.ma2.Array;
|
||||
import ucar.ma2.InvalidRangeException;
|
||||
|
||||
/**
|
||||
* Class for obtaining altimetry and bathymetry values from a netCDF file.
|
||||
* Requires the netCDF libraries (see here: http://www.unidata.ucar.edu/software/netcdf-java/documentation.htm)
|
||||
*
|
||||
* You should use the class in the following way:
|
||||
* <code><pre>
|
||||
* VTIBathymetry bath = new VTIBathymetry("/path/to/bath.nc"); // e.g. gebco_08.nc
|
||||
* bath.open(); // file must be explicitly opened, this takes a short time, avoid opening it several times
|
||||
* short value1 = bath.getZ(142.2, 11.35); // e.g. Mariana Trench
|
||||
* short value2 = bath.getZ(0, 0);
|
||||
* // ...
|
||||
* bath.close(); // file should be closed when not needed any longer
|
||||
* </pre></code>
|
||||
*
|
||||
* @author Frank Loeschau, Terradue Srl.
|
||||
*/
|
||||
public class VTIBathymetry {
|
||||
|
||||
private String filename;
|
||||
private String mode;
|
||||
private java.awt.geom.Point2D.Double[] points;
|
||||
private ucar.nc2.NetcdfFile ncFile;
|
||||
private ucar.nc2.Variable var;
|
||||
//private ucar.ma2.Array arr;
|
||||
private boolean debug = false;
|
||||
public final int GRID_COLS = 360 * 120;
|
||||
public final int GRID_ROWS = 180 * 120;
|
||||
|
||||
/**
|
||||
* The class can also be used as command-line tool.
|
||||
* The syntax is: <p><code>java org.d4science2.vtivre.VTIBathymetry get x1,y1 [x2,y2 [...]] filename</code></p>
|
||||
* If only one pair of coordinates is specified, debug information about the calculation is written.
|
||||
* @param args the command-line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
int status = 0;
|
||||
VTIBathymetry bm = new VTIBathymetry();
|
||||
|
||||
try {
|
||||
if (!bm.parseArguments(args)) System.exit(1);
|
||||
|
||||
bm.open();
|
||||
|
||||
short[][] res = new short[361][181];
|
||||
|
||||
if (bm.mode.compareTo("draw") == 0) {
|
||||
bm.draw();
|
||||
} else if (bm.mode.compareTo("get") == 0) {
|
||||
bm.debug = false;
|
||||
|
||||
if (bm.points == null || bm.points.length == 0) {
|
||||
System.err.println("No point specified");
|
||||
System.exit(1);
|
||||
} else if (bm.points.length == 1) {
|
||||
bm.debug = true;
|
||||
short z = bm.getZ(bm.points[0]);
|
||||
System.out.println(z);
|
||||
} else {
|
||||
short[] zs = bm.getZ(bm.points);
|
||||
for (int i = 0; i < zs.length; i++) System.out.println(zs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
status = 1;
|
||||
} finally {
|
||||
try {
|
||||
bm.close();
|
||||
} catch (Exception e2) {}
|
||||
}
|
||||
System.exit(status);
|
||||
}
|
||||
|
||||
private static void printUsage() {
|
||||
System.out.println("Usage: org.d4science2.vtivre.VTIBathymetry (get x,y [x2,y2 [x3,y3 ...]]) file");
|
||||
System.out.println();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
private VTIBathymetry() {}
|
||||
|
||||
private boolean parseArguments(String[] args) throws Exception {
|
||||
try {
|
||||
if (args.length >= 1) mode = args[0];
|
||||
if (args.length >= 2) filename = args[args.length - 1];
|
||||
|
||||
points = new java.awt.geom.Point2D.Double[args.length > 2 ? args.length - 2 : 0];
|
||||
for (byte i = 0; i < args.length - 2; i++) {
|
||||
String[] s = args[i + 1].split(",");
|
||||
if (s.length != 2) {
|
||||
System.err.println("Invalid coordinate format: must be x,y (e.g. -12.34,56.78)");
|
||||
System.exit(1);
|
||||
}
|
||||
points[i] = new java.awt.geom.Point2D.Double();
|
||||
points[i].setLocation(Double.parseDouble(s[0]), Double.parseDouble(s[1]));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
printUsage();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mode == null) {
|
||||
System.err.println("No mode specified");
|
||||
printUsage();
|
||||
return false;
|
||||
} else if (filename == null) {
|
||||
System.err.println("No filename specified");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of VTIBathymetry with the specified file.
|
||||
* @param filename the netCDF filename containing the altimetry/bathymetry data
|
||||
*/
|
||||
public VTIBathymetry(String filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the netCDF file and loads the data array.
|
||||
* This operation is somewhat slow and requires the creation of a big object in memory. Ideally, this method is called only once, before the altrimetry/bathymetry values are needed.
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public void open() throws java.io.IOException {
|
||||
ncFile = ucar.nc2.dataset.NetcdfDataset.openFile(filename, null);
|
||||
var = ncFile.findVariable("z");
|
||||
//arr = var.read();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the netCDF file.
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public void close() throws java.io.IOException {
|
||||
if (ncFile != null) ncFile.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the altimetric/bathymetric value of the given geographical coordinates.
|
||||
* The value derives from the corresponding cell in the coordinate grid (120 x 120 cells per degree).
|
||||
* If a coordinate is close to the cell border (< 0.1 * arc cell size), the result value is averaged with the value from the adjacent cell.
|
||||
* @param point the geographical coordinates (x = longitude value (-180 to 180), y = latitude value (-90 to 90))
|
||||
* @return the altimetric/bathymetric value for the coordinate (in meters)
|
||||
* @throws java.io.IOException if the netCDF variable <code>z</code> could not been read
|
||||
*/
|
||||
public short getZ(java.awt.geom.Point2D.Double point) throws java.io.IOException {
|
||||
return getZ(point.getX(), point.getY());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the altimetric/bathymetric values of the given array of geographical coordinates.
|
||||
* The value derives from the corresponding cell in the coordinate grid (120 x 120 cells per degree).
|
||||
* If a coordinate is close to the cell border (< 0.1 * arc cell size), the result value is averaged with the value from the adjacent cell.
|
||||
* @param points array of geographical coordinates (x = longitude value (-180 to 180), y = latitude value (-90 to 90))
|
||||
* @return an array of the same shape as points, containing the altimetric/bathymetric value for the coordinate (in meters)
|
||||
* @throws java.io.IOException if the netCDF variable <code>z</code> could not been read
|
||||
*/
|
||||
public short[] getZ(java.awt.geom.Point2D.Double[] points) throws java.io.IOException {
|
||||
short[] result = new short[points.length];
|
||||
for (int i = 0; i < points.length; i++) result[i] = getZ(points[i].getX(), points[i].getY());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the altimetric/bathymetric value of the given geographical coordinates.
|
||||
* The value derives from the corresponding cell in the coordinate grid (120 x 120 cells per degree).
|
||||
* If a coordinate is close to the cell border (< 0.1 * arc cell size), the result value is averaged with the value from the adjacent cell.
|
||||
* @param x longitude coordinate (-180 to 180)
|
||||
* @param y latitude coordinate (-90 to 90)
|
||||
* @return the altimetric/bathymetric value for the coordinate (in meters)
|
||||
* @throws NullPointerException if the netCDF file has not been opened or the variable <code>z</code> (containing the altimetry/bathymetry values) is not found
|
||||
* @throws java.io.IOException if the netCDF variable <code>z</code> could not been read
|
||||
*/
|
||||
public short getZ(double x, double y) throws java.lang.NullPointerException, java.io.IOException {
|
||||
int resultInt = 0;
|
||||
|
||||
if (ncFile == null) throw new NullPointerException("No netCDF file not open");
|
||||
if (var == null) throw new NullPointerException("Variable 'z' not found");
|
||||
|
||||
double gridColD = (x + 180) * 120; // left border of cell
|
||||
boolean averageWithNextCol = false, averageWithNextRow = false;
|
||||
|
||||
int gridCol, gridRow;
|
||||
if (gridColD < 0 || gridColD >= GRID_COLS) {
|
||||
gridCol = GRID_COLS - 1;
|
||||
averageWithNextCol = true;
|
||||
} else {
|
||||
gridCol = (int)Math.floor(gridColD);
|
||||
if (gridColD - gridCol < 0.1) {
|
||||
gridCol = (gridCol + GRID_COLS - 1) % GRID_COLS;
|
||||
averageWithNextCol = true;
|
||||
} else if (gridColD - gridCol > 0.9) {
|
||||
averageWithNextCol = true;
|
||||
}
|
||||
}
|
||||
double gridRowD = (90 - y) * 120; // upper border of cell
|
||||
if (gridRowD < 0) {
|
||||
gridRow = 0;
|
||||
} else if (gridRowD >= GRID_ROWS) {
|
||||
gridRow = GRID_ROWS - 1;
|
||||
} else {
|
||||
gridRow = (int)Math.floor(gridRowD);
|
||||
if (gridRowD - gridRow < 0.1 && gridRow > 0) {
|
||||
gridRow--;
|
||||
averageWithNextRow = true;
|
||||
} else if (gridRowD - gridRow > 0.9 && gridRow < GRID_ROWS - 1) {
|
||||
averageWithNextRow = true;
|
||||
}
|
||||
}
|
||||
|
||||
int[] shape = new int[1];
|
||||
if (averageWithNextCol) shape[0] = 2;
|
||||
else shape[0] = 1;
|
||||
int[] origin = {GRID_COLS * gridRow + gridCol};
|
||||
|
||||
short result = 0;
|
||||
try {
|
||||
Array arr = var.read(origin, shape);
|
||||
resultInt = arr.getShort(0);
|
||||
if (averageWithNextCol) resultInt += arr.getShort(1);
|
||||
if (averageWithNextRow) {
|
||||
origin[0] += GRID_COLS;
|
||||
arr = var.read(origin, shape);
|
||||
resultInt += arr.getShort(0);
|
||||
if (averageWithNextCol) resultInt += arr.getShort(1);
|
||||
}
|
||||
result = (short)(resultInt / ((averageWithNextCol ? 2 : 1) * (averageWithNextRow ? 2 : 1)));
|
||||
} catch (InvalidRangeException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
System.out.println("x,y --- col,row (calculated) --- col[+],row[+] (actual): " + x + "," + y + " --- " + gridColD + "," + gridRowD + " --- " + gridCol + (averageWithNextCol ? "+" : "") + "," + gridRow + (averageWithNextRow ? "+" : ""));
|
||||
|
||||
System.out.print("Grid cell indexes used: " + (GRID_COLS * gridRow + gridCol));
|
||||
if (averageWithNextCol) System.out.print(" " + (GRID_COLS * gridRow + (gridCol + 1) % GRID_COLS));
|
||||
if (averageWithNextRow) {
|
||||
System.out.print(" " + (GRID_COLS * (gridRow + 1) + gridCol));
|
||||
if (averageWithNextCol) System.out.print(" " + (GRID_COLS * (gridRow + 1) + (gridCol + 1) % GRID_COLS));
|
||||
}
|
||||
if (averageWithNextCol) System.out.print(", eastern adjacent cell used");
|
||||
if (averageWithNextRow) System.out.print(", southern adjacent cell used");
|
||||
System.out.println();
|
||||
|
||||
/*System.out.print("Corresponding altimetry/bathymetry values: " + arr.getShort(GRID_COLS * gridRow + gridCol));
|
||||
if (averageWithNextCol) System.out.print(" " + arr.getShort(GRID_COLS * gridRow + (gridCol + 1) % GRID_COLS));
|
||||
if (averageWithNextRow) {
|
||||
System.out.print(" " + arr.getShort(GRID_COLS * (gridRow + 1) + gridCol));
|
||||
if (averageWithNextCol) System.out.print(" " + arr.getShort(GRID_COLS * (gridRow + 1) + (gridCol + 1) % GRID_COLS));
|
||||
}*/
|
||||
System.out.println();
|
||||
System.out.println("Result: " + result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void draw() {
|
||||
/* try {
|
||||
if (arr == null) throw new Exception("Variable 'z' not found");
|
||||
|
||||
long size = arr.getSize();
|
||||
for (int i = 0; i < 30; i++) {
|
||||
for (int j = 0; j < 120; j++) {
|
||||
int index = 31104000 * i + 360 * j + 15552000 + 180;
|
||||
if (index >= size) return;
|
||||
System.out.print(arr.getShort(index) < 0 ? "~" : "@");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("ERROR: " + e.getClass().getName() + ": " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package org.gcube.dataanalysis.geo.vti.vesselsprocessing;
|
||||
|
||||
import org.gcube.dataanalysis.ecoengine.utils.Tuple;
|
||||
|
||||
|
||||
public class VTIClassificator {
|
||||
|
||||
private static int bathymetryThr = -500;
|
||||
|
||||
public static String speedClassification(int classif){
|
||||
|
||||
if (classif==1)
|
||||
return "Hauling";
|
||||
else if (classif==2)
|
||||
return "Fishing";
|
||||
else if (classif==3)
|
||||
return "Steaming";
|
||||
else
|
||||
return "Unclassified";
|
||||
}
|
||||
|
||||
public static String bathymetryClassification(int classif){
|
||||
|
||||
if (classif==1)
|
||||
return "Hauling";
|
||||
else if (classif==2)
|
||||
return "Trawling";
|
||||
else if (classif==3)
|
||||
return "Midwater trawling";
|
||||
else if (classif==4)
|
||||
return "Steaming";
|
||||
else
|
||||
return "Unclassified";
|
||||
}
|
||||
|
||||
public static Tuple<Integer>[] classify(Tuple<String>[] pairs){
|
||||
|
||||
Tuple<Integer>[] outClasses= new Tuple[pairs.length];
|
||||
int i=0;
|
||||
for (Tuple<String> pair:pairs){
|
||||
Double speed = Double.parseDouble(pair.getElements().get(0));
|
||||
Double bathymetry = Double.parseDouble(pair.getElements().get(1));
|
||||
//Hauling, dodging, shooting
|
||||
Integer c1 = 1;
|
||||
Integer c2 = 1;
|
||||
//Fishing
|
||||
if ((speed>2)&&(speed<=5))
|
||||
c1 = 2;
|
||||
//Steaming
|
||||
else if (speed>5)
|
||||
c1 = 3;
|
||||
|
||||
//midwater trawling
|
||||
if ((speed>2)&&(speed<=4)&&(bathymetry<bathymetryThr))
|
||||
c2 = 3;
|
||||
//midwater trawling
|
||||
else if ((speed>4)&&(speed<=6))
|
||||
c2 = 3;
|
||||
|
||||
//trawling
|
||||
else if ((speed>2)&&(speed<=4)&&(bathymetry>=bathymetryThr))
|
||||
c2 = 2;
|
||||
|
||||
//Steaming
|
||||
else if (speed>6)
|
||||
c2 = 4;
|
||||
|
||||
|
||||
|
||||
//classification suggestions by Anton:
|
||||
// if depth > 500 and speed [2.5, 4] -> midwater trawling
|
||||
// else if depth > 500 -> trawling
|
||||
// else -> bottom trawling
|
||||
|
||||
|
||||
|
||||
Tuple<Integer> outTuple = new Tuple<Integer>(c1,c2);
|
||||
outClasses[i] = outTuple;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return outClasses;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue