Iphone 如何将方向箭头旋转到特定位置

Iphone 如何将方向箭头旋转到特定位置,iphone,objective-c,xcode,cllocationmanager,compass-geolocation,Iphone,Objective C,Xcode,Cllocationmanager,Compass Geolocation,在我的应用程序中,我的经纬度为1。现在,使用iPhone设备的用户可以移动到任何地方,甚至可以旋转他的设备,箭头(一些uiimageview)应该指向该固定位置,这样用户每次都可以得到指向该位置的方向。我试了以下方法 -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { C

在我的应用程序中,我的经纬度为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度北

我的问题看起来很像。但是使用这个链接的代码我走错了方向。 请帮我做这个

另外,如果有任何想法使用加速度计或陀螺数据将有助于我


提前下载thanx。

此代码可能会对您有所帮助

-(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;
}

这对我很有用:将方向箭头旋转到特定位置

-(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);
}
-(void)viewDidLoad
{
[超级视图下载];
locationManager=[[CLLocationManager alloc]init];
locationManager.delegate=self;
locationManager.desiredAccuracy=KCallocationAccuracyBest;
locationManager.distanceFilter=KCLDistanceFilterOne;
}
-(无效)计算角度:(CLLocationCoordinate2D)电流{
双x=0,y=0,deg=0,delLon=0;
delLon=fixLon-current.longitude;
y=sin(delLon)*cos(fixLat);
x=cos(当前纬度)*sin(固定纬度)-sin(当前纬度)*cos(固定纬度)*cos(德隆);
度=弧度到度(atan2(y,x));
如果(deg<代码>-(无效)viewDidLoad
{
locationManager=[[CLLocationManager alloc]init];
locationManager.delegate=self;
locationManager.desiredAccuracy=KCallocationAccuracyBest;
locationManager.distanceFilter=KCLDistanceFilterOne;
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
}
-(void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation
{
GeoAngle=[自设置LatlonForDistanceandAngle:newLocation];
}
-(无效)位置管理器:(CLLocationManager*)管理器更新位置:(NSArray*)位置
{
CLLocation*location=[locations lastObject];
GeoAngle=[自设置LatlonforDistanceandAngle:位置];
}
-(浮动)设置LatlonForDistanceAndAngle:(CLLocation*)用户位置
{
浮点lat1=度弧度(userlocation.coordinate.latitude);
float lon1=度弧度(userlocation.coordinate.longitude);
浮动lat2=度数弧度(目标晶格度);
float lon2=度弧度(目的经度);
浮动dLon=lon2-lon1;
浮动y=sin(dLon)*cos(lat2);
浮动x=cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(dLon);
浮动弧度轴承=atan2(y,x);
if(弧度轴承<0.0)
{
弧度轴承+=2*M_π;
}
返回弧度轴承;
}
-(void)locationManager:(CLLocationManager*)manager已更新标题:(CLHeading*)新标题
{
浮动方向=-newHeading.trueHeading;
arrow.transform=CGAffineTransformMakeRotation((方向*M_PI/180)+地理角度);
}
试试这个例子。它是用C#Xamarin-tho:) “双标题”是从CLLocationManager.UpdatedHeading中的eventobject读取的CLHeading.MagneticheReading

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);
}

位置有多远?如果很远,可能需要计算。如何在xcode中使用大圆距离计算(目标c)距离可以远至约1000公里。距离是可变的,它将随着用户移动而更新,但范围约为0到1000公里。我不确定这是否确实是您遇到的问题,大圆只是角度不准确的原因之一。除此之外,我看到您没有实现设备方向。请使用“如果([CLLocationManager headingAvailable])[locationsManager startUpdatingHeading];”以获取航向(方位角)从指南针更新,并实现委托方法didUpdateHeading,该方法为您提供设备的最新航向。使用heading.trueHeading或magnetic获取设备面对的方向,并在计算角度时使用结果角度。请参见此处可能的答案:thanx获得答案,仅需1个查询;这是什么s方法-[自旋转角度视图:轴承视图弧度:弧度];这个方法是什么?我刚刚将一幅速度计图像旋转到产品位置的方向,你在哪里使用getAngleFromLatLon?我有四个不同的位置,它不进入东北方向。这里什么是fltAngle,dblLat1,dblLon1,dblLat2,dblLon2,fltLat,fltLon,你是如何声明的?你还创建了getAngleFromLatLon方法,但您尚未在代码中调用。也许可以添加一个说明,说明它的作用以及OP出错的地方?尝试此方法,它将对您有所帮助。此方法(对iOS 8进行了一点更新)对我来说效果很好!谢谢。ShigaSuresh,你能解释一下什么是GeoAngle吗?我最近实现了这一点,但当箭头指向它应该指向的相反方向时,偶尔会出现问题。就像箭头是镜像的。你有没有想过为什么会发生这种情况?什么是“fixLon”和“fixLat”?在您的文档中找不到任何定义或声明code@chiragshah这些是您希望箭头指向的固定位置的坐标
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);
}