2011-03-29 11 views
6

Quiero determinar si un usuario ha desplazado más de un cierto porcentaje del mapa y deshabilitar el centrado del mapa desde la ubicación del usuario (similar al funcionamiento de la aplicación Mapas).¿Detecta cuando un usuario desplaza MKMapView una cierta distancia?

No estoy seguro de qué métodos utilizar.

Creo que sería sencillo crear un rectángulo y ver si el rectángulo contiene el punto central actual, sin embargo, tengo que apuntar a IOS 3, por lo que no puedo usar muchas de las apk más recientes de Mapkit.

He intentado actualizar con CLLocation, y usando distanceFrom, entre el centro de mapas actual y la ubicación de los usuarios, pero estoy tratando de averiguar si esa distancia es un cierto porcentaje.

Respuesta

15

Personalmente me parece más útil cuando alguien puede publicar un fragmento de código en comparación con la prosa general acerca de cómo se puede ir sobre esto. Esto es lo que le ocurrió con- aproximadamente hackeado a cabo simplemente responder mejor a esta pregunta:

En un archivo de cabecera que tengo:

#define SCROLL_UPDATE_DISTANCE   80.00 

y en mi opinión (que es a la vez un delegado para CLLocationManagerDelegate, MKMapViewDelegate) :

// this method is called when the map region changes as a delegate of MKMapViewDelegate 
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 
{ 
    NSLog(@"regionDidChangeAnimated"); 
    MKCoordinateRegion mapRegion; 
    // set the center of the map region to the now updated map view center 
    mapRegion.center = mapView.centerCoordinate; 

    mapRegion.span.latitudeDelta = 0.3; // you likely don't need these... just kinda hacked this out 
    mapRegion.span.longitudeDelta = 0.3; 

    // get the lat & lng of the map region 
    double lat = mapRegion.center.latitude; 
    double lng = mapRegion.center.longitude; 

    // note: I have a variable I have saved called lastLocationCoordinate. It is of type 
    // CLLocationCoordinate2D and I initially set it in the didUpdateUserLocation 
    // delegate method. I also update it again when this function is called 
    // so I always have the last mapRegion center point to compare the present one with 
    CLLocation *before = [[CLLocation alloc] initWithLatitude:lastLocationCoordinate.latitude longitude:lastLocationCoordinate.longitude]; 
    CLLocation *now = [[CLLocation alloc] initWithLatitude:lat longitude:lng]; 

    CLLocationDistance distance = ([before distanceFromLocation:now]) * 0.000621371192; 
    [before release]; 
    [now release]; 

    NSLog(@"Scrolled distance: %@", [NSString stringWithFormat:@"%.02f", distance]); 

    if(distance > SCROLL_UPDATE_DISTANCE) 
    { 
     // do something awesome 
    } 

    // resave the last location center for the next map move event 
    lastLocationCoordinate.latitude = mapRegion.center.latitude; 
    lastLocationCoordinate.longitude = mapRegion.center.longitude; 

} 

esperanza que le envía en la dirección correcta.

distanceFromLocation es iOS 3.2 y posterior. initWithLatitude es iOS 2.0 y posterior. MKCoordinateRegion es iOS 3.0 y posterior. MKMapView centerCoordinate es iOS 3.0 y posterior.

Además, siéntase libre de saltar y dejarme en línea recta donde me he equivocado. Estoy pensando en todo esto yo mismo, pero esto está funcionando bastante bien para mí hasta ahora.

Espero que esto ayude a alguien.

+0

Tienes razón. Debería haber publicado la respuesta.Si explica por qué usa la constante: 0.000621 ... en su respuesta, marcaré esto como la respuesta aceptada. – Alan

+0

Conversión de metros a millas (aunque descuidado y debería ser una constante de algún tipo). –

2

Primera lección: No haga preguntas tarde en la noche en SO.

Segunda lección: puede lograr esto simplemente mediante la construcción de un CGPoint desde la ubicación actual del usuario y un CGPoint desde el centro de MapView.

Con dos puntos, simplemente calcule la distancia y vea si ha pasado un cierto umbral.

También puede construir un CGRect alrededor del centro del mapa y comprobar CGRectContainsPoint si es más fácil.

- (BOOL) isUserPointInsideMapCenterRegion 
{ 
    CLLocation * ul = _mapView.userLocation.location; 

    CGPoint userPoint = [_mapView convertCoordinate: ul.coordinate toPointToView: _mapView]; 
    CGPoint mapPoint = [_mapView convertCoordinate: _mapView.centerCoordinate toPointToView: _mapView]; 

    if (fabs(userPoint.x - mapPoint.x) > MAP_CENTER_RECTANGLE_SIZE || fabs(userPoint.y - mapPoint.y) > MAP_CENTER_RECTANGLE_SIZE) 
    { 
     return NO; 
    } 

    return YES; 
} 
+1

Sé que esto es viejo, pero es exactamente lo que buscaba código cool! –

+0

Me alegro de que haya ayudado. – Alan

2

Me doy cuenta de que esta pregunta es un poco antigua ahora, pero creo que la respuesta que se describe en this other question es más robusta porque el método de delegado podría ser despedido por algún motivo. Usar un UIPanGestureRecognizer para detectar el desplazamiento significa que el usuario desplazó manualmente el mapa y puede verificar si el mapa desplazó X píxeles, en lugar de depender de los metros, lo que significa que el usuario se desplazó más o menos según el nivel de zoom.

https://stackoverflow.com/a/11675587/159758

+0

Gracias DonnaLea por señalar esa pregunta. – Alan

Cuestiones relacionadas