RACCOON TECH BLOG

株式会社ラクーンホールディングスのエンジニア/デザイナーから技術情報をはじめ、世の中のためになることや社内のことなどを発信してます。

UnityでARアプリの作り方2/4 GPSの緯度経度から地図の表示

こんにちは、Paid開発ユニット werdnaの酒井です。

第2回ARアプリの作り方です。
前回までで環境構築とビルドが出来るように進めてもらったと思いますので、今回は実際にアプリの実装を進めていきます。
UnityでARアプリの作り方1/4 環境構築+androidビルドからカメラ表示
UnityでARアプリの作り方2/4 GPSの緯度経度から地図の表示(本記事)
UnityでARアプリの作り方3/4 Google Direction APIの経路を地図に表示
UnityでARアプリの作り方4/4 磁気センサーで進行方向オブジェクトを回転

概要

本記事では「端末のGPS情報を取得し、Google Maps Static APIから取得した地図の表示」を目標とします。
具体的には下記内容を順に説明していきます。

Google APIの利用設定

次に今回利用するGoogle APIの利用準備です。
本記事にて説明するGoogle Maps Static APIと次の記事で説明するGoogle Direction APIを利用できるようにします。
1からの説明で長くなってしまうので、設定済みの方や設定方法をご存知の方は読み飛ばしてください。

APIを利用するまでの手順

大まかにですが、下記3つの手順を実施することでAPIが利用可能になります。
1. プロジェクトの作成
2. APIの有効化
3. APIキーの作成
画面遷移が多く、分かりやすい説明が難しかったため、画像の赤枠内をクリックしていけばAPIを利用できるようにしています。

プロジェクトの作成

Googleアカウントでログイン後下記ページを開いてください。
Google Cloud PlatformのAPIライブラリページ
https://console.cloud.google.com/apis/library

これでプロジェクトの作成と利用中への設定が完了です。

APIの有効化

作成したプロジェクトでAPIを利用できるように、今回利用するMaps Static API, Directions APIを有効化します。

これでAPIの有効化は完了です。

APIキーの作成

続いてAPIを利用するときに必要な「APIキー」の作成を行います。

作成後の状態だと、全てのAPIが利用可能になっているので、今回利用するMaps Static API, Directions APIの二つのみを利用できるように制限をかけます。

これでAPIの設定は終了です。

APIの実行

ちゃんと設定できたかの確認として、Google Maps Static APIをリクエストしてみます。
このAPIは指定した住所・座標を中心としたGoogleMapのpngファイルを返すAPIです。

下記のようなURLで接続することが可能です。(${APIKey}を作成したapiキーに書き換えてください。)

https://maps.googleapis.com/maps/api/staticmap?center=%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE%E3%83%A9%E3%82%AF%E3%83%BC%E3%83%B3%E3%83%9B%E3%83%BC%E3%83%AB%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%B9&key=${APIKey}&zoom=18&size=640x640&scale=2&maptype=terrain&style=element:labels|visibility:off&style=element:terrain|invert_lightness:true
このURLでは「株式会社ラクーンホールディングス」でGoogleマップを検索した結果を表示しています。
正常に表示されない場合はエラーの文言が表示されているはずですので上の説明を再度確認しつつAPIをリクエストできるよう設定していただければと思います。

端末のGPS情報取得

Google Maps Static APIの利用のために必要なGPSの情報は下記のように取得することが出来ます。

項目 取得方法
緯度-Latitude Input.location.lastData.latitude
経度-Longitude Input.location.lastData.longitude
高度-Altitude Input.location.lastData.altitude
水平方向の精度-horizontalAccuracy Input.location.lastData.horizontalAccuracy
垂直方向の精度-VerticalAccuracy Input.location.lastData.verticalAccuracy
タイムスタンプ-Timestamp Input.location.lastData.timestamp

今回必要なのは現在位置を表す緯度(latitude)・経度(longitude)の二つなので、まずはこの2つの値を画面上に表示出来るようにします。

Hierarchyウィンドウを右クリックしてUI→Textを追加
すると、Canvas下にTextオブジェクトとEventSystemオブジェクトが作成されます。

緯度・経度の2項目を表示するので、HierarchyウィンドウよりCanvasを右クリックしてUI→Textを追加
2つのテキストオブジェクトの名前を分かりやすいようにLatitude, Longitudeに変更しておきます。
[picture Hierarchy.Canvas]

今回は複数のテキストに書き換えを実施するので、Text二つを子に持つCanvasに対してAdd Componentでスクリプトをつけてあげます。
付けるスクリプトは下記のような内容になります。

