diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/KmlTrackWriter.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/KmlTrackWriter.java index a7640edbe..0fc315a96 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/KmlTrackWriter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/KmlTrackWriter.java @@ -18,6 +18,7 @@ package com.google.android.apps.mytracks.io.file; import com.google.android.apps.mytracks.content.DescriptionGenerator; import com.google.android.apps.mytracks.content.DescriptionGeneratorImpl; import com.google.android.apps.mytracks.content.MyTracksLocation; +import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.Sensor; import com.google.android.apps.mytracks.content.Sensor.SensorData; import com.google.android.apps.mytracks.content.Sensor.SensorDataSet; @@ -30,7 +31,9 @@ import com.google.android.maps.mytracks.R; import com.google.common.annotations.VisibleForTesting; import android.content.Context; +import android.database.Cursor; import android.location.Location; +import android.net.Uri; import java.io.OutputStream; import java.io.PrintWriter; @@ -65,7 +68,8 @@ public class KmlTrackWriter implements TrackFormatWriter { TRACK_ICON = "http://earth.google.com/images/kml-icons/track-directional/track-0.png"; private final Context context; - private final DescriptionGenerator descriptionGenerator; + private final DescriptionGenerator descriptionGenerator; + private final MyTracksProviderUtils myTracksProviderUtils; private PrintWriter printWriter; private ArrayList powerList = new ArrayList(); private ArrayList cadenceList = new ArrayList(); @@ -82,6 +86,7 @@ public class KmlTrackWriter implements TrackFormatWriter { KmlTrackWriter(Context context, DescriptionGenerator descriptionGenerator) { this.context = context; this.descriptionGenerator = descriptionGenerator; + this.myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context); } @Override @@ -158,8 +163,15 @@ public class KmlTrackWriter implements TrackFormatWriter { if (printWriter != null) { String styleName = waypoint.getType() == WaypointType.STATISTICS ? STATISTICS_STYLE : WAYPOINT_STYLE; - writePlacemark(waypoint.getName(), waypoint.getCategory(), waypoint.getDescription(), - styleName, waypoint.getLocation()); + String photoUrl = waypoint.getPhotoUrl(); + if (photoUrl != null && !photoUrl.equals("")) { + float heading = getHeading(waypoint.getTrackId(), waypoint.getLocation()); + writePhotoOverlay(waypoint.getName(), waypoint.getCategory(), waypoint.getDescription(), + styleName, waypoint.getLocation(), photoUrl, heading); + } else { + writePlacemark(waypoint.getName(), waypoint.getCategory(), waypoint.getDescription(), + styleName, waypoint.getLocation()); + } } } @@ -307,6 +319,76 @@ public class KmlTrackWriter implements TrackFormatWriter { } } + /** + * Writes a photo overlay. + * + * @param name the name + * @param category the category + * @param description the description + * @param styleName the style name + * @param location the location + * @param photoUrl the photo url + * @param heading the heading + */ + private void writePhotoOverlay(String name, String category, String description, String styleName, + Location location, String photoUrl, float heading) { + if (location != null) { + printWriter.println(""); + printWriter.println("" + StringUtils.formatCData(name) + ""); + printWriter.println("" + + StringUtils.formatCData(StringUtils.getCategoryDescription(category, description)) + + ""); + printWriter.print(""); + printWriter.print("" + location.getLongitude() + ""); + printWriter.print("" + location.getLatitude() + ""); + printWriter.print("20"); + printWriter.print("" + heading + ""); + printWriter.print("90"); + printWriter.println(""); + printWriter.println("#" + styleName + ""); + printWriter.println("" + Uri.decode(photoUrl) + ""); + printWriter.print(""); + printWriter.print("10"); + printWriter.print("-60"); + printWriter.print("60"); + printWriter.print("-45"); + printWriter.print("45"); + printWriter.println(""); + printWriter.println(""); + printWriter.println("" + getCoordinates(location, ",") + ""); + printWriter.println(""); + printWriter.println(""); + } + } + + /** + * Gets the heading to a location. + * + * @param trackId the track id containing the location + * @param location the location + */ + private float getHeading(long trackId, Location location) { + long trackPointId = myTracksProviderUtils.getTrackPointId(trackId, location); + if (trackPointId == -1L) { + return location.getBearing(); + } + Cursor cursor = null; + Location viewLocation; + try { + cursor = myTracksProviderUtils.getTrackPointCursor(trackId, trackPointId, 10, true); + if (cursor == null || cursor.getCount() == 0) { + return location.getBearing(); + } + cursor.moveToPosition(cursor.getCount() - 1); + viewLocation = myTracksProviderUtils.createTrackPoint(cursor); + } finally { + if (cursor != null) { + cursor.close(); + } + } + return viewLocation.bearingTo(location); + } + private String getCoordinates(Location location, String separator) { StringBuffer buffer = new StringBuffer(); buffer.append(location.getLongitude() + separator + location.getLatitude()); diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/ListItemUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/ListItemUtils.java index 75463ff7a..c3716bdee 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/ListItemUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/ListItemUtils.java @@ -109,7 +109,8 @@ public class ListItemUtils { // Set category/description TextView descriptionTextView = (TextView) view.findViewById(R.id.list_item_description); - setTextView(descriptionTextView, getDescription(isRecording, category, description)); + setTextView(descriptionTextView, + isRecording ? null : StringUtils.getCategoryDescription(category, description)); } /** @@ -146,30 +147,6 @@ public class ListItemUtils { return buffer.toString(); } - /** - * Gets the description text. - * - * @param isRecording true if recording - * @param category the category - * @param description the description - */ - private static String getDescription(boolean isRecording, String category, String description) { - if (isRecording) { - return null; - } - if (category == null || category.length() == 0) { - return description; - } - - StringBuffer buffer = new StringBuffer(); - - buffer.append("[" + category + "]"); - if (description != null && description.length() != 0) { - buffer.append(" " + description); - } - return buffer.toString(); - } - /** * Gets the start time text. * diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java index 9771fbbf0..9df516edc 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java @@ -228,6 +228,26 @@ public class StringUtils { return result; } + /** + * Gets a string for category and description. + * + * @param category the category + * @param description the description + */ + public static String getCategoryDescription(String category, String description) { + if (category == null || category.length() == 0) { + return description; + } + + StringBuffer buffer = new StringBuffer(); + + buffer.append("[" + category + "]"); + if (description != null && description.length() != 0) { + buffer.append(" " + description); + } + return buffer.toString(); + } + /** * Formats the given text as a XML CDATA element. This includes adding the * starting and ending CDATA tags. Please notice that this may result in diff --git a/MyTracksLib/src/com/google/android/apps/mytracks/content/MyTracksProviderUtils.java b/MyTracksLib/src/com/google/android/apps/mytracks/content/MyTracksProviderUtils.java index 794e4b036..405126eea 100644 --- a/MyTracksLib/src/com/google/android/apps/mytracks/content/MyTracksProviderUtils.java +++ b/MyTracksLib/src/com/google/android/apps/mytracks/content/MyTracksProviderUtils.java @@ -237,6 +237,15 @@ public interface MyTracksProviderUtils { */ public long getLastTrackPointId(long trackId); + /** + * Gets the track point id of a location. + * + * @param trackId the track id + * @param location the location + * @return track point id if the location is in the track. -1L otherwise. + */ + public long getTrackPointId(long trackId, Location location); + /** * Gets the first valid location for a track. Returns null if it doesn't * exist. diff --git a/MyTracksLib/src/com/google/android/apps/mytracks/content/MyTracksProviderUtilsImpl.java b/MyTracksLib/src/com/google/android/apps/mytracks/content/MyTracksProviderUtilsImpl.java index 5d684476a..d119de9a5 100644 --- a/MyTracksLib/src/com/google/android/apps/mytracks/content/MyTracksProviderUtilsImpl.java +++ b/MyTracksLib/src/com/google/android/apps/mytracks/content/MyTracksProviderUtilsImpl.java @@ -788,6 +788,31 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils { } return -1L; } + + @Override + public long getTrackPointId(long trackId, Location location) { + if (trackId < 0) { + return -1L; + } + Cursor cursor = null; + try { + String selection = TrackPointsColumns._ID + "=(select max(" + TrackPointsColumns._ID + + ") from " + TrackPointsColumns.TABLE_NAME + " WHERE " + TrackPointsColumns.TRACKID + + "=? AND " + TrackPointsColumns.TIME + "=?)"; + String[] selectionArgs = new String[] { + Long.toString(trackId), Long.toString(location.getTime()) }; + cursor = getTrackPointCursor(new String[] { TrackPointsColumns._ID }, selection, + selectionArgs, TrackPointsColumns._ID); + if (cursor != null && cursor.moveToFirst()) { + return cursor.getLong(cursor.getColumnIndexOrThrow(TrackPointsColumns._ID)); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + return -1L; + } @Override public Location getFirstValidTrackPoint(long trackId) {