2013-05-05 79 views
0

我正在研究一個旨在在地圖上顯示活動期間iPhone的位置(在它們之間添加註釋和繪圖線)的應用程序。[iOS] [背景] [CLLocationManager]地圖精度不高

爲此,我使用位置管理器來獲取新位置並通知MapDisplayViewController。當使用模擬器時,我得到了很好的結果,你可以在這裏看到http://www.youtube.com/watch?v=ESLIYSU_Mqw但用iPhone我得到了奇怪的結果,如200米錯誤。

我也使用MKMapView來顯示設備的位置。用這些設置(下一個代碼塊)我得到了那個http://grab.by/mgUU

如果我顯示用戶位置我得到不同的結果,這是正常的嗎?

- (void)setupMap { 
self.mapView.delegate = self; 

[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES]; 
[self.mapView setUserInteractionEnabled:NO]; 

[self.mapView setShowsUserLocation:NO]; 
[self.mapView setZoomEnabled:NO]; 
[self.waitingView start]; 

} 

下面的截圖與真實的設備:

編輯:的差異來櫨我用於這些2案件,使用了獲取設備當前位置的兩種不同的方式:

  • 從MapView的手柄,當應用程序被激活
  • 從位置管理器手柄時,應用程序在後臺

是否一個好主意,這兩個位置的系統混用?

我也測試這個解決方案CLLocationManager and accuracy issues - any experiences?但我得到了同樣的結果。

感謝;)

安裝位置經理:

- (void)setup { 
self.locationManager = [CLLocationManager new]; 
self.locationManager.delegate = self; 

self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
self.isUpdatingLocation = NO; 
} 

通知:時,在後臺添加的位置:

- (void)doUpdateWithLocation:(CLLocation *)location { 

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    [self beginBackgroundUpdateTask]; 


    NSLog(@"%s do update in background %@", __PRETTY_FUNCTION__, location); 

    if (self.userLocationFound == NO && self.isUpdatingLocation == YES) { 
     self.startCoordinate = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude); 

     self.userLocationFound = YES; 
    } 
    else if (self.isUpdatingLocation) { 
     static int distance; 

     ABGPSPosition *position = [[ABGPSPosition alloc] init]; 
     position.startPoint = MKMapPointForCoordinate(self.startCoordinate); 
     position.endPoint = MKMapPointForCoordinate(location.coordinate); 

     //INFO: Get the distance between this new point and the previous point. 
     CLLocationDistance metersApart = MKMetersBetweenMapPoints(position.startPoint, position.endPoint); 
     if (metersApart > MINIMUM_DELTA_METERS) { 
      MKMapPoint points[2] = {position.startPoint, position.endPoint}; 


      distance += metersApart; 
      NSLog(@"%s - %d", __PRETTY_FUNCTION__, distance); 

      NSInteger count = [self.measurementArray count]; 
      [self willChange:NSKeyValueChangeInsertion 
      valuesAtIndexes:[NSIndexSet indexSetWithIndex:count] forKey: @"measurementArray"]; 
      [self.measurementArray insertObject:location atIndex:count]; 
      [self didChange:NSKeyValueChangeInsertion 
      valuesAtIndexes:[NSIndexSet indexSetWithIndex:count] forKey: @"measurementArray"]; 


      self.startCoordinate = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude); 
     } 

    } 

     [self endBackgroundUpdateTask]; 
    }); 
} 

MapDisplayViewController獲得新的位置:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 

if ([keyPath isEqualToString:keyPathMeasurementArray]) { 
    if ([change[NSKeyValueChangeKindKey] intValue] == NSKeyValueChangeInsertion) {  

     NSIndexSet *insertedIndexSet = change[NSKeyValueChangeIndexesKey]; 

     [insertedIndexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { 

      CLLocation *location = self.locationManager.measurementArray[idx]; 

      MKUserLocation *userLocation = [[MKUserLocation alloc] init]; 
      [userLocation setCoordinate:location.coordinate]; 
      NSLog(@"%s - didUpdateUserLocation", __PRETTY_FUNCTION__); 

       [self.locationBackgroundList addObject:userLocation]; 
       NSLog(@"%s | %@", __PRETTY_FUNCTION__, self.locationBackgroundList);     
     }]; 
    } 
} 
else { 
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 
} 
} 

MapDisplayViewController添加註釋新的地圖視圖:

- (void)handleAddLocations { 
NSLog(@"%s | %@", __PRETTY_FUNCTION__, self.locationBackgroundList); 

if ([self.locationBackgroundList count] > 0) { 
    for (MKUserLocation *backgroundUserLocation in self.locationBackgroundList) { 

     { 
      LocAnnotation* annotation = [[LocAnnotation alloc] initWithCoordinate:backgroundUserLocation.coordinate]; 
      NSLog(@"%s %@", __PRETTY_FUNCTION__, [backgroundUserLocation description]); 



      [self.mapView addAnnotation:annotation]; 
     } 
     [self mapView:self.mapView didUpdateUserLocation:backgroundUserLocation]; 
    } 

    NSString *message = [NSString stringWithFormat:@"%s | Annotation number: %d", __PRETTY_FUNCTION__, [self.locationBackgroundList count]]; 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Debug" message:message delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil]; 
    [alert show]; 

    [self.locationBackgroundList removeAllObjects]; 
    self.locationBackgroundList = [[NSMutableArray alloc] init]; 
    } 
} 

回答

0

固定,你必須使用只有一個辦法與CLLocationManager的MapView找到您的設備。 ;)