.NET TIPS

[ASP.NET AJAX]Googleマップを操作するには?[2.0、3.0、3.5、C#、VB]

山田 祥寛
2008/06/19

 Googleマップとは、いわずと知れたGoogleが提供する地図サービスである。Ajax普及のきっかけともなったアプリケーションであり、Ajaxアプリケーションの例として紹介されることも多いことから、読者諸氏も(おそらくは)実際に触れたことがあるはずだ。

 本稿では、このGoogleマップを、ASP.NET AJAXアプリケーションから操作する方法について紹介する。

●Google Maps APIについて

 Google Maps APIは、名前のとおり、Googleマップを外部アプリケーションから利用するためのライブラリである。本稿では、このGoogle Maps APIを利用して、リストボックスから選択された地点の地図を表示するとともに、該当する

 地点の詳細をバルーン表示するようなWebページを作成してみよう。

この際、地点情報の取得から地図の移動、バルーン表示までを、ASP.NET AJAXのブリッジ機能を使って実装するものとする。ブリッジ機能そのものに関する詳細は、「TIPS:Webサービス・ブリッジ機能により構造化データを受け渡しするには?(基本編)」などが詳しいので、こちらも併せてご参照いただきたい。

 次の画面は、実際にリストボックスから地点を選択し、その地点の地図と詳細情報を示すバルーンを表示しているところだ。

左のリストボックスから地点を選択する
リストボックスで選択した地点の情報をバルーン表示

 Google Maps APIを利用するには、あらかじめ本家サイトからアプリケーション識別のためのAPIキーを取得しておく必要がある。キー取得に際しては、Google Maps APIを利用するサイトのURL(例えば、「http://localhost:8080」など)を指定する必要がある。ここで指定したURLと実際にアプリケーションを動作するURLとが異なる場合、Google Maps APIは正しく動作しないので、要注意だ。

 次の画面はAPIキーを取得している例である。

[利用規約に同意します]にチェックを入れ、
[ウェブサイトの URL]にGoogle Maps APIを利用するサイトのURLを指定、
最後に[APIキーを生成]ボタンをクリックする
APIキーの取得例

 [APIキーを生成]ボタンをクリックすると、APIキーとGoogleマップを表示するために最低限必要なコードが表示される(*1)。

 取りあえずここでは、このコードの中から以下のような<script>タグの部分だけをどこかに控えておこう。src属性に記載されているのが、Google Maps APIを呼び出すためのURL(とライセンス・キー)となるものである。

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAFJNqs5yK0cFCLVsP36tpABTwM0brOpm-All5BF6PoaKBxRWWERTXIelDS4kW51ddR8qrLvv48fvtUw" type="text/javascript"></script>
Googleマップを表示するために最低限必要なコードの<script>タグの部分

*1 Googleアカウントでログインしていない場合には、ここでログインを求められるはずだ。もしもアカウントを所有していない場合には、新規にアカウントを作成する必要がある。

●サンプル・アプリケーション実装の手順

 以上で、Google Maps APIを利用するための準備は完了だ。ここからは、サンプル・アプリケーションを実装するための手順を見ていくことにしよう。なお、本サンプル・プログラムを動作させるに当たっては、「DBプログラミング 7つのヒント − 同時実行制御からASP.NET AJAXまで −」の内容に従って、ASP.NET AJAXをインストールしておく必要がある(*2)。

*2 ただし、ASP.NET 3.5ではASP.NET AJAXは標準で搭載されているので、追加インストールは不要。

1. 地点情報テーブルを用意する

 本稿のサンプルを動作させるには、あらかじめデータベース上に以下のようなMapinfoテーブルを作成しておく必要がある。

フィールド名 データ型 概要
mid INT 地点コード(主キー)
place VARCHAR(50) 地名
url VARCHAR(255) 詳細情報を表すURL
longitude FLOAT 経度
latitude FLOAT 緯度
memo VARCHAR(255) 備考
Mapinfoテーブルのフィールド・レイアウト

 また、このMapInfoテーブルにはあらかじめ適当な地点情報を入力しておく必要がある。

2. 新規のXML Webサービス・クラスを定義する

 ASP.NET AJAXのブリッジ機能においてサーバサイドの機能を提供するのは、.asmxファイル(=XML Webサービス・クラス)の役割だ。

 ここでは、クライアントから送信された地点コード(midパラメータ)をキーにMapinfoテーブルを検索し、合致した地点情報をMapInfoオブジェクトとして返すXML Webサービス・クラス(GoogleMap.asmx)を定義してみよう。GoogleMap.asmxの具体的なコードは、以下のとおり。

<%@ WebService Language="C#" Class="GoogleMap" %>

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService()]
public class GoogleMap  : System.Web.Services.WebService {

  [WebMethod()]
  public MapInfo GetMapInfo(String mid) {

    MapInfo info = new MapInfo();
    ConnectionStringSettings setting =
      ConfigurationManager.ConnectionStrings["MyDB"];
    DbProviderFactory factory =
      DbProviderFactories.GetFactory(setting.ProviderName);

    using (DbConnection db = factory.CreateConnection()) {

      db.ConnectionString = setting.ConnectionString;
      DbCommand comm = factory.CreateCommand();

      // midパラメータをキーに住所情報を検索
      comm.CommandText = "SELECT * FROM Mapinfo WHERE mid=@mid";
      comm.Connection = db;
      DbParameter param = factory.CreateParameter();
      param.ParameterName = "@mid";
      param.Value = mid;
      comm.Parameters.Add(param);
      db.Open();
      DbDataReader reader = comm.ExecuteReader();

      // 結果セットから必要な情報をMapInfoオブジェクトに詰め替え
      if (reader.Read()) {
          info.Place = reader["place"].ToString();
          info.Url = reader["url"].ToString();
          info.Longitude = reader["longitude"].ToString();
          info.Latitude = reader["latitude"].ToString();
          info.Memo = reader["memo"].ToString();
      } else {
          throw new Exception("該当するデータが存在しません。");
      }
    }
    return info;
  }
}

// 地点情報を表すMapInfoクラスを定義
public class MapInfo {
  public String Place;
  public String Url;
  public String Longitude;
  public String Latitude;
  public String Memo;
}
<%@ WebService Language="VB" Class="GoogleMap" %>

Imports System.Collections.Generic
Imports System.Data
Imports System.Data.Common
Imports System.Web
Imports System.Web.Script.Services
Imports System.Web.Services
Imports System.Web.Services.Protocols

<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ScriptService()> _
Public Class GoogleMap
  Inherits System.Web.Services.WebService
 
  <WebMethod()> _
  Public Function GetMapInfo(ByVal mid As String) As MapInfo

    Dim info As New MapInfo()
    Dim setting As ConnectionStringSettings = _
      ConfigurationManager.ConnectionStrings("MyDB")
    Dim factory As DbProviderFactory = _
      DbProviderFactories.GetFactory(setting.ProviderName)

    Using db As DbConnection = factory.CreateConnection()

      db.ConnectionString = setting.ConnectionString
      Dim comm As DbCommand = factory.CreateCommand()

       ' midパラメータをキーに住所情報を検索
      comm.CommandText = "SELECT * FROM Mapinfo WHERE mid=@mid"
      comm.Connection = db
      Dim param As DbParameter = factory.CreateParameter()
      param.ParameterName = "@mid"
      param.Value = mid
      comm.Parameters.Add(param)
      db.Open()
      Dim reader As DbDataReader = comm.ExecuteReader()

      ' 結果セットから必要な情報をMapInfoオブジェクトに詰め替え
      If reader.Read() Then
        info.Place = reader("place")
        info.Url = reader("url")
        info.Longitude = reader("longitude")
        info.Latitude = reader("latitude")
        info.Memo = reader("memo")
      Else
        Throw New Exception("該当するデータが存在しません。")
      End If
    End Using
   
    Return info
  End Function
End Class

' 地点情報を表すMapInfoクラスを定義
Public Class MapInfo
  Public Place As String
  Public Url As String
  Public Longitude As String
  Public Latitude As String
  Public Memo As String   
End Class
地点コードをキーに対応する地点情報を検索するためのXML Webサービス・クラス(GoogleMap.asmx)(上:C#、下:VB)

 Webサービス・ブリッジ機能を利用するうえで必要な基本構文については、「TIPS:クライアントサイド・スクリプトからXML Webサービスを非同期呼び出しするには?(サーバサイド編)」が詳しいので、こちらを参照していただきたい。

3. 新規のWebフォームを作成する

 新規のWebフォーム(GoogleMap.aspx)を作成したら、フォーム・デザイナから以下の画面の要領でサーバ・コントロールを配置する。また、それぞれのコントロールに対しては、表の内容でプロパティ値を設定しておこう。

Webフォーム(GoogleMap.aspx)のレイアウト
各コントロールのプロパティ内容は以下のとおり。
コントロール(ID) プロパティ 設定値
ScriptManager(manager) Scripts http://maps.google.com/maps?file=api&amp;v=2&amp;key=
ABQIAAAAFJNqs5yK0cFCLVsP36tpABTwM0brOpm-All5BF6PoaKBxRWWERTXIelDS4kW51ddR8qrLvv48fvtUw (設定方法は「Microsoft AJAX Libraryで実践オブジェクト指向JavaScript」を参照)
Services GoogleMap.asmx(設定方法は「TIPS:クライアントサイド・スクリプトからXML Webサービスを非同期呼び出しするには?(クライアントサイド編)」を参照)
ListBox(list) DataSourceID sds
DataTextField place
DataValueField mid
Rows 10
SqlDataSource(sds) ConnectionString MyDB(接続名)
SelectCommand SELECT [mid], [place] FROM [Mapinfo]
Panel(gmap) Height 400px
Width 500px
Style position:relative;

 ScriptManager.Scriptsプロパティには、Google Maps APIを動作するのに必要なライブラリのURLを指定する必要がある。ここでは、先ほどライセンス・キーを取得した際に保存しておいたURLを指定しておこう。なお、ライセンス・キーの部分は自分自身で取得したキーで置き換えること。

 Panelコントロールは、Google Maps APIを通じて取得した地図画像を表示するための領域を確保するものだ。地図の大きさを変更したい場合には、PanelコントロールのWidth/Heightプロパティを変更すればよい。

4. サービス呼び出しのコードを記述する

 あとは、ScriptManagerコントロールによって自動生成されたプロキシ・クラスを介して、サービス・メソッドを呼び出すJavaScriptのコードを記述するだけだ。具体的なコードは、以下のとおり。

<script type="text/javascript">
var map = null;

// ページ・ロード時に呼び出されるイベント・ハンドラ
function pageLoad() {

  // 使用しているブラウザがGoogleマップに対応しているかを判定
  if (GBrowserIsCompatible) {

    // 「id="gmap"」で定義された領域に地図を表示
    //(ナビゲーションや表示位置、種類を定義)
    map = new GMap2($get('gmap'));
    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    var point = new GLatLng(35.771586, 139.988823);
    map.setCenter(point, 13);
    map.setMapType(G_NORMAL_MAP);

    // リストボックスの内容が変更されたタイミングで、
    // サービス・メソッドを呼び出し
    $addHandler(
      $get('list'),
      'change',
      function() {
        GoogleMap.GetMapInfo(
          $get('list').value,

          // サービス・メソッドの処理が成功した場合の
          // コールバック関数
          function(result){

            // 取得した情報に基づいて、マーカを追加
            map.clearOverlays();
            var point =
              new GLatLng(result.Latitude, result.Longitude);
            var marker = new GMarker(point);
            map.setCenter(point, 12);
            map.addOverlay(marker);

            var builder = new Sys.StringBuilder();
            builder.append('<a href="' + result.Url + '">');
            builder.append(result.Place + '</a><br />');
            builder.append(result.Memo);

            // マーカをクリックした場合に、バルーンを表示
            GEvent.addListener(
              marker,
              'click',
              function(){
                marker.openInfoWindowHtml(builder.toString());
              }
            );
          }
       );
      }
    );
  }
}
</script>
プロキシ・クラス経由でサービス・メソッドにアクセスするコード(GoogleMap.aspx)

 コードの大まかな流れは、リスト内のコメントも参照いただくとして、ここではJavaScriptからGoogleマップを操作する基本的なポイントを押さえておくことにしよう。

地図を表示する基本的な方法

 地図を表示/操作するのは、GMap2オブジェクトの役割だ。GMap2コンストラクタには、地図の表示先となる要素(ここではPanelコントロール「gmap」)を指定する必要がある。

 GMap2.addControlメソッドは、地図上に配置するナビゲーション・バーを追加する。ここでは、GLargeMapControl(地図移動+ズーム操作)、GMapTypeControl(地図切り替えの操作)オブジェクトを指定しているが、このほかにもGSmallZoomControl(ズーム操作)を指定することが可能である。

 また、setCenter/setMapTypeメソッドは、それぞれ地図の表示位置(中心点)と、表示する地図の種類を指定するものだ。setCenterメソッドの第1パラメータには中心座標をGLatLngオブジェクト(引数は緯度、経度の順)として、第2パラメータには倍率を0〜17(0が最もズームアウトした状態、17が最もズームインした状態)の範囲で指定する必要がある。setMapTypeメソッドのパラメータには、ここではG_NORMAL_MAP(標準の地図)を指定しているが、ほかにもG_SATELLITE_MAP(衛星画像)、G_HYBRID_MAP(ハイブリッド地図)などが指定できる。

地図上のマーカを追加/削除する

 本サンプルでは、サービス・メソッドGoogleMap.GetMapInfoで取得した地点情報に基づいて、地図上にマーカを追加している。

 マーカを表すのは、GMarkerオブジェクトの役割だ。GMarkerコンストラクタには、引数として、マーカの座標情報を表すGLatLngオブジェクトを指定する必要がある。ここでは、GMap2.clearOverlaysメソッドでいったん地図上のマーカを破棄したうえで、addOverlayメソッドで新規に作成したマーカを追加している。ただし、このままではマーカが表示されないので(地図の表示位置が自動的にマーカ位置に移動するわけではないので)、setCenterメソッドで地図の表示位置をマーカ位置に移動させているわけだ。

マーカ・クリック時の挙動を定義する

 最後に、マーカ・クリック時にメッセージ・バルーンを表示する方法を見ておこう。クリック時のイベント・ハンドラを定義するのは、GEvent.addListenerメソッドの役割だ。addListenerメソッドの一般的な構文は、以下のとおりだ。

GEvent.addListener(対象のオブジェクト, イベント名, イベント・ハンドラ)

 ここでは、マーカをクリック(click)したタイミングで、GMarker.openInfoWindowHtmlメソッドを呼び出すことで、その地点に対応する詳細情報(地点名と詳細ページへのリンク、メモ情報)をバルーン上に表示しているわけだ。openInfoWindowHtmlメソッドには、バルーンに表示するためのHTML文字列を引き渡すものとする(Sys.StringBuilderオブジェクトについては、「Microsoft AJAX Library&JavaScriptプログラミング 第5回」を参照していただきたい)。

 以上を理解したら、さっそく作成したサンプル・プログラムを実行してみよう。冒頭の画面のように、リストボックス上の地名を選択したタイミングで、地図の表示がその地点に移動し、かつ、地図上のマーカをクリックすると、バルーンが表示されれば成功だ。End of Article

利用可能バージョン:.NET Framework 2.0
利用可能バージョン:.NET Framework 3.0
利用可能バージョン:.NET Framework 3.5
カテゴリ:Webフォーム 処理対象:ASP.NET AJAX
関連TIPS:Webサービス・ブリッジ機能により構造化データを受け渡しするには?(基本編)
関連TIPS:クライアントサイド・スクリプトからXML Webサービスを非同期呼び出しするには?(サーバサイド編)
関連TIPS:クライアントサイド・スクリプトからXML Webサービスを非同期呼び出しするには?(クライアントサイド編)

この記事と関連性の高い別の.NET TIPS
[ASP.NET AJAX]Virtual Earthを操作するには?
[ASP.NET AJAX]AutoCompleteコントロールでGoogleサジェスト風なオートコンプリート機能を実装するには?
[ASP.NET AJAX]Webサービス・ブリッジ機能により構造化データを受け渡しするには?(基本編)
[ASP.NET AJAX]クライアントサイド・スクリプトからXML Webサービスを非同期呼び出しするには?(サーバサイド編)
[ASP.NET AJAX]ダイナミック・コンテキスト機能でポップアップ・コントロールの内容を動的に生成するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間