*/
public class DataPoint
{
- // Hold these as Strings? Or FieldValue objects?
+ /** Array of Strings holding raw values */
private String[] _fieldValues = null;
- // list of fields
+ /** list of field definitions */
private FieldList _fieldList = null;
- // Special fields for coordinates
+ /** Special fields for coordinates */
private Coordinate _latitude = null, _longitude = null;
private Altitude _altitude;
private Timestamp _timestamp = null;
- private boolean _pointValid = false;
+ private Photo _photo = null;
+ private String _waypointName = null;
+ // private boolean _startOfSegment = false;
- // TODO: Make it possible to turn track point into waypoint - may need to alter FieldList
-
/**
* Constructor
* @param inValueArray array of String values
_fieldValues = inValueArray;
// save list of fields
_fieldList = inFieldList;
+ // parse fields into objects
+ parseFields(inAltFormat);
+ }
+
- // parse fields
+ /**
+ * Parse the string values into objects eg Coordinates
+ * @param inAltFormat altitude format
+ */
+ private void parseFields(int inAltFormat)
+ {
_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));
+ _waypointName = getFieldValue(Field.WAYPT_NAME);
+ // TODO: Parse segment start field (format?)
}
/**
- * Private constructor for artificially generated points (eg interpolated)
+ * Constructor for additional points (eg interpolated, photos)
* @param inLatitude latitude
* @param inLongitude longitude
* @param inAltitude altitude
*/
- private DataPoint(Coordinate inLatitude, Coordinate inLongitude, Altitude inAltitude)
+ public DataPoint(Coordinate inLatitude, Coordinate inLongitude, Altitude inAltitude)
{
// Only these three fields are available
- _fieldValues = new String[0];
- _fieldList = new FieldList();
+ _fieldValues = new String[3];
+ Field[] fields = {Field.LATITUDE, Field.LONGITUDE, Field.ALTITUDE};
+ _fieldList = new FieldList(fields);
_latitude = inLatitude;
+ _fieldValues[0] = inLatitude.output(Coordinate.FORMAT_DEG_MIN_SEC);
_longitude = inLongitude;
+ _fieldValues[1] = inLongitude.output(Coordinate.FORMAT_DEG_MIN_SEC);
_altitude = inAltitude;
+ if (inAltitude != null) {_fieldValues[2] = "" + inAltitude.getValue(Altitude.FORMAT_METRES);}
_timestamp = new Timestamp(null);
}
}
+ /**
+ * Set (or edit) the specified field value
+ * @param inField Field to set
+ * @param inValue value to set
+ */
+ public void setFieldValue(Field inField, String inValue)
+ {
+ // See if this data point already has this field
+ int fieldIndex = _fieldList.getFieldIndex(inField);
+ // Add to field list if necessary
+ if (fieldIndex < 0)
+ {
+ // If value is empty & field doesn't exist then do nothing
+ if (inValue == null || inValue.equals(""))
+ {
+ return;
+ }
+ // value isn't empty so extend field list
+ fieldIndex = _fieldList.extendList(inField);
+ }
+ // Extend array of field values if necessary
+ if (fieldIndex >= _fieldValues.length)
+ {
+ resizeValueArray(fieldIndex);
+ }
+ // Set field value in array
+ _fieldValues[fieldIndex] = inValue;
+ // Change Coordinate, Altitude, Name or Timestamp fields after edit
+ if (_altitude != null)
+ {
+ parseFields(_altitude.getFormat());
+ }
+ else
+ {
+ // use default altitude format of metres
+ parseFields(Altitude.FORMAT_METRES);
+ }
+ }
+
+
+ /** @return latitude */
public Coordinate getLatitude()
{
return _latitude;
}
+ /** @return longitude */
public Coordinate getLongitude()
{
return _longitude;
}
+ /** @return true if point has altitude */
public boolean hasAltitude()
{
return _altitude.isValid();
}
+ /** @return altitude */
public Altitude getAltitude()
{
return _altitude;
}
+ /** @return true if point has timestamp */
public boolean hasTimestamp()
{
return _timestamp.isValid();
}
+ /** @return timestamp */
public Timestamp getTimestamp()
{
return _timestamp;
}
+ /** @return waypoint name, if any */
+ public String getWaypointName()
+ {
+ return _waypointName;
+ }
/**
* @return true if point has a waypoint name
*/
public boolean isWaypoint()
{
- String name = getFieldValue(Field.WAYPT_NAME);
- return (name != null && !name.equals(""));
+ return (_waypointName != null && !_waypointName.equals(""));
}
+
/**
- * Compare two DataPoint objects to see if they
- * are duplicates
+ * Compare two DataPoint objects to see if they are duplicates
* @param inOther other object to compare
* @return true if the points are equivalent
*/
{
return false;
}
+ // Make sure photo points aren't specified as duplicates
+ if (_photo != 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
+ // Compare waypoint name (if any)
+ if (!isWaypoint())
{
- return (name2 != null && name2.equals(name1));
+ return !inOther.isWaypoint();
}
+ return (inOther._waypointName != null && inOther._waypointName.equals(_waypointName));
+ }
+
+
+ /**
+ * Set the photo for this data point
+ * @param inPhoto Photo object
+ */
+ public void setPhoto(Photo inPhoto)
+ {
+ _photo = inPhoto;
+ }
+
+
+ /**
+ * @return associated Photo object
+ */
+ public Photo getPhoto()
+ {
+ return _photo;
}
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<inNumPoints; i++)
{
- Coordinate latitude = Coordinate.interpolate(_latitude, endLatitude, i, inNumPoints);
- Coordinate longitude = Coordinate.interpolate(_longitude, endLongitude, i, inNumPoints);
- Altitude altitude = Altitude.interpolate(_altitude, endAltitude, i, inNumPoints);
+ Coordinate latitude = Coordinate.interpolate(_latitude, inEndPoint.getLatitude(), i, inNumPoints);
+ Coordinate longitude = Coordinate.interpolate(_longitude, inEndPoint.getLongitude(), i, inNumPoints);
+ Altitude altitude = Altitude.interpolate(_altitude, inEndPoint.getAltitude(), i, inNumPoints);
range[i] = new DataPoint(latitude, longitude, altitude);
}
return range;
}
+ /**
+ * Interpolate between the two given points
+ * @param inStartPoint start point
+ * @param inEndPoint end point
+ * @param inFrac fractional distance from first point (0.0 to 1.0)
+ * @return new DataPoint object between two given ones
+ */
+ public static DataPoint interpolate(DataPoint inStartPoint, DataPoint inEndPoint, double inFrac)
+ {
+ if (inStartPoint == null || inEndPoint == null) {return null;}
+ return new DataPoint(
+ Coordinate.interpolate(inStartPoint.getLatitude(), inEndPoint.getLatitude(), inFrac),
+ Coordinate.interpolate(inStartPoint.getLongitude(), inEndPoint.getLongitude(), inFrac),
+ Altitude.interpolate(inStartPoint.getAltitude(), inEndPoint.getAltitude(), inFrac)
+ );
+ }
/**
* Calculate the number of radians between two points (for distance calculation)
// phew
return answer;
}
+
+
+ /**
+ * Resize the value array
+ * @param inNewIndex new index to allow
+ */
+ private void resizeValueArray(int inNewIndex)
+ {
+ int newSize = inNewIndex + 1;
+ if (newSize > _fieldValues.length)
+ {
+ String[] newArray = new String[newSize];
+ System.arraycopy(_fieldValues, 0, newArray, 0, _fieldValues.length);
+ _fieldValues = newArray;
+ }
+ }
+
+
+ /**
+ * @return a clone object with copied data
+ */
+ public DataPoint clonePoint()
+ {
+ // Copy all values
+ String[] valuesCopy = new String[_fieldValues.length];
+ System.arraycopy(_fieldValues, 0, valuesCopy, 0, _fieldValues.length);
+ // Make new object to hold cloned data
+ DataPoint point = new DataPoint(valuesCopy, _fieldList, _altitude.getFormat());
+ return point;
+ }
+
+
+ /**
+ * Restore the contents from another point
+ * @param inOther point containing contents to copy
+ * @return true if successful
+ */
+ public boolean restoreContents(DataPoint inOther)
+ {
+ if (inOther != null)
+ {
+ // Copy string values across
+ _fieldValues = inOther._fieldValues;
+ if (_altitude != null)
+ {
+ parseFields(_altitude.getFormat());
+ }
+ else
+ {
+ // use default altitude format of metres
+ parseFields(Altitude.FORMAT_METRES);
+ }
+ return true;
+ }
+ return false;
+ }
+
+
+ /**
+ * Get string for debug
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ return "[Lat=" + getLatitude().toString() + ", Lon=" + getLongitude().toString() + "]";
+ }
}