My favorites | English | Sign in

Google Base Data API (Labs)

JavaScript AutosMasher Mashup

The AutosMasher Application is a simple end-to-end tutorial on creating a JavaScript mashup using the Google Base API and Google Maps APIs. It demonstrates how to query several Google Base data feeds, return a list of vehicles, and interact with markers and info windows in the Maps API.

Contents

  1. Audience
  2. Using the AutosMasher Application
  3. Google Base data API
    1. Querying the attributes feed to get car makes and models
    2. Querying the snippets feed to get car listings
      1. Understanding queries and search results
    3. Parsing JSON
  4. Google Maps API
    1. Drawing a map
    2. Drawing markers to show vehicle locations
    3. Centering and zooming the map
  5. Cleanup

Audience

This document is intended for anyone who wants to develop a Google Base data application in JavaScript.

This document assumes that you're an experienced JavaScript programmer. It also assumes that you're familiar with JSON. To learn more about JSON, and how it is used in the GData APIs, refer to the GData documentation.

These examples assume that you are familiar with Google Base concepts. You also need a basic understanding of how to execute queries.

This sample application also uses the Google Maps API to build a map corresponding to query results. Refer to the Google Maps API documentation for more information.

Using the AutosMasher application

You can get the sample program from this directory and run it from your local machine.

Before you can run it, you will need to sign up for a new Google Maps API key and replace the value for the key parameter in the following <script> tag:

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;
   key=ABQIAAAA-NjjZakzY5MKFK-MdkfixBRfu3r7dH9FYihKTdE4J-EIk6ejuxRKNHpS-zxJaV5DOxQYxtLscHqrVQ"
   type="text/javascript">
</script>

Google Base data API

The Google Base data API code executes queries and loads results from Google Base. It includes the following functions:

getMakeOptions() queries the attributes feed for a list of vehicle makes.
showMakeOptions() parses the JSON results in the vehicle make response feed and populates the Select Make dropdown list in the webpage.
getModels() queries the attributes feed for the list of vehicle models that correspond to the selected make.
showModelOptions() parses the JSON results in the vehicle model response feed and populates the Select Model dropdown list in the webpage.
getSnippets() queries the snippets feed for vehicles that match the user input.
showSnippets() parses the JSON results in the vehicle snippets response feed and displays the matching vehicles.

Querying the attributes feed to get car makes and models

The attributes feed gives aggregate information about what kinds of data exists in Google Base. Given an item type, the attributes feed lists the values that are most frequently used for that item type's attributes.

To get a list of vehicle makes, the getMakeOptions() function queries the attributes feed by adding the following script element to the page:

<script type="text/javascript" src="http://www.google.com/base/feeds/attributes/
     -/vehicles?max-values=30&alt=json-in-script&callback=showMakeOptions" />

This script element is constructed using the getMakeOptions() and getModels() functions.

getMakeOptions() is defined as follows:

function getMakeOptions() {
  // Add a script element with the src set to the Google Base query for vehicle
  // makes. The JSON output is specified by including the alt=json-in-script
  // argument. The callback function is also specified as a URI argument.
  // This is equivalent to adding a script tag that looks like this:
  // <script type="text/javascript" src="http://www.google.com/base/feed/attributes/.." /> 

  var attributesElement = document.createElement("script");
  attributesElement.setAttribute("id", "attributes");
  attributesElement.setAttribute("src", "http://www.google.com/base/"
   + "feeds/attributes/-/vehicles?max-values=30"
   + "&alt=json-in-script&callback=showMakeOptions");
  attributesElement.setAttribute("type", "text/javascript");
  document.documentElement.firstChild.appendChild(attributesElement);
}	

The alt=json-in-script component of the URL tells Google Base to return the results feed in JSON format. The callback=showMakeOptions component specifies the showMakeOptions() function as the callback. Refer to Parsing JSON for a description of showMakeOptions().

Next, to get a list of vehicle models, we query the attributes feed using the getModels() function. The resulting list of vehicle models is used to populate the Select Model dropdown list in the webpage. getModels()calls the same URL as getMakeOptions(), but adds a bq structured query to specify the make. bq is the URL parameter that signifies a Base query. All structured queries must start with bq.

function getModels() {
  // Add a script element with the src set to the Google Base query for vehicle  
  // models.  The JSON output is specified by including the alt=json-in-script 
  // argument. The callback function is also specified as a URI argument.
  // This is equivalent to adding a script tag that looks like this:
  // <script type="text/javascript" src="http://www.google.com/base/feed/attributes/.." /> 

  makeOptions = document.getElementById("make_options");
  make = makeOptions.options[makeOptions.selectedIndex].text;

  var attributesElement = document.createElement("script");
  attributesElement.setAttribute("id", "attributes");
  attributesElement.setAttribute("src", 
     ['http://www.google.com/base/feeds/attributes/-/vehicles?max-values=30',
      '&bq=[make:', make, ']&alt=json-in-script&callback=showModelOptions'].join(''));
  attributesElement.setAttribute("type", "text/javascript");

  document.documentElement.firstChild.appendChild(attributesElement);
}

