Book Image

Learning Bing Maps API

By : Artan Sinani
Book Image

Learning Bing Maps API

By: Artan Sinani

Overview of this book

Provided as a part of Microsoft's Bing suite of search engines, Bing Maps is a web mapping service powered by the Bing Maps for Enterprise framework. The need for geospatial data has increased dramatically in the last few years. Adding a mapping context to any location-based data is becoming more and more common, and businesses are embracing it to improve their user experience with new data richness. Comprising of simple, follow-along examples, Learning Bing Maps API will show you how to use the many features of Bing Maps, from dropping a simple map on a web page, to fetching geospatial data from the Microsoft servers. Through the course of this book you will build a solid foundation for creating your own geo-applications.Following the hands-on recipes of this book, you will build a different web app in each chapter as you communicate with different APIs provided by Bing Maps. You will build your own library of JavaScript modules that talk to the Microsoft Maps API.You will create a custom theme for the map, with your own controls. Taking advantage of the global reach of Bing Maps, you will learn how to build a route scheduler for a delivery company in Madrid, Spain, and then you will discover how to create jobs on the Bing Maps servers for geocoding addresses in California, USA. By the end of the book you will have learned everything you need to know to embed a map on a web page, with your own geo-data, or data obtained by the Bing Map Services.
Table of Contents (14 chapters)

Map events


We need our buttons to respond to mouse clicks. Since we added them to the map's root element, we can use the Bing Maps events to add this functionality. Bing Maps AJAX Control provides a rich event system, that can be attached to the map or its entities. Some of the events include click, dblclick, keydown, keypress, imagerychanged, and so on.

Let's add our eventing functionality to a private method, which accepts a context argument, as shown in the following code:

_bind: function(self) {
  Microsoft.Maps.Events.addHandler(this._map, 'click', function(e) {
    if (e.originalEvent && e.originalEvent.target) {
     var btn = e.originalEvent.target;
      if (btn.tagName === 'BUTTON' && btn.className.match(/lbm-btn/) ) {
        if (btn.id === 'lbm-map-btn-maptype') {
          self._changeMapType(btn);
        } else {
          self._zoom(btn);
        }
        e.handled = true;
      }
    }
  });
}

The self argument passed to the _bind function will call any functions declared within it in the module's context. This is necessary, because JavaScript changes the meaning of this inside the handling function from our module to the DOM element firing the event.

We then add an event handler to the map by calling the Microsoft.Maps.Events.addHandler method, which accepts three parameters—the map (or its entity, such as a pin or shape), the name of the event, and the handler function. To the latter is then passed a MouseEventsArgs object, which exposes a few properties and methods (see the full description available at http://msdn.microsoft.com/en-us/library/gg406731.aspx).

One of these properties is originalEvent. It is tied to the DOM event of the clicked element, which can be found by calling e.originalEvent.target. We then make sure that the elements clicked are, in fact, our buttons, and we call the respective handler depending on their ID, and passing it the button clicked as an argument.

We set the handled property to the Events object to true, telling the map to not call any original handlers attached to the same event.

In order for the events handlers to work, we need to call our binding function in the module's constructor, passing it this as the context, because this in the constructor references the module itself. Now the constructor looks as shown in the following code snippet:

lbm.LearningTheme = function(map) {
  this._map = map;
  this._addCss();
  this._addHeader();
  this._bind(this);
};

To implement the handlers, we start with the _changeMapType:

_changeMapType: function(btn) {
  var options = this._map.getOptions();
  if (btn.innerHTML.match(/aerial/i)) {
    btn.innerHTML = 'Road';
    options.mapTypeId = Microsoft.Maps.MapTypeId.aerial;
  } else {
    btn.innerHTML = 'Aerial';
    options.mapTypeId = Microsoft.Maps.MapTypeId.road;
  }
  this._map.setView(options);
}

First, we cache the map's current options by calling the getOptions method. This allows us to change the options object and pass it back to the map later, without having to set all the options.

The handler then checks the text of the button, and it changes the mapTypeId option to the corresponding Microsoft.Maps.MapTypeId enum value. At the end it passes the options back to the map's setView method, which in return changes the map type.

If we open the index.html file on the browser, and click on the Aerial button, we see how the map changes from the road view to the aerial view. The button's text also changes to Road. Clicking on it again, will change its text back to Aerial and the map view to road. The AJAX Control adds a nice animation when changing the map view; it can be disabled by specifying animation: false in the options object.

The _zoom handler looks like this:

_zoom: function(btn) {
  var zoom = this._map.getZoom();
  if (btn.id === 'lbm-map-btn-zoomout') {
    zoom++
  } else if (btn.id === 'lbm-map-btn-zoomin') {
    zoom--
  }
  var options = this._map.getOptions();
  options.zoom = zoom;
  this._map.setView(options);
}

First, we get the map's current zoom value, by calling the getZoom method, and store it on a zoom variable. We then increase or decrease the value of this variable based on which button was clicked. The IDs we specified earlier for the buttons come in handy here, BECAUSE we can easily identify the event target by its DOM ID. Please note that the Microsoft.Maps API will ignore any zoom levels outside the established range between 1 and 20.

We then get the existing view options of the map and extend them with the updated zoom level. As in the previous handler, we pass them to the setView method of the map. After refreshing the index.html file on the browser, we see how our zoom buttons change the map's zoom level as we click on them.