From 3625b0d9a97cb3d3d874d8b9e0f6db9ea0f546ac Mon Sep 17 00:00:00 2001 From: Alain Knaff Date: Sun, 2 May 2021 21:00:45 +0200 Subject: [PATCH 1/3] Support for multiple track segments. A new track segment is started whenever tracking is suspended and then resumed --- .../osmtracker/activity/DisplayTrackMap.java | 19 +++--- .../java/net/osmtracker/db/DataHelper.java | 5 +- .../net/osmtracker/db/DatabaseHelper.java | 7 ++- .../osmtracker/db/TrackContentProvider.java | 4 +- .../net/osmtracker/gpx/ExportTrackTask.java | 9 ++- .../net/osmtracker/overlay/PathOverlays.java | 59 +++++++++++++++++++ .../net/osmtracker/service/gps/GPSLogger.java | 9 ++- 7 files changed, 98 insertions(+), 14 deletions(-) create mode 100644 app/src/main/java/net/osmtracker/overlay/PathOverlays.java diff --git a/app/src/main/java/net/osmtracker/activity/DisplayTrackMap.java b/app/src/main/java/net/osmtracker/activity/DisplayTrackMap.java index c0e8f3d64..9e4b02f1c 100644 --- a/app/src/main/java/net/osmtracker/activity/DisplayTrackMap.java +++ b/app/src/main/java/net/osmtracker/activity/DisplayTrackMap.java @@ -8,6 +8,7 @@ import net.osmtracker.R; import net.osmtracker.db.TrackContentProvider; import net.osmtracker.overlay.WayPointsOverlay; +import net.osmtracker.overlay.PathOverlays; import org.osmdroid.api.IMapController; import org.osmdroid.config.Configuration; @@ -15,7 +16,6 @@ import org.osmdroid.tileprovider.tilesource.TileSourceFactory; import org.osmdroid.util.GeoPoint; import org.osmdroid.views.MapView; -import org.osmdroid.views.overlay.PathOverlay; import org.osmdroid.views.overlay.mylocation.SimpleLocationOverlay; import org.osmdroid.views.overlay.ScaleBarOverlay; @@ -38,6 +38,7 @@ import android.view.View; import android.view.View.OnClickListener; + /** * Display current track over an OSM map. * Based on osmdroid code http://osmdroid.googlecode.com/ @@ -109,7 +110,7 @@ public class DisplayTrackMap extends Activity { /** * OSM view overlay that displays current path */ - private PathOverlay pathOverlay; + private PathOverlays pathOverlay; /** * OSM view overlay that displays waypoints @@ -379,9 +380,7 @@ private void createOverlays() { this.getWindowManager().getDefaultDisplay().getMetrics(metrics); // set with to hopefully DPI independent 0.5mm - pathOverlay = new PathOverlay(Color.BLUE, (float)(metrics.densityDpi / 25.4 / 2),this); - - osmView.getOverlays().add(pathOverlay); + pathOverlay = new PathOverlays(Color.BLUE, (float)(metrics.densityDpi / 25.4 / 2),this, osmView); myLocationOverlay = new SimpleLocationOverlay(this); osmView.getOverlays().add(myLocationOverlay); @@ -426,7 +425,7 @@ private void pathChanged() { // Projection: The columns to retrieve. Here, we want the latitude, // longitude and primary key only - String[] projection = {TrackContentProvider.Schema.COL_LATITUDE, TrackContentProvider.Schema.COL_LONGITUDE, TrackContentProvider.Schema.COL_ID}; + String[] projection = {TrackContentProvider.Schema.COL_LATITUDE, TrackContentProvider.Schema.COL_LONGITUDE, TrackContentProvider.Schema.COL_ID, TrackContentProvider.Schema.COL_NEW_SEGMENT}; // Selection: The where clause to use String selection = null; // SelectionArgs: The parameter replacements to use for the '?' in the selection @@ -454,15 +453,21 @@ private void pathChanged() { c.moveToFirst(); double lastLat = 0; double lastLon = 0; + boolean newSegment = false; int primaryKeyColumnIndex = c.getColumnIndex(TrackContentProvider.Schema.COL_ID); int latitudeColumnIndex = c.getColumnIndex(TrackContentProvider.Schema.COL_LATITUDE); int longitudeColumnIndex = c.getColumnIndex(TrackContentProvider.Schema.COL_LONGITUDE); - + int newSegmentColumnIndex = c.getColumnIndex(TrackContentProvider.Schema.COL_NEW_SEGMENT); + // Add each new point to the track while(!c.isAfterLast()) { lastLat = c.getDouble(latitudeColumnIndex); lastLon = c.getDouble(longitudeColumnIndex); lastTrackPointIdProcessed = c.getInt(primaryKeyColumnIndex); + newSegment = c.getShort(newSegmentColumnIndex) > 0; + if(newSegment) { + pathOverlay.nextSegment(); + } pathOverlay.addPoint((int)(lastLat * 1e6), (int)(lastLon * 1e6)); if (doInitialBoundsCalc) { if (lastLat < minLat) minLat = lastLat; diff --git a/app/src/main/java/net/osmtracker/db/DataHelper.java b/app/src/main/java/net/osmtracker/db/DataHelper.java index 8c4934020..8c06bac6e 100644 --- a/app/src/main/java/net/osmtracker/db/DataHelper.java +++ b/app/src/main/java/net/osmtracker/db/DataHelper.java @@ -112,7 +112,7 @@ public DataHelper(Context c) { * @param pressure * atmospheric pressure */ - public void track(long trackId, Location location, float azimuth, int accuracy, float pressure) { + public void track(long trackId, Location location, float azimuth, int accuracy, float pressure, boolean newSeg) { Log.v(TAG, "Tracking (trackId=" + trackId + ") location: " + location + " azimuth: " + azimuth + ", accuracy: " + accuracy); ContentValues values = new ContentValues(); values.put(TrackContentProvider.Schema.COL_TRACK_ID, trackId); @@ -146,6 +146,9 @@ public void track(long trackId, Location location, float azimuth, int accuracy, values.put(TrackContentProvider.Schema.COL_ATMOSPHERIC_PRESSURE, pressure); } + values.put(TrackContentProvider.Schema.COL_NEW_SEGMENT, + newSeg ? 1 : 0); + Uri trackUri = ContentUris.withAppendedId(TrackContentProvider.CONTENT_URI_TRACK, trackId); contentResolver.insert(Uri.withAppendedPath(trackUri, TrackContentProvider.Schema.TBL_TRACKPOINT + "s"), values); } diff --git a/app/src/main/java/net/osmtracker/db/DatabaseHelper.java b/app/src/main/java/net/osmtracker/db/DatabaseHelper.java index 75b3f9e9d..f92ebef57 100644 --- a/app/src/main/java/net/osmtracker/db/DatabaseHelper.java +++ b/app/src/main/java/net/osmtracker/db/DatabaseHelper.java @@ -39,7 +39,8 @@ public class DatabaseHelper extends SQLiteOpenHelper { + TrackContentProvider.Schema.COL_TIMESTAMP + " long not null," + TrackContentProvider.Schema.COL_COMPASS + " double null," + TrackContentProvider.Schema.COL_COMPASS_ACCURACY + " integer null," - + TrackContentProvider.Schema.COL_ATMOSPHERIC_PRESSURE + " double null" + ")"; + + TrackContentProvider.Schema.COL_ATMOSPHERIC_PRESSURE + " double null," + + TrackContentProvider.Schema.COL_NEW_SEGMENT + " integer default 0" + ")"; /** * SQL for creating index TRACKPOINT_idx (track id) @@ -125,7 +126,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { * v17: add TBL_TRACKPOINT.COL_ATMOSPHERIC_PRESSURE and TBL_WAYPOINT.COL_ATMOSPHERIC_PRESSURE * */ - private static final int DB_VERSION = 17; + private static final int DB_VERSION = 18; public DatabaseHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); @@ -178,6 +179,8 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { case 16: db.execSQL("alter table " + TrackContentProvider.Schema.TBL_TRACKPOINT + " add column " + TrackContentProvider.Schema.COL_ATMOSPHERIC_PRESSURE + " double null"); db.execSQL("alter table " + TrackContentProvider.Schema.TBL_WAYPOINT + " add column " + TrackContentProvider.Schema.COL_ATMOSPHERIC_PRESSURE + " double null"); + case 17: + db.execSQL("alter table "+TrackContentProvider.Schema.TBL_TRACKPOINT + " add column " + TrackContentProvider.Schema.COL_NEW_SEGMENT + " integer default 0"); } } diff --git a/app/src/main/java/net/osmtracker/db/TrackContentProvider.java b/app/src/main/java/net/osmtracker/db/TrackContentProvider.java index ffb551ed0..a0fcc65fd 100644 --- a/app/src/main/java/net/osmtracker/db/TrackContentProvider.java +++ b/app/src/main/java/net/osmtracker/db/TrackContentProvider.java @@ -496,7 +496,9 @@ public static final class Schema { public static final String COL_COMPASS = "compass_heading"; public static final String COL_COMPASS_ACCURACY = "compass_accuracy"; public static final String COL_ATMOSPHERIC_PRESSURE = "atmospheric_pressure"; - + + public static final String COL_NEW_SEGMENT = "new_segment"; + // virtual colums that are used in some sqls but dont exist in database public static final String COL_TRACKPOINT_COUNT = "tp_count"; public static final String COL_WAYPOINT_COUNT = "wp_count"; diff --git a/app/src/main/java/net/osmtracker/gpx/ExportTrackTask.java b/app/src/main/java/net/osmtracker/gpx/ExportTrackTask.java index c9cc62751..61728aa34 100644 --- a/app/src/main/java/net/osmtracker/gpx/ExportTrackTask.java +++ b/app/src/main/java/net/osmtracker/gpx/ExportTrackTask.java @@ -358,8 +358,15 @@ private void writeTrackPoints(String trackName, Writer fw, Cursor c, boolean fil fw.write("\t\t" + "" + "\n"); int i=0; + boolean havePoint=false; for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext(),i++) { StringBuffer out = new StringBuffer(); + if(havePoint && c.getShort(c.getColumnIndex(TrackContentProvider.Schema.COL_NEW_SEGMENT)) > 0) { + fw.write("\t\t" + "" + "\n"); + fw.write("\t\t" + "" + "\n"); + } + havePoint=true; + out.append("\t\t\t" + "" + "\n"); @@ -612,4 +619,4 @@ public String sanitizeTrackName(String trackName){ public String getErrorMsg() { return errorMsg; } -} \ No newline at end of file +} diff --git a/app/src/main/java/net/osmtracker/overlay/PathOverlays.java b/app/src/main/java/net/osmtracker/overlay/PathOverlays.java new file mode 100644 index 000000000..49408de80 --- /dev/null +++ b/app/src/main/java/net/osmtracker/overlay/PathOverlays.java @@ -0,0 +1,59 @@ +package net.osmtracker.overlay; + +import java.util.ArrayList; +import java.util.List; + +import org.osmdroid.views.MapView; +import org.osmdroid.views.overlay.PathOverlay; + +import android.content.Context; + +/** + * Collection of Overlays, useful to draw interrupted paths + */ +public class PathOverlays { + private int color; + private float width; + private Context ctx; + private MapView osmView; + private boolean havePoint; + + private int curIdx=0; + + private List paths = new ArrayList(); + + private void addPath() { + PathOverlay path = new PathOverlay(color, width, ctx); + paths.add(path); + osmView.getOverlays().add(path); + } + + public void clearPath() { + for(PathOverlay path : paths) + path.clearPath(); + curIdx=0; + } + + public PathOverlays(int color, float width, + Context ctx, MapView osmView) { + this.color=color; + this.width=width; + this.ctx=ctx; + this.osmView = osmView; + addPath(); + havePoint=false; + } + + public void addPoint(double lat, double lon) { + if(curIdx >= paths.size()) + addPath(); + paths.get(curIdx).addPoint(lat, lon); + havePoint=true; + } + + public void nextSegment() { + if(havePoint) + curIdx++; + havePoint=false; + } +} diff --git a/app/src/main/java/net/osmtracker/service/gps/GPSLogger.java b/app/src/main/java/net/osmtracker/service/gps/GPSLogger.java index ce596da58..b32c4240f 100644 --- a/app/src/main/java/net/osmtracker/service/gps/GPSLogger.java +++ b/app/src/main/java/net/osmtracker/service/gps/GPSLogger.java @@ -103,6 +103,8 @@ public class GPSLogger extends Service implements LocationListener { */ private PressureListener pressureListener = new PressureListener(); + private boolean newSeg = true; + /** * Receives Intent for way point tracking, and stop/start logging. */ @@ -129,7 +131,8 @@ public void onReceive(Context context, Intent intent) { dataHelper.wayPoint(trackId, lastLocation, name, link, uuid, sensorListener.getAzimuth(), sensorListener.getAccuracy(), pressureListener.getPressure()); // If there is a waypoint in the track, there should also be a trackpoint - dataHelper.track(currentTrackId, lastLocation, sensorListener.getAzimuth(), sensorListener.getAccuracy(), pressureListener.getPressure()); + dataHelper.track(currentTrackId, lastLocation, sensorListener.getAzimuth(), sensorListener.getAccuracy(), pressureListener.getPressure(),newSeg); + newSeg = false; } } } @@ -243,6 +246,7 @@ public void onCreate() { @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.v(TAG, "Service onStartCommand(-,"+flags+","+startId+")"); + newSeg = true; createNotificationChannel(); startForeground(NOTIFICATION_ID, getNotification()); return Service.START_STICKY; @@ -306,7 +310,8 @@ public void onLocationChanged(Location location) { lastLocation = location; if (isTracking) { - dataHelper.track(currentTrackId, location, sensorListener.getAzimuth(), sensorListener.getAccuracy(), pressureListener.getPressure()); + dataHelper.track(currentTrackId, location, sensorListener.getAzimuth(), sensorListener.getAccuracy(), pressureListener.getPressure(), newSeg); + newSeg = false; } } } From 7866178141c58adec4f039f055ba687a20bad44f Mon Sep 17 00:00:00 2001 From: Alain Knaff Date: Mon, 3 May 2021 07:06:38 +0200 Subject: [PATCH 2/3] Removed extra empty line --- app/src/main/java/net/osmtracker/activity/DisplayTrackMap.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/net/osmtracker/activity/DisplayTrackMap.java b/app/src/main/java/net/osmtracker/activity/DisplayTrackMap.java index 9e4b02f1c..27f8d0d83 100644 --- a/app/src/main/java/net/osmtracker/activity/DisplayTrackMap.java +++ b/app/src/main/java/net/osmtracker/activity/DisplayTrackMap.java @@ -38,7 +38,6 @@ import android.view.View; import android.view.View.OnClickListener; - /** * Display current track over an OSM map. * Based on osmdroid code http://osmdroid.googlecode.com/ From 9f46f950d4e476e643c6ce45c3fbccd05c13e672 Mon Sep 17 00:00:00 2001 From: Alain Knaff Date: Mon, 3 May 2021 21:09:04 +0200 Subject: [PATCH 3/3] Only start a new segment on explicit 'Resume', in order to avoid starting a new segment by just going back to track list --- app/src/main/java/net/osmtracker/service/gps/GPSLogger.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/net/osmtracker/service/gps/GPSLogger.java b/app/src/main/java/net/osmtracker/service/gps/GPSLogger.java index b32c4240f..35d0a5da8 100644 --- a/app/src/main/java/net/osmtracker/service/gps/GPSLogger.java +++ b/app/src/main/java/net/osmtracker/service/gps/GPSLogger.java @@ -103,7 +103,7 @@ public class GPSLogger extends Service implements LocationListener { */ private PressureListener pressureListener = new PressureListener(); - private boolean newSeg = true; + private boolean newSeg = false; /** * Receives Intent for way point tracking, and stop/start logging. @@ -154,6 +154,7 @@ public void onReceive(Context context, Intent intent) { dataHelper.deleteWayPoint(uuid); } } else if (OSMTracker.INTENT_START_TRACKING.equals(intent.getAction()) ) { + newSeg = true; Bundle extras = intent.getExtras(); if (extras != null) { Long trackId = extras.getLong(TrackContentProvider.Schema.COL_TRACK_ID); @@ -246,7 +247,6 @@ public void onCreate() { @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.v(TAG, "Service onStartCommand(-,"+flags+","+startId+")"); - newSeg = true; createNotificationChannel(); startForeground(NOTIFICATION_ID, getNotification()); return Service.START_STICKY;