;

Creating a provider-agnostic online mapping application - Part 2

Posted : Tuesday, 08 December 2009 19:49:04

This is the second in a series of posts where I exemplify a possible architecture for a web based provider-agnostic mapping application. In part one I detailed the basic functionality required to load and display a map as well as toggle between different providers. In this post I shall build on that example and add the functionality to add content to the map.

For this example I considered a few different approaches to address the question of how best to present to the site visitor an intuitive way to add content. The option I selected was to have a pin icon above the map that the user is able to drag onto the map and release at the desired location. While this may not be the best method, it is fairly simple and quick to implement so ideal for the purpose of this post.

The first step in order to add interactivity to the map we created in part one is to add the pin image above the map div, this will act as a template which users will be able to drag into place on the map. In keeping with the style of the application this pin image is implemented via a combination of some very simple css and html so doesn't warrant any further explanation.

In order to make the pin image draggable I am using the jQuery UI plugins Draggable and Droppable. I have added a mapLoaded() function to the prototype object of the GeoTagger object. This will, when invoked, add the requisite behaviour to the pin in order to make it draggable.

   25 GeoTagger.prototype = {

   26     mapLoaded: function() {

   27         //once map is loaded, make the pin image draggable

   28         $('.pin').draggable({

   29             appendTo: 'body',

   30             zIndex: 100000,

   31             scope: 'droppablemap',

   32             revert: 'invalid',

   33             start: function(event, ui) {

   34                 ui.helper.clickoffsetx = (2 + $('.pin').offset().left - event.pageX) * -1;

   35                 ui.helper.clickoffsety = (29 + $('.pin').offset().top - event.pageY) * -1;

   36             },

   37             helper: 'clone'

   38 

   39         });

   40         //make the map droppable so it can accept dropped pins

   41         //also create drop event handler to add pin to the map where pin is dropped

   42         $('#' + this.MapDivId).droppable({

   43             scope: 'droppablemap',

   44             drop: function(event, ui) {

   45                 var mapX = event.pageX - $('#' + GT.MapDivId).offset().left - ui.helper.clickoffsetx;

   46                 var mapY = event.pageY - $('#' + GT.MapDivId).offset().top - ui.helper.clickoffsety;

   47                 var newPin = GT.Map.addPinAtMapXY(mapX, mapY);

   48                 GT.showPopUp(event.pageX, event.pageY, newPin);

   49             }

   50 

   51         });

   52     }

There are a few things of note here. Firstly we are applying a draggable behavior to the pin and a droppable behavior to the map. Doing so means that certain events (as well as the actual draggable behviour itself) become available. In the start event of the pin's draggable behaviour, the pixel location on the image that the click occurred (relative to the top left corner) is calculated and stored. We are then able to retrieve this value later and use it to calculate the location on the map that corresponds to the tip of the pin in the dragged image when the mouse button is released. We can then ens

  • (This will not appear on the site)