初めてのフォトリアルな 3D 地図を作成する

1. 始める前に

この Codelab では、Maps JavaScript の Photorealistic 3D Maps を使用して初めて 3D 地図を作成する方法について説明します。Maps JavaScript API の適切なコンポーネントを読み込み、最初の 3D 地図を表示してその上に対象物を描画するための基礎を学習できます。

作成するアプリの概要

最初に作成する地図。

この Codelab では、次のような 3D ウェブアプリを作成します。

  • Maps JavaScript API を動的に読み込みます。
  • トロントの CN タワーを中心とした 3D 地図を表示します。
  • 場所の周囲の境界を表示します。
  • 3D 地図上のスポットをオフにします。
  • 境界を押し出して、対象地域を覆います。

学習内容

  • Google Maps Platform のスタートガイド。
  • Dynamic Library Import を使用して JavaScript コードから Maps JavaScript API を動的に読み込む。
  • Map3DElement クラスを使用して 3D 地図を読み込みます。
  • ポリゴンとエクストルジョンを使用して地図上に描画する。

2. 前提条件

この Codelab を完了するには、以下の内容を理解しておく必要があります。Google Maps Platform の操作に慣れている場合は、すぐに Codelab に進んでください。

必要な Google Maps Platform プロダクト

この Codelab では次の Google Maps Platform サービスを使用します。

  • Maps JavaScript API

はい、ページに 3D 地図を追加するために必要な手順は以上です。とても簡単です。

この Codelab のその他の要件

この Codelab を実行するには、次のアカウント、サービス、ツールが必要です。

  • 課金が有効になっている Google Cloud アカウント
  • Maps JavaScript API を有効にした Google Maps Platform API キー
  • JavaScript、HTML、CSS に関する基礎的な知識
  • 任意のテキスト エディタまたは IDE(編集したファイルを保存して表示する場合)
  • 作業中にファイルを表示するウェブブラウザ

3. セットアップする

Google Maps Platform を設定する

課金を有効にした Google Cloud Platform アカウントとプロジェクトをまだ作成していない場合は、Google Maps Platform スタートガイドに沿って請求先アカウントとプロジェクトを作成してください。

  1. Cloud Console で、プロジェクトのプルダウン メニューをクリックし、この Codelab に使用するプロジェクトを選択します。

  1. Google Cloud Marketplace で、この Codelab に必要な Google Maps Platform API と SDK を有効にします。詳しい手順については、こちらの動画またはドキュメントをご覧ください。
  2. Cloud Console の [認証情報] ページで API キーを生成します。詳しい手順については、こちらの動画またはドキュメントをご覧ください。Google Maps Platform へのすべてのリクエストで API キーが必要になります。

4. Maps JavaScript API を読み込む

準備セクションの手順をすべて完了したら、最初の 3D 地図の作成を開始できます。

想像できる限りシンプルなウェブページを作成します。

まず、すべてのコードをホストする非常に基本的なウェブページを作成します。これは、任意のエディタまたはプラットフォームで行うことができます。

 <!DOCTYPE html>
 <html>
   <head>
    <title>3D Maps Codelab</title>
     <style>
      html,
      body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
   </head>
   <body>
   </body>
 </html>

コードを追加して、3dmap.html などの名前でアクセス可能な場所にファイルを保存します。次に、ウェブブラウザで開いてページの現在の状態を確認し、エラーがないか確認します。

2D 地図と同様に、3D 地図の基盤となるのは Maps JavaScript API です。そのため、まずこれを読み込む必要があります。

読み込み方法はいくつかあります。詳しくは、ドキュメントの Maps JavaScript API を読み込むをご覧ください。

このデモでは、より新しい動的ライブラリのインポート方法を使用します。この方法では、読み込む必要がある要素のみを制御できるため、ダウンロード サイズと起動時間を短縮できます。

ダイナミック ローダを追加する

動的ローダーを使用するには、次のスクリプトタグをウェブページに追加し、適切な場所に独自の API キー(ステップ 2 で取得したもの)を追加します。このスクリプト タグを、基本的なウェブページの body セクションの間に配置します。

  <script async defer>
    (g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
      key: "YOUR_API_KEY",
      v: "alpha",
    });
  </script>

なお、このプロダクト リリースの段階では、API のアルファ版ブランチを使用して 3D マップにアクセスしています。製品の試験運用版のほとんどの機能が含まれており、早期アクセス コードを開発中にテストして、リリース時にすぐに使用できるようにすることができます。

これで、動的ローダーを含む基本的なウェブページが作成されました(ページを開くとビューは空白になりますが、エラーは発生しません)。3D 地図を追加する準備が整いました。

なんらかの理由でコードが機能しない場合は、ステップ 6 に進んで最終結果と比較し、問題を特定します。

ページが機能しない理由を確認するには、ブラウザのエラー コンソールで原因をデバッグします。エラーページには、さまざまなブラウザでこの操作を行う方法が記載されています。また、さまざまなエラー メッセージの説明や、API が機能しない一般的な理由も記載されています。これは、実装に問題があるかどうかを開発全体で確認するのに適したリソースです。

