2013年7月22日月曜日

[訂正]OpenCVを使った緯度経度のGoogleMap上へのプロット

 前回
OpenCVを使った緯度経度のGoogleMap上へのプロット
 で紹介した「2.やり方」よりもっといいやり方があることに気づいたので、投稿しておきます。

前回のやり方では

 A. 緯度経度座標をメルカトル座標に変換する
 B. 取得した地図の中心点と表示させたい点の距離を測って表示する

というやり方をとっていましたが、このやり方だと

  緯度経度座標を直接ピクセル座標(距離情報)に直接変換できない
  つまり、逆変換する時とか、色々めんどくさい仕様になっている

という事に気が付きました。
そこで、緯度経度座標を直接ピクセル座標に変換できる方法を以下のサイト様を参考に(丸パクリ)させて頂き、作ってみました。

参考にさせて頂いたサイト様↓  本当に感謝です!ありがとうございます!!!!m(_ _)m
グーグルマップ(Google Maps) の座標間変換式について(1)

という事で、c言語で書いた変換式を載せておきます。
上のサイトを読まないとよくわからないと思うのでしっかり読んでからご覧ください。


/*========================================================================================
 Name     : real_frame_to_pix_frame
 Argument : point_data *data : 変換するデータ(緯度経度→ピクセル)
            int zoom         : 地図のズームレベル
 Return   : no return
 About    : 緯度経度座標をピクセル座標に変換する
            ポインタにより、データを直接いじるので注意すること
========================================================================================*/
void real_frame_to_pix_frame(point_data *data, int zoom)
{
  (*data).lo = pow(2,7+zoom) * ((*data).lo/180 + 1);

  (*data).la = pow(2,7+zoom)/PI * (-atanh(sin(PI*(*data).la/180)) + atanh(sin(PI*MAX_LA/180)));
}

/*=======================================================================================
 Name     : pix_frame_to_real_frame
 Argument : point_data *data : 変換するデータ(ピクセル→緯度経度)
            int zoom         : 地図のズームレベル
 Return   : no return
 About    : ピクセル座標を緯度経度座標に変換する
       ポインタにより、データを直接いじるので注すること
========================================================================================*/
void pix_frame_to_real_frame(point_data *data, int zoom)
{
  (*data).lo = 180 * ((*data).lo/pow(2,7+zoom) - 1);

  (*data).la = 180/PI * (asin(tanh(-PI*(*data).la/pow(2,7+zoom) + atanh(sin(PI*MAX_LA/180)))));
}

/*=======================================================================================
 Name     : real_frame_to_picture_frame
 Argument : point_data center : 表示する画像の中心緯度経度座標
            point_data data   : 目標点の緯度経度座標
            int zoom          : 地図のズームレベル
 Return   : no return
 About    : 緯度経度座標を画像座標に変換し、
        CvPoint型 picture_frame に格納する
=========================================================================================*/
void real_frame_to_picture_frame(point_data center, point_data data, int zoom)
{
  picture_frame.x = pow(2,7+zoom) * ((data.lo-center.lo)/180);

  picture_frame.y = pow(2,7+zoom)/PI * (-atanh(sin(PI*center.la/180)) + atanh(sin(PI*data.la/180)));
}

/*========================================================================================
 Name     : picture_frame_to_real_frame
 Argument : point_data center : 表示する画像の中心緯度経度座標
            CvPoint data      : 目標点の画像座標
            int zoom          : 地図のズームレベル
 Return   : no return
 About    : 画像座標を緯度経度座標に変換し、
        point_data型 gps に格納する
========================================================================================*/
void picture_frame_to_real_frame(point_data center, CvPoint2D32f data, int zoom)
{
  gps.lo = 180*data.x/pow(2,7+zoom) + center.lo;

  gps.la = 180/PI * asin(tanh(PI*data.y/pow(2,7+zoom) + atanh(sin(PI*center.la/180))));
}

構造体!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 typedef struct {
  double la;  // la is latitude.  緯度
  double lo;  // lo is longitude. 経度
} point_data;

struct CvPoint{
  int x;
  int y;
}

struct CvPoint2D32f{
  float x;
  float y;
}

必要なinclude, define!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#include 
#include 
#include 

#define PI 3.141592653589793
#define MAX_LA 85.0511287798066

コードが見えづらいと思いますので、一応スクショも貼っときます。






以上です。
必要ないことも若干書いてあるので、読みづらいと思いますが、ご勘弁ください。

次は、OpenCVを使って、Googleより取得した地図をくっつけて巨大な地図を作り、その地図の任意の点をクリックするとその点の緯度経度情報を.datファイルに出力するプログラムを作りたいと思います。

それではまた ! ('A')ノシ

0 件のコメント:

コメントを投稿