Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 131 additions & 12 deletions GPSLogger/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions GPSLogger/GLManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ static NSString *const GLPausesAutomaticallyDefaultsName = @"GLPausesAutomatical
static NSString *const GLResumesAutomaticallyDefaultsName = @"GLResumesAutomaticallyDefaults";
static NSString *const GLDiscardPointsWithinDistanceDefaultsName = @"GLDiscardPointsWithinDistanceDefaults";
static NSString *const GLDiscardPointsWithinSecondsDefaultsName = @"GLDiscardPointsWithinSecondsDefaults";
static NSString *const GLDiscardPointsOutsideAccuracyDefaultsName = @"GLDiscardPointsOutsideAccuracyDefaults";
static NSString *const GLStopsAutomaticallyDefaultsName = @"GLStopsAutomaticallyDefaults";
static NSString *const GLStopsAutomaticallyAfterDefaultsName = @"GLStopsAutomaticallyAfterDefaults";
static NSString *const GLIncludeTrackingStatsDefaultsName = @"GLIncludeTrackingStatsDefaultsName";
static NSString *const GLActivityTypeDefaultsName = @"GLActivityTypeDefaults";
static NSString *const GLDesiredAccuracyDefaultsName = @"GLDesiredAccuracyDefaults";
Expand All @@ -37,10 +40,12 @@ static NSString *const GLNotificationPermissionRequestedDefaultsName = @"GLNotif
static NSString *const GLNotificationsEnabledDefaultsName = @"GLNotificationsEnabledDefaults";
static NSString *const GLIncludeUniqueIdDefaultsName = @"GLIncludeUniqueIdDefaults";
static NSString *const GLConsiderHTTP200SuccessDefaultsName = @"GLConsiderHTTP200SuccessDefaults";
static NSString *const GLPreciseSettingsDefaults = @"GLPreciseSettingsDefaults";
static NSString *const GLBackgroundIndicatorDefaultsName = @"GLBackgroundIndicatorDefaults";
static NSString *const GLLoggingModeDefaultsName = @"GLLoggingModeDefaults";
static NSString *const GLTripModeStatsDefaultsName = @"GLTripModeStats";
static NSString *const GLVisitTrackingEnabledDefaultsName = @"GLVisitTrackingEnabledDefaults";
static NSString *const GLLastTimeMovedBeyondStopThresholdDefaultsName = @"GLLastTimeMovedBeyondStopThresholdDefaults";

static NSString *const GLPurgeQueueOnNextLaunchDefaultsName = @"GLPurgeQueueOnNextLaunch";
static NSString *const GLLastScheduledNotificationDateDefaultsName = @"GLLastScheduledNotificationDateDefaults";
Expand All @@ -54,6 +59,7 @@ static NSString *const GLTripLoggingModeDefaultsName = @"GLTripLoggingModeDefaul
static NSString *const GLTripPointsPerBatchDefaultsName = @"GLTripPointsPerBatchDefaults";
static NSString *const GLTripDiscardPointsWithinDistanceDefaultsName = @"GLTripDiscardPointsWithinDistanceDefaults";
static NSString *const GLTripDiscardPointsWithinSecondsDefaultsName = @"GLTripDiscardPointsWithinSecondsDefaults";
static NSString *const GLTripDiscardPointsOutsideAccuracyDefaultsName = @"GLTripDiscardPointsOutsideAccuracyDefaults";
static NSString *const GLScreenLockEnabledDefaultsName = @"GLScreenLockEnabledDefaults";
/* End */

Expand Down Expand Up @@ -118,6 +124,9 @@ typedef void (^CaseBlock)(void);
@property BOOL notificationsEnabled;
@property (nonatomic) CLLocationDistance resumesAfterDistance;
@property (nonatomic) CLLocationDistance discardPointsWithinDistance;
@property (nonatomic) CLLocationDistance stopsAutomaticallyRadius;
@property (nonatomic) CLLocationAccuracy discardPointsOutsideAccuracy;
@property (nonatomic) int stopsAutomaticallyAfterSeconds;
@property (nonatomic) int discardPointsWithinSeconds;
@property (nonatomic) GLTrackingMode trackingMode;
@property BOOL visitTrackingEnabled;
Expand All @@ -126,6 +135,8 @@ typedef void (^CaseBlock)(void);
@property (nonatomic) CLActivityType activityType;
@property (nonatomic) CLLocationAccuracy desiredAccuracy;
@property (nonatomic) int pointsPerBatch;
@property CLLocation* lastLocationMovedBeyondStopThreshold;
@property NSDate* lastTimeMovedBeyondStopThreshold;

