Your way to Google Developer Day 2011

The Open Call HTML5 Challenge for Google Developer Day 2011 kicked off. With 2 weeks time to turn around a submission, participants were asked to design and implement an original HTML5 doodle of the Google Developer day Dymaxion map, adding their own local twist. Doodles had to be built using open web technologies (HTML5, WebGL, etc.) and feature a theme locally relevant to the participant’s GDD host country.

We received submissions from eight countries around the world, which were then reviewed by panels of local HTML5 experts. Overall, the judges were blown away by the creativity and innovation of the submissions. Top entries were selected from each country based on technical execution, creativity, and cultural theming. See below for the judges’ top picks, with descriptions in the creators’ own words. Some of the comments are in the creator’s native language; for translations, use Google Translate. To see a submission in action, click its thumbnail image.

Argentina

Creator: Diego Nul
How did you do it? Just used html5 canvas to do very simple game functionality and transitions. The Dymaxion map turns into an Argentinian flag when the player takes the sun into the map centre.

Creator: Carlos Olivera
How did you do it? I had to made a simple polygonal animation with background music, so, I’ve used Raphael 1.5.2 – JavaScript Vector Library for loading and display figures (SVG), and I’ve used jQuery with Runloop plugin for looping animation; the result is an HTML5 based animation with so few lines of code. The background music is possible with HTML5 element.

Australia

Creator: Peter Finch
How did you do it? The doodle is created using a HTML5 2D canvas element. The Dymaxion map is programmatically generated by subdividing the triangles in the original map into smaller sub-triangles and then drawing all of them in different colours based on a colour map representing the image to be drawn. The colour maps were generated using a Java program that mapped the relative location of the triangle onto a target image and then back onto the page colour map. The waves then merge the images, one on top of another, to create the transition effect.

Creator: Brian McKenna
How did you do it? I imported the Dymaxion map to Blender and then animated it to transform into the Opera House using “shape keys”. The Dymaxion map, Opera House, Southern Cross and stars all rendered using Three.js. Everything else rendered with normal HTML5/CSS3.

Creator: Marko Vuksanovic
How did you do it? Doodle is a manipulation of the Dymaxion map using HTML canvas element. Interactivity is achieved using native drag and drop events and transitions. Animations are used to transition between the iconic landmarks of Sydney.

Brazil

Creator: Bruno Barbosa
How did you do it? Minha ideia foi criar um jogo da memória com as cartas contendo os principais topicos do Google Developer Day 2011. No jogo foi utilizado tecnologias como HTML5, CSS3 e JAVASCRIPT.

Creator: Rogério Celestino Santos
How did you do it? A idéia do jogo é fugir das outras cidades que caem no cenário. Utilizei um código antigo que eu tinha de um jogo simples em html ai então só adicionei as imagens. Fiz algumas mudanças. Mas ainda estou pensando em melhorias como pegar aleatoriamente a imagem correspondente de cada cidade. Tratar imagem de colisão. Poucas coisas ainda. Eu fiz isso hoje em 1 hora. O tempo que me restou.

Creator: Joao Henrique Cunha Rangel
How did you do it? É um jogo de memorizar as cores do Google. O que usei: Tags de audio HTML5, Geolocation para detectar o país do jogador, CSS3 para animar os pontos, CSS3 @font-face, CSS3 Cores gradiente e opacidade.

Creator: Miguel Antonio Silva
How did you do it? 3D objects and animations were created using the program Blender. The movement of the pencils was detected and painted in a 2D canvas html5. The canvas was used as texture for the 3D objects. For the 3D, the library used was Three.js, and for the animations tween.js.

Germany

Creators: Kay Schneider, Misha Matiyenko-Kupriyanov
Music: Hanno E. Allen
How did you do it? Split SVG Dymaxion map template into small png pieces; position PNG pieces with CSS3 into HTML5 Dymaxion map; read wiki about Icosahedron; reverse engineer positioning of Icosahedron faces in space with Google SketchUp; build 3d icosahedron model with CSS3; Web Audio API Loading Sound via XHR in arraybuffer to play it via the Web Audio API and visualise it on the DymaxionMap (zIndex of elements); canvas mapping; triangle human pictures, using canvas clip(); using of the ecma5 script (forEach and much more); triangle videos by applying SVG mask; Germanizing of the nyan cat by rainbow replacing with German flag; nice fonts with Google Web Fonts.

Creator: Josep del Rio Herrera
How did you do it? The GDD’s Dymaxion map is a icosahedron, and each of the little triangles is the location of a GDD event; the doodle uses that icosahedron as the second “o” for a Google doodle. Clicking on it will show the GDD logo and information for the Berlin event. It uses a WebGL canvas to render the icosahedron and the Dymaxion map, and overlays text over it using SVG and CSS3 animations.

