X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Fdata%2FDataPoint.java;h=bba7adc670f90078a8deb0a3280b6fa109ef8a39;hb=140e9d165f85c3d4f0435a311e091209313faa2a;hp=5d66ec55783a596d7bef1f1cd671dbe75a8c5b13;hpb=312fec956e43f5d0a38617da5d0add9c62563e2c;p=GpsPrune.git diff --git a/tim/prune/data/DataPoint.java b/tim/prune/data/DataPoint.java index 5d66ec5..bba7adc 100644 --- a/tim/prune/data/DataPoint.java +++ b/tim/prune/data/DataPoint.java @@ -1,5 +1,7 @@ package tim.prune.data; +import tim.prune.config.Config; + /** * Class to represent a single data point in the series * including all its fields @@ -7,18 +9,19 @@ package tim.prune.data; */ 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; - - - // TODO: Make it possible to turn track point into waypoint - may need to alter FieldList + private Photo _photo = null; + private String _waypointName = null; + private boolean _startOfSegment = false; + private boolean _markedForDeletion = false; + private int _modifyCount = 0; /** * Constructor @@ -26,35 +29,71 @@ public class DataPoint * @param inFieldList list of fields * @param inAltFormat altitude format */ - public DataPoint(String[] inValueArray, FieldList inFieldList, int inAltFormat) + public DataPoint(String[] inValueArray, FieldList inFieldList, Altitude.Format inAltFormat) { // save data _fieldValues = inValueArray; // save list of fields _fieldList = inFieldList; + // parse fields into objects + parseFields(null, inAltFormat); + } - // 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)); + + /** + * Parse the string values into objects eg Coordinates + * @param inField field which has changed, or null for all + * @param inAltFormat altitude format + */ + private void parseFields(Field inField, Altitude.Format inAltFormat) + { + 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.TIMESTAMP) { + _timestamp = new Timestamp(getFieldValue(Field.TIMESTAMP)); + } + if (inField == null || inField == Field.WAYPT_NAME) { + _waypointName = getFieldValue(Field.WAYPT_NAME); + } + if (inField == null || inField == Field.NEW_SEGMENT) + { + String segmentStr = getFieldValue(Field.NEW_SEGMENT); + if (segmentStr != null) {segmentStr = segmentStr.trim();} + _startOfSegment = (segmentStr != null && (segmentStr.equals("1") || segmentStr.toUpperCase().equals("Y"))); + } } /** - * 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_NONE); _longitude = inLongitude; - _altitude = inAltitude; + _fieldValues[1] = inLongitude.output(Coordinate.FORMAT_NONE); + if (inAltitude == null) { + _altitude = Altitude.NONE; + } + else { + _altitude = inAltitude; + _fieldValues[2] = "" + inAltitude.getValue(); + } _timestamp = new Timestamp(null); } @@ -83,43 +122,151 @@ public class DataPoint } + /** + * Set (or edit) the specified field value + * @param inField Field to set + * @param inValue value to set + * @param inUndo true if undo operation, false otherwise + */ + public void setFieldValue(Field inField, String inValue, boolean inUndo) + { + // 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; + // Increment edit count on all field edits except segment + if (inField != Field.NEW_SEGMENT) { + setModified(inUndo); + } + // Change Coordinate, Altitude, Name or Timestamp fields after edit + if (_altitude != null && _altitude.getFormat() != Altitude.Format.NO_FORMAT) { + // Altitude already present so reuse format + parseFields(inField, _altitude.getFormat()); + } + else { + // use default altitude format from config + parseFields(inField, Config.getConfigBoolean(Config.KEY_METRIC_UNITS)?Altitude.Format.METRES:Altitude.Format.FEET); + } + } + + /** + * 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 field list for this point + */ + public FieldList getFieldList() + { + return _fieldList; + } + + /** @param inFlag true for start of track segment */ + public void setSegmentStart(boolean inFlag) + { + setFieldValue(Field.NEW_SEGMENT, inFlag?"1":null, false); + } + + /** + * Mark the point for deletion + * @param inFlag true to delete, false to keep + */ + public void setMarkedForDeletion(boolean inFlag) { + _markedForDeletion = inFlag; + } + + /** @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 start of new track segment */ + public boolean getSegmentStart() + { + return _startOfSegment; + } + + /** @return true if point marked for deletion */ + public boolean getDeleteFlag() + { + return _markedForDeletion; + } /** * @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 + * @return true if point has been modified since loading + */ + public boolean isModified() + { + return _modifyCount > 0; + } + + /** + * Compare two DataPoint objects to see if they are duplicates * @param inOther other object to compare * @return true if the points are equivalent */ @@ -131,23 +278,39 @@ public class DataPoint { 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; } @@ -159,7 +322,6 @@ public class DataPoint return _latitude.isValid() && _longitude.isValid(); } - /** * Interpolate a set of points between this one and the given one * @param inEndPoint end point of interpolation @@ -169,21 +331,33 @@ public class DataPoint 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 _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 (note that photo not copied) + 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; + } + + + /** + * Get string for debug + * @see java.lang.Object#toString() + */ + public String toString() + { + return "[Lat=" + getLatitude().toString() + ", Lon=" + getLongitude().toString() + "]"; + } }