5. 地図を表示する

これで、最初の 3D 地図をページに追加する準備が整いました。

3D 地図は、google.maps.maps3d.Map3DElement クラスを使用して作成します。このクラスを使用すると、3D 地図インスタンスを作成して操作できます。この Codelab では、HTML タグではなく 3D 地図オブジェクトを直接操作します。

Init 関数を作成し、ライブラリを読み込む

まず、要素をページに読み込む関数を作成します。コードを見ると、まず非同期関数を作成しています。これにより、残りのコードに進む前に要素全体が読み込まれることを確認できます。次に、ページの読み込み時に init 関数を実行します。

ページの body セクション内の読み込みスクリプトの後に追加します。

  <script>
    async function init() {
      const { Map3DElement, MapMode } = await google.maps.importLibrary("maps3d");
    }
    init();
  </script>

await 式を使用して、続行する前にライブラリが読み込まれていることを確認します。

3D 地図要素を作成し、位置情報を指定する

次に、地図ビューを表示する場所を指定する必要があります。3D マップでは、ビューの設定に使用できるパラメータがいくつかあります。これらは、シーン内で撮影対象を記述する仮想カメラ パラメータを指します。

次のような CN タワーのビューを作成しましょう。

最初に作成する地図。

まず、調べる座標を指定する必要があります。これらは 2 つの異なるビューで構成されています。

  1. 標高を含む、確認したいポイント。
  2. ポイントを撮影している仮想カメラの距離と方向。

次の画像は、これらの設定の仕組みを示しています。

地図要素の設定を示す画像。

要素の中心は、視点となるポイントです。範囲は、オブジェクトからの距離で、傾斜は画像を表示する角度です。オブジェクトの向きとロールも制御する場合は、それらを設定することもできますが、ここでは使用しません。

次に、ページに 3D 地図を作成します。ライブラリをインポートした後、ページの init セクションに次のコードを追加します。

  const map3DElement = new Map3DElement({
      center: { lat: 43.6425, lng: -79.3871, altitude: 400 },
      range: 1000,
      tilt: 60,
      mode: MapMode.HYBRID,
  });

  document.body.append(map3DElement);

まず、要素を作成し、適切な位置情報パラメータを設定してから、ページにコンポーネントを追加します(既存の div がある場合は、そこに割り当てることもできます)。

コードは次のようになります。

<!DOCTYPE html>
<html>

<head>
    <title>3D Maps Codelab</title>
    <style>
        html,
        body {
            height: 100%;
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <script async defer>
        (g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
            key: "YOUR_API_KEY",
            v: "alpha",
        });
    </script>
    <script>
        async function init() {
            const { Map3DElement, MapMode } = await google.maps.importLibrary("maps3d");

            const map3DElement = new Map3DElement({
                center: { lat: 43.6425, lng: -79.3871, altitude: 400 },
                range: 1000,
                tilt: 60,
                mode: MapMode.HYBRID
            });

            document.body.append(map3DElement);
        }

        init();
    </script>
</body>
</html>

これで、ファイルを保存してブラウザでページを開き、動作を確認できます。画像のように、カメラがタワーを見下ろしている状態になります。遊んでみてから、タワーの上に箱を追加します。

最初に作成する地図。

6. 特徴を追加して押し出す

3D 地図が完成したので、オブジェクトをハイライトして、ユーザーに注目すべきアイテムであることを伝えましょう。この例では、ポリゴンと押し出し関数を使用して CN タワーの周囲にボックスを作成し、次のビューのようにします。

押し出しポリゴンが表示された場所のビュー。

不要なものを非表示にする

まず、スポットがオフになっていることに気づくと思います。この地図ではタワー自体にフォーカスを当てたいため、他の視覚的要素を削除する必要があります。

そのためには、ラベルを非表示にするコードを追加する必要があります。地図のモードラインを SATELLITE に更新して、ポイントを非表示にします。

  mode: MapMode.SATELLITE,

このプロパティを設定すると、地図上のラベル(スポットだけでなく、道路や境界線も含む)が無効になり、場所の「クリーンな」ビューが作成されます。

ポリゴンを追加してスタイルを設定する

次に、ポリゴンをページに追加します。これは 2 つのステップで行うことができます。まず、必要な情報が含まれている関数を読み込み、次にポリゴンのスタイル設定の詳細(色や他の対象物の背後に表示するかどうかなど)を指定する必要があります。

まず、次のコード行を使用して、必要なクラスをページに追加します。

  const { Polygon3DElement, AltitudeMode } = await google.maps.importLibrary("maps3d");

これにより、ポリゴン オブジェクトをビューに追加するために必要な Polygon3DElement クラスと AltitudeMode クラスがページに読み込まれます。

ポリゴンには、ストロークの太さ、色(名前または 16 進数値)、境界と塗りつぶしの不透明度、他の対象物や建物の背後に表示するかどうか(遮蔽されたセグメントの描画など)など、ビューを制御できるさまざまな設定があります。詳細については、Polygon3DElement クラスのドキュメントをご覧ください。

