地図を表示したい!とりあえず地図を表示するまで

test_mapプロジェクトの開始

  • いつもの手順でサンプルプロジェクトを生成。
  • DBは必要ないけど、レイアウトファイル等の雛形が欲しいので、scaffoldを実行してしまった。(timestampsだけのマイグレーションファイルが生成された)
# ---------- ターミナルでの操作 ----------

rails test_map
cd test_map
script/generate scaffold map
rake db:migrate
script/server

Google Mapsのサンプルをそのまま試す

<%# ---------- app/views/layouts/maps.html.erb ---------- %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Google Maps JavaScript API Example</title>
    <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAubV6ipVCO8c_dPnrcPjEihTJQa0g3IQ9GZqIMmInSLzwtGDKaBTJSx_Ot3L7hrJG-oPV8xD2tPbXsA"
      type="text/javascript"></script>
    <script type="text/javascript">

    //<![CDATA[

    function load() {
      if (GBrowserIsCompatible()) {
        var map = new GMap2(document.getElementById("map"));
        map.setCenter(new GLatLng(37.4419, -122.1419), 13);
      }
    }

    //]]>
    </script>
  </head>
  <body onload="load()" onunload="GUnload()">
    <div id="map" style="width: 500px; height: 300px"></div>
  </body>
</html>
  • あっさり地図が表示された。(場所はアメリカのスタンフォード大学とかパロアルト周辺のようだ)
  • ドラッグしてグリグリ動かせるし、左ダブルクリックで拡大、右ダブルクリックで縮小、楽しい。


Rails環境を利用して少しだけ簡潔に

  • しかし、このままじゃRailsから使うにはあまりにも手抜きなので、もうちょっと整理したみた。
  • あまり変化は無いが、ヘルパメソッドを利用したり、prototype.jsを利用したりで多少は簡潔になった。
<%# ---------- app/views/layouts/maps.html.erb ---------- %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>Maps: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>

<!-- ここから追記 -->
  <%= javascript_include_tag :defaults %>
  <%= javascript_include_tag "http://maps.google.com/maps?file=api&amp;v=2&amp;key=" %>
  <% javascript_tag do %>
  function load() {
    if (GBrowserIsCompatible()) {
      var map = new GMap2($("map"));
      map.setCenter(new GLatLng(37.4419, -122.1419), 13);
    }
  }
  <% end %>
<!-- ここまで追記 -->

</head>
<!-- <body>タグにonload,onunloadを追記 -->
<body onload="load()" onunload="GUnload()">

<p style="color: green"><%= flash[:notice] %></p>

<%= yield  %>

</body>
</html>
<%# ---------- app/views/maps/index.html.erb ---------- %>

<div id="map" style="width: 500px; height: 300px"></div>

APIキーについて

作業中に気付いた。Rails環境に限らず...

  • http://localhostから利用する限り、APIキーは設定しなくても表示できてしまった...。(但し「key=」だけは必要)
  • さらに、production環境でのAPIキーを設定しておいても表示できてしまった...。
  • つまり、http://localhostから利用する限り、APIキーは何でもOKということのようだ。この仕様はかなり便利!

ym4r_gmプラグインを利用してみる

Google Maps APIRails環境から利用するym4r_gmというプラグインも試してみた。

  • まずはインストール
# ---------- ターミナルでの操作 ----------

script/plugin install svn://rubyforge.org/var/svn/ym4r/Plugins/GM/trunk/ym4r_gm
  • インストール後、以下の作業をした。
    • ym4r-gm/javascript/以下のファイルを、public/javascripts/以下にコピーした。
    • ym4r-gm/gmaps_api_key.ymlを、config/gmaps_api_key.ymlへコピーした。
    • gmaps_api_key.ymlにはlocalhost:3000のAPIキーを設定しておいた。(localhostから利用する限りAPIキーは何でもOKなので、この設定はデフォルトのままでもOK。)
# ---------- config/gmaps_api_key.yml ----------

#Fill here the Google Maps API keys for your application
#In this sample:
#For development and test, we have only one possible host (localhost:3000), so there is only a single key associated with the mode.
#In production, the app can be accessed through 2 different hosts: thepochisuperstarmegashow.com and exmaple.com. There then needs a 2-key hash. If you deployed to one host, only the API key would be needed (as in development and test).

development:
  ABQIAAAAubV6ipVCO8c_dPnrcPjEihTJQa0g3IQ9GZqIMmInSLzwtGDKaBTJSx_Ot3L7hrJG-oPV8xD2tPbXsA

test:
  ABQIAAAAubV6ipVCO8c_dPnrcPjEihTJQa0g3IQ9GZqIMmInSLzwtGDKaBTJSx_Ot3L7hrJG-oPV8xD2tPbXsA