/* During-Trip Settings */
@property (nonatomic) CLLocationAccuracy desiredAccuracyDuringTrip;
Expand Down
111 changes: 106 additions & 5 deletions GPSLogger/GLManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,35 @@ - (void)updateSettingsFromResponse:(id _Nullable)responseObject {
@"5m": ^{ self.discardPointsWithinSeconds = 300; },
};
[self runBlock:minTimeBlocks fromDictionary:main forKey:@"min_time"];

NSDictionary *maxAccuracyBlocks = @{
@"off": ^{ self.discardPointsOutsideAccuracy = -1; },
@"10m": ^{ self.discardPointsOutsideAccuracy = 10; },
@"50m": ^{ self.discardPointsOutsideAccuracy = 50; },
@"100m": ^{ self.discardPointsOutsideAccuracy = 100; },
@"500m": ^{ self.discardPointsOutsideAccuracy = 500; },
@"1000m": ^{ self.discardPointsOutsideAccuracy = 1000; },
};
[self runBlock:maxAccuracyBlocks fromDictionary:main forKey:@"max_accuracy"];

NSDictionary *stopsRadiusBlocks = @{
@"off": ^{ self.stopsAutomaticallyRadius = -1; },
@"10m": ^{ self.stopsAutomaticallyRadius = 1; },
@"20m": ^{ self.stopsAutomaticallyRadius = 20; },
@"50m": ^{ self.stopsAutomaticallyRadius = 50; },
@"100m": ^{ self.stopsAutomaticallyRadius = 100; },
@"200m": ^{ self.stopsAutomaticallyRadius = 200; },
};
[self runBlock:stopsRadiusBlocks fromDictionary:main forKey:@"stop_radius"];

NSDictionary *stopsTimeBlocks = @{
@"1min": ^{ self.discardPointsWithinSeconds = 60; },
@"2min": ^{ self.discardPointsWithinSeconds = 60*2; },
@"5min": ^{ self.discardPointsWithinSeconds = 60*5; },
@"10min": ^{ self.discardPointsWithinSeconds = 60*10; },
@"20min": ^{ self.discardPointsWithinSeconds = 60*20; },
};
[self runBlock:stopsTimeBlocks fromDictionary:main forKey:@"stop_time"];

}

Expand Down Expand Up @@ -1149,6 +1178,17 @@ - (void)setDiscardPointsWithinDistance:(CLLocationDistance)distance {
[[NSUserDefaults standardUserDefaults] setDouble:distance forKey:GLDiscardPointsWithinDistanceDefaultsName];
}

- (CLLocationAccuracy)discardPointsOutsideAccuracy {
if([self defaultsKeyExists:GLDiscardPointsOutsideAccuracyDefaultsName]) {
return [[NSUserDefaults standardUserDefaults] doubleForKey:GLDiscardPointsOutsideAccuracyDefaultsName];
} else {
return -1;
}
}
- (void)setDiscardPointsOutsideAccuracy:(CLLocationAccuracy)distance {
[[NSUserDefaults standardUserDefaults] setDouble:distance forKey:GLDiscardPointsOutsideAccuracyDefaultsName];
}

