mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-02 09:33:06 +02:00
Initial import of MyTracks content files and their dependencies.
MyTracksUtils and MyTracksConstants are cut-down versions of the original files which contain only what's used by the content package, we'll later post the rest of them.
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
/**
|
||||
* Constants used by the MyTracks application.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public abstract class MyTracksConstants {
|
||||
|
||||
/**
|
||||
* Should be used by all log statements
|
||||
*/
|
||||
public static final String TAG = "MyTracks";
|
||||
|
||||
/**
|
||||
* This is an abstract utility class.
|
||||
*/
|
||||
private MyTracksConstants() { }
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* An interface for an object that can generate descriptions of waypoints.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public interface DescriptionGenerator {
|
||||
|
||||
/**
|
||||
* Generate a description of the waypoint.
|
||||
*/
|
||||
public String generateWaypointDescription(Waypoint waypoint);
|
||||
|
||||
/**
|
||||
* Generates a description for a track (with information about the
|
||||
* statistics).
|
||||
*
|
||||
* @param track the track
|
||||
* @return a track description
|
||||
*/
|
||||
public String generateTrackDescription(Track track, Vector<Double> distances,
|
||||
Vector<Double> elevations);
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.UriMatcher;
|
||||
import android.database.Cursor;
|
||||
import android.database.SQLException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.database.sqlite.SQLiteQueryBuilder;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A provider that handles recorded (GPS) tracks and their track points.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class MyTracksProvider extends ContentProvider {
|
||||
|
||||
private static final String DATABASE_NAME = "mytracks.db";
|
||||
private static final int DATABASE_VERSION = 17;
|
||||
private static final int TRACKPOINTS = 1;
|
||||
private static final int TRACKPOINTS_ID = 2;
|
||||
private static final int TRACKS = 3;
|
||||
private static final int TRACKS_ID = 4;
|
||||
private static final int WAYPOINTS = 5;
|
||||
private static final int WAYPOINTS_ID = 6;
|
||||
private static final String TRACKPOINTS_TABLE = "trackpoints";
|
||||
private static final String TRACKS_TABLE = "tracks";
|
||||
private static final String WAYPOINTS_TABLE = "waypoints";
|
||||
public static final String TAG = "MyTracksProvider";
|
||||
|
||||
/**
|
||||
* Helper which creates or upgrades the database if necessary.
|
||||
*/
|
||||
private static class DatabaseHelper extends SQLiteOpenHelper {
|
||||
|
||||
public DatabaseHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL("CREATE TABLE " + TRACKPOINTS_TABLE + " ("
|
||||
+ TrackPointsColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ TrackPointsColumns.TRACKID + " INTEGER, "
|
||||
+ TrackPointsColumns.LONGITUDE + " INTEGER, "
|
||||
+ TrackPointsColumns.LATITUDE + " INTEGER, "
|
||||
+ TrackPointsColumns.TIME + " INTEGER, "
|
||||
+ TrackPointsColumns.ALTITUDE + " FLOAT, "
|
||||
+ TrackPointsColumns.ACCURACY + " FLOAT, "
|
||||
+ TrackPointsColumns.SPEED + " FLOAT, "
|
||||
+ TrackPointsColumns.BEARING + " FLOAT);");
|
||||
db.execSQL("CREATE TABLE " + TRACKS_TABLE + " ("
|
||||
+ TracksColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ TracksColumns.NAME + " STRING, "
|
||||
+ TracksColumns.DESCRIPTION + " STRING, "
|
||||
+ TracksColumns.CATEGORY + " STRING, "
|
||||
+ TracksColumns.STARTID + " INTEGER, "
|
||||
+ TracksColumns.STOPID + " INTEGER, "
|
||||
+ TracksColumns.STARTTIME + " INTEGER, "
|
||||
+ TracksColumns.STOPTIME + " INTEGER, "
|
||||
+ TracksColumns.NUMPOINTS + " INTEGER, "
|
||||
+ TracksColumns.TOTALDISTANCE + " FLOAT, "
|
||||
+ TracksColumns.TOTALTIME + " INTEGER, "
|
||||
+ TracksColumns.MOVINGTIME + " INTEGER, "
|
||||
+ TracksColumns.MINLAT + " INTEGER, "
|
||||
+ TracksColumns.MAXLAT + " INTEGER, "
|
||||
+ TracksColumns.MINLON + " INTEGER, "
|
||||
+ TracksColumns.MAXLON + " INTEGER, "
|
||||
+ TracksColumns.AVGSPEED + " FLOAT, "
|
||||
+ TracksColumns.AVGMOVINGSPEED + " FLOAT, "
|
||||
+ TracksColumns.MAXSPEED + " FLOAT, "
|
||||
+ TracksColumns.MINELEVATION + " FLOAT, "
|
||||
+ TracksColumns.MAXELEVATION + " FLOAT, "
|
||||
+ TracksColumns.ELEVATIONGAIN + " FLOAT, "
|
||||
+ TracksColumns.MINGRADE + " FLOAT, "
|
||||
+ TracksColumns.MAXGRADE + " FLOAT, "
|
||||
+ TracksColumns.MAPID + " STRING);");
|
||||
db.execSQL("CREATE TABLE " + WAYPOINTS_TABLE + " ("
|
||||
+ WaypointsColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ WaypointsColumns.NAME + " STRING, "
|
||||
+ WaypointsColumns.DESCRIPTION + " STRING, "
|
||||
+ WaypointsColumns.CATEGORY + " STRING, "
|
||||
+ WaypointsColumns.ICON + " STRING, "
|
||||
+ WaypointsColumns.TRACKID + " INTEGER, "
|
||||
+ WaypointsColumns.TYPE + " INTEGER, "
|
||||
+ WaypointsColumns.LENGTH + " FLOAT, "
|
||||
+ WaypointsColumns.DURATION + " INTEGER, "
|
||||
+ WaypointsColumns.STARTTIME + " INTEGER, "
|
||||
+ WaypointsColumns.STARTID + " INTEGER, "
|
||||
+ WaypointsColumns.STOPID + " INTEGER, "
|
||||
+ WaypointsColumns.LONGITUDE + " INTEGER, "
|
||||
+ WaypointsColumns.LATITUDE + " INTEGER, "
|
||||
+ WaypointsColumns.TIME + " INTEGER, "
|
||||
+ WaypointsColumns.ALTITUDE + " FLOAT, "
|
||||
+ WaypointsColumns.ACCURACY + " FLOAT, "
|
||||
+ WaypointsColumns.SPEED + " FLOAT, "
|
||||
+ WaypointsColumns.BEARING + " FLOAT, "
|
||||
+ WaypointsColumns.TOTALDISTANCE + " FLOAT, "
|
||||
+ WaypointsColumns.TOTALTIME + " INTEGER, "
|
||||
+ WaypointsColumns.MOVINGTIME + " INTEGER, "
|
||||
+ WaypointsColumns.AVGSPEED + " FLOAT, "
|
||||
+ WaypointsColumns.AVGMOVINGSPEED + " FLOAT, "
|
||||
+ WaypointsColumns.MAXSPEED + " FLOAT, "
|
||||
+ WaypointsColumns.MINELEVATION + " FLOAT, "
|
||||
+ WaypointsColumns.MAXELEVATION + " FLOAT, "
|
||||
+ WaypointsColumns.ELEVATIONGAIN + " FLOAT, "
|
||||
+ WaypointsColumns.MINGRADE + " FLOAT, "
|
||||
+ WaypointsColumns.MAXGRADE + " FLOAT);");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
|
||||
+ newVersion + ", which will destroy all old data");
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TRACKPOINTS_TABLE);
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TRACKS_TABLE);
|
||||
db.execSQL("DROP TABLE IF EXISTS " + WAYPOINTS_TABLE);
|
||||
onCreate(db);
|
||||
}
|
||||
}
|
||||
|
||||
private final UriMatcher urlMatcher;
|
||||
|
||||
private SQLiteDatabase db;
|
||||
|
||||
public MyTracksProvider() {
|
||||
urlMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.AUTHORITY,
|
||||
"trackpoints", TRACKPOINTS);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.AUTHORITY,
|
||||
"trackpoints/#", TRACKPOINTS_ID);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.AUTHORITY, "tracks", TRACKS);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.AUTHORITY, "tracks/#", TRACKS_ID);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.AUTHORITY, "waypoints", WAYPOINTS);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.AUTHORITY,
|
||||
"waypoints/#", WAYPOINTS_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
DatabaseHelper dbHelper = new DatabaseHelper(getContext());
|
||||
db = dbHelper.getWritableDatabase();
|
||||
return db != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(Uri url, String where, String[] selectionArgs) {
|
||||
if (urlMatcher.match(url) == TRACKPOINTS) {
|
||||
Log.w(MyTracksProvider.TAG, "provider trackpoints delete!");
|
||||
int count = db.delete(TRACKPOINTS_TABLE, where, selectionArgs);
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return count;
|
||||
} else if (urlMatcher.match(url) == TRACKS) {
|
||||
Log.w(MyTracksProvider.TAG, "provider track delete!");
|
||||
int count = db.delete(TRACKS_TABLE, where, selectionArgs);
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return count;
|
||||
} else if (urlMatcher.match(url) == WAYPOINTS) {
|
||||
Log.w(MyTracksProvider.TAG, "provider waypoint delete!");
|
||||
int count = db.delete(WAYPOINTS_TABLE, where, selectionArgs);
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return count;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri url) {
|
||||
switch (urlMatcher.match(url)) {
|
||||
case TRACKPOINTS:
|
||||
return TrackPointsColumns.CONTENT_TYPE;
|
||||
case TRACKPOINTS_ID:
|
||||
return TrackPointsColumns.CONTENT_ITEMTYPE;
|
||||
case TRACKS:
|
||||
return TracksColumns.CONTENT_TYPE;
|
||||
case TRACKS_ID:
|
||||
return TracksColumns.CONTENT_ITEMTYPE;
|
||||
case WAYPOINTS:
|
||||
return WaypointsColumns.CONTENT_TYPE;
|
||||
case WAYPOINTS_ID:
|
||||
return WaypointsColumns.CONTENT_ITEMTYPE;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri url, ContentValues initialValues) {
|
||||
Log.d(MyTracksProvider.TAG, "MyTracksProvider.insert");
|
||||
ContentValues values;
|
||||
if (initialValues != null) {
|
||||
values = initialValues;
|
||||
} else {
|
||||
values = new ContentValues();
|
||||
}
|
||||
if (urlMatcher.match(url) == TRACKPOINTS) {
|
||||
return insertTrackPoint(url, values);
|
||||
} else if (urlMatcher.match(url) == TRACKS) {
|
||||
return insertTrack(url, values);
|
||||
} else if (urlMatcher.match(url) == WAYPOINTS) {
|
||||
return insertWaypoint(url, values);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
}
|
||||
|
||||
private Uri insertTrackPoint(Uri url, ContentValues values) {
|
||||
Log.d(MyTracksProvider.TAG, "MyTracksProvider.insertTrackPoint");
|
||||
boolean hasLat = values.containsKey(TrackPointsColumns.LATITUDE);
|
||||
boolean hasLong = values.containsKey(TrackPointsColumns.LONGITUDE);
|
||||
boolean hasTime = values.containsKey(TrackPointsColumns.TIME);
|
||||
if (!hasLat || !hasLong || !hasTime) {
|
||||
throw new IllegalArgumentException(
|
||||
"Latitude, longitude, and time values are required.");
|
||||
}
|
||||
long rowId = db.insert(TRACKPOINTS_TABLE, TrackPointsColumns._ID, values);
|
||||
if (rowId >= 0) {
|
||||
Uri uri = ContentUris.appendId(
|
||||
TrackPointsColumns.CONTENT_URI.buildUpon(), rowId).build();
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return uri;
|
||||
}
|
||||
throw new SQLiteException("Failed to insert row into " + url);
|
||||
}
|
||||
|
||||
private Uri insertTrack(Uri url, ContentValues values) {
|
||||
boolean hasStartTime = values.containsKey(TracksColumns.STARTTIME);
|
||||
boolean hasStartId = values.containsKey(TracksColumns.STARTID);
|
||||
if (!hasStartTime || !hasStartId) {
|
||||
throw new IllegalArgumentException(
|
||||
"Both start time and start id values are required.");
|
||||
}
|
||||
long rowId = db.insert(TRACKS_TABLE, TracksColumns._ID, values);
|
||||
if (rowId > 0) {
|
||||
Uri uri = ContentUris.appendId(
|
||||
TracksColumns.CONTENT_URI.buildUpon(), rowId).build();
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return uri;
|
||||
}
|
||||
throw new SQLException("Failed to insert row into " + url);
|
||||
}
|
||||
|
||||
private Uri insertWaypoint(Uri url, ContentValues values) {
|
||||
long rowId = db.insert(WAYPOINTS_TABLE, WaypointsColumns._ID, values);
|
||||
if (rowId > 0) {
|
||||
Uri uri = ContentUris.appendId(
|
||||
WaypointsColumns.CONTENT_URI.buildUpon(), rowId).build();
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return uri;
|
||||
}
|
||||
throw new SQLException("Failed to insert row into " + url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(
|
||||
Uri url, String[] projection, String selection, String[] selectionArgs,
|
||||
String sort) {
|
||||
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
|
||||
int match = urlMatcher.match(url);
|
||||
String sortOrder = null;
|
||||
if (match == TRACKPOINTS) {
|
||||
qb.setTables(TRACKPOINTS_TABLE);
|
||||
if (sort != null) {
|
||||
sortOrder = sort;
|
||||
} else {
|
||||
sortOrder = TrackPointsColumns.DEFAULT_SORT_ORDER;
|
||||
}
|
||||
} else if (match == TRACKPOINTS_ID) {
|
||||
qb.setTables(TRACKPOINTS_TABLE);
|
||||
qb.appendWhere("_id=" + url.getPathSegments().get(1));
|
||||
} else if (match == TRACKS) {
|
||||
qb.setTables(TRACKS_TABLE);
|
||||
if (sort != null) {
|
||||
sortOrder = sort;
|
||||
} else {
|
||||
sortOrder = TracksColumns.DEFAULT_SORT_ORDER;
|
||||
}
|
||||
} else if (match == TRACKS_ID) {
|
||||
qb.setTables(TRACKS_TABLE);
|
||||
qb.appendWhere("_id=" + url.getPathSegments().get(1));
|
||||
} else if (match == WAYPOINTS) {
|
||||
qb.setTables(WAYPOINTS_TABLE);
|
||||
if (sort != null) {
|
||||
sortOrder = sort;
|
||||
} else {
|
||||
sortOrder = WaypointsColumns.DEFAULT_SORT_ORDER;
|
||||
}
|
||||
} else if (match == WAYPOINTS_ID) {
|
||||
qb.setTables(WAYPOINTS_TABLE);
|
||||
qb.appendWhere("_id=" + url.getPathSegments().get(1));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
|
||||
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null,
|
||||
sortOrder);
|
||||
c.setNotificationUri(getContext().getContentResolver(), url);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri url, ContentValues values, String where,
|
||||
String[] selectionArgs) {
|
||||
int count;
|
||||
int match = urlMatcher.match(url);
|
||||
if (match == TRACKPOINTS) {
|
||||
count = db.update(TRACKPOINTS_TABLE, values, where, selectionArgs);
|
||||
} else if (match == TRACKPOINTS_ID) {
|
||||
String segment = url.getPathSegments().get(1);
|
||||
count = db.update(TRACKPOINTS_TABLE, values, "_id=" + segment
|
||||
+ (!TextUtils.isEmpty(where)
|
||||
? " AND (" + where + ')'
|
||||
: ""),
|
||||
selectionArgs);
|
||||
} else if (match == TRACKS) {
|
||||
count = db.update(TRACKS_TABLE, values, where, selectionArgs);
|
||||
} else if (match == TRACKS_ID) {
|
||||
String segment = url.getPathSegments().get(1);
|
||||
count = db.update(TRACKS_TABLE, values, "_id=" + segment
|
||||
+ (!TextUtils.isEmpty(where)
|
||||
? " AND (" + where + ')'
|
||||
: ""),
|
||||
selectionArgs);
|
||||
} else if (match == WAYPOINTS) {
|
||||
count = db.update(WAYPOINTS_TABLE, values, where, selectionArgs);
|
||||
} else if (match == WAYPOINTS_ID) {
|
||||
String segment = url.getPathSegments().get(1);
|
||||
count = db.update(WAYPOINTS_TABLE, values, "_id=" + segment
|
||||
+ (!TextUtils.isEmpty(where)
|
||||
? " AND (" + where + ')'
|
||||
: ""),
|
||||
selectionArgs);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.location.Location;
|
||||
import android.net.Uri;
|
||||
|
||||
/**
|
||||
* Utility to access data from the mytracks content provider.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public interface MyTracksProviderUtils {
|
||||
|
||||
/**
|
||||
* Authority (first part of URI) for the MyTracks content provider:
|
||||
*/
|
||||
public static final String AUTHORITY = "com.google.android.maps.mytracks";
|
||||
|
||||
/**
|
||||
* Deletes all tracks (including track points) from the provider.
|
||||
*/
|
||||
void deleteAllTracks();
|
||||
|
||||
/**
|
||||
* Deletes a track with the given track id.
|
||||
*
|
||||
* @param trackId the unique track id
|
||||
*/
|
||||
void deleteTrack(long trackId);
|
||||
|
||||
/**
|
||||
* Deletes a way point with the given way point id.
|
||||
* This will also correct the next statistics way point after the deleted one
|
||||
* to reflect the deletion.
|
||||
* The generator is needed to stitch together statistics waypoints.
|
||||
*
|
||||
* @param waypointId the unique way point id
|
||||
* @param descriptionGenerator the class to generate descriptions
|
||||
*/
|
||||
void deleteWaypoint(long waypointId,
|
||||
DescriptionGenerator descriptionGenerator);
|
||||
|
||||
/**
|
||||
* Finds the next statistics waypoint after the given waypoint.
|
||||
*
|
||||
* @param waypoint a given waypoint
|
||||
* @return the next statistics waypoint, or null if none found
|
||||
*/
|
||||
Waypoint getNextStatisticsWaypointAfter(Waypoint waypoint);
|
||||
|
||||
/**
|
||||
* Updates the waypoint in the provider.
|
||||
*
|
||||
* @param waypoint
|
||||
* @return true if successful
|
||||
*/
|
||||
boolean updateWaypoint(Waypoint waypoint);
|
||||
|
||||
/**
|
||||
* Finds the last recorded location from the location provider.
|
||||
*
|
||||
* @return the last location, or null if no locations available
|
||||
*/
|
||||
Location getLastLocation();
|
||||
|
||||
/**
|
||||
* Finds the first recorded waypoint for a given track from the location
|
||||
* provider.
|
||||
* This is a special waypoint that holds the stats for current segment.
|
||||
*
|
||||
* @param trackId the id of the track the waypoint belongs to
|
||||
* @return the first waypoint, or null if no waypoints available
|
||||
*/
|
||||
Waypoint getFirstWaypoint(long trackId);
|
||||
|
||||
/**
|
||||
* Finds the given waypoint from the location provider.
|
||||
*
|
||||
* @param waypointId
|
||||
* @return the waypoint, or null if it does not exist
|
||||
*/
|
||||
Waypoint getWaypoint(long waypointId);
|
||||
|
||||
/**
|
||||
* Finds the last recorded location id from the track points provider.
|
||||
*
|
||||
* @param trackId find last location on this track
|
||||
* @return the location id, or -1 if no locations available
|
||||
*/
|
||||
long getLastLocationId(long trackId);
|
||||
|
||||
/**
|
||||
* Finds the id of the 1st waypoint for a given track.
|
||||
* The 1st waypoint is special as it contains the stats for the current
|
||||
* segment.
|
||||
*
|
||||
* @param trackId find last location on this track
|
||||
* @return the waypoint id, or -1 if no waypoints are available
|
||||
*/
|
||||
long getFirstWaypointId(long trackId);
|
||||
|
||||
/**
|
||||
* Finds the id of the 1st waypoint for a given track.
|
||||
* The 1st waypoint is special as it contains the stats for the current
|
||||
* segment.
|
||||
*
|
||||
* @param trackId find last location on this track
|
||||
* @return the waypoint id, or -1 if no waypoints are available
|
||||
*/
|
||||
long getLastWaypointId(long trackId);
|
||||
|
||||
/**
|
||||
* Finds the last recorded track from the track provider.
|
||||
*
|
||||
* @return the last track, or null if no tracks available
|
||||
*/
|
||||
Track getLastTrack();
|
||||
|
||||
/**
|
||||
* Finds the last recorded track id from the tracks provider.
|
||||
*
|
||||
* @return the track id, or -1 if no tracks available
|
||||
*/
|
||||
long getLastTrackId();
|
||||
|
||||
/**
|
||||
* Finds a location by given unique id.
|
||||
*
|
||||
* @param id the desired id
|
||||
* @return a Location object, or null if not found
|
||||
*/
|
||||
Location getLocation(long id);
|
||||
|
||||
/**
|
||||
* Creates a cursor over the locations in the track points provider which
|
||||
* iterates over a given range of unique ids.
|
||||
* Caller gets to own the returned cursor. Don't forget to close it.
|
||||
*
|
||||
* @param trackId the id of the track for which to get the points
|
||||
* @param minTrackPointId the minimum id for the track points
|
||||
* @param maxLocations maximum number of locations retrieved
|
||||
* @param descending if true the results will be returned in descending id
|
||||
* order (latest location first)
|
||||
* @return A cursor over the selected range of locations
|
||||
*/
|
||||
Cursor getLocationsCursor(long trackId, long minTrackPointId,
|
||||
int maxLocations, boolean descending);
|
||||
|
||||
/**
|
||||
* Creates a cursor over the waypoints of a track.
|
||||
* Caller gets to own the returned cursor. Don't forget to close it.
|
||||
*
|
||||
* @param trackId the id of the track for which to get the points
|
||||
* @param minWaypointId the minimum id for the track points
|
||||
* @param maxWaypoints the maximum number of waypoints to return
|
||||
* @return A cursor over the selected range of locations
|
||||
*/
|
||||
Cursor getWaypointsCursor(long trackId, long minWaypointId,
|
||||
long maxWaypoints);
|
||||
|
||||
/**
|
||||
* Finds a track by given unique track id.
|
||||
* Note that the returned track object does not have any track points
|
||||
* attached. Use {@link #getTrackPoints(Track, int)} to load the track points.
|
||||
*
|
||||
* @param id desired unique track id
|
||||
* @return a Track object, or null if not found
|
||||
*/
|
||||
Track getTrack(long id);
|
||||
|
||||
/**
|
||||
* Loads the track points for a given track.
|
||||
*
|
||||
* @param track assumes that startId and stopId are filled in correctly
|
||||
* @param maxPoints maximum number of points to load, or -1 for no limit
|
||||
* (oldest ones will be discarded)
|
||||
* @return the id of the last location in the track
|
||||
*/
|
||||
long getTrackPoints(Track track, int maxPoints);
|
||||
|
||||
/**
|
||||
* Fetches some number of locations for the given track.
|
||||
*
|
||||
* This is designed to be used to stream through large tracks without loading
|
||||
* all points into memory.
|
||||
*
|
||||
* @param track to load locations for
|
||||
* @param buffer an array of locations to fill
|
||||
*/
|
||||
void getTrackPoints(Track track, TrackBuffer buffer);
|
||||
|
||||
/**
|
||||
* Creates a cursor over the tracks provider with a given selection.
|
||||
* Caller gets to own the returned cursor. Don't forget to close it.
|
||||
*
|
||||
* @param selection a given selection
|
||||
* @return a cursor of the selected tracks
|
||||
*/
|
||||
Cursor getTracksCursor(String selection);
|
||||
|
||||
/**
|
||||
* Inserts a track in the tracks provider.
|
||||
* Note: This does not insert any track points.
|
||||
* Use {@link #insertTrackPoint(Location, long)} to insert them.
|
||||
*
|
||||
* @param track the track to insert
|
||||
* @return the content provider URI for the inserted track
|
||||
*/
|
||||
Uri insertTrack(Track track);
|
||||
|
||||
/**
|
||||
* Inserts a track point in the tracks provider.
|
||||
*
|
||||
* @param location the location to insert
|
||||
* @return the content provider URI for the inserted track point
|
||||
*/
|
||||
Uri insertTrackPoint(Location location, long trackId);
|
||||
|
||||
/**
|
||||
* Inserts a waypoint in the provider.
|
||||
*
|
||||
* @param waypoint the waypoint to insert
|
||||
* @return the content provider URI for the inserted track
|
||||
*/
|
||||
Uri insertWaypoint(Waypoint waypoint);
|
||||
|
||||
/**
|
||||
* Inserts a track including its track points in the provider.
|
||||
*
|
||||
* @param track the track to insert
|
||||
* @return the content provider URI for the inserted track
|
||||
*/
|
||||
Uri insertTrackAndTrackPoints(Track track);
|
||||
|
||||
/**
|
||||
* Tests if a track with given id exists.
|
||||
*
|
||||
* @param id the unique id
|
||||
* @return true if track exists
|
||||
*/
|
||||
boolean trackExists(long id);
|
||||
|
||||
/**
|
||||
* Updates a track in the content provider.
|
||||
* Note: This will not update any track points.
|
||||
*
|
||||
* @param track a given track
|
||||
*/
|
||||
void updateTrack(Track track);
|
||||
|
||||
/**
|
||||
* Creates a location object from a given cursor.
|
||||
*
|
||||
* @param cursor a cursor pointing at a db or provider with locations
|
||||
* @return a new location object
|
||||
*/
|
||||
public Location createLocation(Cursor cursor);
|
||||
|
||||
/**
|
||||
* Creates a waypoint object from a given cursor.
|
||||
*
|
||||
* @param cursor a cursor pointing at a db or provider with waypoints
|
||||
* @return a new waypoint object
|
||||
*/
|
||||
public Waypoint createWaypoint(Cursor cursor);
|
||||
|
||||
/**
|
||||
* A factory which can produce instances of {@link MyTracksProviderUtils},
|
||||
* and can be overridden in tests (a.k.a. poor man's guice).
|
||||
*/
|
||||
public static class Factory {
|
||||
private static Factory instance = new Factory();
|
||||
|
||||
/**
|
||||
* Creates and returns an instance of {@link MyTracksProviderUtils} which
|
||||
* uses the given context to access its data.
|
||||
*/
|
||||
public static MyTracksProviderUtils get(Context context) {
|
||||
return instance.newForContext(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the global instance of this factory.
|
||||
*/
|
||||
public static Factory getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the global instance for this factory, to be used for testing.
|
||||
* If used, don't forget to set it back to the original value after the
|
||||
* test is run.
|
||||
*/
|
||||
public static void overrideInstance(Factory factory) {
|
||||
instance = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link MyTracksProviderUtils}.
|
||||
*/
|
||||
protected MyTracksProviderUtils newForContext(Context context) {
|
||||
return new MyTracksProviderUtilsImpl(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,975 @@
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.location.Location;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Helper class providing easy access to locations and tracks in the
|
||||
* MyTracksProvider. All static members.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public MyTracksProviderUtilsImpl(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the ContentValues for a given location object.
|
||||
*
|
||||
* @param location a given location
|
||||
* @param trackId the id of the track it belongs to
|
||||
* @return a filled in ContentValues object
|
||||
*/
|
||||
private static ContentValues createContentValues(
|
||||
Location location, long trackId) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(TrackPointsColumns.TRACKID, trackId);
|
||||
values.put(TrackPointsColumns.LATITUDE,
|
||||
(int) (location.getLatitude() * 1E6));
|
||||
values.put(TrackPointsColumns.LONGITUDE,
|
||||
(int) (location.getLongitude() * 1E6));
|
||||
// This is an ugly hack for Samsung phones that don't properly populate the
|
||||
// time field.
|
||||
values.put(TrackPointsColumns.TIME,
|
||||
(location.getTime() == 0)
|
||||
? System.currentTimeMillis()
|
||||
: location.getTime());
|
||||
if (location.hasAltitude()) {
|
||||
values.put(TrackPointsColumns.ALTITUDE, location.getAltitude());
|
||||
}
|
||||
if (location.hasBearing()) {
|
||||
values.put(TrackPointsColumns.BEARING, location.getBearing());
|
||||
}
|
||||
if (location.hasAccuracy()) {
|
||||
values.put(TrackPointsColumns.ACCURACY, location.getAccuracy());
|
||||
}
|
||||
if (location.hasSpeed()) {
|
||||
values.put(TrackPointsColumns.SPEED, location.getSpeed());
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the ContentValues for a given Track object.
|
||||
*
|
||||
* Note: If the track has an id<0 the id column will not be filled.
|
||||
*
|
||||
* @param track a given track object
|
||||
* @return a filled in ContentValues object
|
||||
*/
|
||||
private static ContentValues createContentValues(Track track) {
|
||||
ContentValues values = new ContentValues();
|
||||
// Values id < 0 indicate no id is available:
|
||||
if (track.getId() >= 0) {
|
||||
values.put(TracksColumns._ID, track.getId());
|
||||
}
|
||||
values.put(TracksColumns.NAME, track.getName());
|
||||
values.put(TracksColumns.DESCRIPTION, track.getDescription());
|
||||
values.put(TracksColumns.MAPID, track.getMapId());
|
||||
values.put(TracksColumns.CATEGORY, track.getCategory());
|
||||
values.put(TracksColumns.NUMPOINTS, track.getNumberOfPoints());
|
||||
values.put(TracksColumns.STARTID, track.getStartId());
|
||||
values.put(TracksColumns.STARTTIME, track.getStartTime());
|
||||
values.put(TracksColumns.STOPTIME, track.getStopTime());
|
||||
values.put(TracksColumns.STOPID, track.getStopId());
|
||||
values.put(TracksColumns.TOTALDISTANCE, track.getTotalDistance());
|
||||
values.put(TracksColumns.TOTALTIME, track.getTotalTime());
|
||||
values.put(TracksColumns.MOVINGTIME, track.getMovingTime());
|
||||
values.put(TracksColumns.MAXLAT, track.getTop());
|
||||
values.put(TracksColumns.MINLAT, track.getBottom());
|
||||
values.put(TracksColumns.MAXLON, track.getRight());
|
||||
values.put(TracksColumns.MINLON, track.getLeft());
|
||||
values.put(TracksColumns.AVGSPEED, track.getAverageSpeed());
|
||||
values.put(TracksColumns.AVGMOVINGSPEED, track.getAverageMovingSpeed());
|
||||
values.put(TracksColumns.MAXSPEED, track.getMaxSpeed());
|
||||
values.put(TracksColumns.MINELEVATION, track.getMinElevation());
|
||||
values.put(TracksColumns.MAXELEVATION, track.getMaxElevation());
|
||||
values.put(TracksColumns.ELEVATIONGAIN, track.getTotalElevationGain());
|
||||
values.put(TracksColumns.MINGRADE, track.getMinGrade());
|
||||
values.put(TracksColumns.MAXGRADE, track.getMaxGrade());
|
||||
return values;
|
||||
}
|
||||
|
||||
private static ContentValues createContentValues(Waypoint waypoint) {
|
||||
ContentValues values = new ContentValues();
|
||||
// Values id < 0 indicate no id is available:
|
||||
if (waypoint.getId() >= 0) {
|
||||
values.put(WaypointsColumns._ID, waypoint.getId());
|
||||
}
|
||||
values.put(WaypointsColumns.NAME, waypoint.getName());
|
||||
values.put(WaypointsColumns.DESCRIPTION, waypoint.getDescription());
|
||||
values.put(WaypointsColumns.CATEGORY, waypoint.getCategory());
|
||||
values.put(WaypointsColumns.ICON, waypoint.getIcon());
|
||||
values.put(WaypointsColumns.TRACKID, waypoint.getTrackId());
|
||||
values.put(WaypointsColumns.TYPE, waypoint.getType());
|
||||
values.put(WaypointsColumns.LENGTH, waypoint.getLength());
|
||||
values.put(WaypointsColumns.DURATION, waypoint.getDuration());
|
||||
values.put(WaypointsColumns.STARTTIME, waypoint.getStartTime());
|
||||
values.put(WaypointsColumns.STARTID, waypoint.getStartId());
|
||||
values.put(WaypointsColumns.STOPID, waypoint.getStopId());
|
||||
|
||||
values.put(WaypointsColumns.TOTALDISTANCE, waypoint.getTotalDistance());
|
||||
values.put(WaypointsColumns.TOTALTIME, waypoint.getTotalTime());
|
||||
values.put(WaypointsColumns.MOVINGTIME, waypoint.getMovingTime());
|
||||
values.put(WaypointsColumns.AVGSPEED, waypoint.getAverageSpeed());
|
||||
values.put(WaypointsColumns.AVGMOVINGSPEED,
|
||||
waypoint.getAverageMovingSpeed());
|
||||
values.put(WaypointsColumns.MAXSPEED, waypoint.getMaxSpeed());
|
||||
values.put(WaypointsColumns.MINELEVATION, waypoint.getMinElevation());
|
||||
values.put(WaypointsColumns.MAXELEVATION, waypoint.getMaxElevation());
|
||||
values.put(WaypointsColumns.ELEVATIONGAIN,
|
||||
waypoint.getTotalElevationGain());
|
||||
values.put(WaypointsColumns.MINGRADE, waypoint.getMinGrade());
|
||||
values.put(WaypointsColumns.MAXGRADE, waypoint.getMaxGrade());
|
||||
|
||||
Location location = waypoint.getLocation();
|
||||
if (location != null) {
|
||||
values.put(WaypointsColumns.LATITUDE,
|
||||
(int) (location.getLatitude() * 1E6));
|
||||
values.put(WaypointsColumns.LONGITUDE,
|
||||
(int) (location.getLongitude() * 1E6));
|
||||
values.put(WaypointsColumns.TIME, location.getTime());
|
||||
if (location.hasAltitude()) {
|
||||
values.put(WaypointsColumns.ALTITUDE, location.getAltitude());
|
||||
}
|
||||
if (location.hasBearing()) {
|
||||
values.put(WaypointsColumns.BEARING, location.getBearing());
|
||||
}
|
||||
if (location.hasAccuracy()) {
|
||||
values.put(WaypointsColumns.ACCURACY, location.getAccuracy());
|
||||
}
|
||||
if (location.hasSpeed()) {
|
||||
values.put(WaypointsColumns.SPEED, location.getSpeed());
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location createLocation(Cursor cursor) {
|
||||
int idxLatitude = cursor.getColumnIndexOrThrow(TrackPointsColumns.LATITUDE);
|
||||
int idxLongitude =
|
||||
cursor.getColumnIndexOrThrow(TrackPointsColumns.LONGITUDE);
|
||||
int idxAltitude = cursor.getColumnIndexOrThrow(TrackPointsColumns.ALTITUDE);
|
||||
int idxTime = cursor.getColumnIndexOrThrow(TrackPointsColumns.TIME);
|
||||
int idxBearing = cursor.getColumnIndexOrThrow(TrackPointsColumns.BEARING);
|
||||
int idxAccuracy = cursor.getColumnIndexOrThrow(TrackPointsColumns.ACCURACY);
|
||||
int idxSpeed = cursor.getColumnIndexOrThrow(TrackPointsColumns.SPEED);
|
||||
|
||||
Location location = new Location("");
|
||||
if (!cursor.isNull(idxLatitude)) {
|
||||
location.setLatitude(1. * cursor.getInt(idxLatitude) / 1E6);
|
||||
}
|
||||
if (!cursor.isNull(idxLongitude)) {
|
||||
location.setLongitude(1. * cursor.getInt(idxLongitude) / 1E6);
|
||||
}
|
||||
if (!cursor.isNull(idxAltitude)) {
|
||||
location.setAltitude(cursor.getFloat(idxAltitude));
|
||||
}
|
||||
if (!cursor.isNull(idxTime)) {
|
||||
location.setTime(cursor.getLong(idxTime));
|
||||
}
|
||||
if (!cursor.isNull(idxBearing)) {
|
||||
location.setBearing(cursor.getFloat(idxBearing));
|
||||
}
|
||||
if (!cursor.isNull(idxSpeed)) {
|
||||
location.setSpeed(cursor.getFloat(idxSpeed));
|
||||
}
|
||||
if (!cursor.isNull(idxAccuracy)) {
|
||||
location.setAccuracy(cursor.getFloat(idxAccuracy));
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Track object from a given cursor.
|
||||
*
|
||||
* @param cursor a cursor pointing at a db or provider with tracks
|
||||
* @return a new Track object
|
||||
*/
|
||||
private static Track createTrack(Cursor cursor) {
|
||||
int idxId = cursor.getColumnIndexOrThrow(TracksColumns._ID);
|
||||
int idxName = cursor.getColumnIndexOrThrow(TracksColumns.NAME);
|
||||
int idxDescription =
|
||||
cursor.getColumnIndexOrThrow(TracksColumns.DESCRIPTION);
|
||||
int idxMapId = cursor.getColumnIndexOrThrow(TracksColumns.MAPID);
|
||||
int idxCategory = cursor.getColumnIndexOrThrow(TracksColumns.CATEGORY);
|
||||
int idxStartId = cursor.getColumnIndexOrThrow(TracksColumns.STARTID);
|
||||
int idxStartTime = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME);
|
||||
int idxStopTime = cursor.getColumnIndexOrThrow(TracksColumns.STOPTIME);
|
||||
int idxStopId = cursor.getColumnIndexOrThrow(TracksColumns.STOPID);
|
||||
int idxNumPoints = cursor.getColumnIndexOrThrow(TracksColumns.NUMPOINTS);
|
||||
int idxMaxlat = cursor.getColumnIndexOrThrow(TracksColumns.MAXLAT);
|
||||
int idxMinlat = cursor.getColumnIndexOrThrow(TracksColumns.MINLAT);
|
||||
int idxMaxlon = cursor.getColumnIndexOrThrow(TracksColumns.MAXLON);
|
||||
int idxMinlon = cursor.getColumnIndexOrThrow(TracksColumns.MINLON);
|
||||
|
||||
int idxTotalDistance =
|
||||
cursor.getColumnIndexOrThrow(TracksColumns.TOTALDISTANCE);
|
||||
int idxTotalTime = cursor.getColumnIndexOrThrow(TracksColumns.TOTALTIME);
|
||||
int idxMovingTime = cursor.getColumnIndexOrThrow(TracksColumns.MOVINGTIME);
|
||||
int idxAverageSpeed = cursor.getColumnIndexOrThrow(TracksColumns.AVGSPEED);
|
||||
int idxAverageMovingSpeed =
|
||||
cursor.getColumnIndexOrThrow(TracksColumns.AVGMOVINGSPEED);
|
||||
int idxMaxSpeed = cursor.getColumnIndexOrThrow(TracksColumns.MAXSPEED);
|
||||
int idxMinElevation =
|
||||
cursor.getColumnIndexOrThrow(TracksColumns.MINELEVATION);
|
||||
int idxMaxElevation =
|
||||
cursor.getColumnIndexOrThrow(TracksColumns.MAXELEVATION);
|
||||
int idxElevationGain =
|
||||
cursor.getColumnIndexOrThrow(TracksColumns.ELEVATIONGAIN);
|
||||
int idxMinGrade = cursor.getColumnIndexOrThrow(TracksColumns.MINGRADE);
|
||||
int idxMaxGrade = cursor.getColumnIndexOrThrow(TracksColumns.MAXGRADE);
|
||||
|
||||
Track track = new Track();
|
||||
if (!cursor.isNull(idxId)) {
|
||||
track.setId(cursor.getLong(idxId));
|
||||
}
|
||||
if (!cursor.isNull(idxName)) {
|
||||
track.setName(cursor.getString(idxName));
|
||||
}
|
||||
if (!cursor.isNull(idxDescription)) {
|
||||
track.setDescription(cursor.getString(idxDescription));
|
||||
}
|
||||
if (!cursor.isNull(idxMapId)) {
|
||||
track.setMapId(cursor.getString(idxMapId));
|
||||
}
|
||||
if (!cursor.isNull(idxCategory)) {
|
||||
track.setCategory(cursor.getString(idxCategory));
|
||||
}
|
||||
if (!cursor.isNull(idxStartId)) {
|
||||
track.setStartId(cursor.getInt(idxStartId));
|
||||
}
|
||||
if (!cursor.isNull(idxStartTime)) {
|
||||
track.setStartTime(cursor.getLong(idxStartTime));
|
||||
}
|
||||
if (!cursor.isNull(idxStopTime)) {
|
||||
track.setStopTime(cursor.getLong(idxStopTime));
|
||||
}
|
||||
if (!cursor.isNull(idxStopId)) {
|
||||
track.setStopId(cursor.getInt(idxStopId));
|
||||
}
|
||||
if (!cursor.isNull(idxNumPoints)) {
|
||||
track.setNumberOfPoints(cursor.getInt(idxNumPoints));
|
||||
}
|
||||
if (!cursor.isNull(idxTotalDistance)) {
|
||||
track.setTotalDistance(cursor.getFloat(idxTotalDistance));
|
||||
}
|
||||
if (!cursor.isNull(idxTotalTime)) {
|
||||
track.setTotalTime(cursor.getLong(idxTotalTime));
|
||||
}
|
||||
if (!cursor.isNull(idxMovingTime)) {
|
||||
track.setMovingTime(cursor.getLong(idxMovingTime));
|
||||
}
|
||||
if (!cursor.isNull(idxMaxlat)
|
||||
&& !cursor.isNull(idxMinlat)
|
||||
&& !cursor.isNull(idxMaxlon)
|
||||
&& !cursor.isNull(idxMinlon)) {
|
||||
int top = cursor.getInt(idxMaxlat);
|
||||
int bottom = cursor.getInt(idxMinlat);
|
||||
int right = cursor.getInt(idxMaxlon);
|
||||
int left = cursor.getInt(idxMinlon);
|
||||
track.setBounds(left, top, right, bottom);
|
||||
}
|
||||
if (!cursor.isNull(idxAverageSpeed)) {
|
||||
track.setAverageSpeed(cursor.getFloat(idxAverageSpeed));
|
||||
}
|
||||
if (!cursor.isNull(idxAverageMovingSpeed)) {
|
||||
track.setAverageMovingSpeed(cursor.getFloat(idxAverageMovingSpeed));
|
||||
}
|
||||
if (!cursor.isNull(idxMaxSpeed)) {
|
||||
track.setMaxSpeed(cursor.getFloat(idxMaxSpeed));
|
||||
}
|
||||
if (!cursor.isNull(idxMinElevation)) {
|
||||
track.setMinElevation(cursor.getFloat(idxMinElevation));
|
||||
}
|
||||
if (!cursor.isNull(idxMaxElevation)) {
|
||||
track.setMaxElevation(cursor.getFloat(idxMaxElevation));
|
||||
}
|
||||
if (!cursor.isNull(idxElevationGain)) {
|
||||
track.setTotalElevationGain(cursor.getFloat(idxElevationGain));
|
||||
}
|
||||
if (!cursor.isNull(idxMinGrade)) {
|
||||
track.setMinGrade(cursor.getFloat(idxMinGrade));
|
||||
}
|
||||
if (!cursor.isNull(idxMaxGrade)) {
|
||||
track.setMaxGrade(cursor.getFloat(idxMaxGrade));
|
||||
}
|
||||
return track;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Waypoint createWaypoint(Cursor cursor) {
|
||||
int idxId = cursor.getColumnIndexOrThrow(WaypointsColumns._ID);
|
||||
int idxName = cursor.getColumnIndexOrThrow(WaypointsColumns.NAME);
|
||||
int idxDescription =
|
||||
cursor.getColumnIndexOrThrow(WaypointsColumns.DESCRIPTION);
|
||||
int idxCategory = cursor.getColumnIndexOrThrow(WaypointsColumns.CATEGORY);
|
||||
int idxIcon = cursor.getColumnIndexOrThrow(WaypointsColumns.ICON);
|
||||
int idxTrackId = cursor.getColumnIndexOrThrow(WaypointsColumns.TRACKID);
|
||||
int idxType = cursor.getColumnIndexOrThrow(WaypointsColumns.TYPE);
|
||||
int idxLength = cursor.getColumnIndexOrThrow(WaypointsColumns.LENGTH);
|
||||
int idxDuration = cursor.getColumnIndexOrThrow(WaypointsColumns.DURATION);
|
||||
int idxStartTime = cursor.getColumnIndexOrThrow(WaypointsColumns.STARTTIME);
|
||||
int idxStartId = cursor.getColumnIndexOrThrow(WaypointsColumns.STARTID);
|
||||
int idxStopId = cursor.getColumnIndexOrThrow(WaypointsColumns.STOPID);
|
||||
|
||||
int idxTotalDistance =
|
||||
cursor.getColumnIndexOrThrow(WaypointsColumns.TOTALDISTANCE);
|
||||
int idxTotalTime = cursor.getColumnIndexOrThrow(WaypointsColumns.TOTALTIME);
|
||||
int idxMovingTime =
|
||||
cursor.getColumnIndexOrThrow(WaypointsColumns.MOVINGTIME);
|
||||
int idxAverageSpeed =
|
||||
cursor.getColumnIndexOrThrow(WaypointsColumns.AVGSPEED);
|
||||
int idxAverageMovingSpeed =
|
||||
cursor.getColumnIndexOrThrow(WaypointsColumns.AVGMOVINGSPEED);
|
||||
int idxMaxSpeed = cursor.getColumnIndexOrThrow(WaypointsColumns.MAXSPEED);
|
||||
int idxMinElevation =
|
||||
cursor.getColumnIndexOrThrow(WaypointsColumns.MINELEVATION);
|
||||
int idxMaxElevation =
|
||||
cursor.getColumnIndexOrThrow(WaypointsColumns.MAXELEVATION);
|
||||
int idxElevationGain =
|
||||
cursor.getColumnIndexOrThrow(WaypointsColumns.ELEVATIONGAIN);
|
||||
int idxMinGrade = cursor.getColumnIndexOrThrow(WaypointsColumns.MINGRADE);
|
||||
int idxMaxGrade = cursor.getColumnIndexOrThrow(WaypointsColumns.MAXGRADE);
|
||||
|
||||
int idxLatitude = cursor.getColumnIndexOrThrow(WaypointsColumns.LATITUDE);
|
||||
int idxLongitude = cursor.getColumnIndexOrThrow(WaypointsColumns.LONGITUDE);
|
||||
int idxAltitude = cursor.getColumnIndexOrThrow(WaypointsColumns.ALTITUDE);
|
||||
int idxTime = cursor.getColumnIndexOrThrow(WaypointsColumns.TIME);
|
||||
int idxBearing = cursor.getColumnIndexOrThrow(WaypointsColumns.BEARING);
|
||||
int idxAccuracy = cursor.getColumnIndexOrThrow(WaypointsColumns.ACCURACY);
|
||||
int idxSpeed = cursor.getColumnIndexOrThrow(WaypointsColumns.SPEED);
|
||||
|
||||
Waypoint waypoint = new Waypoint();
|
||||
if (!cursor.isNull(idxId)) {
|
||||
waypoint.setId(cursor.getLong(idxId));
|
||||
}
|
||||
if (!cursor.isNull(idxName)) {
|
||||
waypoint.setName(cursor.getString(idxName));
|
||||
}
|
||||
if (!cursor.isNull(idxDescription)) {
|
||||
waypoint.setDescription(cursor.getString(idxDescription));
|
||||
}
|
||||
if (!cursor.isNull(idxCategory)) {
|
||||
waypoint.setCategory(cursor.getString(idxCategory));
|
||||
}
|
||||
if (!cursor.isNull(idxIcon)) {
|
||||
waypoint.setIcon(cursor.getString(idxIcon));
|
||||
}
|
||||
if (!cursor.isNull(idxTrackId)) {
|
||||
waypoint.setTrackId(cursor.getLong(idxTrackId));
|
||||
}
|
||||
if (!cursor.isNull(idxType)) {
|
||||
waypoint.setType(cursor.getInt(idxType));
|
||||
}
|
||||
if (!cursor.isNull(idxLength)) {
|
||||
waypoint.setLength(cursor.getDouble(idxLength));
|
||||
}
|
||||
if (!cursor.isNull(idxDuration)) {
|
||||
waypoint.setDuration(cursor.getLong(idxDuration));
|
||||
}
|
||||
if (!cursor.isNull(idxStartTime)) {
|
||||
waypoint.setStartTime(cursor.getLong(idxStartTime));
|
||||
}
|
||||
if (!cursor.isNull(idxStartId)) {
|
||||
waypoint.setStartId(cursor.getLong(idxStartId));
|
||||
}
|
||||
if (!cursor.isNull(idxStopId)) {
|
||||
waypoint.setStopId(cursor.getLong(idxStopId));
|
||||
}
|
||||
if (!cursor.isNull(idxTotalDistance)) {
|
||||
waypoint.setTotalDistance(cursor.getFloat(idxTotalDistance));
|
||||
}
|
||||
if (!cursor.isNull(idxTotalTime)) {
|
||||
waypoint.setTotalTime(cursor.getLong(idxTotalTime));
|
||||
}
|
||||
if (!cursor.isNull(idxMovingTime)) {
|
||||
waypoint.setMovingTime(cursor.getLong(idxMovingTime));
|
||||
}
|
||||
if (!cursor.isNull(idxAverageSpeed)) {
|
||||
waypoint.setAverageSpeed(cursor.getFloat(idxAverageSpeed));
|
||||
}
|
||||
if (!cursor.isNull(idxAverageMovingSpeed)) {
|
||||
waypoint.setAverageMovingSpeed(cursor.getFloat(idxAverageMovingSpeed));
|
||||
}
|
||||
if (!cursor.isNull(idxMaxSpeed)) {
|
||||
waypoint.setMaxSpeed(cursor.getFloat(idxMaxSpeed));
|
||||
}
|
||||
if (!cursor.isNull(idxMinElevation)) {
|
||||
waypoint.setMinElevation(cursor.getFloat(idxMinElevation));
|
||||
}
|
||||
if (!cursor.isNull(idxMaxElevation)) {
|
||||
waypoint.setMaxElevation(cursor.getFloat(idxMaxElevation));
|
||||
}
|
||||
if (!cursor.isNull(idxElevationGain)) {
|
||||
waypoint.setTotalElevationGain(cursor.getFloat(idxElevationGain));
|
||||
}
|
||||
if (!cursor.isNull(idxMinGrade)) {
|
||||
waypoint.setMinGrade(cursor.getFloat(idxMinGrade));
|
||||
}
|
||||
if (!cursor.isNull(idxMaxGrade)) {
|
||||
waypoint.setMaxGrade(cursor.getFloat(idxMaxGrade));
|
||||
}
|
||||
|
||||
Location location = new Location("");
|
||||
if (!cursor.isNull(idxLatitude) && !cursor.isNull(idxLongitude)) {
|
||||
location.setLatitude(1. * cursor.getInt(idxLatitude) / 1E6);
|
||||
location.setLongitude(1. * cursor.getInt(idxLongitude) / 1E6);
|
||||
}
|
||||
if (!cursor.isNull(idxAltitude)) {
|
||||
location.setAltitude(cursor.getFloat(idxAltitude));
|
||||
}
|
||||
if (!cursor.isNull(idxTime)) {
|
||||
location.setTime(cursor.getLong(idxTime));
|
||||
}
|
||||
if (!cursor.isNull(idxBearing)) {
|
||||
location.setBearing(cursor.getFloat(idxBearing));
|
||||
}
|
||||
if (!cursor.isNull(idxSpeed)) {
|
||||
location.setSpeed(cursor.getFloat(idxSpeed));
|
||||
}
|
||||
if (!cursor.isNull(idxAccuracy)) {
|
||||
location.setAccuracy(cursor.getFloat(idxAccuracy));
|
||||
}
|
||||
waypoint.setLocation(location);
|
||||
return waypoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAllTracks() {
|
||||
context.getContentResolver().delete(TracksColumns.CONTENT_URI, null, null);
|
||||
context.getContentResolver().delete(TrackPointsColumns.CONTENT_URI,
|
||||
null, null);
|
||||
context.getContentResolver().delete(
|
||||
WaypointsColumns.CONTENT_URI, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTrack(long trackId) {
|
||||
Track track = getTrack(trackId);
|
||||
if (track != null) {
|
||||
context.getContentResolver().delete(TrackPointsColumns.CONTENT_URI,
|
||||
"_id>=" + track.getStartId() + " AND _id<=" + track.getStopId(),
|
||||
null);
|
||||
}
|
||||
context.getContentResolver().delete(WaypointsColumns.CONTENT_URI,
|
||||
WaypointsColumns.TRACKID + "=" + trackId, null);
|
||||
context.getContentResolver().delete(
|
||||
TracksColumns.CONTENT_URI, "_id=" + trackId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteWaypoint(long waypointId,
|
||||
DescriptionGenerator descriptionGenerator) {
|
||||
final Waypoint deletedWaypoint = getWaypoint(waypointId);
|
||||
if (deletedWaypoint != null
|
||||
&& deletedWaypoint.getType() == Waypoint.TYPE_STATISTICS) {
|
||||
final Waypoint nextWaypoint =
|
||||
getNextStatisticsWaypointAfter(deletedWaypoint);
|
||||
if (nextWaypoint != null) {
|
||||
Log.d(MyTracksProvider.TAG, "Correcting marker " + nextWaypoint.getId()
|
||||
+ " after deleted marker " + deletedWaypoint.getId());
|
||||
nextWaypoint.combine(deletedWaypoint);
|
||||
nextWaypoint.setDescription(
|
||||
descriptionGenerator.generateWaypointDescription(nextWaypoint));
|
||||
if (!updateWaypoint(nextWaypoint)) {
|
||||
Log.w(MyTracksProvider.TAG, "Update of marker was unsuccessful.");
|
||||
}
|
||||
} else {
|
||||
Log.d(MyTracksProvider.TAG,
|
||||
"No statistics marker after the deleted one was found.");
|
||||
}
|
||||
}
|
||||
context.getContentResolver().delete(
|
||||
WaypointsColumns.CONTENT_URI, "_id=" + waypointId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Waypoint getNextStatisticsWaypointAfter(Waypoint waypoint) {
|
||||
final String selection = WaypointsColumns._ID + ">" + waypoint.getId()
|
||||
+ " AND " + WaypointsColumns.TRACKID + "=" + waypoint.getTrackId()
|
||||
+ " AND " + WaypointsColumns.TYPE + "=" + Waypoint.TYPE_STATISTICS;
|
||||
final String sortOrder = WaypointsColumns._ID + " LIMIT 1";
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = context.getContentResolver().query(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
null /*projection*/,
|
||||
selection,
|
||||
null /*selectionArgs*/,
|
||||
sortOrder);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return createWaypoint(cursor);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(MyTracksProvider.TAG, "Caught unexpected exception.", e);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateWaypoint(Waypoint waypoint) {
|
||||
try {
|
||||
final int rows = context.getContentResolver().update(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
createContentValues(waypoint),
|
||||
"_id=" + waypoint.getId(),
|
||||
null /*selectionArgs*/);
|
||||
return rows == 1;
|
||||
} catch (RuntimeException e) {
|
||||
Log.e(MyTracksProvider.TAG, "Caught unexpected exception.", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a locations from the provider by the given selection.
|
||||
*
|
||||
* @param select a selection argument that identifies a unique location
|
||||
* @return the fist location matching, or null if not found
|
||||
*/
|
||||
private Location findLocationBy(String select) {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = context.getContentResolver().query(
|
||||
TrackPointsColumns.CONTENT_URI, null, select, null, null);
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
return createLocation(cursor);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(MyTracksProvider.TAG, "Caught an unexpeceted exception.", e);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a track from the provider by the given selection.
|
||||
*
|
||||
* @param select a selection argument that identifies a unique track
|
||||
* @return the first track matching, or null if not found
|
||||
*/
|
||||
private Track findTrackBy(String select) {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = context.getContentResolver().query(
|
||||
TracksColumns.CONTENT_URI, null, select, null, null);
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
return createTrack(cursor);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(MyTracksProvider.TAG, "Caught unexpected exception.", e);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLastLocation() {
|
||||
return findLocationBy("_id=(select max(_id) from trackpoints)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Waypoint getFirstWaypoint(long trackId) {
|
||||
Cursor cursor = context.getContentResolver().query(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
null /*projection*/,
|
||||
"trackid=" + trackId,
|
||||
null /*selectionArgs*/,
|
||||
"_id LIMIT 1");
|
||||
if (cursor != null) {
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
return createWaypoint(cursor);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(MyTracksProvider.TAG, "Caught an unexpected exception.", e);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Waypoint getWaypoint(long waypointId) {
|
||||
Cursor cursor = context.getContentResolver().query(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
null /*projection*/,
|
||||
"_id=" + waypointId,
|
||||
null /*selectionArgs*/,
|
||||
null /*sortOrder*/);
|
||||
if (cursor != null) {
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
return createWaypoint(cursor);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(MyTracksProvider.TAG, "Caught an unexpected exception.", e);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastLocationId(long trackId) {
|
||||
final String[] projection = {"_id"};
|
||||
Cursor cursor = context.getContentResolver().query(
|
||||
TrackPointsColumns.CONTENT_URI,
|
||||
projection,
|
||||
"_id=(select max(_id) from trackpoints WHERE trackid=" + trackId + ")",
|
||||
null /*selectionArgs*/,
|
||||
null /*sortOrder*/);
|
||||
if (cursor != null) {
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getLong(
|
||||
cursor.getColumnIndexOrThrow(TrackPointsColumns._ID));
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(MyTracksProvider.TAG, "Caught an unexpected exception.", e);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFirstWaypointId(long trackId) {
|
||||
final String[] projection = {"_id"};
|
||||
Cursor cursor = context.getContentResolver().query(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
projection,
|
||||
"trackid=" + trackId,
|
||||
null /*selectionArgs*/,
|
||||
"_id LIMIT 1" /*sortOrder*/);
|
||||
if (cursor != null) {
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getLong(
|
||||
cursor.getColumnIndexOrThrow(WaypointsColumns._ID));
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(MyTracksProvider.TAG, "Caught an unexpected exception.", e);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastWaypointId(long trackId) {
|
||||
final String[] projection = {"_id"};
|
||||
Cursor cursor = context.getContentResolver().query(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
projection,
|
||||
WaypointsColumns.TRACKID + "=" + trackId,
|
||||
null /*selectionArgs*/,
|
||||
"_id DESC LIMIT 1" /*sortOrder*/);
|
||||
if (cursor != null) {
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getLong(
|
||||
cursor.getColumnIndexOrThrow(WaypointsColumns._ID));
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(MyTracksProvider.TAG, "Caught an unexpected exception.", e);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Track getLastTrack() {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = context.getContentResolver().query(
|
||||
TracksColumns.CONTENT_URI, null, "_id=(select max(_id) from tracks)",
|
||||
null, null);
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
return createTrack(cursor);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(MyTracksProvider.TAG, "Caught an unexpected exception.", e);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastTrackId() {
|
||||
String[] proj = { TracksColumns._ID };
|
||||
Cursor cursor = context.getContentResolver().query(
|
||||
TracksColumns.CONTENT_URI, proj, "_id=(select max(_id) from tracks)",
|
||||
null, null);
|
||||
if (cursor != null) {
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getLong(
|
||||
cursor.getColumnIndexOrThrow(TracksColumns._ID));
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation(long id) {
|
||||
String selection = TrackPointsColumns._ID + "=" + id;
|
||||
return findLocationBy(selection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor getLocationsCursor(long trackId, long minTrackPointId,
|
||||
int maxLocations, boolean descending) {
|
||||
String selection;
|
||||
if (minTrackPointId > 0) {
|
||||
selection = String.format("%s=%d AND %s>=%d",
|
||||
TrackPointsColumns.TRACKID, trackId,
|
||||
TrackPointsColumns._ID, minTrackPointId);
|
||||
} else {
|
||||
selection = String.format("%s=%d",
|
||||
TrackPointsColumns.TRACKID, trackId);
|
||||
}
|
||||
|
||||
String sortOrder = "_id " + (descending ? "DESC" : "ASC");
|
||||
if (maxLocations > 0) {
|
||||
sortOrder += " LIMIT " + maxLocations;
|
||||
}
|
||||
|
||||
return context.getContentResolver().query(
|
||||
TrackPointsColumns.CONTENT_URI, null, selection, null, sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor getWaypointsCursor(long trackId, long minWaypointId,
|
||||
long maxWaypoints) {
|
||||
String selection;
|
||||
if (minWaypointId > 0) {
|
||||
selection = String.format("%s=%d AND %s>=%d",
|
||||
WaypointsColumns.TRACKID, trackId,
|
||||
WaypointsColumns._ID, minWaypointId);
|
||||
} else {
|
||||
selection = String.format("%s=%d",
|
||||
WaypointsColumns.TRACKID, trackId);
|
||||
}
|
||||
|
||||
String sortOrder = "_id ASC";
|
||||
if (maxWaypoints > 0) {
|
||||
sortOrder += " LIMIT " + maxWaypoints;
|
||||
}
|
||||
|
||||
return context.getContentResolver().query(
|
||||
WaypointsColumns.CONTENT_URI, null, selection, null, sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Track getTrack(long id) {
|
||||
String select = TracksColumns._ID + "=" + id;
|
||||
return findTrackBy(select);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTrackPoints(Track track, int maxPoints) {
|
||||
long lastId = -1;
|
||||
Cursor cursor = getLocationsCursor(track.getId(), -1, maxPoints, true);
|
||||
if (cursor == null) {
|
||||
Log.w(MyTracksProvider.TAG, "Cannot get a locations cursor!");
|
||||
return lastId;
|
||||
}
|
||||
try {
|
||||
final int idColumnIdx =
|
||||
cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
|
||||
if (cursor.moveToLast()) {
|
||||
do {
|
||||
Location location = createLocation(cursor);
|
||||
if (location == null) {
|
||||
continue;
|
||||
}
|
||||
track.addLocation(location);
|
||||
lastId = cursor.getLong(idColumnIdx);
|
||||
} while (cursor.moveToPrevious());
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(MyTracksProvider.TAG, "Caught unexpected exception.", e);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
return lastId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTrackPoints(Track track, TrackBuffer buffer) {
|
||||
long startingPoint = buffer.getLastLocationRead() == 0 ? track.getStartId()
|
||||
: buffer.getLastLocationRead();
|
||||
buffer.reset();
|
||||
Cursor cursor = getLocationsCursor(track.getId(),
|
||||
startingPoint,
|
||||
buffer.getSize(), false);
|
||||
final int idColumnIdx =
|
||||
cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
|
||||
if (cursor == null) {
|
||||
Log.w(MyTracksProvider.TAG, "Cannot get a locations cursor!");
|
||||
buffer.setInvalid();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (cursor.getCount() == 0) {
|
||||
Log.w(MyTracksProvider.TAG, "No matching locations found.");
|
||||
buffer.resetAt(startingPoint + buffer.getSize());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cursor.moveToFirst()) {
|
||||
Log.w(MyTracksProvider.TAG, "Could not move to first.");
|
||||
buffer.setInvalid();
|
||||
return;
|
||||
}
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
Location location = createLocation(cursor);
|
||||
if (location == null) {
|
||||
continue;
|
||||
}
|
||||
buffer.add(location, cursor.getLong(idColumnIdx));
|
||||
}
|
||||
if (buffer.getLocationsLoaded() == 0) {
|
||||
Log.w(MyTracksProvider.TAG, "No locations read.");
|
||||
buffer.resetAt(startingPoint + buffer.getSize());
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(MyTracksProvider.TAG, "Caught unexpected exception.", e);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor getTracksCursor(String selection) {
|
||||
Cursor cursor = context.getContentResolver().query(
|
||||
TracksColumns.CONTENT_URI, null, selection, null, "_id");
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insertTrack(Track track) {
|
||||
Log.d(MyTracksProvider.TAG, "MyTracksProviderUtilsImpl.insertTrack");
|
||||
return context.getContentResolver().insert(TracksColumns.CONTENT_URI,
|
||||
createContentValues(track));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insertTrackPoint(Location location, long trackId) {
|
||||
Log.d(MyTracksProvider.TAG, "MyTracksProviderUtilsImpl.insertTrackPoint");
|
||||
return context.getContentResolver().insert(TrackPointsColumns.CONTENT_URI,
|
||||
createContentValues(location, trackId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insertWaypoint(Waypoint waypoint) {
|
||||
Log.d(MyTracksProvider.TAG, "MyTracksProviderUtilsImpl.insertWaypoint");
|
||||
waypoint.setId(-1);
|
||||
return context.getContentResolver().insert(WaypointsColumns.CONTENT_URI,
|
||||
createContentValues(waypoint));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insertTrackAndTrackPoints(Track track) {
|
||||
// Insert the track right away to have its ID
|
||||
Uri trackUri = insertTrack(track);
|
||||
long trackId = Long.parseLong(trackUri.getLastPathSegment());
|
||||
track.setId(trackId);
|
||||
|
||||
// Insert all the points (associated with the track ID)
|
||||
boolean firstPoint = true;
|
||||
long pointId = -1;
|
||||
for (Location location : track.getLocations()) {
|
||||
Uri pointUri = insertTrackPoint(location, trackId);
|
||||
pointId = Long.parseLong(pointUri.getLastPathSegment());
|
||||
if (firstPoint) {
|
||||
track.setStartId(pointId);
|
||||
firstPoint = false;
|
||||
}
|
||||
}
|
||||
track.setStopId(pointId);
|
||||
|
||||
// Update the track with the start and end point IDs
|
||||
updateTrack(track);
|
||||
return trackUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trackExists(long id) {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
final String[] projection = { TracksColumns._ID };
|
||||
cursor = context.getContentResolver().query(
|
||||
TracksColumns.CONTENT_URI,
|
||||
projection,
|
||||
TracksColumns._ID + "=" + id/*selection*/,
|
||||
null/*selectionArgs*/,
|
||||
null/*sortOrder*/);
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
return true;
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTrack(Track track) {
|
||||
Log.d(MyTracksProvider.TAG, "MyTracksProviderUtilsImpl.updateTrack");
|
||||
context.getContentResolver().update(TracksColumns.CONTENT_URI,
|
||||
createContentValues(track), "_id=" + track.getId(), null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import android.location.Location;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A class representing a (GPS) Track.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class Track implements Parcelable {
|
||||
|
||||
/**
|
||||
* Creator for a Track object
|
||||
*/
|
||||
public class Creator implements Parcelable.Creator<Track> {
|
||||
|
||||
public Track createFromParcel(Parcel source) {
|
||||
Track track = new Track();
|
||||
track.id = source.readLong();
|
||||
track.name = source.readString();
|
||||
track.description = source.readString();
|
||||
track.mapId = source.readString();
|
||||
track.category = source.readString();
|
||||
track.startId = source.readLong();
|
||||
track.stopId = source.readLong();
|
||||
track.startTime = source.readLong();
|
||||
track.stopTime = source.readLong();
|
||||
track.totalDistance = source.readDouble();
|
||||
track.totalTime = source.readLong();
|
||||
track.movingTime = source.readLong();
|
||||
track.averageSpeed = source.readDouble();
|
||||
track.averageMovingSpeed = source.readDouble();
|
||||
track.maxSpeed = source.readDouble();
|
||||
track.minElevation = source.readDouble();
|
||||
track.maxElevation = source.readDouble();
|
||||
track.totalElevationGain = source.readDouble();
|
||||
track.minGrade = source.readDouble();
|
||||
track.maxGrade = source.readDouble();
|
||||
left = source.readInt();
|
||||
top = source.readInt();
|
||||
right = source.readInt();
|
||||
bottom = source.readInt();
|
||||
track.numberOfPoints = source.readInt();
|
||||
for (int i = 0; i < track.numberOfPoints; ++i) {
|
||||
Location loc = source.readParcelable(null);
|
||||
track.locations.add(loc);
|
||||
}
|
||||
return track;
|
||||
}
|
||||
|
||||
public Track[] newArray(int size) {
|
||||
return new Track[size];
|
||||
}
|
||||
}
|
||||
|
||||
public static final Creator CREATOR = new Track().new Creator();
|
||||
|
||||
/**
|
||||
* The track points.
|
||||
*/
|
||||
private ArrayList<Location> locations = new ArrayList<Location>();
|
||||
|
||||
private long id = -1;
|
||||
private String name = "";
|
||||
private String description = "";
|
||||
private String mapId = "";
|
||||
private long startId = -1;
|
||||
private long stopId = -1;
|
||||
private String category = "";
|
||||
|
||||
// Fields derived from locations. Use setDerivedFields() to set them:
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
private long startTime = -1;
|
||||
private long stopTime = -1;
|
||||
private int numberOfPoints = 0;
|
||||
private double totalDistance = 0;
|
||||
private long totalTime = 0;
|
||||
private long movingTime = 0;
|
||||
private int left;
|
||||
private int top;
|
||||
private int right;
|
||||
private int bottom;
|
||||
|
||||
private double averageSpeed = 0;
|
||||
private double averageMovingSpeed = 0;
|
||||
private double maxSpeed = 0;
|
||||
private double minElevation = 0;
|
||||
private double maxElevation = 0;
|
||||
private double totalElevationGain = 0;
|
||||
private double minGrade = 0;
|
||||
private double maxGrade = 0;
|
||||
|
||||
public Track() {
|
||||
left = Integer.MAX_VALUE;
|
||||
top = Integer.MIN_VALUE;
|
||||
right = Integer.MIN_VALUE;
|
||||
bottom = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeLong(id);
|
||||
dest.writeString(name);
|
||||
dest.writeString(description);
|
||||
dest.writeString(mapId);
|
||||
dest.writeString(category);
|
||||
dest.writeLong(startId);
|
||||
dest.writeLong(stopId);
|
||||
dest.writeLong(startTime);
|
||||
dest.writeLong(stopTime);
|
||||
dest.writeDouble(totalDistance);
|
||||
dest.writeLong(totalTime);
|
||||
dest.writeLong(movingTime);
|
||||
dest.writeDouble(averageSpeed);
|
||||
dest.writeDouble(averageMovingSpeed);
|
||||
dest.writeDouble(maxSpeed);
|
||||
dest.writeDouble(minElevation);
|
||||
dest.writeDouble(maxElevation);
|
||||
dest.writeDouble(totalElevationGain);
|
||||
dest.writeDouble(minGrade);
|
||||
dest.writeDouble(maxGrade);
|
||||
dest.writeInt(left);
|
||||
dest.writeInt(top);
|
||||
dest.writeInt(right);
|
||||
dest.writeInt(bottom);
|
||||
dest.writeInt(numberOfPoints);
|
||||
for (int i = 0; i < numberOfPoints; ++i) {
|
||||
dest.writeParcelable(locations.get(i), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Getters and setters:
|
||||
//---------------------
|
||||
|
||||
public int getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public int getTop() {
|
||||
return top;
|
||||
}
|
||||
|
||||
public int getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public int getBottom() {
|
||||
return bottom;
|
||||
}
|
||||
|
||||
public void setBounds(int aLeft, int aTop, int aRight, int aBottom) {
|
||||
left = aLeft;
|
||||
top = aTop;
|
||||
right = aRight;
|
||||
bottom = aBottom;
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public double getTotalDistance() {
|
||||
return totalDistance;
|
||||
}
|
||||
|
||||
public void setTotalDistance(double totalDistance) {
|
||||
this.totalDistance = totalDistance;
|
||||
}
|
||||
|
||||
public long getTotalTime() {
|
||||
return totalTime;
|
||||
}
|
||||
|
||||
public void setTotalTime(long totalTime) {
|
||||
this.totalTime = totalTime;
|
||||
}
|
||||
|
||||
public long getMovingTime() {
|
||||
return movingTime;
|
||||
}
|
||||
|
||||
public void setMovingTime(long movingTime) {
|
||||
this.movingTime = movingTime;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(long startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public long getStopTime() {
|
||||
return stopTime;
|
||||
}
|
||||
|
||||
public void setStopTime(long stopTime) {
|
||||
this.stopTime = stopTime;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getStartId() {
|
||||
return startId;
|
||||
}
|
||||
|
||||
public void setStartId(long startId) {
|
||||
this.startId = startId;
|
||||
}
|
||||
|
||||
public long getStopId() {
|
||||
return stopId;
|
||||
}
|
||||
|
||||
public void setStopId(long stopId) {
|
||||
this.stopId = stopId;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getMapId() {
|
||||
return mapId;
|
||||
}
|
||||
|
||||
public void setMapId(String mapId) {
|
||||
this.mapId = mapId;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(String category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public double getAverageSpeed() {
|
||||
return averageSpeed;
|
||||
}
|
||||
|
||||
public void setAverageSpeed(double averageSpeed) {
|
||||
this.averageSpeed = averageSpeed;
|
||||
}
|
||||
|
||||
public double getAverageMovingSpeed() {
|
||||
return averageMovingSpeed;
|
||||
}
|
||||
|
||||
public void setAverageMovingSpeed(double averageMovingSpeed) {
|
||||
this.averageMovingSpeed = averageMovingSpeed;
|
||||
}
|
||||
|
||||
public double getMaxSpeed() {
|
||||
return maxSpeed;
|
||||
}
|
||||
|
||||
public void setMaxSpeed(double maxSpeed) {
|
||||
this.maxSpeed = maxSpeed;
|
||||
}
|
||||
|
||||
public double getMinElevation() {
|
||||
return minElevation;
|
||||
}
|
||||
|
||||
public void setMinElevation(double minElevation) {
|
||||
this.minElevation = minElevation;
|
||||
}
|
||||
|
||||
public double getMaxElevation() {
|
||||
return maxElevation;
|
||||
}
|
||||
|
||||
public void setMaxElevation(double maxElevation) {
|
||||
this.maxElevation = maxElevation;
|
||||
}
|
||||
|
||||
public double getTotalElevationGain() {
|
||||
return totalElevationGain;
|
||||
}
|
||||
|
||||
public void setTotalElevationGain(double totalElevationGain) {
|
||||
this.totalElevationGain = totalElevationGain;
|
||||
}
|
||||
|
||||
public double getMinGrade() {
|
||||
return minGrade;
|
||||
}
|
||||
|
||||
public void setMinGrade(double minGrade) {
|
||||
this.minGrade = minGrade;
|
||||
}
|
||||
|
||||
public double getMaxGrade() {
|
||||
return maxGrade;
|
||||
}
|
||||
|
||||
public void setMaxGrade(double maxGrade) {
|
||||
this.maxGrade = maxGrade;
|
||||
}
|
||||
|
||||
public int getNumberOfPoints() {
|
||||
return numberOfPoints;
|
||||
}
|
||||
|
||||
public void setNumberOfPoints(int numberOfPoints) {
|
||||
this.numberOfPoints = numberOfPoints;
|
||||
}
|
||||
|
||||
public void addLocation(Location l) {
|
||||
locations.add(l);
|
||||
}
|
||||
|
||||
public ArrayList<Location> getLocations() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
public void setLocations(ArrayList<Location> locations) {
|
||||
this.locations = locations;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2009 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import com.google.android.apps.mytracks.util.MyTracksUtils;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
/**
|
||||
* A buffer of Locations from a track.
|
||||
* This class contains some additional information about the loaded points.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class TrackBuffer {
|
||||
|
||||
/**
|
||||
* An array of location objects that are part of a track.
|
||||
*/
|
||||
private final Location[] buffer;
|
||||
|
||||
/**
|
||||
* The id of the last location read from the track.
|
||||
*/
|
||||
private long lastLocationRead = 0;
|
||||
|
||||
/**
|
||||
* The number of locations loaded into the buffer.
|
||||
*/
|
||||
private int locationsLoaded = 0;
|
||||
|
||||
/**
|
||||
* Create a TrackBuffer with size elements.
|
||||
*
|
||||
* @param size The size of the buffer
|
||||
*/
|
||||
public TrackBuffer(int size) {
|
||||
buffer = new Location[size];
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the track to a state with no locations.
|
||||
*/
|
||||
public void reset() {
|
||||
resetAt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the track at the given starting location id.
|
||||
*/
|
||||
public void resetAt(long lastLocation) {
|
||||
lastLocationRead = lastLocation;
|
||||
locationsLoaded = 0;
|
||||
}
|
||||
|
||||
public void setInvalid() {
|
||||
lastLocationRead = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of locations that can be stored in this buffer
|
||||
*/
|
||||
public int getSize() {
|
||||
return buffer.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param index The index of the location to fetch
|
||||
* @return The location for the given index
|
||||
*/
|
||||
public Location get(int index) {
|
||||
return buffer[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a location to the end of the buffer.
|
||||
* @param location The location to add
|
||||
* @param id The id of the location to be added
|
||||
*/
|
||||
public void add(Location location, long id) {
|
||||
buffer[locationsLoaded++] = location;
|
||||
lastLocationRead = Math.max(lastLocationRead, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The id of the last location loaded into the buffer
|
||||
*/
|
||||
public long getLastLocationRead() {
|
||||
return lastLocationRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of locations loaded into the buffer
|
||||
*/
|
||||
public int getLocationsLoaded() {
|
||||
return locationsLoaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the start location, i.e. the one which is the first point of a
|
||||
* segment with at least two points.
|
||||
*
|
||||
* @return the start location
|
||||
*/
|
||||
public Location findStartLocation() {
|
||||
int numValidLocations = 0;
|
||||
for (int i = 0; i < getLocationsLoaded(); i++) {
|
||||
Location location = buffer[i];
|
||||
if (MyTracksUtils.isValidLocation(location)) {
|
||||
numValidLocations++;
|
||||
if (numValidLocations == 2) {
|
||||
return buffer[i - 1];
|
||||
}
|
||||
} else {
|
||||
numValidLocations = 0;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.provider.BaseColumns;
|
||||
|
||||
/**
|
||||
* Defines the URI for the track points provider and the available column names
|
||||
* and content types.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public interface TrackPointsColumns extends BaseColumns {
|
||||
public static final Uri CONTENT_URI =
|
||||
Uri.parse("content://com.google.android.maps.mytracks/trackpoints");
|
||||
public static final String CONTENT_TYPE =
|
||||
"vnd.android.cursor.dir/vnd.google.trackpoint";
|
||||
public static final String CONTENT_ITEMTYPE =
|
||||
"vnd.android.cursor.item/vnd.google.trackpoint";
|
||||
public static final String DEFAULT_SORT_ORDER = "_id";
|
||||
|
||||
/* All columns */
|
||||
public static final String TRACKID = "trackid";
|
||||
public static final String LATITUDE = "latitude";
|
||||
public static final String LONGITUDE = "longitude";
|
||||
public static final String ALTITUDE = "elevation";
|
||||
public static final String BEARING = "bearing";
|
||||
public static final String TIME = "time";
|
||||
public static final String ACCURACY = "accuracy";
|
||||
public static final String SPEED = "speed";
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.provider.BaseColumns;
|
||||
|
||||
/**
|
||||
* Defines the URI for the tracks provider and the available column names
|
||||
* and content types.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public interface TracksColumns extends BaseColumns {
|
||||
|
||||
public static final Uri CONTENT_URI =
|
||||
Uri.parse("content://com.google.android.maps.mytracks/tracks");
|
||||
public static final String CONTENT_TYPE =
|
||||
"vnd.android.cursor.dir/vnd.google.track";
|
||||
public static final String CONTENT_ITEMTYPE =
|
||||
"vnd.android.cursor.item/vnd.google.track";
|
||||
public static final String DEFAULT_SORT_ORDER = "_id";
|
||||
|
||||
/* All columns */
|
||||
public static final String NAME = "name";
|
||||
public static final String DESCRIPTION = "description";
|
||||
public static final String CATEGORY = "category";
|
||||
public static final String STARTID = "startid";
|
||||
public static final String STOPID = "stopid";
|
||||
public static final String STARTTIME = "starttime";
|
||||
public static final String STOPTIME = "stoptime";
|
||||
public static final String NUMPOINTS = "numpoints";
|
||||
public static final String TOTALDISTANCE = "totaldistance";
|
||||
public static final String TOTALTIME = "totaltime";
|
||||
public static final String MOVINGTIME = "movingtime";
|
||||
public static final String AVGSPEED = "avgspeed";
|
||||
public static final String AVGMOVINGSPEED = "avgmovingspeed";
|
||||
public static final String MAXSPEED = "maxspeed";
|
||||
public static final String MINELEVATION = "minelevation";
|
||||
public static final String MAXELEVATION = "maxelevation";
|
||||
public static final String ELEVATIONGAIN = "elevationgain";
|
||||
public static final String MINGRADE = "mingrade";
|
||||
public static final String MAXGRADE = "maxgrade";
|
||||
public static final String MINLAT = "minlat";
|
||||
public static final String MAXLAT = "maxlat";
|
||||
public static final String MINLON = "minlon";
|
||||
public static final String MAXLON = "maxlon";
|
||||
public static final String MAPID = "mapid";
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
package com.google.android.apps.mytracks.content;
|
||||
parcelable Waypoint;
|
||||
@@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Copyright 2009 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import android.location.Location;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* A way point. It has a location, meta data such as name, description,
|
||||
* category, and icon, plus it can store track statistics for a "sub-track".
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public final class Waypoint implements Parcelable {
|
||||
|
||||
/**
|
||||
* Creator for a Waypoint object
|
||||
*/
|
||||
public static class Creator implements Parcelable.Creator<Waypoint> {
|
||||
|
||||
public Waypoint createFromParcel(Parcel source) {
|
||||
Waypoint waypoint = new Waypoint();
|
||||
waypoint.id = source.readLong();
|
||||
waypoint.name = source.readString();
|
||||
waypoint.description = source.readString();
|
||||
waypoint.category = source.readString();
|
||||
waypoint.icon = source.readString();
|
||||
waypoint.trackId = source.readLong();
|
||||
waypoint.type = source.readInt();
|
||||
waypoint.length = source.readDouble();
|
||||
waypoint.duration = source.readLong();
|
||||
waypoint.startTime = source.readLong();
|
||||
waypoint.startId = source.readLong();
|
||||
waypoint.stopId = source.readLong();
|
||||
byte hasLocation = source.readByte();
|
||||
if (hasLocation > 0) {
|
||||
waypoint.location = source.readParcelable(null);
|
||||
}
|
||||
waypoint.totalDistance = source.readDouble();
|
||||
waypoint.totalTime = source.readLong();
|
||||
waypoint.movingTime = source.readLong();
|
||||
waypoint.averageSpeed = source.readDouble();
|
||||
waypoint.averageMovingSpeed = source.readDouble();
|
||||
waypoint.maxSpeed = source.readDouble();
|
||||
waypoint.minElevation = source.readDouble();
|
||||
waypoint.maxElevation = source.readDouble();
|
||||
waypoint.totalElevationGain = source.readDouble();
|
||||
waypoint.minGrade = source.readDouble();
|
||||
waypoint.maxGrade = source.readDouble();
|
||||
return waypoint;
|
||||
}
|
||||
|
||||
public Waypoint[] newArray(int size) {
|
||||
return new Waypoint[size];
|
||||
}
|
||||
}
|
||||
|
||||
public static final Creator CREATOR = new Creator();
|
||||
|
||||
public static final int TYPE_WAYPOINT = 0;
|
||||
public static final int TYPE_STATISTICS = 1;
|
||||
|
||||
private long id = -1;
|
||||
private String name = "";
|
||||
private String description = "";
|
||||
private String category = "";
|
||||
private String icon = "";
|
||||
private long trackId = -1;
|
||||
private int type = 0;
|
||||
|
||||
private Location location;
|
||||
|
||||
/** Length along the track in meters. */
|
||||
private double length = 0;
|
||||
/** Time along the track in seconds. */
|
||||
private long duration = 0;
|
||||
/** Start time of a segment */
|
||||
private long startTime = -1;
|
||||
/** Start track point id */
|
||||
private long startId = -1;
|
||||
/** Stop track point id */
|
||||
private long stopId = -1;
|
||||
|
||||
private double totalDistance = 0;
|
||||
private long totalTime = 0;
|
||||
private long movingTime = 0;
|
||||
private double averageSpeed = 0;
|
||||
private double averageMovingSpeed = 0;
|
||||
private double maxSpeed = 0;
|
||||
private double minElevation = 0;
|
||||
private double maxElevation = 0;
|
||||
private double totalElevationGain = 0;
|
||||
private double minGrade = 0;
|
||||
private double maxGrade = 0;
|
||||
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeLong(id);
|
||||
dest.writeString(name);
|
||||
dest.writeString(description);
|
||||
dest.writeString(category);
|
||||
dest.writeString(icon);
|
||||
dest.writeLong(trackId);
|
||||
dest.writeInt(type);
|
||||
dest.writeDouble(length);
|
||||
dest.writeLong(duration);
|
||||
dest.writeLong(startTime);
|
||||
dest.writeLong(startId);
|
||||
dest.writeLong(stopId);
|
||||
dest.writeByte(location == null ? (byte) 0 : (byte) 1);
|
||||
if (location != null) {
|
||||
dest.writeParcelable(location, 0);
|
||||
}
|
||||
dest.writeDouble(totalDistance);
|
||||
dest.writeLong(totalTime);
|
||||
dest.writeLong(movingTime);
|
||||
dest.writeDouble(averageSpeed);
|
||||
dest.writeDouble(averageMovingSpeed);
|
||||
dest.writeDouble(maxSpeed);
|
||||
dest.writeDouble(minElevation);
|
||||
dest.writeDouble(maxElevation);
|
||||
dest.writeDouble(totalElevationGain);
|
||||
dest.writeDouble(minGrade);
|
||||
dest.writeDouble(maxGrade);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines the statistics from another (earlier) waypoint with this one.
|
||||
* This is needed when the user deletes a statistic waypoint.
|
||||
*
|
||||
* @param other the other waypoint
|
||||
*/
|
||||
public void combine(Waypoint other) {
|
||||
totalTime += other.totalTime;
|
||||
movingTime += other.movingTime;
|
||||
totalDistance += other.totalDistance;
|
||||
totalElevationGain += other.totalElevationGain;
|
||||
averageSpeed = totalDistance / totalTime;
|
||||
averageMovingSpeed = totalDistance / movingTime;
|
||||
maxSpeed = Math.max(maxSpeed, other.maxSpeed);
|
||||
minElevation = Math.min(minElevation, other.minElevation);
|
||||
maxElevation = Math.max(maxElevation, other.maxElevation);
|
||||
minGrade = Math.min(minGrade, other.minGrade);
|
||||
maxGrade = Math.max(maxGrade, other.maxGrade);
|
||||
}
|
||||
|
||||
// Getters and setters:
|
||||
//---------------------
|
||||
|
||||
public String getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public void setIcon(String icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setTrackId(long trackId) {
|
||||
this.trackId = trackId;
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public double getTotalDistance() {
|
||||
return totalDistance;
|
||||
}
|
||||
|
||||
public void setTotalDistance(double totalDistance) {
|
||||
this.totalDistance = totalDistance;
|
||||
}
|
||||
|
||||
public long getTotalTime() {
|
||||
return totalTime;
|
||||
}
|
||||
|
||||
public void setTotalTime(long totalTime) {
|
||||
this.totalTime = totalTime;
|
||||
}
|
||||
|
||||
public long getMovingTime() {
|
||||
return movingTime;
|
||||
}
|
||||
|
||||
public void setMovingTime(long movingTime) {
|
||||
this.movingTime = movingTime;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getTrackId() {
|
||||
return trackId;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public double getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(double length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(long duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(long startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public long getStartId() {
|
||||
return startId;
|
||||
}
|
||||
|
||||
public void setStartId(long startId) {
|
||||
this.startId = startId;
|
||||
}
|
||||
|
||||
public long getStopId() {
|
||||
return stopId;
|
||||
}
|
||||
|
||||
public void setStopId(long stopId) {
|
||||
this.stopId = stopId;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(String category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public double getAverageSpeed() {
|
||||
return averageSpeed;
|
||||
}
|
||||
|
||||
public void setAverageSpeed(double averageSpeed) {
|
||||
this.averageSpeed = averageSpeed;
|
||||
}
|
||||
|
||||
public double getAverageMovingSpeed() {
|
||||
return averageMovingSpeed;
|
||||
}
|
||||
|
||||
public void setAverageMovingSpeed(double averageMovingSpeed) {
|
||||
this.averageMovingSpeed = averageMovingSpeed;
|
||||
}
|
||||
|
||||
public double getMaxSpeed() {
|
||||
return maxSpeed;
|
||||
}
|
||||
|
||||
public void setMaxSpeed(double maxSpeed) {
|
||||
this.maxSpeed = maxSpeed;
|
||||
}
|
||||
|
||||
public double getMinElevation() {
|
||||
return minElevation;
|
||||
}
|
||||
|
||||
public void setMinElevation(double minElevation) {
|
||||
this.minElevation = minElevation;
|
||||
}
|
||||
|
||||
public double getMaxElevation() {
|
||||
return maxElevation;
|
||||
}
|
||||
|
||||
public void setMaxElevation(double maxElevation) {
|
||||
this.maxElevation = maxElevation;
|
||||
}
|
||||
|
||||
public double getTotalElevationGain() {
|
||||
return totalElevationGain;
|
||||
}
|
||||
|
||||
public void setTotalElevationGain(double totalElevationGain) {
|
||||
this.totalElevationGain = totalElevationGain;
|
||||
}
|
||||
|
||||
public double getMinGrade() {
|
||||
return minGrade;
|
||||
}
|
||||
|
||||
public void setMinGrade(double minGrade) {
|
||||
this.minGrade = minGrade;
|
||||
}
|
||||
|
||||
public double getMaxGrade() {
|
||||
return maxGrade;
|
||||
}
|
||||
|
||||
public void setMaxGrade(double maxGrade) {
|
||||
this.maxGrade = maxGrade;
|
||||
}
|
||||
|
||||
public void setLocation(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2009 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.provider.BaseColumns;
|
||||
|
||||
/**
|
||||
* Defines the URI for the tracks provider and the available column names
|
||||
* and content types.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public interface WaypointsColumns extends BaseColumns {
|
||||
|
||||
public static final Uri CONTENT_URI =
|
||||
Uri.parse("content://com.google.android.maps.mytracks/waypoints");
|
||||
public static final String CONTENT_TYPE =
|
||||
"vnd.android.cursor.dir/vnd.google.waypoint";
|
||||
public static final String CONTENT_ITEMTYPE =
|
||||
"vnd.android.cursor.item/vnd.google.waypoint";
|
||||
public static final String DEFAULT_SORT_ORDER = "_id";
|
||||
|
||||
/* All columns */
|
||||
public static final String NAME = "name";
|
||||
public static final String DESCRIPTION = "description";
|
||||
public static final String CATEGORY = "category";
|
||||
public static final String ICON = "icon";
|
||||
public static final String TRACKID = "trackid";
|
||||
public static final String TYPE = "type";
|
||||
public static final String LENGTH = "length";
|
||||
public static final String DURATION = "duration";
|
||||
public static final String STARTTIME = "starttime";
|
||||
public static final String STARTID = "startid";
|
||||
public static final String STOPID = "stopid";
|
||||
|
||||
public static final String LATITUDE = "latitude";
|
||||
public static final String LONGITUDE = "longitude";
|
||||
public static final String ALTITUDE = "elevation";
|
||||
public static final String BEARING = "bearing";
|
||||
public static final String TIME = "time";
|
||||
public static final String ACCURACY = "accuracy";
|
||||
public static final String SPEED = "speed";
|
||||
|
||||
public static final String TOTALDISTANCE = "totaldistance";
|
||||
public static final String TOTALTIME = "totaltime";
|
||||
public static final String MOVINGTIME = "movingtime";
|
||||
public static final String AVGSPEED = "avgspeed";
|
||||
public static final String AVGMOVINGSPEED = "avgmovingspeed";
|
||||
public static final String MAXSPEED = "maxspeed";
|
||||
public static final String MINELEVATION = "minelevation";
|
||||
public static final String MAXELEVATION = "maxelevation";
|
||||
public static final String ELEVATIONGAIN = "elevationgain";
|
||||
public static final String MINGRADE = "mingrade";
|
||||
public static final String MAXGRADE = "maxgrade";
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
|
||||
import android.location.Location;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* Utility class for decimating tracks at a given level of precision.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class MyTracksUtils {
|
||||
|
||||
/**
|
||||
* Checks if a given location is a valid (i.e. physically possible) location
|
||||
* on Earth. Note: The special separator locations (which have latitude =
|
||||
* 100) will not qualify as valid. Neither will locations with lat=0 and lng=0
|
||||
* as these are most likely "bad" measurements which often cause trouble.
|
||||
*
|
||||
* @param location the location to test
|
||||
* @return true if the location is a valid location
|
||||
*/
|
||||
public static boolean isValidLocation(Location location) {
|
||||
return location != null && Math.abs(location.getLatitude()) <= 90
|
||||
&& Math.abs(location.getLongitude()) <= 180;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a utility class w/ only static memebers.
|
||||
*/
|
||||
private MyTracksUtils() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
/**
|
||||
* Unit conversion constants.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public abstract class UnitConversions {
|
||||
|
||||
public static final double KM_TO_MI = 0.621371192;
|
||||
public static final double M_TO_FT = 3.2808399;
|
||||
public static final double MI_TO_M = 1609.344;
|
||||
public static final double MI_TO_FEET = 5280.0;
|
||||
public static final double KMH_TO_MPH = 1000 * M_TO_FT / MI_TO_FEET;
|
||||
public static final double TO_RADIANS = Math.PI / 180.0;
|
||||
|
||||
private UnitConversions() {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user