Maps JavaScript API アプリケーションを v2 から v3 にアップグレードする

Maps JavaScript API v2 は、2021 年 5 月 26 日をもってご利用いただけなくなりました。その結果、サイト上の v2 のマップは機能しなくなり、JavaScript エラーが返されます。サイト上で地図を引き続き使用するには、Maps JavaScript API v3 に移行してください。このガイドでは、そのプロセスについて説明します。

概要

アプリケーションごとに移行プロセスは若干異なりますが、すべてのプロジェクトに共通する手順もあります。

  1. 新しいキーを入手します。Maps JavaScript API は、Google Cloud コンソールを使用してキーを管理するようになりました。v2 キーをまだ使用している場合は、移行を開始する前に新しい API キーを取得してください。
  2. API ブートストラップを更新します。ほとんどのアプリケーションでは、次のコードを使用して Maps JavaScript API v3 を読み込みます。
    <script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
  3. コードを更新します。必要な変更の量は、アプリケーションによって大きく異なります。一般的な変更点は次のとおりです。
    • 常に google.maps 名前空間を参照します。v3 では、すべての Maps JavaScript API コードがグローバル名前空間ではなく google.maps.* 名前空間に保存されます。このプロセスの一環として、ほとんどのオブジェクトの名前も変更されています。たとえば、GMap2 ではなく google.maps.Map を読み込むようになります。
    • 非推奨のメソッドへの参照をすべて削除します。GDownloadURLGLog など、汎用ユーティリティ メソッドがいくつか削除されました。この機能をサードパーティのユーティリティ ライブラリに置き換えるか、コードからこれらの参照を削除してください。
    • (省略可)コードにライブラリを追加します。多くの機能がユーティリティ ライブラリに外部化されているため、各アプリは使用する API の部分のみを読み込む必要があります。
    • (省略可)v3 外部関数を使用するようにプロジェクトを構成します。v3 外部関数は、Closure コンパイラでコードを検証したり、IDE で自動補完をトリガーしたりするために使用できます。詳しくは、 高度なコンパイルと外部関数をご覧ください。
  4. テストして繰り返す。この時点ではまだ作業が残っていますが、新しい v3 マップ アプリケーションの作成に向けて大きく前進しています。

Maps JavaScript API の v3 の変更点

移行を計画する前に、Maps JavaScript API v2 と Maps JavaScript API v3 の違いを理解しておく必要があります。最新バージョンの Maps JavaScript API は、最新の JavaScript プログラミング手法、ライブラリの使用の増加、API の簡素化に重点を置いてゼロから作成されています。API には多くの新機能が追加され、いくつかのよく知られた機能が変更または削除されました。このセクションでは、2 つのリリースの主な違いについて説明します。

v3 API の主な変更点は次のとおりです。

  • コア ライブラリを簡素化。補足機能の多くはライブラリに移動されました。これにより、Core API の読み込みと解析時間が短縮され、あらゆるデバイスで地図をすばやく読み込むことができます。
  • ポリゴンのレンダリングやマーカーの配置など、いくつかの機能のパフォーマンスが改善されました。
  • モバイル プロキシと企業のファイアウォールで使用される共有アドレスに対応した、クライアントサイドの使用上限の新しいアプローチ。
  • 複数の最新ブラウザとモバイル ブラウザのサポートを追加しました。Internet Explorer 6 のサポートは終了しました。
  • 汎用ヘルパー クラスの多く( GLog GDownloadUrl など)を削除しました。現在、ClosurejQuery など、同様の機能を提供する優れた JavaScript ライブラリが数多く存在します。
  • あらゆるモバイル端末でロードされる HTML5 ストリート ビューが実装されました。
  • 自分の写真を使ったカスタム ストリートビューのパノラマ。スキー場、売家、その他の興味深い場所のパノラマを共有できます。
  • スタイル付き地図のカスタマイズ: 基本地図上の要素の表示を変更して、独自の視覚スタイルに合わせて表示できます。
  • ElevationServiceDistance Matrix など、複数の新しいサービスのサポート。
  • 改良されたルート案内サービスでは、代替ルート、ルート最適化( 巡回セールスマン問題の近似解)、自転車ルート( 自転車レイヤを使用)、交通機関のルート、 ドラッグ可能なルートを提供します。
  • Geocoding API v2 の accuracy 値よりも正確なタイプ情報を提供する、更新されたジオコーディング形式。
  • 1 つの地図に複数の情報ウィンドウを表示する

アプリケーションのアップグレード

新しいキー

Maps JavaScript API v3 では、v2 の新しいキーシステムが使用されます。アプリケーションで v3 キーをすでに使用している場合は、変更する必要はありません。確認するには、Maps JavaScript API を読み込む URL で key パラメータを確認します。キー値が「ABQIAA」で始まる場合は、v2 キーを使用しています。v2 キーを使用している場合は、移行の一環として v3 キーにアップグレードする必要があります。これにより、次のことが可能になります。

キーは、Maps JavaScript API v3 の読み込み時に渡されます。API キーの生成の詳細

Google Maps API for Work をご利用の場合は、key パラメータではなく、client パラメータでクライアント ID を使用している可能性があります。クライアント ID は Maps JavaScript API v3 でも引き続きサポートされており、キーのアップグレード プロセスを行う必要はありません。

API の読み込み

コードに最初に行う必要がある変更は、API の読み込み方法に関するものです。v2 では、http://maps.google.com/maps へのリクエストを介して Maps JavaScript API を読み込みます。Maps JavaScript API v3 を読み込む場合は、次の変更を行う必要があります。

  1. //maps.googleapis.com/maps/api/js から API を読み込む
  2. file パラメータを削除します。
  3. 新しい v3 キーで key パラメータを更新します。Maps API for Work をご利用の場合は、client パラメータを使用する必要があります。
  4. (Google Maps Platform プレミアム プランのみ) Google Maps Platform プレミアム プラン デベロッパー ガイドに記載されているように、client パラメータが指定されていることを確認します。
  5. v パラメータを削除して最新のリリース バージョンをリクエストするか、v3 バージョニング スキームに応じてその値を変更します。
  6. (省略可)hl パラメータを language に置き換え、値を保持します。
  7. (省略可)libraries パラメータを追加して、オプションのライブラリを読み込みます。