もう 1 つ設定する必要がある機能は、ポリゴンが押し出された状態で描画されるようにすることです。つまり、設定した標高でポリゴンを描画し、地面まで延長します。これにより、ポリゴンにボックスのような高さが付与されます(上の画像を参照)。また、ポリゴンに高度モードを設定する必要もあります。そのため、上記の AltitudeMode 定数を読み込む必要がありました。ポリゴンを押し出すには、ポリゴンの頂点の高さから正しい位置を取得するために、この値を ABSOLUTE または RELATIVE_TO_GROUND に設定する必要があります。

このコードは、これらのプロパティを含むリテラル オブジェクトを作成します。このオブジェクトは、次のように Polygon3DElement オブジェクトの作成に使用できます。

  const polygonOptions = {
    strokeColor: "#EA433580",
    strokeWidth: 4,
    fillColor: "#0000FF80",
    altitudeMode: "ABSOLUTE",
    extruded: true,
    drawsOccludedSegments: true,
  }

  const towerPolygon = new google.maps.maps3d.Polygon3DElement(polygonOptions);

ポリゴン オブジェクトが作成されたので、その地理座標も設定する必要があります。ポリゴンは、表現方法に応じて内側と外側の両方の座標を持つことができます。innerCoordinates はポリゴン内の切り抜きの形状を指定し、outerCoordinates はポリゴンの外側の境界を定義します。これは線ではなくポリゴンであるため、完全な形状にするには、座標の始点と終点が同じポイントである必要があります。

座標は、LatLng オブジェクトまたは LatLngAltitude オブジェクトの配列またはリテラルを使用して指定できます。これは、基本的なポリゴンで確認できます。

  towerPolygon.outerCoordinates = [
    { lat: 43.6427196, lng: -79.3876802, altitude: 600 },
    { lat: 43.6421742, lng: -79.3869184, altitude: 600 },
    { lat: 43.643001, lng: -79.3866475, altitude: 600 },
    { lat: 43.6427196, lng: -79.3876802, altitude: 600 }
  ];

ポリゴンのスタイルと座標を設定したので、ページに追加する準備ができました。ポリゴンは Map 要素の子要素であり、ページ内の既存の地図オブジェクトに追加する必要があります。ページに次のコードを追加します。

  map3DElement.append(towerPolygon);

これで、次のような完全な実装が完成します(ただし、独自の API キーが使用されます)。ページを実行して結果を確認する準備ができました。

<!DOCTYPE html>
<html>

<head>
    <title>3D Maps Codelab</title>
    <style>
        html,
        body {
            height: 100%;
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <script async defer>
        (g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
            key: "YOUR_API_KEY",
            v: "alpha",
        });
    </script>
    <script>
        async function init() {
            const { Map3DElement, MapMode } = await google.maps.importLibrary("maps3d");

            const map3DElement = new Map3DElement({
                center: { lat: 43.6425, lng: -79.3871, altitude: 400 },
                range: 1000,
                tilt: 60,
                mode: MapMode.SATELLITE,
            });

            const { Polygon3DElement, AltitudeMode } = await google.maps.importLibrary("maps3d");

            const polygonOptions = {
                strokeColor: "#EA433580",
                strokeWidth: 4,
                fillColor: "#0000FF80",
                fillOpacity: 0.2,
                altitudeMode: "ABSOLUTE",
                extruded: true,
                drawsOccludedSegments: true,
            }

            const towerPolygon = new google.maps.maps3d.Polygon3DElement(polygonOptions);

            towerPolygon.outerCoordinates = [
                { lat: 43.6427196, lng: -79.3876802, altitude: 600 },
                { lat: 43.6421742, lng: -79.3869184, altitude: 600 },
                { lat: 43.643001, lng: -79.3866475, altitude: 600 },
                { lat: 43.6427196, lng: -79.3876802, altitude: 600 }
            ];

            map3DElement.append(towerPolygon);

            document.body.append(map3DElement);
        }
        
        init();
    </script>

</body>
</html>

コードが正しいと、次の 3D 地図とポリゴンを含むページが表示されます。

コードが完成したときに表示されるビュー。

Google Maps Platform を使用して最初の 3D 地図を作成しました。Maps JavaScript API の読み込み、3D 地図の作成、押し出しポリゴンの追加を行いました。

7. 次のステップ

この Codelab では、Maps JavaScript API の基本的な機能について学習しました。次は、以下の機能を地図に追加してみましょう。

  • スポットのオン / オフを切り替えるボタンを追加します。
  • さまざまな場所との行き来を示すを追加します。
  • 境界制限を設定して、ユーザーがビューを移動できる範囲を制御します。
  • Maps JavaScript API のその他のライブラリで使用できるサービス(プレイスやルートなど)を確認する

Google Maps Platform とウェブ上の 3D を利用するその他の方法については、次のリンクをご覧ください。