Add play in earth with photo overlays

This commit is contained in:
Jimmy Shih
2013-08-19 15:54:32 -07:00
parent 24a343661d
commit ec3f0ddab3
5 changed files with 141 additions and 28 deletions
@@ -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<Integer> powerList = new ArrayList<Integer>();
private ArrayList<Integer> cadenceList = new ArrayList<Integer>();
@@ -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("<PhotoOverlay>");
printWriter.println("<name>" + StringUtils.formatCData(name) + "</name>");
printWriter.println("<description>"
+ StringUtils.formatCData(StringUtils.getCategoryDescription(category, description))
+ "</description>");
printWriter.print("<Camera>");
printWriter.print("<longitude>" + location.getLongitude() + "</longitude>");
printWriter.print("<latitude>" + location.getLatitude() + "</latitude>");
printWriter.print("<altitude>20</altitude>");
printWriter.print("<heading>" + heading + "</heading>");
printWriter.print("<tilt>90</tilt>");
printWriter.println("</Camera>");
printWriter.println("<styleUrl>#" + styleName + "</styleUrl>");
printWriter.println("<Icon><href>" + Uri.decode(photoUrl) + "</href></Icon>");
printWriter.print("<ViewVolume>");
printWriter.print("<near>10</near>");
printWriter.print("<leftFov>-60</leftFov>");
printWriter.print("<rightFov>60</rightFov>");
printWriter.print("<bottomFov>-45</bottomFov>");
printWriter.print("<topFov>45</topFov>");
printWriter.println("</ViewVolume>");
printWriter.println("<Point>");
printWriter.println("<coordinates>" + getCoordinates(location, ",") + "</coordinates>");
printWriter.println("</Point>");
printWriter.println("</PhotoOverlay>");
}
}
/**
* 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());
@@ -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.
*
@@ -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
@@ -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.
@@ -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) {