Thursday, December 9, 2010

Freebase Meetup and JSONP

So, I was invited to speak at a Freebase meetup by Kirrily Roberts. I thought "Cool, Freebase. Oh, I should learn that!" Especially now that Freebase is part of Google! So apologies if you're looking for my intended next sample which was closure as a time slider, that will come.

I did a couple of maps mashups to try and learn the query language. But at the same time, I wanted to learn more about Google Closure. So, here's a couple of samples that I did. Let me explain in further detail:

<link href="http://code.google.com/apis/maps/documentation/javascript/examples/standard.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="goog/base.js"></script>
<script>
   
goog.require('goog.net.Jsonp');
var obj;
var map;
 
function initialize() {
  var latlng = new google.maps.LatLng(0,0);
  var mapOptions = {
        zoom: 2,
        center: latlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
  };
 
 
  map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  getEvents(); 
} 

function getEvents() {
  var envelope = 'http://www.freebase.com/api/service/mqlread?query={%20%22query%22:%20[{%20
        %22type%22:%20%22/time/event%22,%20%22id%22:%20null,%20%22name%22:%20null,
        %20%22included_in_event%22:%20[{%20%22name%22:%20%22world%20war%20ii%22%20}],
        %20%22locations%22:%20[{%20%22geolocation%22:%20{%20%22latitude%22:%20null,
        %20%22longitude%22:%20null%20}%20}]%20}]%20}';
  getData(envelope,'');
} 

function getData(dataUrl,data) {
  var jsonp=new goog.net.Jsonp(dataUrl);
  jsonp.setRequestTimeout(100000);
  jsonp.send('',setObject);
}

function setObject(response){
  obj = response['result'];
  addMarkers();
}
function addMarkers(){
  for(var i in obj){
    for(var j in obj[i].locations){
      var latLng = new google.maps.LatLng(obj[i].locations[j].
            geolocation.latitude,obj[i].locations[j].geolocation.longitude);
      var marker = new google.maps.Marker({
          map: map,
          position: latLng,
          title: obj[i].name
      });}
      console.log(obj[i].name);
  }
}

So what I did there was use goog.net.jsonp from Closure to load the JSON from the query results and then create markers. The first sample finds events during World War II and find their geolocation. Since some events have more than one geolocation, it gives each location a marker with the same title, which will show up as a tool tip on hovering over the marker. In this case, the event contains a /location/location node which has /location/location/geolocation nodes. Someone comment if I'm not getting that quite right.

For those that don't know, I used the JSONP utility to get around the same domain policy of browsers, which prevents you from loading scripts directly from domains other than the one you are loading from. Server side scripting would have solved that issue for me easily, but I decided to set myself the additional challenge of finding that workaround. JSONP takes advantage of the caveat to the same domain policy that allows you to load scripts into <script> tags in HTML. In the case of the Closure library, it creates a temporary <script> tag, uses it to get the JSON object, and then gets rid of the script tag. One must exercise caution when using this approach, of course, that the source of your JSON is trusted to prevent attacks on visitors to your site.

My second sample took a /location/location, in this case Berkeley California (where I grew up) and found all /location/location nodes that had a containedby relationship to Berkeley California. And then mapped them. Then I added in animation to, so if you click on one place it bounces. Just for fun.

It was pretty basic. Figuring out the query language is not easy. Actually, before I spoke at the meetup, Jamie Taylor did a great talk about the schema which really cleared up some things for me. Unfortunately, we experienced a complete A/V failure in the room the meetup was in> Jaime did his talk with a white board, which I think made him happy. I jokingly referred to my talk as interpretive dance. I described my approach, why I was using JSONP, what tools were available, and then we went and had a beer.

Update

I should have credited this article on JQuery and JSONP with part of my inspiration.

No comments: