private FieldList _fieldList = null;
/** Special fields for coordinates */
private Coordinate _latitude = null, _longitude = null;
- private Altitude _altitude;
+ private Altitude _altitude = null;
+ private Speed _hSpeed = null, _vSpeed = null;
private Timestamp _timestamp = null;
+ /** Attached photo */
private Photo _photo = null;
+ /** Attached audio clip */
+ private AudioClip _audio = null;
private String _waypointName = null;
private boolean _startOfSegment = false;
private boolean _markedForDeletion = false;
private int _modifyCount = 0;
+
/**
* Constructor
* @param inValueArray array of String values
* @param inFieldList list of fields
- * @param inAltFormat altitude format
+ * @param inOptions creation options such as units
*/
- public DataPoint(String[] inValueArray, FieldList inFieldList, Altitude.Format inAltFormat)
+ public DataPoint(String[] inValueArray, FieldList inFieldList, PointCreateOptions inOptions)
{
// save data
_fieldValues = inValueArray;
// save list of fields
_fieldList = inFieldList;
+ // Remove double quotes around values
+ removeQuotes(_fieldValues);
// parse fields into objects
- parseFields(null, inAltFormat);
+ parseFields(null, inOptions);
}
/**
* Parse the string values into objects eg Coordinates
* @param inField field which has changed, or null for all
- * @param inAltFormat altitude format
+ * @param inOptions creation options such as units
*/
- private void parseFields(Field inField, Altitude.Format inAltFormat)
+ private void parseFields(Field inField, PointCreateOptions inOptions)
{
+ if (inOptions == null) inOptions = new PointCreateOptions();
if (inField == null || inField == Field.LATITUDE) {
_latitude = new Latitude(getFieldValue(Field.LATITUDE));
}
if (inField == null || inField == Field.LONGITUDE) {
_longitude = new Longitude(getFieldValue(Field.LONGITUDE));
}
- if (inField == null || inField == Field.ALTITUDE) {
- _altitude = new Altitude(getFieldValue(Field.ALTITUDE), inAltFormat);
+ if (inField == null || inField == Field.ALTITUDE)
+ {
+ Unit altUnit = inOptions.getAltitudeUnits();
+ if (_altitude != null && _altitude.getUnit() != null) {
+ altUnit = _altitude.getUnit();
+ }
+ _altitude = new Altitude(getFieldValue(Field.ALTITUDE), altUnit);
+ }
+ if (inField == null || inField == Field.SPEED)
+ {
+ _hSpeed = new Speed(getFieldValue(Field.SPEED), inOptions.getSpeedUnits());
+ }
+ if (inField == null || inField == Field.VERTICAL_SPEED)
+ {
+ _vSpeed = new Speed(getFieldValue(Field.VERTICAL_SPEED), inOptions.getVerticalSpeedUnits());
+ if (!inOptions.getVerticalSpeedsUpwards()) {
+ _vSpeed.invert();
+ }
}
if (inField == null || inField == Field.TIMESTAMP) {
_timestamp = new Timestamp(getFieldValue(Field.TIMESTAMP));
* @param inIndex index number starting at zero
* @return field value, or null if not found
*/
- public String getFieldValue(int inIndex)
+ private String getFieldValue(int inIndex)
{
if (_fieldValues == null || inIndex < 0 || inIndex >= _fieldValues.length)
return null;
_fieldValues[fieldIndex] = inValue;
// Increment edit count on all field edits except segment
if (inField != Field.NEW_SEGMENT) {
- if (!inUndo) {
- _modifyCount++;
- }
- else {
- _modifyCount--;
- }
+ setModified(inUndo);
}
// Change Coordinate, Altitude, Name or Timestamp fields after edit
- if (_altitude != null && _altitude.getFormat() != Altitude.Format.NO_FORMAT) {
+ if (_altitude != null && _altitude.getUnit() != null) {
// Altitude already present so reuse format
- parseFields(inField, _altitude.getFormat());
+ parseFields(inField, null); // current units will be used
}
else {
// use default altitude format from config
- parseFields(inField, Config.getConfigBoolean(Config.KEY_METRIC_UNITS)?Altitude.Format.METRES:Altitude.Format.FEET);
+ parseFields(inField, Config.getUnitSet().getDefaultOptions());
+ }
+ }
+
+ /**
+ * Either increment or decrement the modify count, depending on whether it's an undo or not
+ * @param inUndo true for undo, false otherwise
+ */
+ public void setModified(boolean inUndo)
+ {
+ if (!inUndo) {
+ _modifyCount++;
+ }
+ else {
+ _modifyCount--;
}
}
/** @return true if point has altitude */
public boolean hasAltitude()
{
- return _altitude.isValid();
+ return _altitude != null && _altitude.isValid();
}
/** @return altitude */
public Altitude getAltitude()
{
return _altitude;
}
+ /** @return true if point has horizontal speed (loaded as field) */
+ public boolean hasHSpeed()
+ {
+ return _hSpeed != null && _hSpeed.isValid();
+ }
+ /** @return horizontal speed */
+ public Speed getHSpeed()
+ {
+ return _hSpeed;
+ }
+ /** @return true if point has vertical speed (loaded as field) */
+ public boolean hasVSpeed()
+ {
+ return _vSpeed != null && _vSpeed.isValid();
+ }
+ /** @return vertical speed */
+ public Speed getVSpeed()
+ {
+ return _vSpeed;
+ }
/** @return true if point has timestamp */
public boolean hasTimestamp()
{
return (inOther._waypointName != null && inOther._waypointName.equals(_waypointName));
}
+ /**
+ * Add an altitude offset to this point, and keep the point's string value in sync
+ * @param inOffset offset as double
+ * @param inUnit unit of offset, feet or metres
+ * @param inDecimals number of decimal places
+ */
+ public void addAltitudeOffset(double inOffset, Unit inUnit, int inDecimals)
+ {
+ if (hasAltitude())
+ {
+ _altitude.addOffset(inOffset, inUnit, inDecimals);
+ _fieldValues[_fieldList.getFieldIndex(Field.ALTITUDE)] = _altitude.getStringValue(null);
+ setModified(false);
+ }
+ }
+
+ /**
+ * Reset the altitude to the previous value (by an undo)
+ * @param inClone altitude object cloned from earlier
+ */
+ public void resetAltitude(Altitude inClone)
+ {
+ _altitude.reset(inClone);
+ _fieldValues[_fieldList.getFieldIndex(Field.ALTITUDE)] = _altitude.getStringValue(null);
+ setModified(true);
+ }
+
+ /**
+ * Add a time offset to this point
+ * @param inOffset offset to add (-ve to subtract)
+ */
+ public void addTimeOffset(long inOffset)
+ {
+ if (hasTimestamp())
+ {
+ _timestamp.addOffset(inOffset);
+ _fieldValues[_fieldList.getFieldIndex(Field.TIMESTAMP)] = _timestamp.getText();
+ setModified(false);
+ }
+ }
/**
* Set the photo for this data point
* @param inPhoto Photo object
*/
- public void setPhoto(Photo inPhoto)
- {
+ public void setPhoto(Photo inPhoto) {
_photo = inPhoto;
+ _modifyCount++;
}
-
/**
* @return associated Photo object
*/
- public Photo getPhoto()
- {
+ public Photo getPhoto() {
return _photo;
}
+ /**
+ * Set the audio clip for this point
+ * @param inAudio audio object
+ */
+ public void setAudio(AudioClip inAudio) {
+ _audio = inAudio;
+ _modifyCount++;
+ }
+
+ /**
+ * @return associated audio object
+ */
+ public AudioClip getAudio() {
+ return _audio;
+ }
+
+ /**
+ * Attach the given media object according to type
+ * @param inMedia either a photo or an audio clip
+ */
+ public void attachMedia(MediaObject inMedia)
+ {
+ if (inMedia != null) {
+ if (inMedia instanceof Photo) {
+ setPhoto((Photo) inMedia);
+ inMedia.setDataPoint(this);
+ }
+ else if (inMedia instanceof AudioClip) {
+ setAudio((AudioClip) inMedia);
+ inMedia.setDataPoint(this);
+ }
+ }
+ }
/**
* @return true if the point is valid
return _latitude.isValid() && _longitude.isValid();
}
+ /**
+ * @return true if the point has either a photo or audio attached
+ */
+ public boolean hasMedia() {
+ return _photo != null || _audio != null;
+ }
+
+ /**
+ * @return name of attached photo and/or audio
+ */
+ public String getMediaName()
+ {
+ String mediaName = null;
+ if (_photo != null) mediaName = _photo.getName();
+ if (_audio != null)
+ {
+ if (mediaName == null) {
+ mediaName = _audio.getName();
+ }
+ else {
+ mediaName = mediaName + ", " + _audio.getName();
+ }
+ }
+ return mediaName;
+ }
+
/**
* Interpolate a set of points between this one and the given one
* @param inEndPoint end point of interpolation
// Copy all values (note that photo not copied)
String[] valuesCopy = new String[_fieldValues.length];
System.arraycopy(_fieldValues, 0, valuesCopy, 0, _fieldValues.length);
+
+ PointCreateOptions options = new PointCreateOptions();
+ if (_altitude != null) {
+ options.setAltitudeUnits(_altitude.getUnit());
+ }
// Make new object to hold cloned data
- DataPoint point = new DataPoint(valuesCopy, _fieldList, _altitude.getFormat());
+ DataPoint point = new DataPoint(valuesCopy, _fieldList, options);
+ // Copy the speed information
+ if (hasHSpeed()) {
+ point.getHSpeed().copyFrom(_hSpeed);
+ }
+ if (hasVSpeed()) {
+ point.getVSpeed().copyFrom(_vSpeed);
+ }
return point;
}
+ /**
+ * Remove all single and double quotes surrounding each value
+ * @param inValues array of values
+ */
+ private static void removeQuotes(String[] inValues)
+ {
+ if (inValues == null) {return;}
+ for (int i=0; i<inValues.length; i++)
+ {
+ inValues[i] = removeQuotes(inValues[i]);
+ }
+ }
+
+ /**
+ * Remove any single or double quotes surrounding a value
+ * @param inValue value to modify
+ * @return modified String
+ */
+ private static String removeQuotes(String inValue)
+ {
+ if (inValue == null) {return inValue;}
+ final int len = inValue.length();
+ if (len <= 1) {return inValue;}
+ // get the first and last characters
+ final char firstChar = inValue.charAt(0);
+ final char lastChar = inValue.charAt(len-1);
+ if (firstChar == lastChar)
+ {
+ if (firstChar == '\"' || firstChar == '\'') {
+ return inValue.substring(1, len-1);
+ }
+ }
+ return inValue;
+ }
+
/**
* Get string for debug
* @see java.lang.Object#toString()