最もシンプルなケースでは、v3 ブートストラップで API キー パラメータのみを指定します。

<script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>

次の例では、ドイツ語で Maps JavaScript API v2 の最新バージョンをリクエストします。

<script src="//maps.google.com/maps?file=api&v=2.x&key=YOUR_API_KEY&hl=de"></script>

次の例は、v3 の場合の同等のリクエストです。

<script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&language=de"></script>

google.maps 名前空間の導入

Maps JavaScript API v3 で最も大きな変更点は、google.maps 名前空間の導入です。v2 API はデフォルトですべてのオブジェクトをグローバル名前空間に配置するため、名前の競合が発生する可能性があります。v3 では、すべてのオブジェクトが google.maps Namespace 内に配置されます。

アプリケーションを v3 に移行する場合は、新しい名前空間を使用できるようにコードを変更する必要があります。残念ながら、「G」を検索して「google.maps」に置き換えるだけでは、完全には機能しませんが、コードを確認する際に適用する良い経験則です。v2 と v3 の同等クラスの例を以下に示します。

v2 v3
GMap2 google.maps.Map
GLatLng google.maps.LatLng
GInfoWindow google.maps.InfoWindow
GMapOptions google.map.MapOptions
G_API_VERSION google.maps.version
GPolyStyleOptions google.maps.PolygonOptions
or google.maps.PolylineOptions

廃止されたコードの削除

Maps JavaScript API v3 には、v2 のほとんどの機能に対応するクラスがありますが、サポートが終了したクラスもあります。移行の一環として、これらのクラスをサードパーティのユーティリティ ライブラリに置き換えるか、コードからこれらの参照を削除する必要があります。ClosurejQuery など、同様の機能を提供する優れた JavaScript ライブラリは数多く存在します。

次のクラスは、Maps JavaScript API v3 には対応していません。

GBoundsGLanguage
GBrowserIsCompatibleGLayer
GControlGLog
GControlAnchorGMercatorProjection
GControlImplGNavLabelControl
GControlPositionGObliqueMercator
GCopyrightGOverlay
GCopyrightCollectionGPhotoSpec
GDownloadUrlGPolyEditingOptions
GDraggableObjectGScreenOverlay
GDraggableObjectOptionsGStreetviewFeatures
GFactualGeocodeCacheGStreetviewLocation
GGeoAddressAccuracyGStreetviewOverlay
GGeocodeCacheGStreetviewUserPhotosOptions
GGoogleBarGTileLayerOptions
GGoogleBarAdsOptionsGTileLayerOverlayOptions
GGoogleBarLinkTargetGTrafficOverlayOptions
GGoogleBarListingTypesGUnload
GGoogleBarOptionsGXml
GGoogleBarResultListGXmlHttp
GInfoWindowTabGXslt
GKeyboardHandler

コードの比較

v2 API と v3 API で記述された 2 つの比較的シンプルなアプリを比較しましょう。

<!DOCTYPE html>
<html>
  <head>
    <script src="//maps.google.com/maps?file=api&v=2&key=YOUR_API_KEY"></script>
    <style>
      html, body, #map { height: 100%; margin: 0; }
    </style>
    <script>
    function initialize() {
      if (GBrowserIsCompatible()) {
        var map = new GMap2(
            document.getElementById('map'));
        map.setCenter(new GLatLng(37.4419, -122.1419), 13);
        map.setUIToDefault();

        map.addOverlay(new GMarker(new GLatLng(37.4419, -122.1419)));

      }
    }
    </script>
  </head>
  <body onload="initialize()" onunload="GUnload()">
    <div id="map"></div>
  </body>
</html>
    
<!DOCTYPE html>
<html>
  <head>
    <script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
    <style>
      html, body, #map { height: 100%; margin: 0; }
    </style>
    <script>
    function initialize() {
      var map = new google.maps.Map(
        document.getElementById('map'), {
          center: new google.maps.LatLng(37.4419, -122.1419),
          zoom: 13,
          mapTypeId: google.maps.MapTypeId.ROADMAP
      });

      var marker = new google.maps.Marker({
            position: new google.maps.LatLng(37.4419, -122.1419),
            map: map
      });

    }
    google.maps.event.addDomListener(window, 'load', initialize);
    </script>
  </head>
  <body>
    <div id="map"></div>
  </body>
</html>
    

ご覧のとおり、この 2 つのアプリケーションにはいくつかの違いがあります。主な変更点は、以下の通りです。

  • API のロード元のアドレスが変更されています。
  • GBrowserIsCompatible() メソッドと GUnload() メソッドは v3 では不要になり、API から削除されました。
  • GMap2 オブジェクトは、API の中心オブジェクトとして google.maps.Map に置き換えられました。
  • プロパティは、Options クラスを通じて読み込まれるようになりました。上記の例では、地図の読み込みに必要な 3 つのプロパティ(centerzoommapTypeId)を、インライン化された MapOptions オブジェクトを介して設定しています。
  • V3 では、デフォルト ユーザー インターフェースがデフォルトでオンになっています。これを無効にするには、MapOptions オブジェクトで disableDefaultUI プロパティを true に設定します。

概要

ここまでで、Maps JavaScript API の v2 から v3 への移行に関連する主なポイントを理解できたと思います。知っておく必要のある情報は他にもありますが、これはアプリケーションによって異なります。以降のセクションでは、発生する可能性のある特定のケースの移行手順について説明します。また、アップグレード プロセスで役立つリソースがいくつかあります。

この記事について問題やご不明な点がございましたら、このページの上部にある [フィードバックを送信] リンクを使用してお知らせください。

詳細な参照情報

このセクションでは、Maps JavaScript API の v2 と v3 の両方で最も一般的な機能の詳細な比較を行います。リファレンスの各セクションは、個別に読むように設計されています。このリファレンス全体を読むのではなく、ケースバイケースで移行に役立つ資料として使用することをおすすめします。

  • イベント: イベントの登録と処理を行います。
  • コントロール - 地図上に表示されるナビゲーション コントロールを操作します。
  • オーバーレイ - 地図上のオブジェクトの追加と編集。
  • マップタイプ - 基本地図を構成するタイル。
  • レイヤ - KML レイヤや交通レイヤなど、コンテンツをグループとして追加、編集します。
  • サービス - Google のジオコーディング、ルート検索、ストリートビュー サービスを使用する。

