【问题标题】:Definitive algorithm for determining most accurate returned from iPhone CoreLocation?确定从 iPhone CoreLocation 返回的最准确的最终算法?
【发布时间】:2011-04-22 02:23:15
【问题描述】:

有人解决了吗? 我已经阅读了很多论坛帖子,但我仍然无法判断这是否是一个已解决的问题......

鉴于 didUpdateToLocation() 可以返回缓存或不准确的信息,您如何判断何时有准确的修复?

当您将所需精度设置为 kCLLocationAccuracyNearestTenMeters、HundredMeters、Kilometer、ThreeKilometers 时,显然您可以将返回的点的水平精度与所需精度进行比较,以决定何时接受一个点。

但是 kCLLocationAccuracyBestForNavigation 和 kCLLocationAccuracyBest 的值分别是 -2 和 -1 那么我怎么知道我什么时候达到了所需的精度??

我目前检查修复的年龄并拒绝任何时间上太“旧”的修复。 然后我检查水平精度是否为负,如果是则拒绝。 如果我得到一个正的verticalAccuracy,那么我通常会使用该修复,因为相应的水平精度也很好。

但是当我在寻找 10-100 米的精度时使用了这些检查... 我不知道在运行 ...AccuracyBestForNavigation 或 ...AccuracyBest 时要检查什么?我是否应该对不断运行的 locationManager 进行调整,并且从不期望将其关闭并且不过滤任何结果??

有比我聪明的人回答吗??

谢谢

【问题讨论】:

    标签: iphone core-location


    【解决方案1】:

    我知道这是我要带回来的一个旧线程,但我遇到了这个问题,因为我也在寻找一个最准确的解决方案,并且在阅读了您的解决方案 fspirit 之后,我非常喜欢它。和 morgman 一样,我也在想类似的事情,但你只是把我们的想法写进了代码中,哈哈。我也喜欢你的前向多线程思维;)

    但如果您愿意,我实际上有一个问题/建议。 当我尝试在 iphone 上获取位置数据时,我立即获得了至少 3 组具有相同水平精度的坐标。因此,良好的尝试次数必须超过 4 次。但接下来的问题是,尝试多少次才是好的?

    所以我建议不要改变尝试次数,我们可以稍微调整一下代码,使尝试次数计数器上升只有当水平精度明显低于前一个时,或者小于最准确的一个,类似的。我只是在这里大声思考。因为我查看了从我的 iphone 4 获得的所有位置数据(我不确定它在其他设备上如何工作),从我所看到的情况来看,位置正在不断更新,水平精度在前几次更新中保持相对不变,然后过了一会儿它突然从 400 跳到 100,然后再过一两秒后,它又跳到 30 左右。所有这一切都在大约 30-50 次更新,因此在这种情况下,最大尝试次数 4 可能不起作用,除非您只计算跳跃次数。大家觉得呢?

    【讨论】:

      【解决方案2】:

      这并不是一个真正确定的、完美的算法(我怀疑这个任务有一个算法,因为外部条件,我的意思是,你可以尝试在平原或坟墓内获取你的位置),它是一个临时的,它对我有用。

      我为 LocationManager 做了一个包装器,比如

      @protocol LocationManagerWrapperDelegate <NSObject>
      
      @required
      
      - (void) locationUpdated: (CLLocation *) locationUpdate;
      - (void) errorOccured: (NSError *) error;
      
      @end
      
      @interface LocationManagerWrapper : NSObject <CLLocationManagerDelegate>
      {
          CLLocationManager *locationManager;
          id delegate;
          CLLocation *mostAccurateLocation;
          int updatesCounter;
          BOOL m_acceptableTimePeriodElapsed;
      }
      
      @property (nonatomic, retain) CLLocationManager *locationManager;
      @property (nonatomic, retain) CLLocation *mostAccurateLocation;
      @property (nonatomic, assign) id <LocationManagerWrapperDelegate> delegate;
      
      - (void) startUpdatingLocation;
      
      - (void) locationManager: (CLLocationManager *) manager
          didUpdateToLocation: (CLLocation *) newLocation
                 fromLocation: (CLLocation *) oldLocation;
      
      - (void) locationManager: (CLLocationManager *) manager
         didFailWithError: (NSError *) error;
      
      + (LocationManagerWrapper *) sharedInstance;
      
      @end
      

      实施

      #define NUMBER_OF_TRIES 4   
      #define ACCEPTABLE_TIME_PERIOD 15.0
      
      - (void) startUpdatingLocation
      {
      NSAssert(self.delegate != nil, @"No delegate set to receive location update.");
      
      updatesCounter = 0;
      self.mostAccurateLocation = nil;
      m_acceptableTimePeriodElapsed = NO;
      [NSTimer scheduledTimerWithTimeInterval:ACCEPTABLE_TIME_PERIOD
                                       target:self
                                     selector:@selector(acceptableTimePeriodElapsed:) 
                                     userInfo:nil
                                      repeats:NO];
      [self.locationManager startUpdatingLocation];
      }
      
      - (void) acceptableTimePeriodElapsed: (NSTimer *) timer
      {
      @synchronized(self)
      {
          m_acceptableTimePeriodElapsed = YES;
          // TODO: if period is set by user - check we have mostAccurateLocation at this point
          [self.delegate locationUpdated:self.mostAccurateLocation];
          [self.locationManager stopUpdatingLocation];
      }
      }
      
      - (void) locationManager: (CLLocationManager *) manager
          didUpdateToLocation: (CLLocation *) newLocation
                 fromLocation: (CLLocation *) oldLocation
      {
      @synchronized(self)
      {
          if (m_acceptableTimePeriodElapsed) return;
          NSLog([NSString stringWithFormat:@"lat: %@, long: %@, acc: %@", 
                 [ [NSNumber numberWithDouble:newLocation.coordinate.latitude] stringValue],
                 [ [NSNumber numberWithDouble:newLocation.coordinate.longitude] stringValue],
                 [ [NSNumber numberWithDouble:newLocation.horizontalAccuracy] stringValue]  ] );
      
          updatesCounter++;
          // ignore first returned value
          if (updatesCounter <= 1) return;
          if (self.mostAccurateLocation == nil ||
              self.mostAccurateLocation.horizontalAccuracy > newLocation.horizontalAccuracy)
          {
              self.mostAccurateLocation = newLocation;
          }
          if  (updatesCounter >= NUMBER_OF_TRIES)
          {
              [self.delegate locationUpdated:self.mostAccurateLocation];
              [self.locationManager stopUpdatingLocation];
          }
      }
      }
      

      代码不是很好(格式也不是),但我认为这个想法简单明了,获取第一个位置,将其丢弃,它是一个缓存的,最多尝试 3 次以获得最准确的位置。这可能需要很长时间,如果用户正在等待(如我的情况),请定义时间限制。再一次,它适用于我的应用,但您可以随意调整它或采用其他方法。

      【讨论】:

      • 好吧,这或多或少也是我想出的。我没有将它包装在一个类中,但看起来我涵盖了您实现的所有内容。感谢您的回答。
      猜你喜欢
      • 2010-10-09
      • 2016-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多