Skip to content

Commit

Permalink
Merge pull request #1717 from OpenTracksApp/type#1608
Browse files Browse the repository at this point in the history
Introduced ActivityType is now non-localized (i.e., English) value
  • Loading branch information
dennisguse authored Oct 10, 2023
2 parents 374656a + 55495da commit 65b5339
Show file tree
Hide file tree
Showing 25 changed files with 317 additions and 255 deletions.
9 changes: 9 additions & 0 deletions doc/opentracks-schema-1.0.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,13 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="typeTranslated"
type="xsd:string">
<xsd:annotation>
<xsd:documentation xml:lang="en">
User-defined translation of GPX's <![CDATA[<type>]]>.
Only used in GPX.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:schema>
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.stream.Collectors;

import de.dennisguse.opentracks.content.data.TestDataUtil;
import de.dennisguse.opentracks.content.data.TestSensorDataUtil;
Expand Down Expand Up @@ -860,7 +859,7 @@ public void testGetTrackPointCursor_asc() {

List<TrackPoint.Id> trackpointIds = track.second.stream()
.map(it -> ContentUris.parseId(contentProviderUtils.insertTrackPoint(it, track.first.getId())))
.map(TrackPoint.Id::new).collect(Collectors.toList());
.map(TrackPoint.Id::new).toList();

// when
try (Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds.get(8))) {
Expand All @@ -878,7 +877,7 @@ public void testGetTrackPointLocationIterator_asc() {

List<TrackPoint.Id> trackpointIds = track.second.stream()
.map(it -> ContentUris.parseId(contentProviderUtils.insertTrackPoint(it, track.first.getId())))
.map(TrackPoint.Id::new).collect(Collectors.toList());
.map(TrackPoint.Id::new).toList();

TrackPoint.Id startTrackPointId = trackpointIds.get(0);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,10 @@ public void kmz_with_trackdetail_and_sensordata() throws TimeoutException, IOExc
// 1. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack);
assertEquals(track.getActivityType(), importedTrack.getActivityType());
assertEquals(track.getActivityTypeLocalized(), importedTrack.getActivityTypeLocalized());
assertEquals(track.getDescription(), importedTrack.getDescription());
assertEquals(track.getName(), importedTrack.getName());
assertEquals(track.getActivityType(), importedTrack.getActivityType());

// 2. trackpoints
TrackPointAssert a = new TrackPointAssert();
Expand Down Expand Up @@ -380,13 +380,11 @@ public void gpx() throws TimeoutException, IOException {
// 1. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack);
assertEquals(track.getActivityType(), importedTrack.getActivityType());
assertEquals(track.getActivityTypeLocalized(), importedTrack.getActivityTypeLocalized());
assertEquals(track.getDescription(), importedTrack.getDescription());
assertEquals(track.getName(), importedTrack.getName());

//TODO exporting and importing a track icon is not yet supported by GpxTrackWriter.
//assertEquals(track.getIcon(), importedTrack.getIcon());

// 2. trackpoints
// The GPX exporter does not support exporting TrackPoints without lat/lng.
// Therefore, the track segmentation is changes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public void gpx_with_pause_resume() throws IOException {
// 2. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack);
assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
assertEquals("the category", importedTrack.getActivityTypeLocalized());
assertEquals("the description", importedTrack.getDescription());
assertEquals("2021-01-07 22:51", importedTrack.getName());
Expand Down
3 changes: 2 additions & 1 deletion src/androidTest/res/raw/gpx_timezone.gpx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/
<trk>
<name><![CDATA[2021-01-07 22:51]]></name>
<desc><![CDATA[the description]]></desc>
<type><![CDATA[the category]]></type>
<type><![CDATA[unknown]]></type>
<extensions>
<topografix:color>c0c0c0</topografix:color>
<opentracks:trackid>7002101e-4198-4613-8c24-544e01ca3981</opentracks:trackid>
<opentracks:typeTranslated><![CDATA[unknown]]></opentracks:typeTranslated>
<gpxtrkx:TrackStatsExtension>
<gpxtrkx:Distance>0.0</gpxtrkx:Distance>
<gpxtrkx:TimerTime>0</gpxtrkx:TimerTime>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public static Track createTrack(Cursor cursor) {
int uuidIndex = cursor.getColumnIndexOrThrow(TracksColumns.UUID);
int nameIndex = cursor.getColumnIndexOrThrow(TracksColumns.NAME);
int descriptionIndex = cursor.getColumnIndexOrThrow(TracksColumns.DESCRIPTION);
int activityTypeIndex = cursor.getColumnIndexOrThrow(TracksColumns.ACTIVITY_TYPE);
int activityTypeLocalizedIndex = cursor.getColumnIndexOrThrow(TracksColumns.ACTIVITY_TYPE_LOCALIZED);
int startTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME);
int startTimeOffsetIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME_OFFSET);
Expand All @@ -113,7 +114,6 @@ public static Track createTrack(Cursor cursor) {
int maxAltitudeIndex = cursor.getColumnIndexOrThrow(TracksColumns.MAX_ALTITUDE);
int altitudeGainIndex = cursor.getColumnIndexOrThrow(TracksColumns.ALTITUDE_GAIN);
int altitudeLossIndex = cursor.getColumnIndexOrThrow(TracksColumns.ALTITUDE_LOSS);
int iconIndex = cursor.getColumnIndexOrThrow(TracksColumns.ICON);

Track track = new Track(ZoneOffset.ofTotalSeconds(cursor.getInt(startTimeOffsetIndex)));
TrackStatistics trackStatistics = track.getTrackStatistics();
Expand All @@ -129,6 +129,9 @@ public static Track createTrack(Cursor cursor) {
if (!cursor.isNull(descriptionIndex)) {
track.setDescription(cursor.getString(descriptionIndex));
}
if (!cursor.isNull(activityTypeIndex)) {
track.setActivityType(ActivityType.findBy(cursor.getString(activityTypeIndex)));
}
if (!cursor.isNull(activityTypeLocalizedIndex)) {
track.setActivityTypeLocalized(cursor.getString(activityTypeLocalizedIndex));
}
Expand Down Expand Up @@ -163,9 +166,7 @@ public static Track createTrack(Cursor cursor) {
if (!cursor.isNull(altitudeLossIndex)) {
trackStatistics.setTotalAltitudeLoss(cursor.getFloat(altitudeLossIndex));
}
if (!cursor.isNull(iconIndex)) {
track.setActivityType(ActivityType.findBy(cursor.getString(iconIndex)));
}

return track;
}

Expand Down Expand Up @@ -230,13 +231,18 @@ public List<Track> getTracks(ContentProviderSelectionInterface selection) {

public Cursor searchTracks(String searchQuery) {
// Needed, because MARKER_COUNT is a virtual column and has to be explicitly requested.
final String[] PROJECTION = new String[]{TracksColumns._ID, TracksColumns.UUID, TracksColumns.NAME,
TracksColumns.DESCRIPTION, TracksColumns.ACTIVITY_TYPE_LOCALIZED, TracksColumns.STARTTIME,
TracksColumns.STARTTIME_OFFSET, TracksColumns.STOPTIME, TracksColumns.MARKER_COUNT,
TracksColumns.TOTALDISTANCE, TracksColumns.TOTALTIME, TracksColumns.MOVINGTIME,
TracksColumns.AVGSPEED, TracksColumns.AVGMOVINGSPEED, TracksColumns.MAXSPEED,
TracksColumns.MIN_ALTITUDE, TracksColumns.MAX_ALTITUDE, TracksColumns.ALTITUDE_GAIN,
TracksColumns.ALTITUDE_LOSS, TracksColumns.ICON
// Used only be TrackListAdapter
final String[] PROJECTION = new String[]{
TracksColumns._ID,
TracksColumns.NAME,
TracksColumns.DESCRIPTION, //TODO Needed?
TracksColumns.ACTIVITY_TYPE,
TracksColumns.ACTIVITY_TYPE_LOCALIZED,
TracksColumns.STARTTIME,
TracksColumns.STARTTIME_OFFSET,
TracksColumns.TOTALDISTANCE,
TracksColumns.TOTALTIME,
TracksColumns.MARKER_COUNT,
};

String selection = null;
Expand Down Expand Up @@ -316,6 +322,7 @@ private ContentValues createContentValues(Track track) {
values.put(TracksColumns.UUID, UUIDUtils.toBytes(track.getUuid()));
values.put(TracksColumns.NAME, track.getName());
values.put(TracksColumns.DESCRIPTION, track.getDescription());
values.put(TracksColumns.ACTIVITY_TYPE, track.getActivityType() != null ? track.getActivityType().getId() : null);
values.put(TracksColumns.ACTIVITY_TYPE_LOCALIZED, track.getActivityTypeLocalized());
values.put(TracksColumns.STARTTIME_OFFSET, track.getZoneOffset().getTotalSeconds());
if (trackStatistics.getStartTime() != null) {
Expand All @@ -334,7 +341,6 @@ private ContentValues createContentValues(Track track) {
values.put(TracksColumns.MAX_ALTITUDE, trackStatistics.getMaxAltitude());
values.put(TracksColumns.ALTITUDE_GAIN, trackStatistics.getTotalAltitudeGain());
values.put(TracksColumns.ALTITUDE_LOSS, trackStatistics.getTotalAltitudeLoss());
values.put(TracksColumns.ICON, track.getActivityType() != null ? track.getActivityType().getIconId() : "");

return values;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.zone.ZoneRules;
import java.util.Map;
import java.util.UUID;

import de.dennisguse.opentracks.Startup;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.data.tables.MarkerColumns;
import de.dennisguse.opentracks.data.tables.TrackPointsColumns;
Expand All @@ -28,7 +30,9 @@ public class CustomSQLiteOpenHelper extends SQLiteOpenHelper {

private static final String TAG = CustomSQLiteOpenHelper.class.getSimpleName();

private static final int DATABASE_VERSION = 36;
private static final int DATABASE_VERSION = 37;

private final Context context;

public CustomSQLiteOpenHelper(Context context) {
this(context, ((Startup) context.getApplicationContext()).getDatabaseName());
Expand All @@ -37,11 +41,13 @@ public CustomSQLiteOpenHelper(Context context) {
@VisibleForTesting
public CustomSQLiteOpenHelper(Context context, String databaseName) {
super(context, databaseName, null, DATABASE_VERSION);
this.context = context;
}

@VisibleForTesting
public CustomSQLiteOpenHelper(Context context, String databaseName, int databaseVersion) {
super(context, databaseName, null, databaseVersion);
this.context = context;
}

@Override
Expand Down Expand Up @@ -75,6 +81,7 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
case 34 -> upgradeFrom33to34(db);
case 35 -> upgradeFrom34to35(db);
case 36 -> upgradeFrom35to36(db);
case 37 -> upgradeFrom36to37(db);
default -> throw new RuntimeException("Not implemented: upgrade to " + toVersion);
}
}
Expand All @@ -98,6 +105,7 @@ public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
case 33 -> downgradeFrom34to33(db);
case 34 -> downgradeFrom35to34(db);
case 35 -> downgradeFrom36to35(db);
case 36 -> downgradeFrom37to36(db);
default -> throw new RuntimeException("Not implemented: downgrade to " + toVersion);
}
}
Expand Down Expand Up @@ -170,7 +178,7 @@ private void upgradeFrom25to26(SQLiteDatabase db) {
db.beginTransaction();

db.execSQL("ALTER TABLE tracks ADD COLUMN uuid BLOB");
try (Cursor cursor = db.query("tracks", new String[]{"_id" }, null, null, null, null, null)) {
try (Cursor cursor = db.query("tracks", new String[]{"_id"}, null, null, null, null, null)) {
if (cursor.moveToFirst()) {
int trackIdIndex = cursor.getColumnIndexOrThrow("_id");
do {
Expand Down Expand Up @@ -445,7 +453,7 @@ private void upgradeFrom32to33(SQLiteDatabase db) {

ZoneRules zoneRules = ZoneOffset.systemDefault().getRules();

try (Cursor cursor = db.query("tracks", new String[]{"_id", "starttime" }, null, null, null, null, null)) {
try (Cursor cursor = db.query("tracks", new String[]{"_id", "starttime"}, null, null, null, null, null)) {
if (cursor.moveToFirst()) {
int trackIdIndex = cursor.getColumnIndexOrThrow("_id");
int startTimeIndex = cursor.getColumnIndexOrThrow("starttime");
Expand Down Expand Up @@ -564,4 +572,77 @@ private void downgradeFrom36to35(SQLiteDatabase db) {
db.setTransactionSuccessful();
db.endTransaction();
}

private void upgradeFrom36to37(SQLiteDatabase db) {
Map<String, String> activityIcon2ActivityTypeId = Map.ofEntries(
Map.entry("AIRPLANE", "airplane"),
Map.entry("BIKE", "biking"),
Map.entry("MOUNTAIN_BIKE", "mountain biking"),
Map.entry("MOTOR_BIKE", "motor bike"),
Map.entry("KAYAK", "kayaking"),
Map.entry("BOAT", "boat"),
Map.entry("SAILING", "sailing"),
Map.entry("DRIVE", "driving"),
Map.entry("RUN", "running"),
Map.entry("SKI", "skiing"),
Map.entry("SNOW_BOARDING", "snowboarding"),
Map.entry("WALK", "walking"),
Map.entry("ESCOOTER", "escooter"),
Map.entry("KICKSCOOTER", "kickscooter"),
Map.entry("INLINES_SKATING", "inline skating"),
Map.entry("SKATE_BOARDING", "skateboarding"),
Map.entry("CLIMBING", "climbing"),
Map.entry("SWIMMING", "swimming"),
Map.entry("SWIMMING_OPEN", "swimming in open water"),
Map.entry("WORKOUT", "workout"),
Map.entry("UNKNOWN", "unknown")
);

db.beginTransaction();

db.execSQL("ALTER TABLE tracks ADD COLUMN activity_type TEXT");

try (Cursor cursor = db.query("tracks", new String[]{"_id", "icon", "category"}, null, null, null, null, null)) {
if (cursor.moveToFirst()) {
int trackIdIndex = cursor.getColumnIndexOrThrow("_id");
int iconIndex = cursor.getColumnIndexOrThrow("icon");
int activityTypeLocalizedIndex = cursor.getColumnIndexOrThrow("category");
do {
Track.Id trackId = new Track.Id(cursor.getLong(trackIdIndex));
String iconId = cursor.getString(iconIndex);
String activityTypeLocalized = cursor.getString(activityTypeLocalizedIndex);

ActivityType activityType = ActivityType.findByLocalizedString(context, activityTypeLocalized);
if (activityType.equals(ActivityType.UNKNOWN)) {
String activityTypeId = activityIcon2ActivityTypeId.get(iconId);
activityType = ActivityType.findBy(activityTypeId);
}

ContentValues cv = new ContentValues();
cv.put("activity_type", activityType.getId());
db.update("tracks", cv, "_id = ?", new String[]{String.valueOf(trackId.id())});
} while (cursor.moveToNext());
}
}

db.setTransactionSuccessful();
db.endTransaction();
}

private void downgradeFrom37to36(SQLiteDatabase db) {
db.beginTransaction();

db.execSQL("DROP INDEX tracks_uuid_index");

db.execSQL("ALTER TABLE tracks RENAME TO tracks_old");
db.execSQL("CREATE TABLE tracks (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, description TEXT, category TEXT, starttime INTEGER, stoptime INTEGER, numpoints INTEGER, totaldistance FLOAT, totaltime INTEGER, movingtime INTEGER, avgspeed FLOAT, avgmovingspeed FLOAT, maxspeed FLOAT, minelevation FLOAT, maxelevation FLOAT, elevationgain FLOAT, icon TEXT, uuid BLOB, elevationloss FLOAT, starttime_offset INTEGER)");
db.execSQL("INSERT INTO tracks SELECT _id, name, description, category, starttime, stoptime, numpoints, totaldistance, totaltime, movingtime, avgspeed, avgmovingspeed, maxspeed, minelevation, maxelevation, elevationgain, icon, uuid, elevationloss, starttime_offset FROM tracks_old");
db.execSQL("DROP TABLE tracks_old");

db.execSQL("CREATE UNIQUE INDEX tracks_uuid_index ON tracks(uuid)");

db.setTransactionSuccessful();
db.endTransaction();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,8 @@

import de.dennisguse.opentracks.R;

public enum ActivityIcon {
AIRPLANE("AIRPLANE", R.drawable.ic_activity_flight_24dp),
BIKE("BIKE", R.drawable.ic_activity_bike_24dp),
MOUNTAIN_BIKE("MOUNTAIN_BIKE", R.drawable.ic_activity_mtb_24dp),
MOTOR_BIKE("MOTOR_BIKE", R.drawable.ic_activity_motorbike_24dp),
KAYAK("KAYAK", R.drawable.ic_activity_kayaking_24dp),
BOAT("BOAT", R.drawable.ic_activity_boat_24dp),
SAILING("SAILING", R.drawable.ic_activity_sailing_24dp),
DRIVE("DRIVE", R.drawable.ic_activity_drive_24dp),
RUN("RUN", R.drawable.ic_activity_run_24dp),
SKI("SKI", R.drawable.ic_activity_skiing_24dp),
SNOW_BOARDING("SNOW_BOARDING", R.drawable.ic_activity_snowboarding_24dp),
UNKNOWN("UNKNOWN", R.drawable.ic_logo_24dp),
WALK("WALK", R.drawable.ic_activity_walk_24dp),
ESCOOTER("ESCOOTER", R.drawable.ic_activity_escooter_24dp),
KICKSCOOTER("KICKSCOOTER", R.drawable.ic_activity_scooter_24dp),
INLINE_SKATING("INLINES_SKATING", R.drawable.ic_activity_inline_skating_24dp),
SKATE_BOARDING("SKATE_BOARDING", R.drawable.ic_activity_skateboarding_24dp),
CLIMBING("CLIMBING", R.drawable.ic_activity_climbing_24dp),
SWIMMING("SWIMMING", R.drawable.ic_activity_swimming_24dp),
SWIMMING_OPEN("SWIMMING_OPEN", R.drawable.ic_activity_swimming_open_24dp),
WORKOUT("WORKOUT", R.drawable.ic_activity_workout_24dp);
public class ActivityIcon {

@Deprecated //TODO should be removed.
final String iconId;
final int iconDrawableId;
static final int ICON_UNKNOWN = R.drawable.ic_logo_24dp;

ActivityIcon(String iconId, int iconDrawableId) {
this.iconId = iconId;
this.iconDrawableId = iconDrawableId;
}
}
Loading

0 comments on commit 65b5339

Please sign in to comment.