イベント

Maps JavaScript API v3 のイベントモデルは v2 で使用されているものと似ていますが、内部的には大幅に変更されています。

V3 API は、MVC の状態変化を反映する新しいタイプのイベントが追加されています。イベントには、以下の 2 つのタイプがあります。

  • ユーザー イベント(マウスの「クリック」イベントなど)。DOM から Maps JavaScript API に伝達されます。このイベントは、標準の DOM イベントとは異なる無関係のイベントです。
  • MVC の状態変化の通知は、Maps API オブジェクトの変化を反映しており、これには property_changed 規則に基づいて名前が付けられています。

各 Maps API オブジェクトは、いくつかの名前付きイベントをエクスポートします。特定のイベントに関心があるアプリケーションは、それらのイベントのイベント リスナーを登録し、それらのイベントを受信したときにコードを実行する必要があります。このイベントドリブン メカニズムは、名前空間が GEvent から google.maps.event に変更されたことを除き、Maps JavaScript API v2 と v3 の両方で同じです。

GEvent.addListener(map, 'click', function() {
  alert('You clicked the map.');
});
google.maps.event.addListener(map, 'click', function() {
  alert('You clicked the map.');
});

パフォーマンス上の理由から、不要になったイベント リスナーは削除することをおすすめします。イベント リスナーの削除は、v2 と v3 で同じ方法で行います。

  1. イベント リスナーを作成すると、不透明なオブジェクト(v2 では GEventListener、v3 では MapsEventListener)が返されます。
  2. イベント リスナーを削除する場合は、このオブジェクトを removeListener() メソッド(v2 では GEvent.removeListener()、v3 では google.maps.event.removeListener())に渡して、イベント リスナーを削除します。

DOM(ドキュメント オブジェクト モデル)イベントをキャプチャして応答する場合は、v2 の GEvent.addDomListener() メソッドと同等の google.maps.event.addDomListener() 静的メソッドが v3 で用意されています。

多くの場合、UI イベントはイベント引数を渡します。このイベント引数にイベント リスナーがアクセスできます。v3 のほとんどのイベント引数は、API 内のオブジェクトとの整合性を高めるために簡素化されました。(詳しくは、v3 リファレンスをご覧ください)。

v3 イベント リスナーには overlay 引数はありません。v3 マップ上に click イベントを登録すると、コールバックはユーザーがベースマップをクリックした場合にのみ発生します。クリック可能なオーバーレイでクリックに反応する必要がある場合は、追加のコールバックを登録できます。

// Passes an overlay argument when clicking on a map

var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(-25.363882, 131.044922), 4);
map.setUIToDefault();

GEvent.addListener(map,'click', function(overlay, latlng) {
  if (latlng) {
    var marker = new GMarker(latlng);
    map.addOverlay(marker);
  }
});
// Passes only an event argument

var myOptions = {
    center: new google.maps.LatLng(-25.363882, 131.044922),
    zoom: 4,
    mapTypeId: google.maps.MapTypeId.ROADMAP
};

var map = new google.maps.Map(document.getElementById('map'),
    myOptions);

google.maps.event.addListener(map, 'click', function(event) {
  var marker = new google.maps.Marker({
      position: event.latLng,
      map: map
  });
});

コントロール

Maps JavaScript API は、ユーザーが地図を操作できるようにする UI コントロールを表示します。API を使用して、これらのコントロールの表示方法をカスタマイズできます。

v3 API では、control 型にいくつかの変更が導入されています。

  1. v3 API は、地形地図やカスタム マップタイプの追加など、その他のマップタイプをサポートしています。
  2. v2 階層制御 GHierarchicalMapTypeControl は使用できなくなりました。google.maps.MapTypeControlStyle.HORIZONTAL_BAR コントロールを使用しても同様の効果が得られます。
  3. v2 の GMapTypeControl で提供される横向きレイアウトは、v3 では使用できません。

Maps JavaScript API v2 では、地図オブジェクトの addControl() メソッドを使用して地図にコントロールを追加します。v3 では、コントロールに直接アクセスまたは変更するのではなく、関連する MapOptions オブジェクトを変更します。次のサンプルは、地図をカスタマイズして次のコントロールを追加する方法を示しています。

  • 使用可能なマップタイプをユーザーが切り替えることができるボタン
  • マップの縮尺
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(-25.363882, 131.044922), 4);

// Add controls
map.addControl(new GMapTypeControl());
map.addControl(new GScaleControl());
var myOptions = {
    center: new google.maps.LatLng(-25.363882, 131.044922),
    zoom: 4,
    mapTypeId: google.maps.MapTypeId.ROADMAP,

    // Add controls
    mapTypeControl: true,
    scaleControl: true
};

var map = new google.maps.Map(document.getElementById('map'),
    myOptions);

V3 では、コントロールの配置方法が大きく変更されています。v2 では、addControl() メソッドに 2 つ目のパラメータを指定できます。このパラメータを使用すると、地図の角を基準としたコントロールの位置を指定できます。

v3 では、コントロール オプションの position プロパティを使用してコントロールの位置を設定します。これらのコントロールの配置は絶対的なものではありません。代わりに、地図サイズなどの与えられた制約の範囲内で、既存の地図要素の位置を考慮して、API によって適切に配置されます。これにより、デフォルトのコントロールがコントロールと互換性を持つようになります。 詳細については、v3 での位置決めの制御をご覧ください。

次のコードは、上のサンプルのコントロールを再配置します。

var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(-25.363882, 131.044922), 4);

// Add map type control
map.addControl(new GMapTypeControl(), new GControlPosition(
    G_ANCHOR_TOP_LEFT, new GSize(10, 10)));

// Add scale
map.addControl(new GScaleControl(), new GControlPosition(
    G_ANCHOR_BOTTOM_RIGHT, new GSize(20, 20)));
