Unity で GPS と Google Map API を使ってみる


お疲れ様です。
横浜オフィス改め、システム開発部の松山です。

前回から時間が空いてしまいました。
一旦 AR から離れて、今回は GPS 機能と Google Map について書いていきます。
とりあえず、こんなモノを作ってみましょうか。

作るもの

・GPS で現在位置を取得
・その地点を中心としたマップ画像を表示
・一定時間ごとに、移動していたらマップを更新
・マップの現在位置にアイコンを表示する

位置情報の取得

まず位置情報ですが、LocationService クラスで取得できます。
Reference LocationService

まずはロケーションの更新を開始します。
ついでにコンパス機能も有効にしておきましょう。
Reference Compass

Input.location.Start();
Input.compass.enabled = true;

起動するまで情報は取得できないので以下の判定で待ち合わせます。

// GPS が許可されていない
if (!Input.location.isEnabledByUser) yield break;

// サービスの状態が起動中になるまで待機
while (Input.location.status != LocationServiceStatus.Running) yield return null;

GPS が許可されていない場合は、どうしようもないですが一応。

ちなみに、ProjectSettings の Location Usage Description を設定をしないと、
実機で位置情報が取得できないので注意!

位置情報(緯度・経度)は LocationService の lastData で確認できます。

LocationInfo curr = Input.location.lastData;

現在位置(緯度経度)が取得できたら、その座標からマップ画像を取得します。

マップ表示

Google map を使用するには、事前に Google Maps Platform の登録が必要です。(説明は省きます)
Google Maps Platform 公式

シンプルな地図画像の表示であれば、Google Static Map API で取得できます。
GPS で取得した現在位置を中心とした画像を取得します。

① URL にパラメータを指定

// ベース URL
string url = @"https://maps.googleapis.com/maps/api/staticmap?";
// 中心座標
url += "center=" + curr.latitude + "," + curr.longitude;
// ズーム
url += "&zoom=" + 18;  // デフォルトで 0 なので適当なサイズにしておく
// 画像サイズ(640x640まで)
url += "&size=" + 640 + "x" + 640;
// API Key(Google Maps Platform で発行されるキー)
url += "&key=" + GoogleApiKey;

② UnityWebRequest で地図画像をダウンロード

url = UnityWebRequest.UnEscapeURL(url);
UnityWebRequest req = UnityWebRequestTexture.GetTexture(url);
yield return req.SendWebRequest();

③ ダウンロードした画像をスプライトとして表示

// テクスチャ生成
Texture2D tex = new Texture2D(MapSpriteSize, MapSpriteSize);
tex.LoadImage(data);

// スプライト(インスタンス)を動的に生成
mapImage.sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);

で、
この処理を一定時間ごとに更新するようコルーチンで回しておきます。
常時マップを更新する必要はないので、直前の座標から一定以上移動した場合だけマップを更新するようにします。
距離はこんな感じで求めました。

/// <summary>
/// 緯度(経度)1度の距離(m)
/// </summary>
private const float Lat2Meter = 111319.491f;

private float getDistanceFromLocation(LocationInfo curr, LocationInfo prev)
{
    Vector3 cv = new Vector3((float)curr.longitude, 0, (float)curr.latitude);
    Vector3 pv = new Vector3((float)prev.longitude, 0, (float)prev.latitude);
    returnVector3.Distance(cv, pv) * Lat2Meter;
}

現在位置にカーソルを配置

マップ上のカーソルをおいて、向いている方向へ回転させます。

this.transform.localEulerAngles = new Vector3(0, 0, 360 - Input.compass.trueHeading);

こんだけ。

出来上がりはこんな感じですね。

まとめ

ちょっと簡単な内容にはなってしまいましたが、今回はこのあたりで締めます。
ざっくり所感です。
・Google Map API は機能が豊富なので、いろいろ触ってみると面白そう。
・GPS の誤差は割と大きい。
・この程度であれば、コードはかなりシンプルにできる。

AR、マップ(GPS)と来たので、次回あたりで組み合わせて何か作ってみましょうか。
それでは、今回のお話はこれまでになります。

一応、GitHub に上げておきます。
Unity サンプル


この記事をかいた人

About the author

松山賢勝

2019年8月から横浜オフィスに勤務。
経歴としてはクライアント開発が多いため、クライアント寄りの記事が多いかも。
趣味は自転車(ロード)と競馬。