如何在最佳 GPS 位置调用 URL API?

Posted

技术标签:

【中文标题】如何在最佳 GPS 位置调用 URL API?【英文标题】:How to invoke URL API at the best GPS location? 【发布时间】:2013-05-30 11:25:44 【问题描述】:

我尝试在最佳 GPS 位置调用 URL API。用户单击触发 findMe 方法的按钮来设置 desiredAccuracydistanceFilter 并运行 [self.locationManager startUpdatingLocation]。。 p>

我检查最佳垂直和水平精度,如果它们在下一次迭代中没有改变,我会运行 API 和 [self.locationManager stopUpdatingLocation]

关键是在那之后最好的准确度被改变了,即使我停止更新位置,-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation也会运行几次。

-(void)findMe 
  self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
  self.locationManager.distanceFilter = kCLDistanceFilterNone;
  [self.locationManager startUpdatingLocation];


-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

  double longitude = newLocation.coordinate.longitude;
  double latitude = newLocation.coordinate.latitude;

  if ( ((_bestVertivalAccuracy == 0) || (_bestVertivalAccuracy > newLocation.verticalAccuracy))
    || ((_bestHorizontalAccuracy == 0) || (_bestHorizontalAccuracy > newLocation.horizontalAccuracy)) ) 
      NSLog(@"bestVer: %f", _bestVertivalAccuracy);
      NSLog(@"bestHor: %f", _bestHorizontalAccuracy);
      NSLog(@"Given ver: %f", newLocation.verticalAccuracy);
      NSLog(@"Given hor: %f", newLocation.horizontalAccuracy);
      NSLog(@"-------------------------------------------------------");

      _bestVertivalAccuracy = newLocation.verticalAccuracy;
      _bestHorizontalAccuracy = newLocation.horizontalAccuracy;
      return;
  

  [_locationManager stopUpdatingLocation];

  [POSharedLocation sharedInstance].lng = longitude;
  [POSharedLocation sharedInstance].lat = latitude;
  [POSharedLocation sharedInstance].showUserLocation = YES;

  NSLog(@"Longitude : %f", longitude);
  NSLog(@"Latitude : %f", latitude);
  NSLog(@"Acc. Ver: %f", newLocation.verticalAccuracy);
  NSLog(@"Acc. Hor: %f", newLocation.horizontalAccuracy);
  NSLog(@"-------------------------------------------------------");

  _resultsVC = [[ResultsListViewController alloc] init];
  UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:_resultsVC];

  NSString *locationQuery = [NSString stringWithFormat:@"/json?method=find&lat=%f&lng=%f&distance=%f", latitude, longitude, _distance];

  NSString *url = [API_URL stringByAppendingString:locationQuery];
  NSString* urlEncoded = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];


  // For debuging only
  NSLog(@"URL: %@", urlEncoded);

  NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlEncoded]];

  // Run an asynchronous connection and download the JSON
  (void)[[NSURLConnection alloc] initWithRequest:request delegate:_resultsVC startImmediately:YES];
  [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

  [self presentModalViewController:navVC animated:YES];
  [navVC release];

还有输出:

2013-05-30 12:59:13.906 MyApp[30569:907] bestVer: 0.000000
2013-05-30 12:59:13.918 MyApp[30569:907] bestHor: 0.000000
2013-05-30 12:59:13.922 MyApp[30569:907] Given ver: 3.000000
2013-05-30 12:59:13.927 MyApp[30569:907] Given hor: 50.000000
2013-05-30 12:59:13.933 MyApp[30569:907] -------------------------------------------------------
2013-05-30 12:59:14.112 MyApp[30569:907] Longitude : 16.934037
2013-05-30 12:59:14.114 MyApp[30569:907] Latitude : 51.096827
2013-05-30 12:59:14.116 MyApp[30569:907] Acc. Ver: 10.000000
2013-05-30 12:59:14.119 MyApp[30569:907] Acc. Hor: 1414.000000
2013-05-30 12:59:14.131 MyApp[30569:907] -------------------------------------------------------
2013-05-30 12:59:14.138 MyApp[30569:907] URL: http://example.com/json?method=find&lat=51.096827&lng=16.934037&distance=1.000000
2013-05-30 12:59:14.241 MyApp[30569:907] Longitude : 16.933006
2013-05-30 12:59:14.244 MyApp[30569:907] Latitude : 51.096140
2013-05-30 12:59:14.247 MyApp[30569:907] Acc. Ver: 10.000000
2013-05-30 12:59:14.248 MyApp[30569:907] Acc. Hor: 1414.000000
2013-05-30 12:59:14.250 MyApp[30569:907] -------------------------------------------------------
2013-05-30 12:59:14.253 MyApp[30569:907] URL: http://example.com/json?method=find&lat=51.096140&lng=16.933006&distance=1.000000
2013-05-30 12:59:14.256 MyApp[30569:907] Warning: Attempt to present <UINavigationController: 0x1e068fd0> on <HomeViewController: 0x1d572130> while a presentation is in progress!
2013-05-30 12:59:14.260 MyApp[30569:907] Longitude : 16.932491
2013-05-30 12:59:14.262 MyApp[30569:907] Latitude : 51.095797
2013-05-30 12:59:14.263 MyApp[30569:907] Acc. Ver: 10.000000
2013-05-30 12:59:14.264 MyApp[30569:907] Acc. Hor: 1414.000000
2013-05-30 12:59:14.269 MyApp[30569:907] -------------------------------------------------------
2013-05-30 12:59:14.287 MyApp[30569:907] URL: http://example.com/json?method=find&lat=51.095797&lng=16.932491&distance=1.000000
2013-05-30 12:59:14.291 MyApp[30569:907] Warning: Attempt to present <UINavigationController: 0x1d599790> on <HomeViewController: 0x1d572130> while a presentation is in progress!
2013-05-30 12:59:14.298 MyApp[30569:907] Longitude : 16.932234
2013-05-30 12:59:14.301 MyApp[30569:907] Latitude : 51.095625
2013-05-30 12:59:14.302 MyApp[30569:907] Acc. Ver: 10.000000
2013-05-30 12:59:14.303 MyApp[30569:907] Acc. Hor: 1414.000000
2013-05-30 12:59:14.304 MyApp[30569:907] -------------------------------------------------------
2013-05-30 12:59:14.307 MyApp[30569:907] URL: http://example.com/json?method=find&lat=51.095625&lng=16.932234&distance=1.000000
2013-05-30 12:59:14.309 MyApp[30569:907] Warning: Attempt to present <UINavigationController: 0x1e06c930> on <HomeViewController: 0x1d572130> while a presentation is in progress!

如您所见,API 被调用了几次,而它应该只被调用一次。知道如何让它变得更好吗?

【问题讨论】:

两种方法可以做到这一点,1)使用flag,在发出url请求之前检查flag=false。发送 url 请求后设置flag=true。 2) 在视图控制器初始化期间,开始获取位置更新,存储坐标并在findMe 方法中使用存储的坐标发出 URL 请求。 @Amar 您可以将此评论添加为答案。 好的,但是为什么定位精度比以前大了? delegate 的第一个回调通常包含一个缓存位置,可能是缓存位置精度很高(50m)。如果您不想要缓存的位置,您应该检查位置的年龄并丢弃旧的(>30 秒),请参阅example here 您保存的是最准确的位置,但您没有保存收到的最准确的位置。并且不要指望准确率会连续 3 次保持在最佳值,它可能处于临界点并不断在两个值之间来回切换。当您获得所需的准确性时,使用它并停止。 【参考方案1】:

尝试将 nil 设置为您的 locationManagers 委托

_locationManager.delegate = nil;

【讨论】:

【参考方案2】:

不要依赖位置管理器调用您的委托方法特定次数。您无法控制位置管理器,因此取决于超出记录范围的特定行为总是会给您带来问题。不过,您确实可以控制自己的代码,所以让它做您想做的事:如果您不再需要位置更新,让您的委托方法在您不想要更新时忽略它们,或者只是将位置管理器的委托设置为 nil。

【讨论】:

【参考方案3】:

按照建议,将其添加为答案。

有两种方法可以做到这一点,

    使用标志,在发出 url 请求之前检查flag=false。 url请求发送后设置flag=true. 在视图控制器初始化期间,开始获取位置更新,存储坐标,并在 findMe 方法中使用存储的坐标发出 URL 请求。

【讨论】:

以上是关于如何在最佳 GPS 位置调用 URL API?的主要内容,如果未能解决你的问题,请参考以下文章