Saturday, November 16, 2013

UTFGrid in Bing Maps (Part 2 - Bing Maps Module)

Part 1 - Introduction
Part 2 -Bing Maps Module

On this post I'm adapting my previous UTFGrid code and packaging it into a very easy to use Bing Maps Module.

I'm going to show a couple of simple demos on how to use it.

Demo #1 - Basic (try it here)

Very simple demo. Click a country and an alert message will display its name. All this without any round-trip to the server.

Note: in all these demos there are only 4 zoom levels of UTFGrid tiles. Thus, if zooming paste the satellite images, nothing should happen when clicking/hovering the map.

The module is declared similarly to any other Bing Maps module:
 MM.registerModule("UtfGridModule", "js/UtfGridModule.js");
        MM.loadModule("UtfGridModule", {
            callback: function () {
The UTFGrid is created specifying the URL template of the tiles:
var utfGrid = new UtfGrid(map, 'Tiles/World/{z}/{x}/{y}.grid.json');
Then it's simply added to the map.
Obviously, as the UTFGrid is all about client-side interaction, just declaring it like this is not that useful. For this particular demo I defined a callback for the mouseclick event:
var utfGrid = new UtfGrid(map, 'Tiles/World/{z}/{x}/{y}.grid.json', {
    mouseclickCallback: function (result) {

The mouseclickCallback receives a "result" parameter which includes all the metadata associated with the item that is being hovered. For example, tile 4/8/4 (z/x/y) contains the following meta-data:
Thus, the "result" parameter will be an object that contains a field called "NAME" and another one called "POP_EST".

Demo #2 - Onmouseover (try it here)

This demos also displays the same world-map but, while moving the cursor, the country name and population are displayed on a floating-div.

Similarly to what was done for the mouseclick event, on this particular example a callback for mouseover is also defined:
mouseoverCallback: function (result) {
    if (result == undefined) {
        map.getRootElement().style.cursor = "default";
    else {
        var template = _.template($("#countryTemplate").html());
        map.getRootElement().style.cursor = "crosshair";

It uses Underscore's templating engine to change the contents of the floating div.

Demo #3 - Onmouseover AJAX (try it here)

The exact same end-result, but instead of fetching the UTFGrid tiles by JSONP uses regular AJAX calls.

By default, as it's less restrictive, this module loads UTFGrid tiles using JSONP (which was the approach used on the previous examples).

I've added a parameter that allows changing this behavior so that the tiles may be loaded by regular Ajax calls, which sometimes provides a better performance.

So, just declare the UTFGrid as:
    var utfGrid = new UtfGrid(map, 'Tiles/World_ajax/{z}/{x}/{y}.grid.json', {
    mouseoverCallback: function (result) {
Note: The UTFGrid tiles themselves need to be different for JSONP or Ajax calls, hence why the url template is different on this demo.


Here's the full list of supported options for defining an UTFGrid:

- tileSize (default 4) 
The size (in pixels) of each UtfGrid element. Thus, for each raster tile of 256x256, by default there will be an accompanying UTFGrid tile of 64x64.

- maxZoomLevel (default 20): 
Maximum zoom level until the UtfGrid is applied. For example, if set to 10 it means that will be available from zoom level 0 (the furthest away) to level 10.

- jsonp (default true):
Indicates if the tiles should be loaded by JSONP or regular ajax.

- mouseclickCallback (default undefined):
callback that is called when there's a click on an UTFGrid tile

- mouseoverCallback (default undefined):
callback that is called when hovering an UTFGrid tile

- tileLoadedCallback (default undefined):
callback that is executed each time a UTFGrid tile is loaded

No comments:

Post a Comment