Geographic data of Google Search with the WebGL Globe

Today we’re sharing a new Chrome Experiment called the WebGL Globe. It’s a simple, open visualization platform for geographic data that runs in WebGL-enabled browsers like Google Chrome. The globe below shows world population, and we’ve created another globe showing Google search traffic.

The primary challenge of this project was figuring out how to draw several thousand 3D data spikes as quickly and smoothly as possible. To do this, we turned to Three.js, a JavaScript library for building lightweight 3D graphics. For each data point, we generate a cube with five faces – the bottom face, which touches the globe, is removed to improve performance. We then stretch the cube relative to the data value and position it based on latitude and longitude. Finally, we merge all of the cubes into a single geometry to make it more efficient to draw.

The second challenge of the project was animating the globe – we wanted it to be fun for the user to manipulate. Thanks to WebGL, we’re able to display thousands of moving points at high frame rates by using the user’s graphics processing unit (GPU) for 3D computations. Each state of the globe has its own geometry and we morph between them with a vertex shader, saving precious CPU resources. Additionally, to make the globe look nice, we took advantage of the possibilities of GLSL and created two fragment shaders, one to simulate the atmosphere and another to simulate frontal illumination of the planet.

Now that we’ve released the globe, we’re hoping that developers like you will create your own. What data will you show on it? If you’re feeling inclined, you can learn more about the data format (represented in JSON) and get the code here. If you create your own globe, please also consider sharing a link with us — at some point in the future, we hope to post a list of interesting globes that have been submitted.

Public data visualization with Google Maps and Fusion Tables

The Bay Citizen is a nonprofit, nonpartisan news organization dedicated to fact-based, independent reporting of issues in the San Francisco Bay Area. We are interested in visualizing public data that is useful to the local community. One such effort is our Bike Accident Tracker. In this post, I’ll present a simple example of how we used Google Maps and Google Fusion Tables to accomplish this.

This is what our accident map looks like:

Want to add our accident map to your site? Here is the code:

[php]<html style=’height: 100%’>
<head>
<script type=’text/javascript’ src=’http://maps.google.com/maps/api/js?sensor=false’></script>
<script type=’text/javascript’>
function initialize() {
var bc_office = new google.maps.LatLng(37.788901, -122.403806);
var map = new google.maps.Map(document.getElementById(‘accident-map’), {
center: bc_office,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var accidents_layer = new google.maps.FusionTablesLayer(433634);
accidents_layer.setMap(map);
}
</script>
</head>
<body onload=’initialize()’ style=’height: 100%; margin: 0px; padding: 0px’>
<div id="accident-map" style=’height: 100%’></div>
</body>
</html>[/php]

That’s it. To test this yourself, just save the raw file, open the file with a browser and you will have a copy of the accidents map running locally on your computer. The code mainly deals with setting up Google Maps, with one critical line that sets up Fusion Table integration:

[php]var accidents_layer = new google.maps.FusionTablesLayer(433634);[/php]

You can expand this integration by filtering the results through the use of Fusion Tables’ sql-like query syntax. As an example, to display accidents from May 2009, change the line above to look like this:

[php]var accidents_layer = new google.maps.FusionTablesLayer(433634, {
query: ‘SELECT FullAddress FROM 433634 WHERE Year=2009 AND Month=5’
});[/php]

A quick gotcha to point out here is that Google Maps v3 only supports a SELECT operation on the location value column. So the location query above works just fine, but the COUNT query needed to get the number of accidents does not work:

[php]’SELECT COUNT() FROM 433634 WHERE Year=2009 AND Month=5′[/php]

Instead, to get the number of accidents in this case, you can use the Fusion Tables API endpoint directly:

[php]https://www.google.com/fusiontables/api/query?sql=SELECT COUNT() FROM 433634 WHERE Year=2009 AND Month=5[/php]

You can see the actual response from the count query here. Because The Bay Citizen is built on the Django framework, we can leverage the Python libraries Google provides for query generation and API calls. Also, since the location query is so similar to the count query, I consolidated the filter logic so it happens on the server side using a jQuery AJAX call. As a result, when users apply a filter, they see an updated map and results bar all thanks to the following few JavaScript lines:

[php]$(‘#filter-form’).ajaxForm({
success: function(responseText, statusText) {
var data = $.parseJSON(responseText);
accidents_layer.setMap(null);
accidents_layer = new google.maps.FusionTablesLayer(433634, {
query: data.map_query});
accidents_layer.setMap(map);
$(‘#filter-results’).html(data.results);
}
});[/php]

I was really happy with this approach. The performance hit is negligible, the code is much cleaner, and the filter logic is rewritten in the programming language I currently know best (Python).

I hope this post gives you a taste of what it’s like to work with Google Maps and Fusion Tables. Also, please note that our data is public and can be referenced at Table #433634. This means you’re free to use the same data we do to develop and design your own map interface. When we update the data, your project will be updated as well.

From our end, we don’t have to worry about our servers being overloaded with data API and map generation calls that come from your project. So by all means, hack away, improve the design, and create a better version. All we ask is that if you do come up with something cool, please link back to us, let us know, and then maybe we can even work together.

Open Trip Planner Portland

A trip planner with a difference

“A trip planner helps you figure out how best to get where you want to go. A multi-modal trip planner lets you plan routes using multiple “modes,” for example, on foot, bike, train, bus, or some combination thereof. A good multi-modal trip planner allows you to easily tailor your trip to your preferences, for example by eliminating transfers, walking a more scenic path, or only riding buses with bike storage.”

What is OpenTripPlanner?

OpenTripPlanner is an open source multi-modal trip planner. It brings together work from a number of existing open source projects, including Graphserver, OneBusAway, and FivePoints, and aims to be easy-to-use, flexible, reliable, and fast.

OpenTripPlanner Portland
Planning a trip is very straightforward – right click to create start point and right click to add destination.
OpenTripPlanner Portland Route
Lots of Options – like Transit only – with changes includes – clearly laid-out.

For Developers

  • Plans true multi-modal trips combining walking, biking and transit
  • Plans wheelchair accessible trips
  • Plans depart by/arrive by trips
  • Takes road type, bike lane, and elevation data into account when planning bike trips
  • Show elevation maps for bike trips
  • Imports data from GTFS, shapefiles, OpenStreetMap, and the National Elevation Dataset
  • Plans trips in about 100ms in a moderate sized city
  • Exposes a RESTful API (XML and JSON), which other apps or front-ends can build on

Try the OpenTripPlanner for Portland
http://maps5.trimet.org/otp/

wiki for developers
http://opentripplanner.org/wiki