跟踪用户走路跑步距离像耐克+跑步应用程序

时间:2014-09-26 10:38:21

标签: ios objective-c iphone ios8

在我的应用程序中,我试图计算一个人走路的距离。为此我搜索了很多并应用了很多代码来获取用户距离,但每次我得到错误的距离计算。 有些时候用户没有走路,但仍然用户醒来的距离在我的应用程序中增加。 我想在用户不走路时停止计算距离 我正在使用此代码获取用户行进距离

if (oldLocation == nil) return;
BOOL isStaleLocation = ([oldLocation.timestamp compare:self.startTimestamp] == NSOrderedAscending);

[self.locationPingTimer invalidate];

if (newLocation.horizontalAccuracy <= kRequiredHorizontalAccuracy) {
    self.signalStrength = PSLocationManagerGPSSignalStrengthStrong;
} else {
    self.signalStrength = PSLocationManagerGPSSignalStrengthWeak;
}

double horizontalAccuracy;
if (self.allowMaximumAcceptableAccuracy) {
    horizontalAccuracy = kMaximumAcceptableHorizontalAccuracy;
} else {
    horizontalAccuracy = kRequiredHorizontalAccuracy;
}

if (!isStaleLocation && newLocation.horizontalAccuracy >= 0 && newLocation.horizontalAccuracy <= horizontalAccuracy) {

    [self.locationHistory addObject:newLocation];
    if ([self.locationHistory count] > kNumLocationHistoriesToKeep) {
        [self.locationHistory removeObjectAtIndex:0];
    }

    BOOL canUpdateDistanceAndSpeed = NO;
    if ([self.locationHistory count] >= kMinLocationsNeededToUpdateDistanceAndSpeed) {
        canUpdateDistanceAndSpeed = YES && self.readyToExposeDistanceAndSpeed;
    }

    if (self.forceDistanceAndSpeedCalculation || [NSDate timeIntervalSinceReferenceDate] - self.lastDistanceAndSpeedCalculation > kDistanceAndSpeedCalculationInterval) {
        self.forceDistanceAndSpeedCalculation = NO;
        self.lastDistanceAndSpeedCalculation = [NSDate timeIntervalSinceReferenceDate];

        CLLocation *lastLocation = (self.lastRecordedLocation != nil) ? self.lastRecordedLocation : oldLocation;

        CLLocation *bestLocation = nil;
        CGFloat bestAccuracy = kRequiredHorizontalAccuracy;
        for (CLLocation *location in self.locationHistory) {
            if ([NSDate timeIntervalSinceReferenceDate] - [location.timestamp timeIntervalSinceReferenceDate] <= kValidLocationHistoryDeltaInterval) {
                if (location.horizontalAccuracy <= bestAccuracy && location != lastLocation) {
                    bestAccuracy = location.horizontalAccuracy;
                    bestLocation = location;
                }
            }
        }
        if (bestLocation == nil) bestLocation = newLocation;

        CLLocationDistance distance = [bestLocation distanceFromLocation:lastLocation];
        if (canUpdateDistanceAndSpeed) self.totalDistance += distance;
        self.lastRecordedLocation = bestLocation;

        NSTimeInterval timeSinceLastLocation = [bestLocation.timestamp timeIntervalSinceDate:lastLocation.timestamp];
        if (timeSinceLastLocation > 0) {
            CGFloat speed = distance / timeSinceLastLocation;
            if (speed <= 0 && [self.speedHistory count] == 0) {
                // don't add a speed of 0 as the first item, since it just means we're not moving yet
            } else {
                [self.speedHistory addObject:[NSNumber numberWithDouble:speed]];
            }
            if ([self.speedHistory count] > kNumSpeedHistoriesToAverage) {
                [self.speedHistory removeObjectAtIndex:0];
            }
            if ([self.speedHistory count] > 1) {
                double totalSpeed = 0;
                for (NSNumber *speedNumber in self.speedHistory) {
                    totalSpeed += [speedNumber doubleValue];
                }
                if (canUpdateDistanceAndSpeed) {
                    double newSpeed = totalSpeed / (double)[self.speedHistory count];
                    if (kPrioritizeFasterSpeeds > 0 && speed > newSpeed) {
                        newSpeed = speed;
                        [self.speedHistory removeAllObjects];
                        for (int i=0; i<kNumSpeedHistoriesToAverage; i++) {
                            [self.speedHistory addObject:[NSNumber numberWithDouble:newSpeed]];
                        }
                    }
                    self.currentSpeed = newSpeed;
                }
            }
        }

        if ([self.delegate respondsToSelector:@selector(locationManager:waypoint:calculatedSpeed:)]) {
            [self.delegate locationManager:self waypoint:self.lastRecordedLocation calculatedSpeed:self.currentSpeed];
        }
    }
}

// this will be invalidated above if a new location is received before it fires
self.locationPingTimer = [NSTimer timerWithTimeInterval:kMinimumLocationUpdateInterval target:self selector:@selector(requestNewLocation) userInfo:nil repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:self.locationPingTimer forMode:NSRunLoopCommonModes];

0 个答案:

没有答案