]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/gui/colour/DateColourer.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / src / tim / prune / gui / colour / DateColourer.java
diff --git a/src/tim/prune/gui/colour/DateColourer.java b/src/tim/prune/gui/colour/DateColourer.java
new file mode 100644 (file)
index 0000000..6dfeca6
--- /dev/null
@@ -0,0 +1,128 @@
+package tim.prune.gui.colour;
+
+import java.awt.Color;
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.TimeZone;
+
+import tim.prune.config.Config;
+import tim.prune.data.DataPoint;
+import tim.prune.data.Timestamp;
+import tim.prune.data.Track;
+import tim.prune.data.TrackInfo;
+
+/**
+ * Point colourer giving a different colour to each date.
+ * Uses the currently selected timezone, so the results
+ * may be different when selecting a different timezone
+ */
+public class DateColourer extends DiscretePointColourer
+{
+       // Doesn't really matter what format is used here, as long as dates are different
+       private static final DateFormat DEFAULT_DATE_FORMAT = DateFormat.getDateInstance();
+       // Selected timezone for deciding which date a timestamp falls on
+       private TimeZone _selectedTimezone = null;
+
+       /**
+        * Constructor
+        * @param inStartColour start colour of scale
+        * @param inEndColour end colour of scale
+        * @param inWrapLength number of unique colours before wrap
+        */
+       public DateColourer(Color inStartColour, Color inEndColour, int inWrapLength)
+       {
+               super(inStartColour, inEndColour, inWrapLength);
+       }
+
+       /**
+        * Calculate the colours for each of the points in the given track
+        * @param inTrackInfo track info object
+        */
+       @Override
+       public synchronized void calculateColours(TrackInfo inTrackInfo)
+       {
+               // Note, this method needs to be synchronized because otherwise the
+               // Calendar objects in the different threads get confused and the
+               // wrong colours are generated.
+
+               // TODO: Move this timezone-selection into a helper for use by others?
+               // Select the current timezone
+               final String zoneId = Config.getConfigString(Config.KEY_TIMEZONE_ID);
+               if (zoneId == null || zoneId.equals("")) {
+                       _selectedTimezone = TimeZone.getDefault();
+               }
+               else {
+                       _selectedTimezone = TimeZone.getTimeZone(zoneId);
+               }
+               // initialise the array to the right size
+               Track track = inTrackInfo == null ? null : inTrackInfo.getTrack();
+               final int numPoints = track == null ? 0 : track.getNumPoints();
+               init(numPoints);
+               // Make a hashmap of the already-used dates
+               HashMap<String, Integer> usedDates = new HashMap<String, Integer>(20);
+               // Also store the previous one, because they're probably consecutive
+               String prevDate = null;
+               int prevIndex = -1;
+
+               // loop over track points
+               int dayIndex = -1;
+               for (int i=0; i<numPoints; i++)
+               {
+                       DataPoint p = track.getPoint(i);
+                       if (p != null && !p.isWaypoint())
+                       {
+                               dayIndex = 0; // default index 0 will be used if no date found
+                               String date = getDate(p.getTimestamp());
+                               if (date != null)
+                               {
+                                       // Check if it's the previous one
+                                       if (prevDate != null && date.equals(prevDate)) {
+                                               dayIndex = prevIndex;
+                                       }
+                                       else
+                                       {
+                                               // Look up in the hashmap to see if it's been used before
+                                               Integer foundIndex = usedDates.get(date);
+                                               if (foundIndex == null)
+                                               {
+                                                       // not been used before, so add it
+                                                       dayIndex = usedDates.size() + 1;
+                                                       usedDates.put(date, dayIndex);
+                                               }
+                                               else
+                                               {
+                                                       // found it
+                                                       dayIndex = foundIndex;
+                                               }
+                                               // Remember what we've got for the next point
+                                               prevDate = date;
+                                               prevIndex = dayIndex;
+                                       }
+                               }
+                               // if date is null (no timestamp or invalid) then dayIndex remains 0
+                               setColour(i, dayIndex);
+                       }
+               }
+
+               // generate the colours needed
+               generateDiscreteColours(usedDates.size() + 1);
+       }
+
+
+       /**
+        * Find which date (in the currently selected timezone) the given timestamp falls on
+        * @param inTimestamp timestamp
+        * @return String containing description of date, or null
+        */
+       private String getDate(Timestamp inTimestamp)
+       {
+               if (inTimestamp == null || !inTimestamp.isValid()) {
+                       return null;
+               }
+               Calendar cal = inTimestamp.getCalendar(null);
+               // use selected time zone, not system one
+               DEFAULT_DATE_FORMAT.setTimeZone(_selectedTimezone);
+               return DEFAULT_DATE_FORMAT.format(cal.getTime());
+       }
+}