« 多対多のsave エラー | トップページ | ruby on rails で history back »

google maps api と ruby on rails の連携

以前google maps apiをちょっとやってたことがあって

これをねたに日記をかけないかと昨日から苦戦してましたが今日ようやく完成

1. rails スタート!!

: rails gmap

2. spotモデル作成

: cd gmap
: ruby script/generate model spot

3. DB/テーブル作成

(SQL発行)
: create database gmap_development;
: create database gmap_test;
: create database gmap_production;

(gmap/db/migrate/001_create_spots.rb に以下の内容を記述)

class CreateSpots < ActiveRecord::Migration
   def self.up
     create_table :spots do |t|
       t.column :name , :text
       t.column :lat , :string
       t.column :lng , :string
     end
   end

   def self.down
     drop_table :spots
   end
end

(rake を 実行してテーブルを作成します)

: rake db:migrate

4. scaffold で地点情報を登録して行きましょう。

  例)大阪城       34.68848 135.52974
      心斎橋そごう 34.67364 135.50075

: ruby script/generate scaffold Spot Gmap
: ruby script/server

  http://localhost:3000/gmap/new

5. 登録した spots の情報を google maps api で表示してみましょう。
   まず、helperメソッドを記述します。

以下、http://blog.maxdunn.com/articles/2006/06/30/google-map-mashup-in-rails
より大部分を転載しています。google maps api バージョンが古かったので、最新でも
動くように変更しました。

app/helpers/application_helper.rb に以下の記述を追加します。

( map というヘルパーメソッドを追加しています)

def map(options = {})
  gmap_defaults = {
    :width => "525",
    :height => "500",
    :center => "35.64836, 139.77905",
    :zoom => "10",
    :key => MY_CONFIG[:google_key]
  }
  @gmap = gmap_defaults.merge(options)
  @gmap[:marker] = @gmap[:center] if @gmap[:marker].nil?

  # Convert from single marker syntax to multiple markers syntax
  marker_hash = {}
  marker_hash[:point] = @gmap[:marker] if @gmap[:marker]
  marker_hash[:text] = @gmap[:text] if @gmap[:text]
  marker_hash[:url] = @gmap[:url] if @gmap[:url]
  markers = {:markers => [marker_hash]}
  @gmap = markers.merge(@gmap)

  render(:partial => "layouts/google_map", :no_layout => true)
end

6. 次に、gmap/app/views/layouts/_google_map.rhtml というファイルを作成し、以下のように記述します。

<% @body_tag = 'onload="initMap()"' %>

<div id="map" style="width: <%= @gmap[:width] %>px; height: <%= @gmap[:height] %>px"></div>
<% if @gmap[:locator] %>
  <hr>
  <div id="message"></div>
<% end %>

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=<%= @gmap[:key] %>" type="text/javascript"></script>

<script type="text/javascript">
//<![CDATA[
var map;
function initMap() {

  // Create a base icon for all of our markers that specifies the
  // shadow, icon dimensions, etc.
  var baseIcon = new GIcon();
  baseIcon.shadow = "
http://www.google.com/mapfiles/shadow50.png";
  baseIcon.iconSize = new GSize(20, 34);
  baseIcon.shadowSize = new GSize(37, 34);
  baseIcon.iconAnchor = new GPoint(9, 34);
  baseIcon.infoWindowAnchor = new GPoint(9, 2);
  baseIcon.infoShadowAnchor = new GPoint(18, 25);

  // Center the map on Cupertino
  map = new GMap2(document.getElementById("map"));
  map.addControl(new GLargeMapControl());
  map.addControl(new GMapTypeControl());
  map.setCenter(new GLatLng(<%= @gmap[:center] %>), <%= @gmap[:zoom] %>);

  // Creates a marker whose info window displays the given number
  function createMarker(point, icon_image, text, url) {
    var icon = new GIcon(baseIcon);
    if (icon_image && icon_image.length > 0) {
      icon.image = icon_image;
    } else {
      icon.image = "
http://www.google.com/mapfiles/marker.png";
    }

    var marker = new GMarker(point,icon);

    // Show this marker's index in the info window when it is clicked
    if (text.length > 0) {
      if (url.length > 0) {
        var html = "<a href='" + url + "'>" + text + "</a>";
      } else {
        var html = text;
      }
      html = '<div style="white-space:nowrap;">' + html + '</div>';

      GEvent.addListener(map, "click", function(marker) {
        marker.openInfoWindowHtml(html);
      });
    }
    return marker;
  }

  <%-
  n = 1
  for marker in @gmap[:markers]
      icon_image = image_path("marker#{n}")
  -%>
    var point<%= n %> = new GLatLng(<%=marker[:point]%>);
    var marker<%= n %> = createMarker(point<%= n %>, "<%= icon_image %>", "<%= marker[:text] %>", "<%= marker[:url] %>");
    map.addOverlay(marker<%= n %>);
  <%-
    n += 1
  end
  -%>
 
}

function newPoint(lat, lng){
  map.setCenter(new GLatLng(lat, lng))
}
//]]>
</script>

7. さらに、gmap/app/views/layouts/gmap.rhtml の「<body>」の記述を以下のように変更します。

<% if @body_tag -%>
  <body <%= @body_tag %>>
<% else -%>
  <body>
<% end -%>

8. マーカー用の画像を取得します。以下のURLより取得してください。

http://blog.maxdunn.com/articles/2006/06/30/google-map-mashup-in-rails

9. google maps api のAPI Key を取得します。

   http://www.google.com/apis/maps/

  「My web site URL: 」には、「http://localhost」を入力します。
 
10. gmap//config/environment.rb の最後に、以下の記述を追加します。

MY_CONFIG = {
  :google_key => "(9. で取得したAPI Key)"  # カッコは不要です。
}

11. gmap/app/views/gmap/list.rhtml の最後に以下の記述を追加します。

   <%= map :center => "139.77905, 35.64836" %>

  これで、とりあえず地図は表示されるようになりました。

12. spot 情報の取得

  次に、「show」リンクに移動したときに、地図の中央にその場所がきて、マーカーも表示されるようにしてみましょう。
 
  gmap/app/views/gmap/show.rhtml の最終行に以下を追加
 
<%= map :center => @spot.lat << ',' << @spot.lng ,
        :text => @spot.name.gsub(/\r\n/,"") ,
        :zoom => "15" %>
 
  (改行が入るとうまく表示されないので姑息な手で改行を削除しました)
 
  でましたか??

13. 一覧表示

  最後に仕上げとして、「list」に表示される地図に、リスト上に表示されているマーカーをすべて配置して、さらに一覧に「move」リンクを追加し、マーカーを中央に移動させる処理を実装しましょう。
 
(1) Destroy のリンクの下に、一行追加します。

    <td><input type="button" value="Move"  onclick="newPoint(<%= spot.lat << ',' << spot.lng %>)" /></td>

(2) ページの最後に以下の記述を追加しましょう。

<% @markers = Array.new %>
<% n = 1 %>
<% for spot in @spots %>
  <% @center = spot.lat << ',' << spot.lng if n == 1 %>
  <% @markers << {:point => spot.lat << ',' << spot.lng ,
                  :text  => spot.name.gsub(/\r\n/,'<br />') } %>
  <% n = n + 1 %>
<% end %>

<%= map :width => "500", :height => "400",
  :center => @center ,
  :markers => @markers %>

以上、うまくできましたか??

 

« 多対多のsave エラー | トップページ | ruby on rails で history back »

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/437240/7550999

この記事へのトラックバック一覧です: google maps api と ruby on rails の連携:

« 多対多のsave エラー | トップページ | ruby on rails で history back »