Querying the Snippets feed to get car listings

The snippets feed is a public feed that contains all of the Google Base data.

The getSnippets() function collects the user input, and builds a query from it.

The following code, extracted from getSnippets(), collects the search criteria for the query:

location_input = document.getElementById("location_input").value;
makeOptions = document.getElementById("make_options");
make = makeOptions.options[makeOptions.selectedIndex].text;
modelOptions = document.getElementById("model_options");
model = modelOptions.options[modelOptions.selectedIndex].text;
min_price = document.getElementById("min_price").value;
max_price = document.getElementById("max_price").value;
keywords = document.getElementById("keywords").value;
loc_sort_input = document.getElementById("location_sort_input").value;     

The following code constructs a query.

var query = "bq=";      

The following code adds the car make and model to the query. The user sets the values for the make and model variables by selecting from a dropdown list on the web page.

if (make != "Select Make") {
  query = query + "[make:" + make + "]";
}
if (model != "Select Model") {
  query = query + "[model:" + model + "]";
}

The following code adds an optional location to the query.

if (location_input != "") {
  query = query + "[location:@" + location_input + "]";
}

The following code adds an optional price range to the query.

if (min_price != "") {
  query = query + "[price:" + min_price + ".." + max_price + "]";
}

The following code adds optional keywords to the query. Keywords are stored as unstructured data. Therefore, keyword queries are passed using the q URL parameter. This is the standard GData query delineator.

if (keywords != "") {
  query = query + "&q="+keywords;
}

The following code orders the query by either price, year or location, depending on the user selection.

if (orderby == "price") {
  query = query + "&orderby=price(float%20USD)";
}
if (orderby == "year") {
  query = query + "&orderby=year(int)";
}
if (orderby == "location") {
  query = query + "&orderby=[x=location(location):neg(min(dist(x,@'" + loc_sort_input + "')))]";
}

Understanding queries and search results

Depending on user input, the code above might construct the following query:

http://www.google.com/base/feeds/snippets/-/vehicles/&bq=[make:honda][model:civic]
   [location:@chicago][price:2000...10000]&q=red

For this query, the item type is vehicle.

The Google Base structured query contains the following specifications:

  • The make is honda.
  • The model is civic.
  • The car should be located in Chicago
  • An acceptable price range is between 2000-5000 USD.

The Google Data unstructured query, starting with &q, specifies that the car should be red.

When you build a query on using the dropdown menus on the tutorial page, the resulting query is shown as an alert. You can use this to better understand how queries are constructed.

Using the above example, a partial XML response for a single response might be as follows:

<entry>
   <id>http://www.google.com/base/feeds/snippets/9032647622616759218</id>
   <published>2007-05-07T14:00:04.000Z</published>
   <updated>2007-05-22T23:33:32.000Z</updated>
   <category scheme='http://base.google.com/categories/itemtypes' term='Vehicles'></category>
   <title type='text'>Honda Civic 2000</title>
   <content type='html'></content>
   <link rel='alternate' type='text/html' href='http://www.cars.com/go/search/detail.jsp?tracktype=usedcc&amp;searchType=21&amp;paId=134322625&amp;pageNumber=0&amp;aff=google&amp;PSRCH2=googbase'></link>
   <link rel='self' type='application/atom+xml' href='http://www.google.com/base/feeds/snippets/9032647622616759218'></link>
   <author>
      <name>Cars.com</name>
      <email>foobar@cars.com</email>
   </author>
   <g:make type='text'>Honda</g:make>
   <g:item_type type='text'>Vehicles</g:item_type>
   <g:color type='text'>Red</g:color>
   <g:price type='floatUnit'>8900.0 usd</g:price>
   <g:model type='text'>Civic</g:model>
   <g:location type='location'>Chicago,IL,60638</g:location>
</entry>

Parsing JSON

To use the Google Base data API with JavaScript, you will need to use JSON-format feeds.

JSON is a lightweight data-interchange format. Like XML, it consists of a collection of name/value pairs.

The following excerpt shows the JSON equivalent of the above query response:

{"id":
 {
   "$t": "http://www.google.com/base/feeds/snippets/9032647622616759218"},
   "published":{"$t" :"2007-05-07T14:00:04.000Z"},
   "updated":{"$t" :"2007-05-22T23:33:32.000Z"},
   "category":[{
      "scheme":"http://base.google.com/categories/itemtypes",
      "term":"Vehicles"}],
   "title":{"type":"text","$t":"Honda Civic 2000"},
   "content":{"type":"html","$t":""},
   "link":[{"rel":"alternate",
      "type":"text/html",
      "href":"http://www.cars.com/go/search/detail.jsp?tracktype\u003Dusedcc\u0026searchType\u003D21\u0026paId\u003D134322625\u0026pageNumber\u003D0\u0026aff\u003Dgoogle\u0026PSRCH2\u003Dgoogbase"},{
      "rel":"self",
      "type":"application/atom+xml",
      "href":"http://www.google.com/base/feeds/snippets/9032647622616759218"}],
   "author":[{
      "name":{"$t":"Cars.com"},
      "email":{"$t":"foobar@cars.com"}}],
   "g$make":[{"type":"text","$t":"Honda"}],
   "g$category":[{"type":"text","$t":"VEHICLES"}],
   "g$color":[{"type":"text","$t":"Red"}],
   "g$price":[{"type":"floatUnit","$t":"8900.0 usd"}],   "g$model":[{"type":"text","$t":"Civic"}],
   "g$location":[{"type":"location","$t":"Chicago,IL,60638"}],}