- (CLLocationDistance)discardPointsWithinDistanceDuringTrip {
if([self defaultsKeyExists:GLTripDiscardPointsWithinDistanceDefaultsName]) {
return [[NSUserDefaults standardUserDefaults] doubleForKey:GLTripDiscardPointsWithinDistanceDefaultsName];
Expand Down Expand Up @@ -1198,6 +1238,28 @@ - (int)discardPointsWithinSecondsCurrentValue {
}
}

- (CLLocationDistance)stopsAutomaticallyRadius {
if([self defaultsKeyExists:GLStopsAutomaticallyDefaultsName]) {
return [[NSUserDefaults standardUserDefaults] doubleForKey:GLStopsAutomaticallyDefaultsName];
} else {
return -1;
}
}
- (void)setStopsAutomaticallyRadius:(CLLocationDistance)distance {
[[NSUserDefaults standardUserDefaults] setDouble:distance forKey:GLStopsAutomaticallyDefaultsName];
}

- (int)stopsAutomaticallyAfterSeconds {
if([self defaultsKeyExists:GLStopsAutomaticallyAfterDefaultsName]) {
return (int)[[NSUserDefaults standardUserDefaults] integerForKey:GLStopsAutomaticallyAfterDefaultsName];
} else {
return 60;
}
}
- (void)setStopsAutomaticallyAfterSeconds:(int)seconds {
[[NSUserDefaults standardUserDefaults] setInteger:seconds forKey:GLStopsAutomaticallyAfterDefaultsName];
}


#pragma mark CLLocationManager

Expand Down Expand Up @@ -1608,6 +1670,13 @@ - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray
// This probably shouldn't happen, but just in case, don't log anything if they have tracking mode set to off
return;
}

// Just incase these wont be restarted after stopped and user moved significantly, make sure updates start again.
if (self.trackingMode == kGLTrackingModeStandardAndSignificant) {
[self.locationManager startUpdatingLocation];
[self.locationManager startUpdatingHeading];
[self.locationManager startMonitoringSignificantLocationChanges];
}

// If a wifi override is configured, replace the input location list with the location in the wifi mapping
if([GLManager currentWifiHotSpotName]) {
Expand Down Expand Up @@ -1668,6 +1737,12 @@ - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray
}
}

if(self.discardPointsOutsideAccuracy > 0) {
if(loc.horizontalAccuracy > self.discardPointsOutsideAccuracy) {
continue;
}
}

NSString *timestamp = [GLManager iso8601DateStringFromDate:loc.timestamp];
NSDictionary *update;
if(self.loggingModeCurrentValue == kGLLoggingModeOwntracks) {
Expand Down Expand Up @@ -1719,6 +1794,32 @@ - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray
self.lastLocationDictionary = [self currentDictionaryFromLocation:self.lastLocation];

}

// If stopsautomatically is active, update the saved location and time whenever user exits the radius.
// Also make sure that the location timestamp isnt older than 20 seconds to handle apple delivering locations late.
if (self.stopsAutomaticallyRadius != -1 && ([self.lastLocation.timestamp timeIntervalSinceNow] > -20 || !self.lastTimeMovedBeyondStopThreshold)) {
if ([self.lastLocationMovedBeyondStopThreshold distanceFromLocation:self.lastLocation] > self.stopsAutomaticallyRadius || !self.lastTimeMovedBeyondStopThreshold) {
self.lastLocationMovedBeyondStopThreshold = self.lastLocation;
self.lastTimeMovedBeyondStopThreshold = NSDate.now;
}
}


// if all necessary settings are activated, and user spent enough time within radius, stop location updates,
// and rely only on significant location change to signal movement and subsequent restarting of the updates.
// this will happen after around 500 meters, but will DRASTICALLY save battery life.
if (self.trackingMode == kGLTrackingModeStandardAndSignificant \
&& self.stopsAutomaticallyRadius != -1 \
&& self.lastTimeMovedBeyondStopThreshold \
&& [self.lastTimeMovedBeyondStopThreshold timeIntervalSinceNow] < -self.stopsAutomaticallyAfterSeconds) {

[self.locationManager stopUpdatingLocation];
[self.locationManager stopUpdatingHeading];
[self.locationManager startMonitoringSignificantLocationChanges];

NSLog(@"Stopping loc updates");
[self notify:@"Location updates paused. Waiting for significant movement." withTitle:@"Paused"];
}

if(didAddData) {
[[NSNotificationCenter defaultCenter] postNotificationName:GLNewDataNotification object:self];
Expand Down Expand Up @@ -1756,11 +1857,11 @@ - (NSDictionary *)currentDictionaryFromLocation:(CLLocation *)loc {
},
@"properties": [NSMutableDictionary dictionaryWithDictionary:@{
@"timestamp": timestamp,
@"altitude": [NSNumber numberWithInt:(int)round(loc.altitude)],
@"speed": [NSNumber numberWithInt:(int)round(loc.speed)],
@"course": [NSNumber numberWithInt:(int)round(loc.course)],
@"horizontal_accuracy": [NSNumber numberWithInt:(int)round(loc.horizontalAccuracy)],
@"vertical_accuracy": [NSNumber numberWithInt:(int)round(loc.verticalAccuracy)],
@"altitude": [NSNumber numberWithDouble:((int)(loc.altitude * 1000)) / 1000.0],
@"speed": [NSNumber numberWithDouble:((int)(loc.speed * 1000)) / 1000.0],
@"course": [NSNumber numberWithDouble:((int)(loc.course * 1000)) / 1000.0],
@"horizontal_accuracy": [NSNumber numberWithDouble:((int)(loc.horizontalAccuracy * 1000)) / 1000.0],
@"vertical_accuracy": [NSNumber numberWithDouble:((int)(loc.verticalAccuracy * 1000)) / 1000.0],
@"speed_accuracy": [NSNumber numberWithDouble:((int)(loc.speedAccuracy * 100)) / 100.0],
@"course_accuracy": [NSNumber numberWithDouble:((int)(loc.courseAccuracy * 100)) / 100.0],
@"motion": [self motionArrayFromLastMotion],
Expand Down
10 changes: 10 additions & 0 deletions GPSLogger/Settings.bundle/Root.plist
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@
<string>Root</string>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Precise Settings</string>
<key>Key</key>
<string>GLPreciseSettingsDefaults</string>
<key>DefaultValue</key>
<false/>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
Expand Down
15 changes: 15 additions & 0 deletions GPSLogger/SettingsViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@
@property (strong, nonatomic) IBOutlet UISegmentedControl *resumesWithGeofence;
@property (strong, nonatomic) IBOutlet UISegmentedControl *discardPointsWithinDistance;
@property (strong, nonatomic) IBOutlet UISegmentedControl *discardPointsWithinSeconds;
@property (strong, nonatomic) IBOutlet UISegmentedControl *stopsAutomatically;
@property (strong, nonatomic) IBOutlet UISegmentedControl *stopsAutomaticallyAfter;
@property (strong, nonatomic) IBOutlet UISegmentedControl *discardPointsOutsideAccuracy;
@property (strong, nonatomic) IBOutlet UISlider *discardDistanceSlider;
@property (strong, nonatomic) IBOutlet UISlider *discardSecondsSlider;
@property (strong, nonatomic) IBOutlet UISlider *discardAccuracySlider;
@property (strong, nonatomic) IBOutlet UILabel *discardDistanceValueLabel;
@property (strong, nonatomic) IBOutlet UILabel *discardSecondsValueLabel;
@property (strong, nonatomic) IBOutlet UILabel *discardAccuracyValueLabel;
@property (strong, nonatomic) IBOutlet UISwitch *enableNotifications;
@property (strong, nonatomic) IBOutlet UIStackView *locationAuthorizationStatusSection;
@property (strong, nonatomic) IBOutlet UILabel *locationAuthorizationStatus;
Expand All @@ -43,6 +52,12 @@
- (IBAction)resumeWithGeofenceWasChanged:(UISegmentedControl *)sender;
- (IBAction)discardPointsWithinDistanceWasChanged:(UISegmentedControl *)sender;
- (IBAction)discardPointsWithinSecondsWasChanged:(UISegmentedControl *)sender;
- (IBAction)stopsAutomaticallyWasChanged:(UISegmentedControl *)sender;
- (IBAction)stopsAutomaticallyAfterWasChanged:(UISegmentedControl *)sender;
- (IBAction)discardPointsOutsideAccuracyWasChanged:(UISegmentedControl *)sender;
- (IBAction)discardPointsWithinDistancePreciseWasChanged:(UISlider *)sender;
- (IBAction)discardPointsWithinSecondsPreciseWasChanged:(UISlider *)sender;
- (IBAction)discardPointsOutsideAccuracyPreciseWasChanged:(UISlider *)sender;
- (IBAction)toggleNotificationsEnabled:(UISwitch *)sender;
- (IBAction)requestLocationPermissionsWasPressed:(UIButton *)sender;
- (IBAction)privacyPolicyWasPressed:(UIButton *)sender;
Expand Down
Loading