var myOptions = {
  center: new google.maps.LatLng(-25.363882, 131.044922),
  zoom: 4,
  mapTypeId: google.maps.MapTypeId.ROADMAP,

  // Add map type control
  mapTypeControl: true,
  mapTypeControlOptions: {
      style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
      position: google.maps.ControlPosition.TOP_LEFT
  },

  // Add scale
  scaleControl: true,
  scaleControlOptions: {
      position: google.maps.ControlPosition.BOTTOM_RIGHT
  }
};

var map = new google.maps.Map(document.getElementById('map'),
    myOptions);

Maps JavaScript API を使用すると、カスタムのナビゲーション コントロールを作成できます。v2 API でコントロールをカスタマイズするには、GControl クラスのサブクラスを作成し、initialize() メソッドと getDefaultPosition() メソッドのハンドラを定義します。v3 には GControl クラスに相当するものはありません。代わりに、コントロールは DOM 要素として表されます。v3 API を使用してカスタム コントロールを追加するには、コンストラクタで Node の子としてコントロールの DOM 構造を作成します(<div> 要素など)。また、DOM イベントを処理するイベント リスナーを追加します。Node を地図の controls[position] 配列にプッシュして、カスタム コントロールのインスタンスを地図に追加します。

上記のインターフェース要件に準拠する HomeControl クラスの実装を前提としています(詳細については、カスタム コントロールのドキュメントをご覧ください)。次のコードサンプルは、カスタム コントロールを地図に追加する方法を示しています。

map.addControl(new HomeControl(),
    GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10, 10)));
var homeControlDiv = document.createElement('DIV');
var homeControl = new HomeControl(homeControlDiv, map);

map.controls[google.maps.ControlPosition.TOP_RIGHT].push(
    homeControlDiv);

オーバーレイ

オーバーレイは、地図に「追加」してポイント、ライン、エリア、またはオブジェクトの集合を指定できるオブジェクトを表します。

Overlay で表されるオブジェクトのタイプは v2 と v3 で同じですが、処理方法は異なります。

v2 API では、GMap2 オブジェクトの addOverlay() メソッドと removeOverlay() メソッドを使用して、オーバーレイを地図に追加したり、地図から削除したりしていました。v3 では、関連するオーバーレイ オプション クラスの map プロパティを使用して、地図をオーバーレイに割り当てます。オーバーレイ オブジェクトの setMap() メソッドを呼び出して目的のマップを指定することで、オーバーレイを直接追加または削除することもできます。map プロパティを null に設定すると、オーバーレイが削除されます。

v3 には clearOverlays() メソッドはありません。複数のオーバーレイを同時に管理する場合は、配列を作成してオーバーレイを保持する必要があります。この配列を使用して、配列内の各オーバーレイで setMap() を呼び出すことができます(削除が必要な場合は null を渡します)。

デフォルトでは、マーカーはクリック可能ですが、ドラッグ可能ではありません。次の 2 つのサンプルでは、ドラッグ可能なマーカーを追加します。

var myLatLng = new GLatLng(-25.363882, 131.044922);
var map = new GMap2(document.getElementById('map'));
map.setCenter(myLatLng, 4);

var marker = new GMarker(latLng, {
  draggable: true
});
map.addOverlay(marker);
var myLatLng = new google.maps.LatLng(-25.363882, 131.044922);
var map = new google.maps.Map(
  document.getElementById('map'), {
  center: myLatLng,
  zoom: 4,
  mapTypeId: google.maps.MapTypeId.ROADMAP
});

var marker = new google.maps.Marker({
    position: myLatLng,
    draggable: true,
    map: map
});

デフォルトのマーカーの代わりに表示するカスタム アイコンを定義できます。v2 でカスタム イメージを使用するには、G_DEFAULT_ICON type から GIcon インスタンスを作成して変更します。画像がデフォルトのアイコンよりも大きい場合や小さい場合は、GSize インスタンスで指定する必要があります。v3 API では、このプロセスが少し簡素化されています。マーカーの icon プロパティにカスタム イメージの URL を設定すると、API によってアイコンのサイズが自動的に調整されます。

Maps JavaScript API では、複雑なアイコンもサポートされています。複雑なアイコンには、複数のタイルや複雑なシェイプを含めたり、他のオーバーレイに対して画像をどのように表示するかの「重ね順序」を指定したりできます。v2 でマーカーにシェイプを追加するには、各 GIcon インスタンスで追加のプロパティを指定し、これをオプションとして GMarker コンストラクタに渡す必要があります。v3 では、この方法で指定するアイコンには、icon プロパティを Icon タイプのオブジェクトに設定する必要があります。v3 では、マーカー シャドウはサポートされません。

次の例は、オーストラリアのボンダイビーチにあるビーチフラグを表示しています。アイコンの透明な部分はクリックできません。

var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(-25.363882, 131.044922), 4);
map.setUIToDefault();

var flagIcon = new GIcon(G_DEFAULT_ICON);
flagIcon.image = '/images/beachflag.png';
flagIcon.imageMap = [1, 1, 1, 20, 18, 20, 18 , 1];
var bbLatLng = new GLatLng(-33.890542, 151.274856);

map.addOverlay(new GMarker(bbLatLng, {
  icon: flagIcon
}));
var map = new google.maps.Map(
  document.getElementById('map'), {
  center: new google.maps.LatLng(-25.363882, 131.044922),
  zoom: 4,
  mapTypeId: google.maps.MapTypeId.ROADMAP
});

var shape = {
    coord: [1, 1, 1, 20, 18, 20, 18 , 1],
    type: 'poly'
};
var bbLatLng = new google.maps.LatLng(-33.890542, 151.274856);

var bbMarker = new google.maps.Marker({
    icon: '/images/beachflag.png'
    shape: shape,
    position: bbLatLng,
    map: map
});

ポリラインは、LatLng の配列と、それらの位置を順序付けされた順序で接続する一連の線分で構成されます。v3 で Polyline オブジェクトを作成して表示する方法は、v2 で GPolyline オブジェクトを使用する方法と似ています。次のサンプルは、チューリッヒからシンガポールを経由してシドニーまでの半透明の 3 ピクセル幅の測地線ポリラインを描画します。

var polyline = new GPolyline(
  [
    new GLatLng(47.3690239, 8.5380326),
    new GLatLng(1.352083, 103.819836),
    new GLatLng(-33.867139, 151.207114)
  ],
  '#FF0000', 3, 0.5, {
  geodesic: true
});

