14

私のアプリでは、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 度。

私の質問はこのスタックオーバーフローの質問に似ていますが、このリンクのコードを使用すると、間違った方向に進んでいます。これについて私を助けてください。

また、加速度計やジャイロデータを使用するアイデアが役立つかどうか。

事前に感謝します。

4

4 に答える 4

14

これは私にとってはうまくいきます:方向矢印を特定の場所に回転させる

-(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);
}
于 2012-10-12T06:44:39.470 に答える
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;
}
于 2011-10-03T11:13:57.967 に答える
4
-(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);
}
于 2014-09-25T10:36:01.750 に答える
-1

この例を試してください。そのC#Xamarin tho :)「ダブルヘッダー」は、CLLocationManager.UpdatedHeadingのイベントオブジェクトからの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);
}
于 2016-07-14T19:23:03.493 に答える