2011-02-23 8 views
5

Estoy tratando de desarrollar una brújula para una aplicación que tiene un conjunto de anotaciones en un mapa. Me gustaría poder elegir una anotación y luego hacer que la brújula señale al usuario a la ubicación elegida.Señalar con la brújula

He calculado el error desde la ubicación del usuario hasta la ubicación de la anotación y tengo el encabezado magnético y el verdadero título del iPhone. También sé cómo rotar una imagen. Pero no puedo entender cuál es el siguiente paso.

Los grados entre la ubicación del usuario y la ubicación de la anotación se calcula así:

// get user location 
    locationManager = [[CLLocationManager alloc] init]; 
    locationManager.delegate = self; 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
    locationManager.distanceFilter = kCLDistanceFilterNone; 
    [locationManager startUpdatingLocation]; 
    [locationManager startUpdatingHeading]; 
    CLLocation *location = [locationManager location]; 
    CLLocationCoordinate2D coordinate = [location coordinate]; 

    float x1 = coordinate.latitude; 
    float y1 = coordinate.longitude; 
    float x2 = [annLatitude floatValue]; 
    float y2 = [annLongitude floatValue]; 

    float dx = (x2 - x1); 
    float dy = (y2 - y1); 

    if (dx == 0) { 
     if (dy > 0) { 
      result = 90; 
     } 
     else { 
      result = 270; 
     } 
    } 
    else { 
     result = (atan(dy/dx)) * 180/M_PI; 
    } 

    if (dx < 0) { 
     result = result + 180; 
    } 

    if (result < 0) { 
     result = result + 360; 
    } 

El verdadero y el rumbo magnético se recupera de esta manera:

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { 
    arrow.transform = CGAffineTransformMakeRotation(newHeading.magneticHeading); 

    // NSLog(@"magnetic heading: %f", newHeading.magneticHeading); 
    // NSLog(@"true heading: %f", newHeading.trueHeading); 
} 

Puede alguien mí lo que diga debería hacer ahora para que la flecha apunte a la ubicación, incluso si se gira el iPhone?

Respuesta

8

Tuve tiempo de volver a jugar con esto.

Esto lo hará:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    locationManager = [[CLLocationManager alloc] init]; 
    locationManager.delegate = self; 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
    locationManager.distanceFilter = kCLDistanceFilterNone; 
    [locationManager startUpdatingLocation]; 
    [locationManager startUpdatingHeading]; 

    CLLocation *location = [locationManager location]; 
    CLLocationCoordinate2D user = [location coordinate]; 

    [self calculateUserAngle:user]; 
} 

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 
    CLLocationCoordinate2D here = newLocation.coordinate; 

    [self calculateUserAngle:here]; 
} 

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { 
    compass.transform = CGAffineTransformMakeRotation(newHeading.magneticHeading * M_PI/180); 
    needle.transform = CGAffineTransformMakeRotation((degrees - newHeading.magneticHeading) * M_PI/180); 
} 

-(void) calculateUserAngle:(CLLocationCoordinate2D)user { 
    locLat = [[targetLocationDictionary objectForKey:@"latitude"] floatValue]; 
    locLon = [[targetLocationDictionary objectForKey:@"longitude"] floatValue]; 

    NSLog(@"%f ; %f", locLat, locLon); 

    float pLat; 
    float pLon; 

    if(locLat > user.latitude && locLon > user.longitude) { 
     // north east 

     pLat = user.latitude; 
     pLon = locLon; 

     degrees = 0; 
    } 
    else if(locLat > user.latitude && locLon < user.longitude) { 
     // south east 

     pLat = locLat; 
     pLon = user.longitude; 

     degrees = 45; 
    } 
    else if(locLat < user.latitude && locLon < user.longitude) { 
     // south west 

     pLat = locLat; 
     pLon = user.latitude; 

     degrees = 180; 
    } 
    else if(locLat < user.latitude && locLon > user.longitude) { 
     // north west 

     pLat = locLat; 
     pLon = user.longitude; 

     degrees = 225; 
    } 

    // Vector QP (from user to point) 
    float vQPlat = pLat - user.latitude; 
    float vQPlon = pLon - user.longitude; 

    // Vector QL (from user to location) 
    float vQLlat = locLat - user.latitude; 
    float vQLlon = locLon - user.longitude; 

    // degrees between QP and QL 
    float cosDegrees = (vQPlat * vQLlat + vQPlon * vQLlon)/sqrt((vQPlat*vQPlat + vQPlon*vQPlon) * (vQLlat*vQLlat + vQLlon*vQLlon)); 
    degrees = degrees + acos(cosDegrees); 
} 
+0

esto es muy bueno .. Voy a tratar a mi proyecto y espero que funcione bien .. Me salvaste el día :) –

+0

favor de enviarme la clase completa para esto :) –

+0

sí, esta información es realmente útil. ¿Puedes responder mi pregunta relacionada con esto? - http://stackoverflow.com/questions/7173925/how-to-rotate-a-direction-arrow-using-clheading – Dhawal

Cuestiones relacionadas