【问题标题】:iPhone Compass GPS DirectioniPhone 指南针 GPS 方向
【发布时间】:2011-05-07 01:26:35
【问题描述】:

我正在尝试开发一个使用 iPhone 的 GPS 和指南针的应用程序,以便将某种指针指向特定位置(就像指南针总是指向北方)。该位置是固定的,无论用户位于何处,我总是需要指针指向该特定位置。我有这个位置的纬度/经度坐标,但不知道如何使用指南针和 GPS 指向那个位置......就像 http://www.youtube.com/watch?v=iC0Xn8hY80w 这个链接 1:20'

我写了一些代码,但是它不能向右旋转。

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

        ^
        |
        | 
        |
        :
        |
    */

【问题讨论】:

    标签: iphone gps location compass-geolocation


    【解决方案1】:

    有一个标准的“航向”或“方位”方程可供您使用 - 如果您位于 lat1,lon1,而您感兴趣的点位于 lat2,lon2,则该等式为:

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

    这为您提供了以弧度为单位的方位,您可以通过乘以 180/π 将其转换为度数。然后该值介于 -180 和 180 度之间,因此要获得标准指南针方位,请在任何否定答案上加上 360。

    atan2 是一个与 arctan 相关的标准函数,与您所在的位置相比,它对您的目标点可能位于的四个可能的象限执行正确的操作。

    【讨论】:

    • 我希望这对某人有所帮助,您必须先将纬度/经度转换为弧度,然后再执行其他任何操作。这是一个非常有用的链接:movable-type.co.uk/scripts/latlong.html
    【解决方案2】:

    1) 获取您当前的位置(通过 GPS)

    2) 获取经纬度差异

    3) 使用atan2方法获取角度

    即(警告:未经测试的代码)

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

    您可能需要对其进行调整才能使其编译,但想法就在那里!

    【讨论】:

    • 在我得到角度之后。如何使用指南针实现的当前航向。
    • 我只使用当前航向 - 角度。然后将箭头旋转(当前航向-角度),但我无法得到正确的答案?
    【解决方案3】:

    我前段时间做过,这里有两种不同的实现。第一个类似于您的方法,第二个没有三角数学。第一个是我在我的应用程序中使用的,但第二个似乎也能正常工作,虽然看起来不那么干净。您还需要记住在您的 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)];
    }
    

    还有第二个。

    // 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;
    

    }

    【讨论】:

      【解决方案4】:

      使用这个。您必须从 getHeadingForDirection 的结果中减去您的实际罗盘航向,以确定正确的相对航向。返回值以弧度为单位。

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

      【讨论】:

        猜你喜欢
        • 2011-05-22
        • 1970-01-01
        • 2011-12-05
        • 2015-08-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多