map.addOverlay(polyline);
var polyline = new google.maps.Polyline({
  path: [
    new google.maps.LatLng(47.3690239, 8.5380326),
    new google.maps.LatLng(1.352083, 103.819836),
    new google.maps.LatLng(-33.867139, 151.207114)
  ],
  strokeColor: '#FF0000',
  strokeOpacity: 0.5,
  strokeWeight: 3,
  geodesic: true
});

polyline.setMap(map);

エンコード済みポリライン

v3 では、エンコードされたポリラインから Polyline オブジェクトを直接作成することはできません。代わりに、ジオメトリ ライブラリには、ポリラインをエンコードおよびデコードするメソッドが用意されています。このライブラリを読み込む方法について詳しくは、v3 Maps API のライブラリをご覧ください。

以下の例は、同じエンコードされたポリラインを描画します。v3 コードは、google.maps.geometry.encoding 名前空間の decodePath() メソッドを使用します。

var polyline = new GPolyline.fromEncoded({
  points: 'kwb`Huqbs@ztzwGgvpdQbw}uEoif`H',
  levels: 'PPP',
  zoomFactor: 2,
  numLevels: 18,
  color: '#ff0000',
  opacity: 0.8,
  weight: 3
});

map.addOverlay(polyline);
var polyline = new google.maps.Polyline({
  path: google.maps.geometry.encoding.decodePath(
    'kwb`Huqbs@ztzwGgvpdQbw}uEoif`H'),
  strokeColor: '#FF0000',
  strokeOpacity: 0.5,
  strokeWeight: 3,
});

polyline.setMap(map);

ポリゴンは、閉ループ内の領域を定義します。Polyline オブジェクトと同様に、Polygon オブジェクトは、指定された順序の一連の点で構成されます。v3 の Polygon クラスは v2 の GPolygon クラスとほとんど同じですが、ループを閉じるためにパスの末尾で開始頂点を繰り返す必要がなくなった点が異なります。v3 API では、最後の座標から最初の座標に接続するストロークを描画して、ポリゴンを自動的に閉じます。次のコード スニペットは、バミューダ トライアングルを表すポリゴンを作成します。

var map = new GMap2(document.getElementById('map'));

map.setCenter(new GLatLng(24.886436, -70.268554), 5);

var bermudaTriangle = new GPolygon(
  [
    new GLatLng(25.774252, -80.190262),
    new GLatLng(18.466465, -66.118292),
    new GLatLng(32.321384, -64.75737),
    new GLatLng(25.774252, -80.190262)
  ],
  '#FF0000', 2, 0.8, '#FF0000', 0.35);

map.addOverlay(bermudaTriangle);
var map = new google.maps.Map(document.getElementById('map'), {
  center: new google.maps.LatLng(24.886436, -70.268554),
  mapTypeId: google.maps.MapTypeId.TERRAIN,
  zoom: 5
});

var bermudaTriangle = new google.maps.Polygon({
  paths: [
    new google.maps.LatLng(25.774252, -80.190262),
    new google.maps.LatLng(18.466465, -66.118292),
    new google.maps.LatLng(32.321384, -64.75737)
  ],
  strokeColor: '#FF0000',
  strokeWeight: 2,
  strokeOpacity: 0.8,
  fillColor: '#FF0000',
  fillOpacity: 0.35
});

bermudaTriangle.setMap(map);

ポリラインとポリゴンは、ユーザーによる編集を可能にすることができます。次のコード スニペットは同等です。

map.addOverlay(polyline);
polyline.enableEditing();
polyline.setMap(map);
polyline.setEditable(true);

高度な描画機能については、v3 ドキュメントの描画ライブラリをご覧ください。

InfoWindow は、地図の上にフローティング ウィンドウでコンテンツを表示します。v2 と v3 の情報ウィンドウには、いくつかの重要な違いがあります。

  • v2 API は地図ごとに GInfoWindow のみをサポートしますが、v3 API は各地図で複数の InfoWindow を同時にサポートします。
  • 地図をクリックしても、v3 の InfoWindow は開いたままになります。v2 GInfoWindow は、地図をクリックすると自動的に閉じます。v2 の動作をエミュレートするには、Map オブジェクトに click リスナーを追加します。
  • v3 API では、タブ形式の InfoWindow はネイティブでサポートされていません。

地図上に画像を配置するには、GroundOverlay オブジェクトを使用する必要があります。GroundOverlay のコンストラクタは、v2 と v3 で基本的に同じです。画像の URL と画像の境界をパラメータとして指定します。

次の例では、ニュージャージー州ニューアークの古い地図をオーバーレイとして地図に配置します。

var bounds = new GLatLngBounds(
    new GLatLng(40.716216, -74.213393),
    new GLatLng(40.765641, -74.139235));

var overlay = new GGroundOverlay(
    'http://lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
    bounds);

map.addOverlay(overlay);
var bounds = new google.maps.LatLngBounds(
    new google.maps.LatLng(40.716216, -74.213393),
    new google.maps.LatLng(40.765641, -74.139235));

var overlay = new google.maps.GroundOverlay(
    'http://lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
    bounds);

overlay.setMap(map);

マップタイプ

v2 と v3 で使用できる地図の種類は若干異なりますが、基本的な地図タイプはどちらのバージョンの API でも使用できます。デフォルトでは、v2 は標準の「ペイントされた」道路地図タイルを使用します。ただし、v3 では、google.maps.Map オブジェクトを作成するときに特定のマップタイプを指定する必要があります。

v2 および v3 では、次の 4 つの基本マップタイプを使用できます。

  • MapTypeId.ROADMAPG_NORMAL_MAP に代わる): 道路地図ビューを表示します。
  • MapTypeId.SATELLITEG_SATELLITE_MAP に代わる): Google Earth の衛星画像を表示します。
  • MapTypeId.HYBRIDG_HYBRID_MAP に代わる)は、通常ビューと衛星画像ビューの複合ビューを表示します。
  • MapTypeId.TERRAING_PHYSICAL_MAP に代わる)は、地形情報に基づいた物理地図を表示します。

