package tim.prune.data; /** * Class to represent a single data point in the series * including all its fields * Can be either a track point or a waypoint */ public class DataPoint { // Hold these as Strings? Or FieldValue objects? private String[] _fieldValues = null; // list of fields private FieldList _fieldList = null; // Special fields for coordinates private Coordinate _latitude = null, _longitude = null; private Altitude _altitude; private Timestamp _timestamp = null; private boolean _pointValid = false; // TODO: Make it possible to turn track point into waypoint - may need to alter FieldList /** * Constructor * @param inValueArray array of String values * @param inFieldList list of fields * @param inAltFormat altitude format */ public DataPoint(String[] inValueArray, FieldList inFieldList, int inAltFormat) { // save data _fieldValues = inValueArray; // save list of fields _fieldList = inFieldList; // parse fields _latitude = new Latitude(getFieldValue(Field.LATITUDE)); _longitude = new Longitude(getFieldValue(Field.LONGITUDE)); _altitude = new Altitude(getFieldValue(Field.ALTITUDE), inAltFormat); _timestamp = new Timestamp(getFieldValue(Field.TIMESTAMP)); } /** * Private constructor for artificially generated points (eg interpolated) * @param inLatitude latitude * @param inLongitude longitude * @param inAltitude altitude */ private DataPoint(Coordinate inLatitude, Coordinate inLongitude, Altitude inAltitude) { // Only these three fields are available _fieldValues = new String[0]; _fieldList = new FieldList(); _latitude = inLatitude; _longitude = inLongitude; _altitude = inAltitude; _timestamp = new Timestamp(null); } /** * Get the value for the given field * @param inField field to interrogate * @return value of field */ public String getFieldValue(Field inField) { return getFieldValue(_fieldList.getFieldIndex(inField)); } /** * Get the value at the given index * @param inIndex index number starting at zero * @return field value, or null if not found */ public String getFieldValue(int inIndex) { if (_fieldValues == null || inIndex < 0 || inIndex >= _fieldValues.length) return null; return _fieldValues[inIndex]; } public Coordinate getLatitude() { return _latitude; } public Coordinate getLongitude() { return _longitude; } public boolean hasAltitude() { return _altitude.isValid(); } public Altitude getAltitude() { return _altitude; } public boolean hasTimestamp() { return _timestamp.isValid(); } public Timestamp getTimestamp() { return _timestamp; } /** * @return true if point has a waypoint name */ public boolean isWaypoint() { String name = getFieldValue(Field.WAYPT_NAME); return (name != null && !name.equals("")); } /** * Compare two DataPoint objects to see if they * are duplicates * @param inOther other object to compare * @return true if the points are equivalent */ public boolean isDuplicate(DataPoint inOther) { if (inOther == null) return false; if (_longitude == null || _latitude == null || inOther._longitude == null || inOther._latitude == null) { return false; } // Compare latitude and longitude if (!_longitude.equals(inOther._longitude) || !_latitude.equals(inOther._latitude)) { return false; } // Note that conversion from decimal to dms can make non-identical points into duplicates // Compare description (if any) String name1 = getFieldValue(Field.WAYPT_NAME); String name2 = inOther.getFieldValue(Field.WAYPT_NAME); if (name1 == null || name1.equals("")) { return (name2 == null || name2.equals("")); } else { return (name2 != null && name2.equals(name1)); } } /** * @return true if the point is valid */ public boolean isValid() { return _latitude.isValid() && _longitude.isValid(); } /** * Interpolate a set of points between this one and the given one * @param inEndPoint end point of interpolation * @param inNumPoints number of points to generate * @return the DataPoint array */ public DataPoint[] interpolate(DataPoint inEndPoint, int inNumPoints) { DataPoint[] range = new DataPoint[inNumPoints]; Coordinate endLatitude = inEndPoint.getLatitude(); Coordinate endLongitude = inEndPoint.getLongitude(); Altitude endAltitude = inEndPoint.getAltitude(); // Loop over points for (int i=0; i