Google Maps in Rails

The Google Maps API  offers the ability to add mapping functionality, similar to maps.google.com, to their websites. All of Google Maps functionalities, including markers, directions, zoom options and satellite view are only a few lines of code away. To get a Google Maps API key, login to your google account (gmail.com), visit http://code.google.com/apis/maps/signup.html, type the “Website URL” in the box provided (for eg.., localhost:3000, samplesite.com, etc..,) and click on “Generate API key” button. It will take to you to next page and display the API key there. Copy and save it somewhere safely. If you want to get key for both local and server, you need to signup multiple times for “API key”. Now you are ready to code :-

First you need to install couple of plugins for using Google Maps API (YM4R/GM and GEOKIT)

ruby script/plugin install git://github.com/queso/ym4r-gm.git
ruby script/plugin install svn://rubyforge.org/var/svn/geokit/trunk

Consider ‘index’ is the action where you going to display the Google Map in “home controller”.

home_controller.rb

class HomeController < ApplicationController
require ‘rubygems’
include GeoKit::Geocoders
def index
coordinates =[13.0343841,  80.2502535] #you can get the coordinates for the location you want from http://stevemorse.org/jcal/latlon.php
@map = GMap.new(“map”)
@map.control_init(:large_map => true, :map_type => true)
@map.center_zoom_init(coordinates,10) # here 10 referes to the zoom level for a map
@map.overlay_init(GMarker.new(coordinates,:title => “Chennai”, :info_window => “Chennai”))
end
end

/home/index.html.erb

<%= @map.div(:width => 800, :height => 500) %>

That’s it, now run the app. You can see the Google Map pointing out a static location (the location what your coordinates refers too, in this case “Chennai”)

Right, now it’s time perform a dynamic mapping by entering a location in a text box. So for this purpose, add a form in “/home/index.html.erb” at the bottom of the page after <%= @map.div(:width => 800, :height => 500) %>

<% form_for “new_location”, :url => searchmap_path, :html => { :method => :post } do %>
<label>Enter a new Location to map:</label>
<%= text_field_tag :new_location %>
<%= submit_tag “Map It” %>
<% end %>

Now add a routes for searchmap_path in routes.rb

map.searchmap ‘/searchmap’, :controller=>’home’, :action=>’location’

Now, again come back to home_controller.rb, create a method ‘location’

def location
new_location = params[:new_location]
gg = GeoKit::Geocoders::google=”YOUR API KEY GOES HERE”
gg_locate = GeoKit::Geocoders::MultiGeocoder.geocode(new_location)
coordinates = [gg_locate.lat, gg_locate.lng]
@map = GMap.new(“map”)
@map.control_init(:large_map => true, :map_type => true)
@map.center_zoom_init(coordinates,14)
@map.overlay_init(GMarker.new(coordinates, :title => new_location,:info_window =>new_location))
render :action => “index”
end

That’s it. Now you can map to any location you want by entering the address, city or zipcode in the textbox.

Now let’s see how to find the multiple nearby locations (or) how to find the distance between any two locations. For this purpose, add another text_field in the form in “/posts/index.html.erb”

<label>Enter another Location to find distance:</label>
<%= text_field_tag :dist_location %>

Go back to the “home_controller.rb” and add these lines at the bottom before this line(render :action => “index”) in the “location” method  :-