次に、マップを地形ビューに設定している v2 と v3 の例を示します。

map.setMapType(G_PHYSICAL_MAP);
    
map.setMapTypeId(google.maps.MapTypeId.TERRAIN);
    

Maps JavaScript API v3 では、あまり一般的でない地図タイプにもいくつかの変更が加えられています。

  • 地球以外の天体のマップタイルは、v3 API では地図タイプとして使用できませんが、こちらの例に示すように、カスタムの地図タイプとしてアクセスできます。
  • v2 の G_SATELLITE_3D_MAP タイプに代わる特別なマップタイプは v3 にはありません。代わりに、このライブラリを使用して、Google Earth プラグインを v3 マップに統合できます。

航空写真の場合、高いズーム レベルが利用できるとは限りませんズームレベルを設定する前に、使用可能な最大ズームレベルを確認したい場合は、google.maps.MaxZoomService クラスを使用します。このクラスは、v2 の GMapType.getMaxZoomAtLatLng() メソッドに代わるものです。

var point = new GLatLng(
    180 * Math.random() - 90, 360 * Math.random() - 180);
var map = new GMap2(document.getElementById("map"));
map.setUIToDefault();
map.setCenter(point);
map.setMapType(G_HYBRID_MAP);

map.getCurrentMapType().getMaxZoomAtLatLng(point,
  function(response) {
    if (response.status) {
      map.setZoom(response.zoom);
    } else {
      alert("Error in Max Zoom Service.");
    }
});
var myLatlng = new google.maps.LatLng(
    180 * Math.random() - 90, 360 * Math.random() - 180);
var map = new google.maps.Map(
  document.getElementById("map"),{
    zoom: 0,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.HYBRID
});
var maxZoomService = new google.maps.MaxZoomService();
maxZoomService.getMaxZoomAtLatLng(
  myLatlng,
  function(response) {
    if (response.status == google.maps.MaxZoomStatus.OK) {
      map.setZoom(response.zoom);
    } else {
      alert("Error in Max Zoom Service.");
    }
});

v3 で航空写真を有効にすると、コントロールは v2 の GLargeZoomControl3D コントロールに似ていますが、サポートされている方向に回転するためのインタースティシャル ローテーション コントロールが追加されています。

45 度画像が現在利用可能な都市は、こちらの地図で確認できます。45° の画像が利用可能な場合、Maps API の「衛星」ボタンにサブメニュー オプションが追加されます。

レイヤ

レイヤは、1 つ以上のオーバーレイで構成される地図上のオブジェクトです。これらは 1 つの単位として操作でき、通常はオブジェクトのコレクションを反映します。

V3 API は、さまざまなレイヤに対するアクセスを可能にします。これらのレイヤは、次の領域で v2 GLayer クラスと重複しています。

  • KmlLayer オブジェクトは、KML 要素と GeoRSS 要素を v3 オーバーレイにレンダリングし、v2 GeoXml レイヤと同等の機能を提供します。
  • TrafficLayer オブジェクトは、v2 GTrafficOverlay オーバーレイと同様に、交通状況を示すレイヤをレンダリングします。

各レイヤは、V2 とは異なります。相違点は次のとおりです。setMap() を呼び出して、レイヤを表示する Map オブジェクトを渡すことで、地図に追加できます。

サポートされているレイヤの詳細については、レイヤのドキュメントをご覧ください。

Maps JavaScript API は、地理情報を表示するために KML および GeoRSS のデータ形式をサポートしています。KML ファイルまたは GeoRSS ファイルを地図に含める場合は、一般公開されている必要があります。v3 では、これらのデータ形式は KmlLayer のインスタンスを使用して表示されます。これは、v2 の GGeoXml オブジェクトに代わるものです。

v3 API は KML のレンダリング時に柔軟性があり、InfoWindow を抑制したり、クリック レスポンスを変更したりできます。詳細については、V3 の KML レイヤと GeoRSS レイヤのドキュメントをご覧ください。

KmlLayer をレンダリングする場合、サイズと複雑さに関する制限が適用されます。詳細については、KmlLayer のドキュメントをご覧ください。

次のサンプルは、KML ファイルをロードする方法を比較しています。

geoXml = new GGeoXml(
  'https://googlearchive.github.io/js-v2-samples/ggeoxml/cta.kml');

map.addOverlay(geoXml);
var layer = new google.maps.KmlLayer(
  'https://googlearchive.github.io/js-v2-samples/ggeoxml/cta.kml', {
    preserveViewport: true
});
layer.setMap(map);

v3 では、TrafficLayer オブジェクトを使用してリアルタイムの交通情報(対象地域に限る)を地図に追加できます。交通情報は、リクエストが行われた時点の情報です。次の例は、ロサンゼルスの交通情報を示しています。

var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(34.0492459, -118.241043), 13);
map.setUIToDefault();

var trafficOptions = {incidents:false};
trafficInfo = new GTrafficOverlay(trafficOptions);
map.addOverlay(trafficInfo);
var map = new google.maps.Map(
    document.getElementById('map'), {
  center: new google.maps.LatLng(34.0492459, -118.241043),
  mapTypeId: google.maps.MapTypeId.ROADMAP,
  zoom: 13
});

var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);

v2 とは異なり、v3 の TrafficLayer コンストラクタにはオプションがありません。インシデントは v3 では使用できません。

サービス

Maps JavaScript API には、ユーザー入力から動的に住所をジオコーディングするための geocoder オブジェクトが用意されています。既知の住所を静的にジオコーディングしたい場合は、Geocoding API のドキュメントをご覧ください。

Geocoding API が大幅にアップグレードされ、新機能が追加され、データの表現方法が変更されました。

