-->

麻烦CLLocation方法distanceFromLocation:不准确的结果(Trouble

2019-06-23 16:26发布

我试图使用distanceFromLocation:方法来计算,我与我的iPhone在我的手走的总距离。 到目前为止,我一直在寻找全国各地,以帮助解决我的困惑,不准确,和看似随意的结果。 在这些代码片段,theLabel仅仅是一个标签对象存在于我的应用程序界面,distanceMoved是,我试图储存我走的总距离的变量,locMan是在我的@interface文件中声明的位置经理。

- (void)viewDidLoad
{
   locMan = [[CLLocationManager alloc] init];
   locMan.delegate = self;
   [locMan startUpdatingLocation];
   isInitial = true;
   distanceMoved = 0.0;
   [super viewDidLoad];
}

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
   distanceMoved += [newLocation distanceFromLocation: oldLocation];
   theLabel.text = [NSString stringWithFormat: @"%f meters", distanceMoved];
}

用于固定什么,我做错了任何帮助将不胜感激。 谢谢!

Answer 1:

  1. 过滤掉缓存的(旧)位置数据,
  2. 滤除无效位置结果(精度<0),
  3. 设置精度要求设置为kCLLocationAccuracyBest
  4. 设定的最小距离过滤器,优选至少10米到滤除位置噪声。
  5. 编辑 :不计算距离时oldLocation为零。

还有更多你可以做,但应该工作只要你得到不错的horizo​​nalAccuracy(<30米)。 你可以滤除低精度的结果,但你不得不跟踪oldLocation自己这是一个比较复杂的。

添加的NSLog(见下文),这样你就可以找出发生了什么。 如果你还没有取得好成绩发布的NSLog的输出,所以我们可以看到发生了什么事情,帮助更多。

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    NSTimeInterval age = -[newLocation.timestamp timeIntervalSinceNow]; 

    if (age > 120) return;    // ignore old (cached) updates

    if (newLocation.horizontalAccuracy < 0) return;   // ignore invalid udpates

    // EDIT: need a valid oldLocation to be able to compute distance
    if (oldLocation == nil || oldLocation.horizontalAccuracy < 0) return; 

    CLLocationDistance distance = [newLocation distanceFromLocation: oldLocation];

    NSLog(@"%6.6f/%6.6f to %6.6f/%6.6f for %2.0fm, accuracy +/-%2.0fm",
        oldLocation.coordinate.latitude,
        oldLocation.coordinate.longitude,
        newLocation.coordinate.latitude,
        newLocation.coordinate.longitude, 
        distance,
        newLocation.horizontalAccuracy);

    distanceMoved += distance;
    theLabel.text = [NSString stringWithFormat: @"%f meters", distanceMoved];
}

- (void)viewDidLoad
{
   locMan = [[CLLocationManager alloc] init];
   locMan.delegate = self;
   locMan.desiredAccuracy = kCLLocationAccuracyBest;
   locMan.distanceFilter = 10;

   [locMan startUpdatingLocation];
   isInitial = true;
   distanceMoved = 0.0;
   [super viewDidLoad];
}

编辑iOS6的 ,如果你想要做的使用相同的didUpdateLocations: (因为上面的方法现在已经过时)最简单的办法是简单地保存每个位置的属性,以便在下次更新时,你有以前的位置。 声明一个属性的类来保存oldLocation

@property (nonatomic, retain) CLLocation* oldLocation;

然后在委托方法您将每个newLocation用作oldLocation下一次委托方法被调用:

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocations:(NSArray *)locations
{
    CLLocation* newLocation = [locations lastObject];

    NSTimeInterval age = -[newLocation.timestamp timeIntervalSinceNow]; 

    if (age > 120) return;    // ignore old (cached) updates

    if (newLocation.horizontalAccuracy < 0) return;   // ignore invalid udpates

    // EDIT: need a valid oldLocation to be able to compute distance
    if (self.oldLocation == nil || self.oldLocation.horizontalAccuracy < 0) {
        self.oldLocation = newLocation;
        return; 
    }

    CLLocationDistance distance = [newLocation distanceFromLocation: self.oldLocation];

    NSLog(@"%6.6f/%6.6f to %6.6f/%6.6f for %2.0fm, accuracy +/-%2.0fm",
        self.oldLocation.coordinate.latitude,
        self.oldLocation.coordinate.longitude,
        newLocation.coordinate.latitude,
        newLocation.coordinate.longitude, 
        distance,
        newLocation.horizontalAccuracy);

    distanceMoved += distance;
    theLabel.text = [NSString stringWithFormat: @"%f meters", distanceMoved];

    self.oldLocation = newLocation;    // save newLocation for next time
}


Answer 2:

您没有设置你的位置管理器的准确性。 通过苹果文档去,这是一样的东西准确性= bestfornavigation。 或者其他的东西。 这应该耗尽电池像地狱,而是​​意味着这种目的。

编辑:只记得我曾经有过在眼前。

// Create the Location Manager
locationManager = [[CLLocationManager alloc] init];

// Configure the Location Manager
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;


Answer 3:

CLLocationDistance distance = [secondLocation distanceFromLocation:firstLocation];  // distance is expressed in meters

CLLocationDistance kilometers = distance / 1000.0;
// or you can also use this..
CLLocationDistance meters = distance;

NSString *distanceString = [[NSString alloc] initWithFormat: @"%f", kilometers];

flot totaldistancecovered = [distanceString floatValue];

//Now,you can use this float value for addition...
// distanceMoved  should be float type variable which is declare in .h file...

 distanceMoved = distanceMoved + totaldistancecovered ;
 theLabel.text = [NSString stringWithFormat: @"%f meters", distanceMoved];

希望对你有帮助..



Answer 4:

你应该做的第一件事是,通过检查你的位置管理器获得的第一个更新的时间戳排出第一次更新,它通常会缓存最后已知位置。 其次记住的准确性,你会得到的初始值总是在范围广泛。



文章来源: Trouble with CLLocation method distanceFromLocation: Inaccurate results