dist_location = params[:dist_location]
#The below part will get execute if you give the second location
if params[:dist_location] && !params[:dist_location].blank?
gg_locate1 = GeoKit::Geocoders::MultiGeocoder.geocode(dist_location)
coordinates1 = [gg_locate1.lat, gg_locate1.lng]
@dist=gg_locate.distance_to(gg_locate1) # will get the distance in miles
@dist=@dist*1.6 #converting it into kms
@map.overlay_init(GMarker.new(coordinates1, :title => “#{dist_location} – #{@dist.round(2)} Kms from #{new_location}”, :info_bubble => “#{@dist} from #{new_location}”))
end

Now, run the app, consider i’m entering “Chennai” as the first location and “Tambaram” as the second location. I will get the below map :-

To get the directions between two locations (by car)

Install the gem google_directions

sudo gem install google_directions

Add these lines in the “home_controller.rb” within the if condition (if params[:dist_location] && !params[:dist_location].blank?) :-

require ‘google_directions’

require ‘net/http’
require ‘rexml/document’

@directions = GoogleDirections.new(new_location, dist_location)
url = “#{@directions.xml_call}”
# get the XML data as a string
xml_data = Net::HTTP.get_response(URI.parse(url)).body
# extract event information
doc = REXML::Document.new(xml_data)
duration = []
way = []
kms=[]
full_text=[]
doc.elements.each(‘DirectionsResponse/route/leg/step/html_instructions’) do |a|
way<<a.text
end
doc.elements.each(‘DirectionsResponse/route/leg/step/distance/text’) do |a|
kms<<a.text
end
doc.elements.each(‘DirectionsResponse/route/leg/step/duration/text’) do |a|
duration<<a.text
end
way.each_with_index do|text, index|
full_text<<“#{kms[index]}(#{duration[index]})—>#{way[index]}<br/>”
end
@full_text=full_text

Add these lines in the view file at the bottom (‘/home/index.html.erb’)

<% if @full_text %>
<b>
Total Kms : <%= @directions.distance_in_miles*1.6 %><br/>
Total Time Required (minimum) : <%= (@directions.drive_time_in_minutes/60).round %> Hour(s) <%= @directions.drive_time_in_minutes%60 %> Mins<br/>
Directions :- <b/><br/>
<%= @full_text %>
<% end %>

Result of this :-


.

.

.

.

Here is the overall code of “home_controller.rb

require ‘rubygems’
require ‘google_directions’
include GeoKit::Geocoders

def index
coordinates =[13.0343841,  80.2502535] #you can get the coordinates for the location you want from http://stevemorse.org/jcal/latlon.php
@map = GMap.new(“map”)
@map.control_init(:large_map => true, :map_type => true)
@map.center_zoom_init(coordinates,10) # here 10 referes to the zoom level for a map
@map.overlay_init(GMarker.new(coordinates,:title => “Chennai”, :info_window => “Chennai”))
end

def location
new_location = params[:new_location]
dist_location = params[:dist_location]
gg = GeoKit::Geocoders::google=”YOUR API KEY GOES HERE”
gg_locate = GeoKit::Geocoders::MultiGeocoder.geocode(new_location)
coordinates = [gg_locate.lat, gg_locate.lng]
@map = GMap.new(“map”)
@map.control_init(:large_map => true, :map_type => true)
@map.center_zoom_init(coordinates,10)
@map.overlay_init(GMarker.new(coordinates, :title => new_location, :info_window => new_location))

if params[:dist_location] && !params[:dist_location].blank?
gg_locate1 = GeoKit::Geocoders::MultiGeocoder.geocode(dist_location)
coordinates1 = [gg_locate1.lat, gg_locate1.lng]
@dist=gg_locate.distance_to(gg_locate1)
@dist=@dist*1.6
@directions = GoogleDirections.new(new_location, dist_location)
@map.overlay_init(GMarker.new(coordinates1, :title => “#{dist_location} – #{@dist.round(2)} Kms away from #{new_location}”, :info_window => “#{dist_location} – #{@dist.round(2)} Kms <br/> away from #{new_location}”))
require ‘net/http’
require ‘rexml/document’
url = “#{@directions.xml_call}”
# get the XML data as a string
xml_data = Net::HTTP.get_response(URI.parse(url)).body
# extract event information
doc = REXML::Document.new(xml_data)
duration = []
way = []
kms=[]
full_text=[]
doc.elements.each(‘DirectionsResponse/route/leg/step/html_instructions’) do |a|
way<<a.text
end
doc.elements.each(‘DirectionsResponse/route/leg/step/distance/text’) do |a|
kms<<a.text
end
doc.elements.each(‘DirectionsResponse/route/leg/step/duration/text’) do |a|
duration<<a.text
end
way.each_with_index do|text, index|
full_text<<“#{kms[index]}(#{duration[index]})—>#{way[index]}<br/>”
end
@full_text=full_text
end
render :action => “index”
end

Here is the overall code of “/home/index.html.erb”

<%= @map.div(:width => 800, :height => 500) %>

<% form_for “new_location”, :url => searchmap_path, :html => { :method => :post } do %>
<label>Enter a new Location to map:</label>
<%= text_field_tag :new_location %>
<label>Enter another Location to find distance:</label>
<%= text_field_tag :dist_location %>
<%= submit_tag “Map It” %>
<% end %>

<% if @full_text %>
<b>
Total Kms : <%= @directions.distance_in_miles*1.6 %><br/>
Total Time Required (minimum) : <%= (@directions.drive_time_in_minutes/60).round %> Hour(s) <%= @directions.drive_time_in_minutes%60 %> Mins<br/>
Directions :- <b/><br/>
<%= @full_text %>
<% end %>

Advertisements

2 thoughts on “Google Maps in Rails”

  1. When i display the erb containing 800, :height => 500)%> it display :

    in the browser with :

    <div id=”map” style=”width:800px;height:500px” ></div>

    As source code.

    Why is it trying to converse my HTML code to be read into a browser instead of displaying it as wanted in the source code?

Comments are closed.