iPhone Компас Направление GPS - PullRequest
3 голосов
/ 09 ноября 2010

Я пытаюсь разработать приложение, которое использует GPS и компас iPhone, чтобы указывать какой-то указатель на определенное местоположение (например, компас всегда указывает на север). Местоположение является фиксированным, и мне всегда нужен указатель, указывающий на это конкретное местоположение, независимо от того, где находится пользователь. У меня есть координаты широты / долготы этого местоположения, но я не уверен, как я могу указать это местоположение с помощью компаса и 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

        ^
        |
        | 
        |
        :
        |
    */

Ответы [ 4 ]

5 голосов
/ 02 ноября 2010

Существует стандартное уравнение "заголовок" или "азимут", которое вы можете использовать - если вы находитесь на 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, которая правильно делает для четырех возможных квадрантов, в которых может быть ваша точка назначения, по сравнению с тем, где вы находитесь.

1 голос
/ 09 ноября 2010

Я сделал это некоторое время назад, вот две разные реализации.Первый похож на ваш подход, второй без триггера.Первый - это то, что я использовал в своем приложении, но второй, похоже, тоже работает, хотя и не такой чистый.Вам также нужно помнить, чтобы сместить этот азимут в северном направлении в вашем пользовательском интерфейсе.

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

и второй.

1 голос
/ 13 октября 2010

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

Возможно, вам придется настроить его для компиляции, но идея есть!

0 голосов
/ 05 ноября 2010

Используйте это.Вам нужно будет вычесть фактический заголовок компаса из результата 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));         
}
...