12

在我的應用程序中,我有1個固定位置的經度 - 緯度。現在,使用iPhone設備的用戶可以在任何地方移動,甚至他可以旋轉他的設備,箭頭(某些uiimageview)應該指向該修復位置,以便用戶每次都可以獲取指向該位置的路線。我嘗試如下。如何將方向箭頭旋轉到特定位置

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 

CLLocationCoordinate2D here = newLocation.coordinate; 
[self calculateUserAngle:here]; 
} 


-(void) calculateUserAngle:(CLLocationCoordinate2D)user { 
    NSLog(@"my destination is %f ; %f", fixlocLat, fixlocLon); 
    degrees = degrees + atan2(sin(fixlocLon-user.longitude)*cos(fixlocLat),cos(user.latitude)*sin(fixlocLat) - sin(user.latitude)*cos(fixlocLat)*cos(fixlocLon-user.longitude)); 
//get angle between user location and fix location 
} 

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

,但上面的代碼將永遠旋轉箭頭約。每個位置向北2-3度。

我的問題與this Stack Overflow question類似,但使用此鏈接中的代碼我得到錯誤的方向。 請幫助我。

以及使用加速度計或gyrodata的任何想法對我都有幫助。

thanx提前。

+0

位置有多遠?如果距離很遠,則可能需要[大圓距離](http://en.wikipedia.org/wiki/Great-circle_distance)計算。 – RabinDev

+0

我們如何使用xcode(物鏡c)中的大圓距離計算和距離可以遠遠大約。千公里。 – Dhawal

+0

距離是可變的,它會隨着用戶移動而更新,但範圍大約在0到1000km之間。 – Dhawal

回答

10

這段代碼可以幫助你

-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { 
    // Use the true heading if it is valid. 
    CLLocationDirection direction = newHeading.magneticHeading; 
    CGFloat radians = -direction/180.0 * M_PI; 

    self.strAccuracy = [NSString stringWithFormat:@"%.1fmi",newHeading.headingAccuracy];  
    [lblAccuracy setText:self.strAccuracy]; 

    //Rotate Bearing View 
    [self rotateBearingView:bearingView radians:radians]; 

    //For Rotate Niddle 
    CGFloat angle = RadiansToDegrees(radians); 
    [self setLatLonForDistanceAndAngle]; 
    [self rotateArrowView:arrowView degrees:(angle + fltAngle)]; 
} 

-(void)rotateArrowView:(UIView *)view degrees:(CGFloat)degrees 
{ 
    CGAffineTransform transform = CGAffineTransformMakeRotation(DegreesToRadians(degrees)); 
    view.transform = transform; 
} 

-(void)setLatLonForDistanceAndAngle 
{ 
    dblLat1 = DegreesToRadians(appDelegate.dblLatitude); 
    dblLon1 = DegreesToRadians(appDelegate.dblLongitude); 

    dblLat2 = DegreesToRadians(objClsProductSearch.dblLatitude); 
    dblLon2 = DegreesToRadians(objClsProductSearch.dblLongitude); 

    fltLat = dblLat2 - dblLat1; 
    fltLon = dblLon2 - dblLon1; 
} 

-(float)getAngleFromLatLon 
{ 
    //Calculate angle between two points taken from http://www.movable-type.co.uk/scripts /latlong.html 
    double y = sin(fltLon) * cos(dblLat2); 
    double x = cos(dblLat1) * sin(dblLat2) - sin(dblLat1) * cos(dblLat2) * cos(dblLon2); 
    CGFloat angle = RadiansToDegrees(atan2(y, x)); 
    return angle; 
} 
+0

thanx爲答案和只是1查詢;這個方法怎麼樣 - [self rotateBearingView:bearingView radians:radians];這個方法是什麼? – Dhawal

+0

我剛剛在產品位置的方向上旋轉了一個車速表種類圖像 – NIKHIL

+4

您在哪裏使用getAngleFromLatLon? –

15

這對我的作品:以箭頭的方向旋轉到特定位置

-(void)viewDidLoad 
{ 
    [super viewDidLoad]; 

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

} 

-(void) calculateUserAngle:(CLLocationCoordinate2D)current { 
    double x = 0, y = 0 , deg = 0,delLon = 0; 

    delLon = fixLon - current.longitude;  
    y = sin(delLon) * cos(fixLat); 
    x = cos(current.latitude) * sin(fixLat) - sin(current.latitude) * cos(fixLat) * cos(delLon);  
    deg = RADIANS_TO_DEGREES(atan2(y, x));  

    if(deg<0){  
     deg = -deg; 
    } else { 
     deg = 360 - deg; 
    }  
    degrees = deg; 
} 


-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 

    CLLocationCoordinate2D here = newLocation.coordinate; 
    [self calculateUserAngle:here]; 
} 


- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading 
{ 
    arrow.transform = CGAffineTransformMakeRotation((degrees-newHeading.trueHeading) * M_PI/180); 
} 
+0

我最近實現了這一點,但是當箭頭直接指向相反的方向時,它一直有偶然的問題。這就像箭頭被鏡像。你有什麼想法,爲什麼會發生? – Chris

+1

什麼是「fixLon」和「fixLat」?在代碼中找不到任何定義或聲明 –

+2

@chiragshah這些是您希望箭頭指向的固定位置的座標 – SteBra

3
-(void)viewDidLoad 
{ 
    locationManager = [[CLLocationManager alloc] init]; 
    locationManager.delegate = self; 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
    locationManager.distanceFilter = kCLDistanceFilterNone; 
    [locationManager startUpdatingLocation]; 
    [locationManager startUpdatingHeading]; 
} 
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
{ 
    GeoAngle = [self setLatLonForDistanceAndAngle:newLocation]; 
} 

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 
{ 
    CLLocation *location=[locations lastObject]; 
    GeoAngle = [self setLatLonForDistanceAndAngle:location]; 
} 
-(float)setLatLonForDistanceAndAngle:(CLLocation *)userlocation 
{ 
    float lat1 = DegreesToRadians(userlocation.coordinate.latitude); 
    float lon1 = DegreesToRadians(userlocation.coordinate.longitude); 

    float lat2 = DegreesToRadians(Destination lattitude); 
    float lon2 = DegreesToRadians(Destination Longitude); 

    float dLon = lon2 - lon1; 

    float y = sin(dLon) * cos(lat2); 
    float x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon); 
    float radiansBearing = atan2(y, x); 
    if(radiansBearing < 0.0) 
    { 
     radiansBearing += 2*M_PI; 
    } 
    return radiansBearing; 
} 

-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading 
{ 
    float direction = -newHeading.trueHeading; 
    arrow.transform=CGAffineTransformMakeRotation((direction* M_PI/180)+ GeoAngle); 
} 
+0

也許是說明它的作用以及OP出錯的位置? –

+0

嘗試這一個它會幫助你。 – ShigaSuresh

+0

這對iOS 8來說非常適合我!謝謝。 –

0

試試這個例子。它在C#Xamarin tho :) 「雙標題」是來自CLLocationManager.UpdatedHeading中eventobject的CLHeading.MagneticHeading。

void UpdateCompass(Location origin, Location target, double heading) 
{ 
    var angle1 = GetAngleBetweenPoints(origin, target); 
    var angle2 = GetAngleFromHeading(heading); 
    var radian = Math.PI * (angle1 + angle2)/180.0; 
    CompassArrow.Transform = CGAffineTransform.MakeRotation((nfloat)radian); 
} 

double GetAngleBetweenPoints(Location origin, Location target) 
{ 
    var n = 270 - (Math.Atan2(origin.Latitude - target.Latitude, origin.Longitude - target.Longitude)) * 180/Math.PI; 
    return n % 360; 
} 

double GetAngleFromHeading(double heading) 
{ 
    var radians = -heading/180.0 * Math.PI; 
    return radians * (180.0/Math.PI); 
}