Dirección de GPS Compass de iPhone

Estoy tratando de desarrollar una aplicación que use el GPS y la brújula del iPhone para señalar algún tipo de puntero a una ubicación específica (como la brújula siempre apunta hacia el norte). La ubicación es fija y siempre necesito que el puntero apunte a esa ubicación específica sin importar dónde se encuentre el usuario. Tengo las coordenadas Lat / Long de esta ubicación, pero no estoy seguro de cómo apuntar a esa ubicación usando la brújula y el GPS … al igual que http://www.youtube.com/watch?v=iC0Xn8hY80w este enlace 1: 20 ‘

Escribo un código, sin embargo, no puede rotar en la dirección correcta.

-(float) angleToRadians:(double) a { return ((a/180)*M_PI); } -(void)updateArrow { double alon=[longi doubleValue];//source double alat=[lati doubleValue];//source double blon=[pointlongi doubleValue];//destination double blat=[pointlati doubleValue];//destination float fLat = [self angleToRadians:alat]; float fLng = [self angleToRadians:alon]; float tLat = [self angleToRadians:blat]; float tLng = [self angleToRadians:blon]; float temp = atan2(sin(tLng-fLng)*cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng)); double temp2= previousHeading; double temp1=temp-[self angleToRadians:temp2]; /*I using this,but it can't rotate by :point even i change the coordinate in CGPointMake */ Compass2.layer.anchorPoint=CGPointMake(0, 0.5); [Compass2 setTransform:CGAffineTransformMakeRotation(temp1)]; /* Compass2 is a UIImageView like below picture I want to rotate it around : point in image ^ | | | : | */ 

Hay una ecuación estándar de “rumbo” o “rumbo” que puedes usar: si estás en lat1, lon1, y el punto que te interesa está en lat2, lon2, entonces la ecuación es:

 heading = atan2( sin(lon2-lon1)*cos(lat2), cos(lat1)*sin(lat2) - sin(lat1)*cos(lat2)*cos(lon2-lon1)) 

Esto te da un rumbo en radianes, que puedes convertir en grados multiplicando por 180 / π. El valor está entonces entre -180 y 180 grados, por lo que para obtener un rumbo de brújula estándar, agregue 360 ​​a cualquier respuesta negativa.

atan2 es una función estándar relacionada con arctan, que hace lo correcto para los cuatro cuadrantes posibles en los que su punto de destino podría estar en comparación con el lugar donde se encuentra.

1) Obtenga su ubicación actual (desde el GPS)

2) Obtenga las diferencias en latitud y longitud

3) use el método atan2 para obtener el ángulo

es decir (ADVERTENCIA: código no probado)

 CLLocation *targetLocation = [CLLocation alloc] initWithLatitude:1 longitude:2]; CLLocation *sourceLocation =  double dx = [targetLocation coordinate].latitude - [sourceLocation coordinate].latitude; double dy = [targetLocation coordinate].longitude - [sourceLocation coordinate].longitude; double angle = atan2(dx, dy); 

Es posible que tenga que modificar eso para que compile, ¡pero la idea está allí!

Hice esto hace un tiempo, aquí hay dos implementaciones diferentes. El primero es similar a su enfoque, el segundo es sin el trig math. El primero es lo que utilicé en mi aplicación, pero el segundo parecía funcionar también, aunque no parece ser tan limpio. También deberá recordar compensar este rumbo según el norte en su UI.

 - (double) toRadian: (double) val { return val * (M_PI / 180); } // Convert to degrees from radians - (double) toDegrees: (double) val { return val * 180 / M_PI; } // convert from a radian to a 360 degree format. - (double) toBearing: (double) val { return ( (int)([self toDegrees: val]) + 360 ) % 360; // use mod to get the degrees } // Calculate the bearing based off of the passed coordinates and destination. // - (double) calcBearingWithLatitude:(CLLocationDegrees)latSource latitude:(CLLocationDegrees)latDest longitude:(CLLocationDegrees)lonSrc longitude:(CLLocationDegrees)lonDest { double lat1 = [self toRadian:latSource]; double lat2 = [self toRadian:latDest]; double dLon = [self toRadian:(lonDest - lonSrc)]; double y = sin(dLon) * cos(lat2); double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon); return [self toBearing:atan2(y, x)]; } 

Y el segundo.

 // got this code from some forums and modified it, thanks for posting it coullis! Mostly here for reference on how to do this without sin and cos. - (CLLocationDegrees) altCalcBearingWithLatitude:(CLLocationDegrees)latSource latitude:(CLLocationDegrees)latDest longitude:(CLLocationDegrees)lonSrc longitude:(CLLocationDegrees)lonDest { CLLocationDegrees result; // First You calculate Delta distances. float dx = lonSrc - latSource; float dy = lonDest - latDest; // If x part is 0 we could get into division by zero problems, but in that case result can only be 90 or 270: if (dx==0) { if (dy > 0) result = 90; else result = 270; } else { result = [self toDegrees: atan(dy/dx)]; } // This is only valid for two quadrants (for right side of the coordinate system) so modify result if necessary... if (dx < 0) result = result + 180; // looks better if all numbers are positive (0 to 360 range) if (result < 0) result = result + 360; // return our result. return result; 

}

Utilizar esta. Deberá restar el rumbo real de su brújula del resultado de getHeadingForDirection para determinar el rumbo relativo correcto. El valor de retorno se dirige en radianes .

 -(float) angleToRadians:(float) a { return ((a/180)*M_PI); } - (float) getHeadingForDirectionFromCoordinate:(CLLocationCoordinate2D)fromLoc toCoordinate:(CLLocationCoordinate2D)toLoc { float fLat = [self angleToRadians:fromLoc.latitude]; float fLng = [self angleToRadians:fromLoc.longitude]; float tLat = [self angleToRadians:toLoc.latitude]; float tLng = [self angleToRadians:toLoc.longitude]; return atan2(sin(tLng-fLng)*cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng)); } 
    Intereting Posts