Google Map Mashup in Rails

Posted by Max Dunn Fri, 30 Jun 2006 17:03:00 GMT

How would you like to put an interactive Google map in your Ruby on Rails page with single or multiple markers? Here is how to do this.

Helper Code

First, in your app/helpers/application_helper.rb, add this method:

def map(options = {})
  gmap_defaults = {:width => "525", :height => "500",
    :center => "-122.01686382293701, 37.31932181336203",
    :zoom => "2",
    :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

Google Map Layout

Then create 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&v=1&key=<%= @gmap[:key] %>" type="text/javascript"></script>

<script type="text/javascript">
//<![CDATA[

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
  var map = new GMap(document.getElementById("map"));
  map.addControl(new GLargeMapControl());
  map.addControl(new GMapTypeControl());
  map.centerAndZoom(new GPoint(<%= @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(marker, "click", function() {
          marker.openInfoWindowHtml(html);
        });
      }
    return marker;
  }

    GEvent.addListener(map, "click", function(overlay, point) {
        var latLngStr = 'new GPoint(' + point.x + ', ' + point.y + ');';
        document.getElementById("message").innerHTML = latLngStr;
  });

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

Main Layout

In your main layout file, for instance /app/layout/main.rhtml, add the following:

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

Get Markers

Download at least the first image below as “marker1.png” and place it in public/images. If you are going to be using multiple markers on the same map, download the others too as “marker2.png” through “marker9.png”.

marker1.gif marker2.gif marker3.gif marker4.gif marker5.gif marker6.gif marker7.gif marker8.gif marker9.gif

Get a Google Maps Key

Now go to the Google Maps API page and get a key.

Config

Next add this to your environment file /config/environment.rb

MY_CONFIG = {
  :google_key => "(Your Google Key Here)" 
}

Using

Now you are now ready to insert a Google Map mashup into your Rails web page.

In it’s simpliest form use this in any rhtml page:

<%= map :center => "-122.00958967208862, 37.301094586321284" %>

The :center parameter can be determined by adding a locator to a map, then clicking on any location and reading the coordinates underneath the map.

You can add a locator to any map using:

<%= map :center => "-122.00958967208862, 37.301094586321284", :locator => true %>

Here are the parameters that can be used with maps:

:center => "-122.01686382293701, 37.31932181336203" 
:locater => true # When on, the coordinates will appear underneath the map when you click on it.
:width => "525"*
:height => "500"*
:zoom => "3" # Smaller numbers zoom in closer
:key => Abp123asdfu77asncZDSf # The Google maps key
:marker => "-122.02016830444336, 37.31850270698815" # Used to show the marker at a different location than :center.
:text => "Tri-Cities Little League" # The text to appear when you click on the marker
:url => "http://www.tricitiesbaseball.org" # The URL to go to when the text is clicked

Here is an example that shows two markers:

<%= map :width => "500", :height => "400", 
  :center => "-122.024846, 37.306761",
  :markers => [
    {:point => "-122.02517867088318, 37.306505188827586", 
     :text => "Meyerholz Field 1"},
    {:point => "-122.0241916179657, 37.30522511298032",
     :text => "Meyerholz Field 2"}] %>

Posted in ,  | no comments

Comments

(leave url/email »)

   Comment Markup Help Preview comment