v2 API の GClientGeocoder には、前方ジオコーディングと逆方向ジオコーディングの 2 つの異なるメソッドと、ジオコーディングの実行方法に影響する追加のメソッドが用意されていました。一方、v3 の Geocoder オブジェクトは geocode() メソッドのみを提供します。このメソッドは、入力語句を含むオブジェクト リテラル(ジオコーディング リクエスト オブジェクトの形式)とコールバック メソッドを受け取ります。リクエストにテキスト形式の address 属性が含まれているか、LatLng オブジェクトが含まれているかに応じて、Geocoding API は順方向または逆方向のジオコーディング レスポンスを返します。ジオコーディング リクエストに追加のフィールドを渡すことで、ジオコーディングの実行方法に影響を与えることができます。

  • テキスト形式の address を含めると、getLatLng() メソッドを呼び出す場合と同様に、前方ジオコーディングがトリガーされます。
  • latLng オブジェクトを含めると、getLocations() メソッドを呼び出すのと同じようにリバース ジオコーディングがトリガーされます。
  • bounds 属性を含めると、ビューポート バイアスが有効になります。これは、setViewport() メソッドを呼び出す場合と同じです。
  • region 属性を含めると、リージョン コードのバイアスが有効になります。これは、setBaseCountryCode() メソッドを呼び出す場合と同じです。

v3 のジオコーディング レスポンスは、v2 レスポンスと大きく異なります。v3 API では、v2 で使用されているネストされた構造を、解析が容易なフラットな構造に置き換えています。さらに、v3 レスポンスはより詳細です。各結果には、各結果の解決策を把握するのに役立ついくつかのアドレス コンポーネントがあります。

次のコードは、テキスト形式のアドレスを受け取り、ジオコーディングの結果の最初の結果を表示します。

var geocoder = new GClientGeocoder();
var infoPanel;
var map;
var AccuracyDescription = [
  'Unknown accuracy', 'country level accuracy',
  'region level accuracy', 'sub-region level accuracy',
  'town level accuracy', 'post code level accuracy',
  'street level accuracy', 'intersection level accuracy',
  'address level accuracy', 'premise level accuracy',
];

function geocode_result_handler(response) {
  if (!response || response.Status.code != 200) {
    alert('Geocoding failed. ' + response.Status.code);
  } else {
    var bounds = new GLatLngBounds(new GLatLng(
        response.Placemark[0].ExtendedData.LatLonBox.south,
        response.Placemark[0].ExtendedData.LatLonBox.west
    ), new GLatLng(
        response.Placemark[0].ExtendedData.LatLonBox.north,
        response.Placemark[0].ExtendedData.LatLonBox.east
    ));
    map.setCenter(bounds.getCenter(),
        map.getBoundsZoomLevel(bounds));
    var latlng = new GLatLng(
        response.Placemark[0].Point.coordinates[1],
        response.Placemark[0].Point.coordinates[0]);
    infoPanel.innerHTML += '<p>1st result is <em>' +
        // No info about location type
        response.Placemark[0].address +
        '</em> of <em>' +
        AccuracyDescription[response.Placemark[0].
            AddressDetails.Accuracy] +
        '</em> at <tt>' + latlng + '</tt></p>';
    var marker_title = response.Placemark[0].address +
        ' at ' + latlng;
    map.clearOverlays();

    var marker = marker = new GMarker(
        latlng,
        {'title': marker_title}
    );
    map.addOverlay(marker);
  }
}

function geocode_address() {
  var address = document.getElementById('input-text').value;
  infoPanel.innerHTML = '<p>Original address: ' + address + '</p>';
  geocoder.getLocations(address, geocode_result_handler);
}

function initialize() {
  map = new GMap2(document.getElementById('map'));
  map.setCenter(new GLatLng(38, 15), 2);
  map.setUIToDefault();

  infoPanel = document.getElementById('info-panel');
}
var geocoder = new google.maps.Geocoder();
var infoPanel;
var map;
var marker;

function geocode_result_handler(result, status) {
  if (status != google.maps.GeocoderStatus.OK) {
    alert('Geocoding failed. ' + status);
  } else {
    map.fitBounds(result[0].geometry.viewport);
    infoPanel.innerHTML += '<p>1st result for geocoding is <em>' +
        result[0].geometry.location_type.toLowerCase() +
        '</em> to <em>' +
        result[0].formatted_address + '</em> of types <em>' +
        result[0].types.join('</em>, <em>').replace(/_/, ' ') +
        '</em> at <tt>' + result[0].geometry.location +
        '</tt></p>';
    var marker_title = result[0].formatted_address +
        ' at ' + latlng;
    if (marker) {
      marker.setPosition(result[0].geometry.location);
      marker.setTitle(marker_title);
    } else {
      marker = new google.maps.Marker({
        position: result[0].geometry.location,
        title: marker_title,
        map: map
      });
    }
  }
}

function geocode_address() {
  var address = document.getElementById('input-text').value;
  infoPanel.innerHTML = '<p>Original address: ' + address + '</p>';
  geocoder.geocode({'address': address}, geocode_result_handler);
}

function initialize() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: new google.maps.LatLng(38, 15),
    zoom: 2,
    mapTypeId: google.maps.MapTypeId.HYBRID
  });
  infoPanel = document.getElementById('info-panel');
}

Maps JavaScript API v3 では、ルートの計算に v2 の GDirections クラスではなく DirectionsService クラスが使用されます。

v3 の route() メソッドは、v2 API の load() メソッドと loadFromWaypoints() メソッドの両方を置き換えます。このメソッドは、入力語句を含む DirectionsRequest オブジェクト リテラルと、レスポンスの受信時に実行するコールバック メソッドを受け取ります。オプションは、v2 の GDirectionsOptions オブジェクト リテラルと同様に、このオブジェクト リテラルで指定できます。

Maps JavaScript API v3 では、ルート リクエストの送信タスクがリクエストのレンダリング タスクから分離され、DirectionsRenderer クラスで処理されるようになりました。DirectionsRenderer オブジェクトを任意の地図または DirectionsResult オブジェクトに関連付けるには、setMap() メソッドと setDirections() メソッドを使用します。レンダラは MVCObject であるため、プロパティへの変更がある場合は検出し、関連付けられたルートが変更されると地図を更新します。

次のコードは、住所から自転車道を使用して特定の場所までの徒歩ルートをリクエストする方法を示しています。なお、ダブリンの動物園の歩道を案内できるのは v3 のみです。

var map;
var directions;
var directionsPanel;

