26 August 2010
I’ve used my Boris Bikes API which serves live data about bike and docking station availability and Google Earth to create a 3D visualisation that shows the current bike availability across London.
Movie by Andrew Hudson-Smith, Digital Urban/UCL CASA
To use it:
Install Google Earth on your computer if you don’t already have it. It’s a desktop application, not a website.
Go to the Boris Bikes API and click the View live in Google Earth[urldisplaymode=nomap] link. This will download a file called london-cycle-hire.kml to your computer.
Double-click to open the KML file in Google Earth.
You should see the visualisation in the 3D viewer and London Cycle Hire Bike Availability in your Places sidebar.
Move around the view with your mouse. It’s more interesting if you tilt the angle of view and fly between the “buildings” rather than just view it from above. Do this using the four-arrow cluster in the top-right hand of the 3D view.
Once a minute it’ll automatically fetch fresh live data from the API showing where bikes are available. If you open up the disclosure triangles in the Places sidebar you can see the network link icon change from green to orange and start moving when it’s fetching fresh data.
Right-click on London Cycle Hire Bike Availability in your Places sidebar and choose Save to My Places. This moves it out of your Temporary Places so it’ll be available the next time you open Google Earth.
Be kind to my server by unticking the box for this visualisation in your Places sidebar so it’s not constantly loading live data when you’re not looking at it.
The Boris Bikes API is written in the Ruby language using the Sinatra web application framework. You can get the code here on Github.
The 3D Google Earth visualisation is essentially a geographical bar chart generator that updates itself live from the web using a feature called a network link in Google Earth.
Google Earth uses a file format called KML which is its own vocabulary of XML tags. My Ruby application uses the Ruby Builder gem to generate its XML.
The “buildings” that make up the bar chart are Polygons in KML that are placed at an altitude above the surface of the Earth according to the number of bikes currently available at that docking station. I generate a rectangular Polygon starting at the coordinates of the docking station and work clockwise using pre-set offsets of latitudes and longitudes to create the four vertices (corners) of the rectangle, like this:
Vertex Latitude Longitude
1 - top-left
2 - top-right
lat + lat_offset
3 - bottom-right
lat + lat_offset
lng + lng_offset
4 - bottom-left
lng + lng_offset
5 - top-left (again)
The last vertex must be the same as the first to close the loop.
Each vertex is also given an altitude which is the number of bikes currently available multiplied by a constant. This gives us a rectangle floating above the ground which we then specify must be extruded down to the ground to give a solid column.
Google Earth/KML doesn’t let us label Polygons so we also add a Point feature at the same location with the description of the docking station and the number of bikes available written as text. We place this on the top of the extruded Polygon but use a style to effectively remove the Point’s icon so it’s invisible. This gives us a labelled column.
Network links work by downloading a KML file into Google Earth (the “source file”) which then pulls another KML file containing the actual place data according to certain conditions. It can do this periodically (as we do here), when the user changes their view, or when the user moves to a certain region on the Earth.
If you look at the source code for app.rb, the KML source file is generated by this section:
get '/london-cycle-hire.kml' do headers "Content-Disposition" => "inline", "Content-Type" => "application/vnd.google-earth.kml+xml" xml = Builder::XmlMarkup.new( :indent => 2 ) xml.instruct! xml.kml :xmlns => "http://earth.google.com/kml/2.0" do xml.Document do xml.name "London Cycle Hire Bike Availability" xml.NetworkLink do xml.description "London Cycle Hire Bike Availability" xml.Link do xml.href "http://" + hostname + "/stations.kml" xml.refreshMode "onInterval" xml.refreshInterval "60" end end end end end
This tells Google Earth to pull the http://borisapi.heroku.com/stations.kml file every 60 seconds.
Currently this visualisation only shows available bikes not available docks. It could easily be modified to generate the docks instead or perhaps they could be displayed as a second “building” alongside the first in a different colour.
This geographical bar chart visualisation could be applied in countless situations, e.g. showing world cities and their populations.