- Filtrar cabo en caché (de edad) los datos de localización,
- a filtrar válido da como resultado la ubicación (precisión < 0),
- Conjunto requisito de precisión ajustado a
kCLLocationAccuracyBest
,
- establecer un filtro de distancia mínima, preferiblemente a al menos 10 metros para filtrar el ruido de posición.
- EDITAR: No calcule la distancia cuando el
oldLocation
es nula.
Hay más que podría hacer, pero esto debería funcionar siempre que obtenga una precisión horizonal suficiente (< 30m). Podrías filtrar los resultados de baja precisión, pero tendrías que hacer un seguimiento del oldLocation, que es un poco más complicado.
Añadir un NSLog (véase más adelante) para que pueda encontrar lo que está sucediendo. Si aún no obtiene buenos resultados, publique el resultado del NSLog para que podamos ver qué está sucediendo y obtener más ayuda.
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSTimeInterval age = -[newLocation.timestamp timeIntervalSinceNow];
if (age > 120) return; // ignore old (cached) updates
if (newLocation.horizontalAccuracy < 0) return; // ignore invalid udpates
// EDIT: need a valid oldLocation to be able to compute distance
if (oldLocation == nil || oldLocation.horizontalAccuracy < 0) return;
CLLocationDistance distance = [newLocation distanceFromLocation: oldLocation];
NSLog(@"%6.6f/%6.6f to %6.6f/%6.6f for %2.0fm, accuracy +/-%2.0fm",
oldLocation.coordinate.latitude,
oldLocation.coordinate.longitude,
newLocation.coordinate.latitude,
newLocation.coordinate.longitude,
distance,
newLocation.horizontalAccuracy);
distanceMoved += distance;
theLabel.text = [NSString stringWithFormat: @"%f meters", distanceMoved];
}
- (void)viewDidLoad
{
locMan = [[CLLocationManager alloc] init];
locMan.delegate = self;
locMan.desiredAccuracy = kCLLocationAccuracyBest;
locMan.distanceFilter = 10;
[locMan startUpdatingLocation];
isInitial = true;
distanceMoved = 0.0;
[super viewDidLoad];
}
EDITAR para iOS6 si quería hacer lo mismo usando didUpdateLocations: (ya que el método anterior se considera obsoleto) la solución más sencilla es simplemente guardar cada ubicación en una propiedad para que en la próxima actualización que tiene la ubicación anterior.Declarar una propiedad de la clase para mantener el oldLocation
:
@property (nonatomic, retain) CLLocation* oldLocation;
Luego, en el método delegado guardar cada newLocation
para su uso como el oldLocation
para la próxima vez que el método delegado se llama:
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocations:(NSArray *)locations
{
CLLocation* newLocation = [locations lastObject];
NSTimeInterval age = -[newLocation.timestamp timeIntervalSinceNow];
if (age > 120) return; // ignore old (cached) updates
if (newLocation.horizontalAccuracy < 0) return; // ignore invalid udpates
// EDIT: need a valid oldLocation to be able to compute distance
if (self.oldLocation == nil || self.oldLocation.horizontalAccuracy < 0) {
self.oldLocation = newLocation;
return;
}
CLLocationDistance distance = [newLocation distanceFromLocation: self.oldLocation];
NSLog(@"%6.6f/%6.6f to %6.6f/%6.6f for %2.0fm, accuracy +/-%2.0fm",
self.oldLocation.coordinate.latitude,
self.oldLocation.coordinate.longitude,
newLocation.coordinate.latitude,
newLocation.coordinate.longitude,
distance,
newLocation.horizontalAccuracy);
distanceMoved += distance;
theLabel.text = [NSString stringWithFormat: @"%f meters", distanceMoved];
self.oldLocation = newLocation; // save newLocation for next time
}
Acabo de utilizar este código exacto, pero cambié el filtro de distancia a 1. Por alguna razón, mi distancia movida comienza en -1. Aquí está mi salida después de caminar unos 2 m hacia adelante: 2012-04-17 17: 58: 05.341 LocationManagerTest2 [422: 707] 0.000000/0.000000 a 39.856110/-74.940113 para -1m, precisión +/- 10m 2012-04 -17 17: 58: 10.248 LocationManagerTest2 [422: 707] 39.856110/-74.940113 a 39.856165/-74.940107 para 6m, precisión +/- 50m 2012-04-17 17: 58: 11.248 LocationManagerTest2 [422: 707] 39.856165/- 74.940107 39.856223 a/-74.940010 de 10m, 50m precisión de +/- El distanceMoved salieron a alrededor de 15 m - demasiado – bnasty
he intentado utilizar el código varias veces antes, así, y me dieron algunos resultados aparentemente precisos y algunos que estaban lejos de – bnasty
la distancia -1 es donde su ubicación anterior era 0, lo que probablemente significa que el parámetro de ubicación anterior era nulo. Necesitarás agregar un cheque para eso también (mira mi edición arriba). No se puede esperar una alta precisión cuando se informa que la precisión es horizontal 50 m !!! Eso significa que el GPS no tiene una señal lo suficientemente buena, lo que significa que la posición reportada puede estar a 50 metros en cualquier dirección. – progrmr