production:
 thepochisuperstarmegashow.com: ABQIAAAAzMUFFnT9uH0Sfg76Y4kbhTJQa0g3IQ9GZqIMmInSLzwtGDmlRT6e90j135zat56yhJKQlWnkaidDIQ
 example.com: ABQIAAAAzMUFFnT9uH0Sfg98Y4kbhGFJQa0g3IQ9GZqIMmInSLrthJKGDmlRT98f4j135zat56yjRKQlWnkmod3TB


すると、Google Maps APIのサンプルと同等のコードは、さらに簡潔に以下のように書ける。

  • コントローラーで地図の設定をして...
# ---------- app/controllers/maps_controller.rb ----------

class MapsController < ApplicationController
  def index
    @map = GMap.new("map_div")
    @map.center_zoom_init([37.4419, -122.1419], 13)
  end
end
  • レイアウトファイルでjavascriptを生成
<%# ---------- app/views/layouts/maps.html.erb ---------- %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>Maps: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>

<!-- ここから追記 -->
  <%= GMap.header %>
  <%= @map.to_html %>
<!-- ここまで追記 -->

</head>
<body>

<p style="color: green"><%= flash[:notice] %></p>

<%= yield  %>

</body>
</html>
  • テンプレートファイルindex.html.erbに地図を表示するdivブロックを設定
<%# ---------- app/views/maps/index.html.erb ---------- %>

<%= @map.div(:width => 500, :height => 300) %>
  • それぞれのヘルパメソッドは、以下のjavascriptまたはHTMLコードを生成してくれるようだ。
    • GMap.headerは、javascriptの読み込みとcssの定義
    • @map.to_htmlで、コントローラーで設定した@mapをjavascriptに変換
    • @map.divは、地図を表示するdivブロックを生成
<%= GMap.header %>
<script src="http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=ABQIAAAAubV6ipVCO8c_dPnrcPjEihTJQa0g3IQ9GZqIMmInSLzwtGDKaBTJSx_Ot3L7hrJG-oPV8xD2tPbXsA&amp;hl=" type="text/javascript"></script>
<script src="/javascripts/ym4r-gm.js" type="text/javascript"></script> 
<style type="text/css"> 
 v:* { behavior:url(#default#VML);}
</style> 


<%= @map.to_html %>
<script type="text/javascript"> 
var map;
window.onload = addCodeToFunction(window.onload,function() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map_div"));
map.setCenter(new GLatLng(37.4419,-122.1419),13);
}
});
</script> 


<%= @map.div(:width => 500, :height => 300) %>
<div id="map_div" style="width:500px;height:300px" ></div>

ym4r_gmでの地図の設定はコントローラーで

  • あまりにも素っ気ないので、ym4r_gmのサンプルのHello worldをやってみると...
# ---------- app/controllers/maps_controller.rb ----------

class MapsController < ApplicationController
  def index
    @map = GMap.new("map_div")
    @map.center_zoom_init([37.4419, -122.1419], 13)

    # 地図をコントロールする部品を表示する(拡大縮小スライダーとボタン、地図と航空写真の切替ボタン)
    @map.control_init(:large_map => true,:map_type => true)

    # マーカーと吹き出しウィンドウを表示する
    @map.overlay_init(GMarker.new([37.4419, -122.1419],:title => "Hello", :info_window => "Info! Info!"))
  end
end
  • 以下のように、地図をコントロールするUIやマーカー、クリックで吹き出しウィンドウも表示された。


  • @map.to_htmlで生成されたコードを確認すると以下のようになっていた。(3行追記されたようだ)
<script type="text/javascript"> 
var map;
window.onload = addCodeToFunction(window.onload,function() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map_div"));
map.setCenter(new GLatLng(37.4419,-122.1419),13);
// ---------- 以下追記されたコード ----------
map.addOverlay(addInfoWindowToMarker(new GMarker(new GLatLng(37.4419,-122.1419),{title : "Hello"}),"Info! Info!",{}));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
}
});

Rails環境では断然ym4r_gmを使ってみたくなるが、ym4r_gmから利用すればGoogle Maps APIの知識は不要になると言うことではなく、やはりちょっとオリジナルなことをやろうとすれば、Google Maps APIの詳細な知識はどうしても必要と感じた。かつ、ym4r_gmプラグインの知識も必要になる。

さらにjavascriptから直接利用する方法をいろいろなページで解説してくれている。自分が参考にさせて頂いたのは以下のページ。(感謝です!)


Railsとym4r_gmjavascriptGoogle Maps APIの試行錯誤の連続が始まる...。