function initialize() {
  var origin = new google.maps.LatLng(53.348172, -6.297285);
  var destination = new google.maps.LatLng(53.355502, -6.30557);
  directionsPanel = document.getElementById("route");

  map = new GMap2(document.getElementById('map'));
  map.setCenter(origin, 10);
  map.setUIToDefault();

  directions = new GDirections(map, directionsPanel);

  directions.loadFromWaypoints(
      [origin, destination], {
        travelMode: 'G_TRAVEL_MODE_WALKING',
  });
}
var map;
var directionsRenderer;
var directionsService = new google.maps.DirectionsService();

function initialize() {
  var origin = new google.maps.LatLng(53.348172, -6.297285);
  var destination = new google.maps.LatLng(53.355502, -6.30557);
  directionsRenderer = new google.maps.DirectionsRenderer();

  map = new google.maps.Map(
      document.getElementById('map'), {
        center: origin,
        zoom: 10,
        mapTypeId: google.maps.MapTypeId.ROADMAP
  });

  directionsRenderer.setPanel(document.getElementById("route"));
  directionsRenderer.setMap(map);
  directionsService.route({
    origin: origin,
    destination: destination,
    travelMode: google.maps.DirectionsTravelMode.WALKING
  }, function(result, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsRenderer.setDirections(result);
    }
  });
}

Google ストリートビューは、対象地域内の指定された場所からのインタラクティブな 360 度ビューを提供します。v3 API は、ストリートビュー画像を表示するために Flash® プラグインを必要とする v2 とは異なり、ブラウザ内でネイティブにストリートビューをサポートしています。

ストリートビュー画像は、v3 の StreetViewPanorama オブジェクトまたは v2 の GStreetviewPanorama オブジェクトを使用することでサポートされます。これらのクラスはインターフェースが異なりますが、div コンテナをストリートビュー画像に接続し、ストリートビューのパノラマの位置と視点(POV)を指定するという同じ役割を果たします。

function initialize() {
  var fenwayPark = new GLatLng(42.345573, -71.098326);
  panoramaOptions = {
    latlng: fenwayPark,
    pov: {
      heading: 35,
      pitch: 5,
      zoom: 1
    }
  };

  var panorama = new GStreetviewPanorama(
      document.getElementById('pano'),
      panoramaOptions);

  GEvent.addListener(myPano, "error", handleNoFlash);
}

function handleNoFlash(errorCode) {
  if (errorCode == FLASH_UNAVAILABLE) {
    alert('Error: Your browser does not support Flash');
    return;
  }
}
function initialize() {
  var fenway = new google.maps.LatLng(42.345573, -71.098326);
  var panoramaOptions = {
    position: fenway,
    pov: {
      heading: 35,
      pitch: 5,
      zoom: 1
    }
  };

  var panorama = new google.maps.StreetViewPanorama(
      document.getElementById('pano'),
      panoramaOptions);
}

ストリートビュー データに直接アクセスするには、v3 の StreetViewService オブジェクトまたは v2 の類似の GStreetviewClient オブジェクトを使用します。どちらも、ストリートビュー データの取得や利用可否の確認、場所またはパノラマ ID による検索を行うための類似のインターフェースを提供します。

V3 では、ストリートビューはデフォルトで有効になっています。地図にストリートビューのペグマン コントロールが表示され、API は地図 div を再利用してストリートビューのパノラマを表示します。次のコードは、ストリートビューのパノラマを別の div に分割して v2 の動作をエミュレートする方法を示しています。

var marker;
var panoClient = new GStreetviewClient();

function initialize() {
  if (GBrowserIsCompatible()) {
    var myPano = new GStreetviewPanorama(
        document.getElementById('pano'));
    GEvent.addListener(myPano, 'error', handleNoFlash);
    var map = new GMap2(document.getElementById('map'));
    map.setCenter(new GLatLng(42.345573, -71.098326), 16);
    map.setUIToDefault();

    GEvent.addListener(map, 'click', function(overlay, latlng) {
      if (marker) {
        marker.setLatLng(latlng);
      } else {
        marker = new GMarker(latlng);
        map.addOverlay(marker);
      }
      var nearestPano = panoClient.getNearestPanorama(
          latlng, processSVData);
    });

    function processSVData(panoData) {
      if (panoData.code != 200) {
        alert("Panorama data not found for this location.");
      }
      var latlng = marker.getLatLng();
      var dLat = latlng.latRadians()
          - panoData.location.latlng.latRadians();
      var dLon = latlng.lngRadians()
          - panoData.location.latlng.lngRadians();
      var y = Math.sin(dLon) * Math.cos(latlng.latRadians());
      var x = Math.cos(panoData.location.latlng.latRadians()) *
              Math.sin(latlng.latRadians()) -
              Math.sin(panoData.location.latlng.latRadians()) *
              Math.cos(latlng.latRadians()) * Math.cos(dLon);
      var bearing = Math.atan2(y, x) * 180 / Math.PI;

      myPano.setLocationAndPOV(panoData.location.latlng, {
        yaw: bearing
      });
    }

    function handleNoFlash(errorCode) {
      if (errorCode == FLASH_UNAVAILABLE) {
        alert('Error: Your browser does not support Flash');
        return;
      }
    }
  }
}
// Load the API with libraries=geometry
var map;
var marker;
var panorama;
var sv = new google.maps.StreetViewService();

function radians(degrees) { return Math.PI * degrees / 180.0 };

function initialize() {

  panorama = new google.maps.StreetViewPanorama(
      document.getElementById("pano"));

  map = new google.maps.Map(
      document.getElementById('map'), {
    center: new google.maps.LatLng(42.345573, -71.098326),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    zoom: 16
  });

  google.maps.event.addListener(map, 'click', function(event) {
    if (!marker) {
      marker = new google.maps.Marker({
          position: event.latLng,
          map: map
      });
    } else {
      marker.setPosition(event.latLng);
    }
    sv.getPanoramaByLocation(event.latLng, 50, processSVData);
  });
}

function processSVData(panoData, status) {
  if (status == google.maps.StreetViewStatus.OK) {
    alert("Panorama data not found for this location.");
  }
  var bearing = google.maps.geometry.spherical.computeHeading(
      panoData.location.latLng, marker.getPosition());

  panorama.setPano(panoData.location.pano);

  panorama.setPov({
    heading: bearing,
    pitch: 0,
    zoom: 1
  });

  panorama.setVisible(true);
  marker.setMap(panorama);
}