Creator: Connor Bunting
How did you do it? Googlespiel is an interactive HTML glockenspiel. It was built using inline SVG, HTML audio and jQuery. It can be played either by clicking on the ‘keys’ with the mouse or by using the keyboard. When Googlespiel loads it play Fur Elise by Beethoven. The key sounds were created using Apple Logic Studio music software.

Japan

Creator: Akira Takegahara
How did you do it?
・「自分の国(日本)をアピールするものである」という課題であるため、文字は毛筆文字、(ベクター)画像は日本の水墨画を採用致しました。
・フォントや画像を含めて全てインラインSVGを使用しております。
ただし、クリエイティブ・コモンズの画像だけは提供されたラスター画像です。
webフォントは使用しておりません。
・提供頂いたOpenCallVisual.svgの画像を基に、文字がモーフィングのように変化致します。当然ながらjavascriptでギミックも実装しております。
・背景画像はラスター画像からSVGに変換して使用しております。
・開発ツールとしては特にAdobe Edgeなどを使用しないで、テキストエディターで作成しております。
・フォント及び背景画像は著作権フリー・改変許可の素材を使用しています。
・三〇秒ぐらいは見て頂ければ幸いです。

Creator: Nanako SAWA
How did you do it?
1. SVGから座標情報を取得
2. canvasで描画
3. 背景, アニメーションを追加

Creator: Shigeki Ohtsu
How did you do it? The title of this doodle is “Thank you the World from JAPAN”. This doodle expresses our gratitude to the people in the world for their hearty support for Japan at the last disaster, with the Japanese traditional style of manner of “OJIGI”. It’s also showing “”Thank you”” tweets all over the world at the location of the Dymaxion map in the background.

Creator: Aiham Hammami
How did you do it? I have been previously creating an object oriented 2d canvas animation library so I used that to create a puzzle game in the shape of the Dymaxion map. It implements MVC design to separate concerns (UI and logic) so it makes the code easy to follow (i hope). I cut up all the photos into triangles manually, then I had to pinpoint exactly where on the rectangular image the triangle vertices were, so I could create accurate mouse overs. Enjoy.

Creator: Risa ITO
How did you do it? SVGとcss3を使って、
日本の色合いを出してみました

Russia

Creator: Valentyn Shybanov
How did you do it? All animations are done using CSS3 transitions – mostly no Javascript is used for it. Triangles are drawn using ‘-webkit-mask-image’: -webkit-canvas()’ trick (canvas as mask). Currently only Google Chrome supports CSS3 ‘mask-image’ so doodle can be watched only on it. Simple quiet music is pre-generated and played by HTML5 Audio.

Creator: Anton Eprev
How did you do it? The idea is to show the Dymaxion map so that it would be like on ignition of a fluorescent lamp. The host country area and text letters continue to flicker after turning on. Requires browsers that support inline SVG.

Creator: Roman Fedorov
How did you do it? I really love this game and I really love Chrome and HTML5. I’ve made this doodle with great pleasure!

Creator: Mikhail Kalinin
How did you do it? This is the Memorize game. I used jQuery library with plugins. For best compatibility with all modern browsers, I used CSS3 2D transform instead of 3D transform.

Creator: Alexey Belozerov
How did you do it? I have used 2 HTML5 canvas objects as layers and performed ‘destination-over’ composition mode to make erasing effect.

Phoebe Peronto is a Developer Marketing Intern working to coordinate the launch of Google Developer Days 2011. She hails from UC Berkeley as a rising senior studying Political Science and Business, and is excited to work with the Google team for summer 2011.

Handling Multiple Spatial Columns

Some spatial data formats can store only a single logical set of features. Any given ESRI shapefile, for example, can store only POINTs, LINESTRINGs, or POLYGONs – not a mixture of each type of geometry. What’s more, all of those geometries must all be defined using the same spatial reference system, as defined in the associated .PRJ file.

Some other formats are more flexible. A SQL Server table, for example, can have many separate geometry or geography columns, and the values can contain both a mixture of geometry types, and even different spatial reference systems within the same column. I frequently use multiple spatial columns as a way of storing pre-calculated geometries relating to each feature at different levels of approximation, or different coordinate systems. For example, suppose that I have a table of features that were originally supplied in EPSG:27700 (OS National Grid of Great Britain). In addition to keeping the original geometry, I re-project those features into EPSG:4326 (WGS84) for displaying on Bing Maps. I also frequently simplify those features (using Reduce()) to create simpler approximations for display at far zoom levels. I keep each of these modified versions of the geometry in separate columns of the same table, named according to the datatype, SRID, and any modifications that have been performed, such as this:

 

CREATE TABLE (
  FeatureID int,
  geom27700 geometry,
  geog4326 geography,
  geog4326_reduce1000 geography
);

 

I came across a situation earlier today trying out Safe FME against a table with this structure that held me up for a few hours, so I thought I’d write about it here.

