/*
* Copyright (C) 2011-2014 GeoForge Project
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.geoforge.guillc.table;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.logging.Logger;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.JTableHeader;
import org.geoforge.guillc.optionpane.GfrOptionPaneAbs;
import org.geoforge.guillc.tablemodel.GfrAtmLatLonPoints;
import org.geoforge.java.awt.geom.GfrUtilRangeLatLon;
import org.geoforge.java.util.logging.filehandler.FileHandlerLogger;
/**
*
* @author bantchao
*
* email: bantchao_AT_gmail.com
* ... please remove "_AT_" from the above string to get the right email address
*
*/
public class GfrTblCheckablePoints extends GfrTblEditCheckableAbs
{
final static private int _INT_MIN_POINTS_ = 0;
// ----
// begin: instantiate logger for this class
final private static Logger _LOGGER_ = Logger.getLogger(GfrTblCheckablePoints.class.getName());
static
{
GfrTblCheckablePoints._LOGGER_.addHandler(FileHandlerLogger.s_getInstance());
}
// end: instantiate logger for this class
// ----
final static private String[] _STRS_TIP_HEADER_ =
{
"Point number",
"Latitude in degrees",
"Longitude in degrees"
};
final static private String[] _STRS_TIP_DATA_ =
{
"Not editable field",
"Please enter value of type double, in between -90 and 90",
"Please enter value of type double, in between -180 and 180"
};
public GfrTblCheckablePoints(
TableModelListener tmlParentDialog,
TableModelListener tmlParentPanel,
MouseListener mlrParentDialog)
{
super();
super.setModel(new GfrAtmLatLonPoints());
if (tmlParentDialog != null)
super.getModel().addTableModelListener(tmlParentDialog);
if (tmlParentPanel != null)
super.getModel().addTableModelListener(tmlParentPanel);
if (mlrParentDialog != null)
super.addMouseListener(mlrParentDialog);
super.setFillsViewportHeight(true);
}
public ArrayList<Point2D.Double> getValue()
{
int intNbPointConsecOk = _getNumberRowValidConsecutive_();
ArrayList<Point2D.Double> alt = new ArrayList<Point2D.Double>();
for (int i=0; i<intNbPointConsecOk; i++)
{
Double dblLat = (Double) super.getValueAt(i, 1);
Double dblLon = (Double) super.getValueAt(i, 2);
Point2D.Double dbl = new Point2D.Double(dblLon, dblLat);
alt.add(dbl);
}
return alt;
}
@Override
public boolean isOk()
{
int intNbPointConsecOk = _getNumberRowValidConsecutive_();
if (intNbPointConsecOk < _INT_MIN_POINTS_)
{
return false;
}
if (intNbPointConsecOk == 0)
{
// check for missing data in one col
if (! _hasNoMissingData())
return false;
return true;
}
int intLastIdRowValid = _getLastIdRowValid_();
if (intLastIdRowValid+1 != intNbPointConsecOk)
{
if (intLastIdRowValid+1 > intNbPointConsecOk)
{
return false;
}
else
{
String str = "intLastIdRowValid+1 < intNbPointConsecOk, intLastIdRowValid=" + intLastIdRowValid +
", intLastIdRowValid=" + intLastIdRowValid;
GfrTblCheckablePoints._LOGGER_.severe(str);
GfrOptionPaneAbs.s_showDialogError(null, str);
System.exit(1);
}
}
// check for missing data in one col
if (! _hasNoMissingData())
return false;
return true;
}
private boolean _hasNoMissingData()
{
int intCountRow = super.getRowCount();
for (int i=intCountRow-1; i>-1; i--)
{
Double dblCurLat = null;
Double dblCurLon = null;
try
{
dblCurLat = (Double) super.getValueAt(i, 1);
dblCurLon = (Double) super.getValueAt(i, 2);
}
catch(Exception exc)
{
continue;
}
if (dblCurLat==null && dblCurLon==null)
continue;
if (dblCurLat == null)
return false;
if (dblCurLon == null)
return false;
}
return true;
}
@Override
public void tableChanged(TableModelEvent e)
{
super.tableChanged(e);
}
private String _getWrongFormatIdenticalPoints_() throws Exception
{
int intCountRow = super.getRowCount();
ArrayList<Point2D.Double> alt = new ArrayList<Point2D.Double>();
Double dblCurLat = (Double) super.getValueAt(0, 1);
Double dblCurLon = (Double) super.getValueAt(0, 2);
Point2D.Double dbl1 = new Point2D.Double(dblCurLat, dblCurLon);
alt.add(dbl1);
for (int i=1; i<intCountRow; i++)
{
dblCurLat = (Double) super.getValueAt(i, 1);
dblCurLon = (Double) super.getValueAt(i, 2);
Point2D.Double dblCur = new Point2D.Double(dblCurLat, dblCurLon);
for (int j=0; j<alt.size(); j++)
{
double dblDist = dblCur.distanceSq(alt.get(j));
if (dblDist < 0.000000000001d) // !!!!
{
String str = "Same point in row #" + (j+1) + "& row #" + (i+1);
return str;
}
}
alt.add(dblCur);
}
// ending
return null;
}
// not checking last consecutive, just the last one in list
private int _getLastIdRowValid_()
{
int intCountRow = super.getRowCount();
for (int i=intCountRow-1; i>-1; i--)
{
Double dblCurLat = null;
Double dblCurLon = null;
try
{
dblCurLat = (Double) super.getValueAt(i, 1);
dblCurLon = (Double) super.getValueAt(i, 2);
}
catch(Exception exc)
{
continue;
}
if (dblCurLat==null || dblCurLon==null)
continue;
if (! GfrUtilRangeLatLon.s_isOkLat(dblCurLat.doubleValue()))
{
continue;
}
if (! GfrUtilRangeLatLon.s_isOkLon(dblCurLon.doubleValue()))
{
continue;
}
return i;
}
return -1;
}
// starting from first row, else: wrong
private int _getNumberRowValidConsecutive_()
{
int intCountRow = super.getRowCount();
int intCountValid = 0;
for (int i=0; i<intCountRow; i++)
{
Double dblCurLat = null;
Double dblCurLon = null;
try
{
dblCurLat = (Double) super.getValueAt(i, 1);
dblCurLon = (Double) super.getValueAt(i, 2);
}
catch(Exception exc)
{
return intCountValid;
}
if (dblCurLat==null || dblCurLon==null)
return intCountValid;
if (! GfrUtilRangeLatLon.s_isOkLat(dblCurLat.doubleValue()))
{
return intCountValid;
}
if (! GfrUtilRangeLatLon.s_isOkLon(dblCurLon.doubleValue()))
{
return intCountValid;
}
intCountValid ++;
}
return intCountValid;
}
private String _getWrongFormatOutOfRange_()
{
int intCountRow = super.getRowCount();
for (int i=0; i<intCountRow; i++)
{
Double dblCur = null;
try
{
dblCur = (Double) super.getValueAt(i, 1);
}
catch(Exception exc)
{
String str = "Point #" + (i+1) + ": not a valid value of type double for latitude";
return str;
}
if (dblCur == null)
{
return null;
//String str = "Point #" + (i+1) + ": no latitude value";
//return str;
}
if (! GfrUtilRangeLatLon.s_isOkLat(dblCur.doubleValue()))
{
String str = "Latitude out of range: " + dblCur;
str += ", valid range: " + GfrUtilRangeLatLon.s_getMessageRangeLat();
return str;
}
try
{
dblCur = (Double) super.getValueAt(i, 2);
}
catch(Exception exc)
{
String str = "Point #" + (i+1) + ": not a valid value of type double for longitude";
return str;
}
if (dblCur == null)
{
return null;
//String str = "Point #" + (i+1) + ": no longitude value";
//return str;
}
if (! GfrUtilRangeLatLon.s_isOkLon(dblCur.doubleValue()))
{
String str = "Longitude out of range: " + dblCur;
str += ", valid range: " + GfrUtilRangeLatLon.s_getMessageRangeLon();
return str;
}
}
return null;
}
@Override
public String getWrongFormat()
{
// ----
int intNbPointConsecOk = _getNumberRowValidConsecutive_();
int intLastIdRowValid = _getLastIdRowValid_();
if (intLastIdRowValid+1 != intNbPointConsecOk)
{
if (intLastIdRowValid+1 > intNbPointConsecOk)
{
String str = "Gap in between points " + intNbPointConsecOk + " and " + (intLastIdRowValid+1);
return str;
}
else
{
String str = "intLastIdRowValid+1 < intNbPointConsecOk, intLastIdRowValid=" + intLastIdRowValid +
", intLastIdRowValid=" + intLastIdRowValid;
GfrTblCheckablePoints._LOGGER_.severe(str);
GfrOptionPaneAbs.s_showDialogError(null, str);
System.exit(1);
}
}
// ----
String strOutOfRange = this._getWrongFormatOutOfRange_();
if (strOutOfRange != null)
return strOutOfRange;
try
{
String strIdenticalPoints = this._getWrongFormatIdenticalPoints_();
if (strIdenticalPoints != null)
return strIdenticalPoints;
}
catch(Exception exc)
{
return exc.getMessage();
}
// ending
return null;
}
//Implement table cell tool tips.
@Override
public String getToolTipText(MouseEvent e)
{
// beg quick fix
if (! super.isEnabled())
return _STRS_TIP_DATA_[0];
// end quick fix
java.awt.Point p = e.getPoint();
int colIndex = columnAtPoint(p);
return GfrTblCheckablePoints._STRS_TIP_DATA_[colIndex];
}
//Implement table header tool tips.
@Override
protected JTableHeader createDefaultTableHeader()
{
return new JTableHeader(super.columnModel)
{
@Override
public String getToolTipText(MouseEvent e)
{
java.awt.Point p = e.getPoint();
int intIndex = super.columnModel.getColumnIndexAtX(p.x);
int intIndexReal = super.columnModel.getColumn(intIndex).getModelIndex();
return GfrTblCheckablePoints._STRS_TIP_HEADER_[intIndexReal];
}
};
}
}