如何在最佳 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?的主要内容,如果未能解决你的问题,请参考以下文章

Android API 30 及更高级别在后台获取 GPS 位置的最佳方式

如何将用户的GPS位置与可用的GPS位置进行比较?

如何在 Django REST API 中使用 GPS 位置?

在整个应用程序中以角度进行连续 api 调用的最佳位置

html5 如何调用安卓手机获取gps坐标

如何使用 Target API 23 及更高版本通过 GPS 获取用户位置