If you create a Feature Reader from a SQL Server table that has only a single geometry or geography column (as, I suppose, is probably the norm), you don’t need to explicitly specify the name of the column, as Safe FME is intelligent enough to work it out for you. Looking in the log, you’ll see a line that says

MS SQL Server (Spatial) Reader: Spatial column not specified for Feature Type 'dbo.Mastermap'.
Using Column 'GEOMETRY' with type 'geometry'

 

If you’ve only ever used tables with one spatial column, you’ve probably not even noticed this as it shoots past in the log screen – you just drag your MS SQL Feature Reader onto the workspace and use it just as you would use a ESRI shapefile reader, or any other single data source. FME loads the values in the spatial column as features, and the values of all other columns of the table as attributes of those features.

But what if, like me, your source table has more than one spatial column? How do you specify which geometry/geography column should be used in the MSSQL reader to populate the feature type? Well, if you go to the parameters tab of the feature type you’ll see a couple of options:

  • “Specify Geography (geodetic) Column” – Yes if you’re using the geography datatype, or No if you’re using a column of the geometry datatype.
  • Geometry Column Name / Geography Column Name – The name of the column to retrieve.

In my dataset, the source column was of the geometry datatype and named Geom27700, so I set the parameters in my reader feature type as follows:

clip_image001[7]

I then carried on with building my (rather simple) workflow, as follows – check for valid data, reproject to WGS84, orient polygons using the left-hand rule, and then output to a writer:

image

Rather than insert the records into a new dataset, the writer in this case was designed to update the same table from which I’d read the features, but populate the geog4326 column (remember that features had been read from the geom27700 column).

So, I set the Writer Mode to UDPATE, selected the FEATURE_ID (the primary key of the table) as the key on which features would be matched, and set the other  parameters as follows:

Then, I clicked execute.

10 hours later, and FME was reporting that the transformation had been a success, with 48 million rows loaded into the destination table. But when I came to look at the table in SQL Server Management Studio, the geog4326 column that should have been populated by my writer was empty. Blank. NULL. Zilch. Zip.

So, what had gone wrong? I went back and looked through the FME log – everything seemed sound. I tried searching the internet and found some old posts about whether Safe FME supported multiple spatial columns per feature (like this one), so wondered if this was a limitation of the software, but nothing concrete came up. So then I contacted Safe FME’s “Doctors” over twitter. They asked me to send them a simple repro script, so I ditched my original package and started again. I built up a simple script, this time just looking at a test table with 100 rows, and…. it worked.

Much head-scratching later and I found the reason – when you specify the Geometry Column Name or Geography Column Name in a Feature Reader, the entered column is CASE-SENSITIVE, and must match exactly the definition of that column in the database. Frustratingly, there is no drop-down list of columns from which to choose this value – it must be manually typed. What’s more, if you enter the correct column name but using the wrong case, no error will be thrown. The package will run quite happily, in fact, loading all the attribute values from the table, but not the spatial data from the geometry/geography column itself. So your transformation will still load ‘000s of rows from the reader, but not with the (generally rather crucial) spatial feature itself.

For some reason, in this particular case, I’d named the column from which I was reading data GEOM27700 rather than geom27700. This is why, in my earlier example, the geog4326 column was NULL – it’s not that my UPDATE query hadn’t executed – the column had in fact been updated, but with NULL values that had been carried right the way through the FME transformation, since the reader had never successfully retrieved any values from the geom27700 column (since it was actually called GEOM27700).

I found this slightly odd behaviour, since my SQL Server collation itself is not case-sensitive, and will quite happily accept either GEOM27700 or geom27700 in a SELECT statement. What’s also odd is that this same behaviour is not mirrored in the Safe FME MS SQL Writer. In the writer, case sensitivity of the spatial column name is still significant, but if you attempt to specify a column with the wrong case, an error is thrown straight away and you’ll be unable to run the transformation, rather than the “let you carry on but don’t read anything” approach of the reader.

So, a slightly frustrating experience, and 10hrs of processing spent updating a table with a load of NULLs, but never mind – fortunately I’m only still learning Safe FME and this was just an experiment, so no angry clients ringing up asking where their data is (this time)

And, to give credit where it’s due, having found the problem myself I then contacted the FME doctors again over twitter and they immediately replied, acknowledging the problem and informing that an update was in the works. I can think of a few software companies who could learn a thing or two about customer service like that….

by Alastair “Bing” Aitchison

Creating Dynamic Animated Tile Layers in Bing Maps 4

 

If you’ve been following this series of blog posts, you’ll know that I’ve been investigating methods to create an animated background tile layer to display weather maps using the Bing Maps v7 AJAX control.

For this final post, I’m going to wrap everything I’ve done so far into a reusable module.

Bing Maps Custom Modules and the “Ninja” update

