]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/data/DataPoint.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / tim / prune / data / DataPoint.java
diff --git a/tim/prune/data/DataPoint.java b/tim/prune/data/DataPoint.java
deleted file mode 100644 (file)
index 84f4800..0000000
+++ /dev/null
@@ -1,615 +0,0 @@
-package tim.prune.data;
-
-import tim.prune.config.Config;
-
-/**
- * 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
-{
-       /** Array of Strings holding raw values */
-       private String[] _fieldValues = null;
-       /** list of field definitions */
-       private FieldList _fieldList = null;
-       /** Special fields for coordinates */
-       private Coordinate _latitude = null, _longitude = null;
-       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 inOptions creation options such as units
-        */
-       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, inOptions);
-       }
-
-
-       /**
-        * Parse the string values into objects eg Coordinates
-        * @param inField field which has changed, or null for all
-        * @param inOptions creation options such as units
-        */
-       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)
-               {
-                       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 TimestampUtc(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")));
-               }
-       }
-
-
-       /**
-        * Constructor for additional points (eg interpolated, photos)
-        * @param inLatitude latitude
-        * @param inLongitude longitude
-        * @param inAltitude altitude
-        */
-       public DataPoint(Coordinate inLatitude, Coordinate inLongitude, Altitude inAltitude)
-       {
-               // Only these three fields are available
-               _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;
-               _fieldValues[1] = inLongitude.output(Coordinate.FORMAT_NONE);
-               if (inAltitude == null) {
-                       _altitude = Altitude.NONE;
-               }
-               else {
-                       _altitude = inAltitude;
-                       _fieldValues[2] = "" + inAltitude.getValue();
-               }
-               _timestamp = new TimestampUtc(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
-        */
-       private String getFieldValue(int inIndex)
-       {
-               if (_fieldValues == null || inIndex < 0 || inIndex >= _fieldValues.length)
-                       return null;
-               return _fieldValues[inIndex];
-       }
-
-
-       /**
-        * 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.getUnit() != null) {
-                       // Altitude already present so reuse format
-                       parseFields(inField, null); // current units will be used
-               }
-               else {
-                       // use default altitude format from config
-                       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 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 != 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 _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()
-       {
-               return (_waypointName != null && !_waypointName.equals(""));
-       }
-
-       /**
-        * @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
-        */
-       public boolean isDuplicate(DataPoint inOther)
-       {
-               if (inOther == null) return false;
-               if (_longitude == null || _latitude == null
-                       || inOther._longitude == null || inOther._latitude == null)
-               {
-                       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 waypoint name (if any)
-               if (!isWaypoint())
-               {
-                       return !inOther.isWaypoint();
-               }
-               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 addTimeOffsetSeconds(long inOffset)
-       {
-               if (hasTimestamp())
-               {
-                       _timestamp.addOffsetSeconds(inOffset);
-                       _fieldValues[_fieldList.getFieldIndex(Field.TIMESTAMP)] = _timestamp.getText(null);
-                       setModified(false);
-               }
-       }
-
-       /**
-        * Set the photo for this data point
-        * @param inPhoto Photo object
-        */
-       public void setPhoto(Photo inPhoto) {
-               _photo = inPhoto;
-               _modifyCount++;
-       }
-
-       /**
-        * @return associated Photo object
-        */
-       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
-        */
-       public boolean isValid()
-       {
-               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
-        * @param inNumPoints number of points to generate
-        * @return the DataPoint array
-        */
-       public DataPoint[] interpolate(DataPoint inEndPoint, int inNumPoints)
-       {
-               DataPoint[] range = new DataPoint[inNumPoints];
-               // Loop over points
-               for (int i=0; i<inNumPoints; i++)
-               {
-                       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)
-        * @param inPoint1 first point
-        * @param inPoint2 second point
-        * @return angular distance between points in radians
-        */
-       public static double calculateRadiansBetween(DataPoint inPoint1, DataPoint inPoint2)
-       {
-               if (inPoint1 == null || inPoint2 == null)
-                       return 0.0;
-               final double TO_RADIANS = Math.PI / 180.0;
-               // Get lat and long from points
-               double lat1 = inPoint1.getLatitude().getDouble() * TO_RADIANS;
-               double lat2 = inPoint2.getLatitude().getDouble() * TO_RADIANS;
-               double lon1 = inPoint1.getLongitude().getDouble() * TO_RADIANS;
-               double lon2 = inPoint2.getLongitude().getDouble() * TO_RADIANS;
-               // Formula given by Wikipedia:Great-circle_distance as follows:
-               // angle = 2 arcsin( sqrt( (sin ((lat2-lat1)/2))^^2 + cos(lat1)cos(lat2)(sin((lon2-lon1)/2))^^2))
-               double firstSine = Math.sin((lat2-lat1) / 2.0);
-               double secondSine = Math.sin((lon2-lon1) / 2.0);
-               double term2 = Math.cos(lat1) * Math.cos(lat2) * secondSine * secondSine;
-               double answer = 2 * Math.asin(Math.sqrt(firstSine*firstSine + term2));
-               // 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 (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, 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()
-        */
-       public String toString()
-       {
-               return "[Lat=" + getLatitude().toString() + ", Lon=" + getLongitude().toString() + "]";
-       }
-}