showMakeOptions() uses the resulting list of vehicle makes to populate the Select Make dropdown list in the webpage. showMakeOptions() is defined as follows:

function showMakeOptions(json) {
  // transform the JSON results into a drop down menu
  var select = document.getElementById("make_options");
  select.disabled=false;           // enable the dropdown
  select.onchange=getModels;       
  select.options[select.selectedIndex].disabled=true; // disable the 'Loading...' option
  select.options[select.selectedIndex].text="Select Make";
  
  for (var i = 0; i < json.feed.entry.length; ++i) {
    var entry = json.feed.entry[i];
    
    // find the make entry
    if (entry.title.$t == "make(text)") {
      makeList = entry.gm$attribute.gm$value;
      for (var j=0; j<makeList.length; ++j) {
        var option = document.createElement("option");
        make = makeList[j].$t;
        option.appendChild(document.createTextNode(make));
        select.appendChild(option);
      }
      break;
    }
  }
  document.getElementById("make_div").appendChild(select);
}

Google Maps API

The Google Maps API code displays a map that corresponds to the geographical locations of the results from Google Base. It includes the following functions:

onLoad() draws the map and instantiates the geocoder.
showAddress() creates a market and draws it on the map at the given address.
openInfoWindow() is called when a user clicks on a snippets entry. It opens the info window on the map for the marker that corresponds to that snippets entry.
centerAndZoomMap() centers the map on the markers and sets an appropriate zoom level.

Drawing a map

To add a map using the Google Maps API you need to include three things.

First, register for a Maps API key here and include the following script tag in your program:

<script src="http://maps.google.com/maps?file=api&v=2&key=<Your Maps API key>" type="text/javascript"></script>

Next, create a div where you want to display the map:

<div id="map_div" style="width:100%; height:300px"></div>

Finally, create the map and insert it in the div you created. The following excerpt from onLoad() accomplishes this.

  map = new GMap2(document.getElementById("map_div"));
  map.addControl(new GSmallMapControl());
  map.addControl(new GMapTypeControl());
  map.setCenter(new GLatLng(37.44, -92.25), 3);

Drawing markers to show vehicle locations

The Google Maps API requires latitude and longitude to plot markers, but the locations provided by the Base data API are given as addresses. To plot the markers, showAddress() uses the geocoder from the Maps API:

function showAddress(address, title, alturl, imgLinks) {
  geocoder.getLatLng(
    address,
    function(point) {
      if (point) {
        var marker = new GMarker(point);
        bounds.extend(point);
        centerAndZoomMap();
        //populates array
        markers.push(marker);
        map.addOverlay(marker);
        html = '<a href="' + alturl + '">'+title+'</a>';
        if (imgLinks) {
          html+="<br/>";
          imgIndex = 0;
          while (imgIndex<3) {
            html+='<a href="' + alturl + '"><img height="50" width="50" src="'+imgLinks[imgIndex++].$t+'"/></a>'
          }
        }
        //populates array
        markerHtmls.push(html);        
      }
    }
  );
}

You can make the map zoom in on the appropriate area by keeping track of the bounds of the markers displayed.

The GLatLng point is created with the following code in the showAddress() function:

var marker = new GMarker(point);

The GLatLngBounds point is created with the following code in the onLoad() function:

bounds = new GLatLngBounds();

Each time the application gets a GLatLng point from the geocoder, it adds the point to a GLatLngBounds object.

For more examples of displaying markers, see the Maps API documentation.

This application creates and maintains two global parallel arrays of markers:

var markers = [];
var markerHtmls = [];

These arrays are built by showAddress(). Every time showAddress() is called, it adds a new entry to both arrays.

The openInfoWindow() function uses the data in these arrays to display the map marker that corresponds to the specified Google Base entry.

  markers[markerIndex].openInfoWindowHtml(markerHtmls[markerIndex]);    

Centering and zooming the map

Once all the points have been processed, centerAndZoomMap() zooms the map to the appropriate level:

  map.setZoom(map.getBoundsZoomLevel(bounds));
  map.setCenter(bounds.getCenter());

Cleanup

This tutorial also includes the following housekeeping functions.

clearMarkers() is called before each query to remove old markers from the map.
clearOldAttributes() deletes pre-existing children of the data div from the page.
clearOldSnippets() deletes pre-existing query results from the page.
resetForm() resets the query form.