The most recent update to the Bing Maps AJAX control, introduced in early May 2011, became slightly notorious as the “ninja” update. The reason being that, silent but deadly, the unannounced update accidentally broke many websites with no warning. Unfortunately, these breaking changes rather eclipsed some of the other nice new features introduced in the update – one of which was the introduction of a common framework through which Bing Maps could be extended by creating custom modules.

Now that the bugs introduced in the latest update have mostly been ironed out, I thought it time to investigate the new module functionality. It’s pretty easy to move your custom code into a module – the main requirement is that, at the end of your function, you place a call to the Microsoft.Maps.moduleLoaded() method. This lets Bing Maps know that your module had been loaded and ready to use.

So, I added the moduleLoaded() call, rolled my animatedTileLayer function into a file and uploaded it to http://www.a3uk.com/bm_modules/animatedtilelayer.js. Note that custom modules registered via the Bing Maps registerModule() method must be placed on a publicly-accessible website – you can’t register a custom module on a local URL. So, when you’re developing a module locally, I recommend that you get it working properly first using a regular embedded script, and then wrap it in a module at the last minute.

To use my new module, I registered and loaded it as follows:

// Register and load the animation module
Microsoft.Maps.registerModule('animatedTileLayerModule', 'http://www.a3uk.com/bm_modules/animatedtilelayer.js');
Microsoft.Maps.loadModule("animatedTileLayerModule", { callback: animationModuleLoaded });

The animationModuleLoaded callback would be fired after the module had loaded, and was responsible for creating a new instance of the animatedTileLayer class and adding it to the map, as follows:

function animationModuleLoaded() {

// Define the array of frame URLs. The URL for the tiles of each frame are
// stored in subdirectories corresponding to each timestamp, named by quadkey
var frames = [
  'http://www.a3uk.com/demos/aniamtedtilelayer/tiles/201105271015/{quadkey}.png',
  'http://www.a3uk.com/demos/aniamtedtilelayer/tiles/201105271030/{quadkey}.png',
  'http://www.a3uk.com/demos/aniamtedtilelayer/tiles/201105271045/{quadkey}.png',
  ...
];

// Create a new instance of the AnimatedTileLayer class
animatedTileLayer = new AnimatedTileLayer(
  map,     // Map instance to which tilelayer should be added
  frames,  // Array of frames of the animation
  {
     framerate: 1000,        // Delay between frame changes (ms)
     loopbehaviour: 'loop',  // Behaviour when last frame is met
     opacity: 1,             // Opacity of tile layer
     mode: 'dangerous',      // Method to use when switching layers
     frameChangeCallback: updateFrameCounter     // Callback on every frame change
   }
);

// Add the tilelayer to the map
map.entities.push(animatedTileLayer);
}

(The options passed to the AnimatedTileLayer constructor are explained in my previous posts). I also added a couple of basic HTML buttons to the page that would control starting, stopping, and resetting the animation, and a text input box that would display the timestamp of the currently displayed frame:

Animation Controls
 

The current frame counter would be updated by the function specified in the frameChangeCallback:

// Callback gets called every time frame changes
function updateFrameCounter(n) {

  // Display the frame counter
  document.getElementById('frameIndex').value = n;

  // Show the timestamp corresponding to this frame
  var t = String(timeStamps[n]);
  document.getElementById('frameTimeStamp').value = t.substr(0, 4) + '-' + t.substr(4, 2) + '-' + t.substr(6, 2) + ' ' + t.substr(8, 2) + ':' + t.substr(10,2);
}

Put it all together and what have you got?

So that’s it – my animatedtilelayer class wrapped into a custom module, registered and loaded from a page that creates a new animated tile layer and calls into a couple of the methods provided by the class.

You can play with (version 1.0) of the final product at http://www.a3uk.com/demos/animatedtilelayer/:

image

To Do:

There’s still a few bugs that I’m aware of that, at some point, I might try to fix:

  • Memory usage (especially in Firefox) seems to be an issue, and grows substantially if the animation is left running for a while – I’m not sure memory from the old tile layers is properly released following entitycollection.clear(), but I haven’t investigated this fully yet. (This problem is also reported by another user here). IE9 and Chrome appear to fare much better.
  • The tile layer vanishes while the map is scrolled (but then reappears when the map has finished scrolling) – this doesn’t seem to be unique to my animated tile layer, but is a behaviour of the way Bing Maps handles custom tile layers in general, so I’m not sure there is anything I can do about it.
  • By necessity of my attempt to pre-load the next tilelayer before displaying it on the map (to enable smoother transitions between frames), there is an initial delay after clicking “Play” before the first frame change. Again, I think this might end up being marked as “by design”!
  • I’m sure there’s more – I haven’t exactly comprehensively QA’d this module, but you’re free to make use of it as you see fit.