その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

CLLocationCoordinate2D から指定方向に指定距離離れた場所の緯度経度を計算する

たとえば渋谷の緯度経度が (35.659406, 139.70203) だったとして、そこから北東に時速4km(徒歩)で1時間移動した先の緯度経度はどうなるか、という計算です。


こんな風にしました。(引数のdistance、directionの型がポイントなので、詳細を後述します)

+ (CLLocationCoordinate2D)calcNewLocationFrom:(CLLocationCoordinate2D)current 
                                     distance:(CLLocationDistance)distance     
                                    direction:(CLLocationDirection)direction {
    
    if (!(distance > 0.0) || direction < 0) {
        return current;
    }
    CLLocationDistance distX =  distance * sin(direction * (M_PI / 180.0f));
    CLLocationDistance distY = -distance * cos(direction * (M_PI / 180.0f));
    MKMapPoint currentPoint = MKMapPointForCoordinate(current);
    double mapPointsPerMeter = MKMapPointsPerMeterAtLatitude(current.latitude);
    double deltaMapPointsX = mapPointsPerMeter * distX;
    double deltaMapPointsY = mapPointsPerMeter * distY;
    MKMapPoint newPoint = MKMapPointMake(currentPoint.x + deltaMapPointsX, currentPoint.y + deltaMapPointsY);
    CLLocationCoordinate2D new = MKCoordinateForMapPoint(newPoint);

    return new;
}

で、この計算まわりで出てくる型の仕様を調べるのが意外と面倒だった(ちょっとググっただけじゃわからなかった)ので下記に書いておきます。

CLLocationDirection

真北を0として、時計回りに 0 から 359.9 度の値をとる。つまり、

  • 北:0
  • 南:180
  • 東:90
  • 西:270

となる。
マイナス値は無効。

CLLocationDistance

実態はdouble、単位はメートル。

MKMapPoint

iOS SDKの座標系に従う。従って

  • 原点は左上隅
  • プロパティ y がプラス方向に増える=南に移動する

座標系云々はクラスリファレンスみてもヘッダの定義みてもよくわからず、実際に値を入れてみて検証しました。


上記コードの実行例

渋谷(35.659406,139.70203)から真北に10000m移動した先の緯度経度の計算

CLLocationCoordinate2D new = [MapCommon calcNewLocationFrom:CLLocationCoordinate2DMake(35.659406,139.70203) distance:10000 direction:0];

元の場所
http://maps.google.co.jp/maps?q=35.659406,139.70203
計算後の場所
http://maps.google.co.jp/maps?q=35.656512,139.702492