2011-01-08 15 views
27

Así que estoy lidiando con algunos problemas de precisión con iPhone GPS. Tengo una aplicación que usa la ubicación.CLLocationManager y problemas de precisión - ¿alguna experiencia?

En el método delegado locationManager: didUpdateToLocation: fromLocation: Me devuelven una ubicación. A partir de un poco de investigación, parece que el GPS no siempre es preciso en el primer resultado que devuelve, incluso cuando se establece la propiedad desiredAccuracy en .

Para evitar esto, no llamo al stopUpdatingLocation antes de que se devuelva newLocation: al menos 3 veces (esto es muy rápido). También jugué con otros dos "requisitos" para saber stopUpdatingLocation y devolver el newLocation. Una de las formas en que lo intenté fue verificar el lat y long para newLocation y compararlo con oldLocation y si estos no eran idénticos, entonces mantén la actualización de la ubicación ejecutándose. También traté de verificar la distancia entre oldLocation y newLocation y si está a menos de 20 metros, está bien. Ambos se prueban con la devolución de al menos 3 carreras. La última manera es menos "estricta", ya que newLocation y oldLocation es bastante difícil de conseguir con ser 100% idénticos si el usuario está en un vehículo en movimiento.

Ahora, mi problema es que, incluso al hacer lo anterior (básicamente no aceptar una ubicación, hasta que se hayan producido algunas actualizaciones en CLLocationManager Y verificar la distancia entre CLLocations (o si son idénticas) todavía estoy viendo algo resultados raros para ubicaciones a veces, al probar

Sería una solución a veces si dejo la aplicación, voy a Maps.app, uso el GPS, luego abro la multitarea, fuerzo salir de mi aplicación y luego la vuelvo a abrir para obtener una limpieza lanzamiento.

¿Alguna experiencia y posibles soluciones que las personas han utilizado para resolver el mismo tipo de problema? Comentarios y soluciones apreciadas :)

Respuesta

45

No recuerdo de qué proyecto era exactamente de donde obtuve el siguiente código, pero me ha funcionado muy bien (recuerdo que fue de un video de la WWDC 2010). En mi código, dejé intactos los comentarios del proyecto original, así que espero que esto ayude.

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 
    // test the age of the location measurement to determine if the measurement is cached 
    // in most cases you will not want to rely on cached measurements 
    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow]; 

    if (locationAge > 5.0) return; 

    // test that the horizontal accuracy does not indicate an invalid measurement 
    if (newLocation.horizontalAccuracy < 0) return; 

    // test the measurement to see if it is more accurate than the previous measurement 
    if (bestEffortAtLocation == nil || bestEffortAtLocation.horizontalAccuracy > newLocation.horizontalAccuracy) { 
     // store the location as the "best effort" 
     self.bestEffortAtLocation = newLocation; 

     // test the measurement to see if it meets the desired accuracy 
     // 
     // IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue 
     // accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of 
     // acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout. 
     // 
     if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) { 
      // we have a measurement that meets our requirements, so we can stop updating the location 
      // 
      // IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible. 
      // 
      [self stopUpdatingLocation:NSLocalizedString(@"Acquired Location", @"Acquired Location")]; 

      // we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary 
      [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil]; 
     } 
    } 
} 

Hope this helps!

Via GetLocationViewController.m en proyecto de ejemplo de Apple "Localízame", disponible en:

https://developer.apple.com/library/content/samplecode/LocateMe/Introduction/Intro.html

+0

Ah , ¡Perfecto! Debería haber mirado más de cerca las propiedades para la nueva ubicación de CLLocation, no me di cuenta que también tenía una marca de tiempo. Probablemente usaré este junto con mi propio código. ¡Gracias un montón! – runmad

+1

que es del ejemplo "Localizarme" de apple: https://developer.apple.com/library/ios/#samplecode/LocateMe/Listings/Classes_TrackLocationViewController_m.html#//apple_ref/doc/uid/DTS40007801-Classes_TrackLocationViewController_m-DontLinkElementID_14 – Garoal

+0

this es exactamente lo que estoy buscando. Gracias. – bselvan

0

De la respuesta de donkim considerar la sustitución de esta línea

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil]; 

con la línea

[NSObject cancelPreviousPerformRequestsWithTarget: self]; 
Cuestiones relacionadas