using System;
using UnityEngine;
using UnityEngine.UI;

public class ShowGPSTest : MonoBehaviour
{
    // GameObjectをメソッド外で定義することで、InspectorにてObjectを紐づけできる。
    public GameObject LatitudeText = null;
    public GameObject LongitudeText = null;

    // Start is called before the first frame update
    void Start()
    {
        // GPS機能の利用開始
        Input.location.Start();
    }

    // Update is called once per frame
    void Update()
    {
        // 紐づけたTextのオブジェクトを変数に格納
        Text latitude_component = LatitudeText.GetComponent<Text>();
        Text longitude_component = LongitudeText.GetComponent<Text>();

        // Textオブジェクトのtext部分を取得したGPS情報の緯度・経度で上書き
        latitude_component.text = Convert.ToString(Input.location.lastData.latitude);
        longitude_component.text = Convert.ToString(Input.location.lastData.longitude);
    }
}

追記後保存してCanvasに付与したScript部分を見ると、Latitude Text, Longitude Textという欄が作成されていると思います。
ここに先ほど作成したTextをドラッグアンドドロップしてあげることにより、それぞれが10, 11行目で定義したGemeObjectに紐づけられ、Updateメソッド内部でテキスト部分の更新が可能になります。

ビルドして端末で実行した画面は下記の通りです。
見やすさのために後ろのCanvasにつけているBackgroundCamera.csを無効化しています。

このアプリを立ち上げたまま、移動するとGPSの座標が変わっていくことが分かるかと思います。
(歩きスマホは危険なので、周囲に人がいないことを確認したうえで座標を見てみてください。)

Google Maps Static APIを利用した地図表示

取得したGPS情報より、Google Maps Static APIを実行します。
APIが利用可能か確認のために一度触れていますが、指定した住所・座標を中心としたGoogleMapのpngファイルを返すAPIです。
GPSの緯度・経度を利用して表示する場合にはURLの中に”center=緯度,経度”と入れてあげることで表示できます。

アプリ上に表示するために、APIより返ってきたpngファイルをテクスチャとしてオブジェクトに張り付けることで地図を表示します。
カメラの映像を表示したときと同様に、テクスチャ貼り付け用にPlaneを作成しAdd Componentで新しいスクリプトを作成します。

作成するScriptは下記のようになります。

using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class StaticMapController : MonoBehaviour
{

    //Google Maps Static API URL
    // ${APIKey}を作成したapiキーに書き換えてください。
    private const string STATIC_MAP_URL = "https://maps.googleapis.com/maps/api/staticmap?key=${APIKey}&zoom=15&size=640x640&scale=2&maptype=terrain&style=element:labels|visibility:off";

    private int frame = 0;

    // Start is called before the first frame update
    void Start()
    {
        // 非同期処理
        StartCoroutine(getStaticMap());
    }

    // Update is called once per frame
    void Update()
    {
        // 5秒に一度の実行
        if (frame >= 300)
        {
            StartCoroutine(getStaticMap());
            frame = 0;
        }
        frame++;
    }

    IEnumerator getStaticMap()
    {
        var query = "";

        // centerで取得するミニマップの中央座標を設定
        query += "&center=" + UnityWebRequest.UnEscapeURL(string.Format("{0},{1}", Input.location.lastData.latitude, Input.location.lastData.longitude));
        // markersで渡した座標(=現在位置)にマーカーを立てる
        query += "&markers=" + UnityWebRequest.UnEscapeURL(string.Format("{0},{1}", Input.location.lastData.latitude, Input.location.lastData.longitude));

        // リクエストの定義
        var req = UnityWebRequestTexture.GetTexture(STATIC_MAP_URL + query);
        // リクエスト実行
        yield return req.SendWebRequest();

        if (req.error == null)
        {
            // すでに表示しているマップを更新
            Destroy(GetComponent<Renderer>().material.mainTexture);
            GetComponent<Renderer>().material.mainTexture = ((DownloadHandlerTexture)req.downloadHandler).texture;
        }
    }
}

内容はコメントに記載していますが補足です。

上記Scriptを反映して実行すると、現在地点を中心にしたマップの画像が表示されることを確認できるかと思います。

ここまでで本記事で説明したい地図表示は実装完了です。
次の記事では目的地の入力と、今回表示した地図に目的地までの経路を表示までを実装していきます。
UnityでARアプリの作り方3/4 Google Direction APIの経路を地図に表示

一緒にラクーンのサービスを作りませんか? 採用情報を詳しく見る

関連記事

運営会社:株式会社ラクーンホールディングス(c)2000 RACCOON HOLDINGS, Inc