My first Ruby mashup - placing geotagged photo data on a Google Map using flickr.rb
To help me learn Ruby, I created a mashup that takes a photo from Flickr, extracts its geotags and places the location of the photo on a Google map. Yes, I know that Flickr already has this functionality thru Yahoo maps, but I wanted to try out Google.
I'll lay this out in a series of easy steps.
Step 1 (flickr.rb)
Download and install the Flickr.rb library- it's easiest to just install the gem. This library is the main wrapper for the Flickr API set. Spend a few moments learning how this wrapper works by watching the tutorial.
Step 2 - create a new Rails application (I called mine 'fotoplaces' )
rails c:\rails\fotoplaces
Step 3 - Apply for a Flickr API key and a Google Maps API key.
NOTE: If you are using the default Ruby install and testing under WEBrick, then the website you want to enter for the Google Map API is "http://localhost:3000"
Step 4 - Update your ruby environment to include flickr.rb
Add the following code to %RAILS_ROOT%/app/config/environment.rb
# Include your application configuration below
require 'flickr'
Step 5 - Update flickr.rb to utilize Flickr's geo tag API's
Add the following code to the "photo" class of C:\ruby\lib\ruby\gems\1.8\gems\flickr-1.0.0\flickr.rb
# Implements flickr.photos.geo.getLocation
def get_location
location = @client.photos_geo_getLocation('photo_id'=>@id)['photo']['location']
end
Step 6 - Update flickr.rb to fix the APP KEY bugs
Update User.initialize to look like this. It used to fail due to lack of an API key.
def initialize(id=nil, username=nil, email=nil, password=nil, api_key=nil)
@id = id
@username = username
@email = email
@password = password
@client.login(email, password) if email and password
@api_key = '<TYPE YOUR FLICKR API KEY HERE>'
@client = Flickr.new @api_key
end
Step 7 - Create the Flickr controller code
I created 2 classes in %RAILS_ROOT%\fotoplaces\app\controller\fotoplaces_controller.rb. Here's what my code looks like:
class FotoplacesController < ApplicationController
def initialize
@flickr = Flickr.new '<TYPE YOUR FLICKR API KEY HERE>'
@user = @flickr.users('nomadicentrepreneur')
end
def show_google_map
photos = @user.photos
photo= photos[rand(photos.length)]
#TODO -- add error checking for photos that don't have geo tags
@pix= {'latitude' => photo.get_location['latitude'].to_s,
'longitude' => photo.get_location['longitude'].to_s,
'description' =>photo.title,
'accuracy' => 2
}
end
end
Step 8 - Create the show_google_map laoyout. I copied a lot of this code from Andre at Earthcode.
Place the following code in %RAILS_ROOT%\fotoplaces\app\views\fotoplaces\show_google_map.rhtml.
<html>
<head>
<title>Google maps example</title>
<!-- This includes the google maps API code.
You need to put your own key here -->
<script src="http://maps.google.com/maps?file=api&v=2&key=<TYPE YOUR GOOGLE MAPS API KEY HERE>"
type="text/javascript"></script>
<script type="text/javascript">
// helper function to create markers
function createMarker(point,html) {
var marker = new GMarker(point);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
// this is called when the page loads.
// it initializes the map, and creates each marker
function initialize() {
var map = new GMap(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.centerAndZoom(new GPoint(<%=@pix['longitude']%>, <%=@pix['latitude']%>), <%=@pix['accuracy']%>);
var point = new GPoint(<%=@pix['longitude']%>,<%=@pix['latitude']%>);
var marker = createMarker(point,'<div><%= @pix['description']%></div>')
map.addOverlay(marker);
}
</script>
</head>
<body onload="initialize()">
Here's the map:
<!-- This is the element in which the map will be displayed. -->
<div id="map" style="width: 800px; height: 800px"></div>
</body>
</html>
That's it! You're finished! Run your code in your favorite browser w/ your favorite Ruby server (I'm using FireFox along with the test server WEBrick) and see the result. I might add a couple more things to this like more information about the photo, multiple pictures and error checking. The picture of what it looks like is at the top of this post (admittedly its nothing special, but hey, it works!)