2011-02-17 12 views
6

Me gustaría seguir el punto azul del usuario de la misma forma que lo hace Google Maps. Significa que cuando la ubicación está cambiando, el mapa (o su centro) debe seguirlo sin problemas. Pero cuando se utiliza manera estándar con el delegado:Seguimiento suave de la ubicación del usuario en MKMapView

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation 
{ 
    [map setCenterCoordinate:map.userLocation.coordinate animated:YES]; 
} 

u observador keyValue en mapview.userLocation a continuación, pasar del mapa es muy "volátil", rápidamente se "salta" a la nueva ubicación, incluso si uso animated parámetro.

Además, creo que el punto azul en sí no se mueve tan bien como en la aplicación nativa de Google Maps y con frecuencia salta a una nueva ubicación en lugar de moverse allí.

Gracias por cualquier ayuda.

+0

iOS 5 agrega esta característica con el modo de seguimiento. ¡Finalmente! – d0n13

Respuesta

3

'hola Jak

he tratado de resolver este así pero parece MKMapView podría estar utilizando alguna materia de lujo entre las actualizaciones de predecir la siguiente posición y hacer el movimiento más suave.

Si nos fijamos en la forma en que manejan la brújula, están filtrando mucho ya que los datos de la brújula bruta no son muy estables, por lo que la hacen realmente resbaladiza y sin problemas.

Además, tenga en cuenta que al realizar el seguimiento, puede ampliar pero no desplazarse. No he podido replicar esta funcionalidad en mi aplicación, incluso con el desplazamiento desactivado, todavía se desplaza cuando haces zoom si das un rodeo con los dedos.

supongo que no exponen a todo sólo para mantenerse por delante de nosotros :) D

+0

Bueno, llegué a la misma conclusión. ; o) La aplicación Mapas tiene que usar algunos métodos privados que no podemos. También traté de poner 'setCenterCoordinate: animado:' en una animación UIView pero sin ningún efecto. – JakubM

0

También puede probar esto:

- (void)adjustRegion:(CLLocation*)location { 
    MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, 150.0, 150.0); 
    MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:viewRegion]; 
    [self.mapView setRegion:adjustedRegion animated:YES]; 
} 
+0

¿Qué es 'CMModel'? – Raptor

+1

@ShivanRaptor Oh, esa es una clase singleton donde guardé algunos params. Solo copié y pegué esa línea. Sry, voy a editar mi respuesta. – borisdiakur

+0

@Lego no obliga al usuario a usar el nivel de zoom que ha definido?(En lugar de dejar que lo personalicen) – RonLugge

1

que utilizan los métodos de actualización CLLocationManager delegado para obtener la corriente ubicación sobre cada segundo, guardado la ubicación anterior e interpolado entre ellos. Es un poco más de esfuerzo, pero hace que el seguimiento sea mucho más fluido. Aquí está mi código:

#define zoomSpan MKCoordinateSpanMake(0.001f, 0.001f) 

@property (strong, nonatomic) CLLocation *lastLocation; 
@property (strong, nonatomic) MKMapView *mapView; 
@property (strong, nonatomic) CLLocationManager *locationManager; 

... 

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 
{ 
    CLLocation *currentLocation = locations[locations.count - 1]; 
    // Set to last location, for faster setting to correct position 
    [self.mapView setRegion:MKCoordinateRegionMake(self.lastLocation.coordinate, zoomSpan) animated:NO]; 

    // Locations in-between coordinates for smooth tracking 
    CLLocationDegrees deltaLat = currentLocation.coordinate.latitude - self.lastLocation.coordinate.latitude; 
    CLLocationDegrees deltaLon = currentLocation.coordinate.longitude - self.lastLocation.coordinate.longitude; 
    NSArray *locationsArray = @[[[CLLocation alloc] initWithLatitude:(self.lastLocation.coordinate.latitude + deltaLat * 0.2) 
                  longitude:(self.lastLocation.coordinate.longitude + deltaLon * 0.2)], 
           [[CLLocation alloc] initWithLatitude:(self.lastLocation.coordinate.latitude + deltaLat * 0.4) 
                  longitude:(self.lastLocation.coordinate.longitude + deltaLon * 0.4)], 
           [[CLLocation alloc] initWithLatitude:(self.lastLocation.coordinate.latitude + deltaLat * 0.6) 
                  longitude:(self.lastLocation.coordinate.longitude + deltaLon * 0.6)], 
           [[CLLocation alloc] initWithLatitude:(self.lastLocation.coordinate.latitude + deltaLat * 0.8) 
                  longitude:(self.lastLocation.coordinate.longitude + deltaLon * 0.8)], 
           currentLocation]; 

    float timer = 0; 
    for (CLLocation *nextLocation in locationsArray) { 
     [self performSelector:@selector(updateMapCenterLocation:) withObject:nextLocation afterDelay:timer]; 
     timer += 0.2; 
    } 
    self.lastLocation = currentLocation; 
} 

- (void)updateMapCenterLocation:(CLLocation *)location 
{ 
    [self.mapView setRegion:MKCoordinateRegionMake(location.coordinate, zoomSpan) animated:YES]; 
} 

Asegúrese de que la clase que usted está usando esto en (normalmente el controlador de vista que mantiene la vista del mapa) se ajusta a los delegados y la implementación del protocolo CLLocationManagerDelegate la CLLocationManager 's.

Algunos comentarios adicionales:

  • El comportamiento de este código es similar al MKUserTracking, pero esto no es compatible con los niveles de zoom conjunto personalizado. Parece que hay un error al restablecer el nivel de zoom al iniciar el seguimiento, por lo tanto, esta solución alternativa.
  • zoomSpan actualmente está corregido, pero también puede utilizar el lapso de la región actual con self.mapView.region.span.
Cuestiones relacionadas