The MapQuest Platform provides a powerful means for developers to integrate MapQuest technology into their web applications. In this article, I will demonstrate how to add interactive drawing to a map using the JavaScript-based API. In the resulting application, a user can set up a real-life game of Capture the Flag by drawing components of the game on an online map. You can see the application live here, and you can download the source in a .zip file here.

Regardless of whether they have actually played Capture the Flag, most people can at least picture it in their heads. Traditionally, the game has been played primarily by children, with two teams pitted against each another in a quest to capture the opposing team's flag. Over the years, there have been innumerable variations of this game, in both the computer realm and in real life. In recent years, urban gaming has grown in popularity. Capture the Flag is just one of a number of games that are being played on an ever-increasing scale on the streets of cities throughout North America and Europe. The application that I show you in this article demonstrates how you can use the MapQuest API to facilitate planning this type of game.

Starting From the Same Place

Although the application is not overly complicated, I have set it up a bit differently than the introductory applications in the JavaScript API developer guide. To make things easier to understand, I will introduce a couple of the techniques that I used.

To begin, I have split the application into three separate files: index.html, StyleSheet.css, and jrtmq.js. The focus of this article will be the code, which is contained almost exclusively within the jrtmq.js file. Within this file, I have created a namespace for all of the script, reducing the number of global symbols and allowing the <script> tags in the HTML file to contain just one line of code:

Listing 1 - Called from the <script> tags


Because namespacing is not natively supported in JavaScript, you can use many different techniques to accomplish it. The approach I use is described in David Flanagan's book, JavaScript, The Definitive Guide. Essentially, this approach uses a JavaScript object to define the namespace. The first two lines of the file create that object.

Listing 2 - Basics of a JavaScript namespace

  var jrtmq;
  if (!jrtmq) jrtmq = {};

  (function() {
    // The majority of the code is contained within this function.
    // ******* The Code *********
    // The following declaration assigns the InitMap function to the jrtmq
    // object. This becomes the public portion of the namespace, and is also
    // the only global symbol, reducing the potential for conflicts.

  jrtmq.initMap = InitMap;


The majority of the code for this application is contained within the anonymous function which is called immediately after being loaded into the browser. The final line in that function assigns an initialization function, InitMap, to the jrtmq object that was created at the start of the file. When this method is called, using jrtmq.initMap(), it initializes the application. The remainder of the code (apart from some namespace-wide variables and the initialization function, startUp) resides within five separate objects: InfoBarTextChange, Utilities, ToolboxHandler, Draw, and InitFunc. The focus of this article is interactive drawing, and most of that functionality is contained within the Draw object.

Working with Overlays

The base class for all overlays within the JavaScript API is MQShapeOverlay. Although this application strictly uses MQLineOverlay and MQPolygonOverlay, most of the functionality is inherited from MQShapeOverlay. This means that most of the techniques and methods are the same, regardless of the type of overlay.

The methods that actually do the drawing in the Capture the Flag application are Draw.borders and Draw.finish for polygons, and Draw.flags for points of interest (POIs). (Because of the much simpler nature of placing POIs, I won't discuss this method in the article.) Draw.borders allows the user to draw lines on the map using the MQLineOverlay class. These lines remain on the map while the user is drawing the shape. When the user signifies that the shape is complete, Draw.finish is called, placing an MQPolygonOverlay to replace the lines. I've used a simple HTML button to let users indicate that the shape is complete, but in a more complex application this could be done differently. Utilities.cancelDrawing, the final method in the process, cleans everything up and removes the lines.

Draw.borders is called from an event listener. I will discuss events within the API later in this article. For now, it is sufficient to know that e is the event object that's passed into the method, and that the event we are handling is a click event (note that all events are lowercase). The event object contains a few different pieces of information, but the one we are concerned with is the latitude and longitude (Lat/Long) of the point that was clicked, e.ll.

Listing 3 - Draw.borders

            var myLine = new MQLineOverlay();

            if(startEnd == "start"){
                startEnd = "end";
                ProcessLLFirst = e.ll;
            } else{
	      ProcessLLSecond = e.ll;
                var ProcessLL = new MQLatLngCollection();
                ProcessLLFirst = ProcessLLSecond;

The main components of Draw.borders are the myLine object, the startEnd variable, two MQLatLng objects and two MQLatLngCollection objects.

When the method is first called, startEnd is true. (Although I have not declared startEnd within this method, it is not actually a global variable. It is declared in the anonymous function that encloses all of our code, allowing it to act like a global variable for the purpose of this namespace.) The latitude and longitude of the click are added to both an MQLatLng object and an MQLatLngCollection, UltimateLL. The objects ProcessLLFirst and ProcessLLSecond are used for constructing the lines, and UltimateLL is used for constructing the MQPolygonOverlay by which they will eventually be replaced.

On subsequent clicks, startEnd is false and e.ll is placed into ProcessLLSecond. The two "process" objects are then added to a new MQLatLngCollection, which is passed to myLine. This step is necessary because all of the MQShapeOverlay objects expect an MQLatLngCollection as the argument for their setShapePoints method. Setting the other attributes is fairly straightforward, and a list of all possible attributes can be found in the API developer guide. After the line is added to the map using the addOverlay method, myLine is added to an MQOverlayCollection, Lines, which will eventually be used to remove the lines from the map.

Listing 4 - Draw.finish

                var myColors =
                var myBorders = new MQPolygonOverlay();
                var LLList = new MQLatLngCollection();
                for(var i = 0;i<UltimateLL.getSize();i++){

The method that finishes off the drawing is Draw.finish. As I mentioned above, it is called when the user clicks the Finish button in the toolbox. The method first checks to make sure there are at least two objects present in the UltimateLL collection (preventing an accidental button click from messing things up). If the two objects are present, the method goes on to create a polygon using latitude and longitude coordinates that are contained within the collection. Adding properties to the polygon is fairly straightforward, and is the same as for all MQShapeOverlay objects. There are a couple of things in this method that I will point out, however, before I move on. The first is the Utilities.colorGen method. This method takes a string as an argument and returns an object that contains two string properties representing the border color and the fill color of the polygon.

Listing 5 - Utilities.colorGen


   // For the sake of simplicity, I hardcoded a few values
            // to represent the colors. The ColorGen function could
            // easily be modified to implement a more complicated
            // color selection system. Whatever the system, the function
            // should accept a parameter and return an object containing the
            // two color values.

                case 'red':
                    return { a:"#DF374E", b:"#FFCFCF" };
                case 'green':
                    return { a:"#008F13", b:"#C7AFFF" };
                case 'grey':
                    return { a:"#999999", b:"#ffffff" };

The second thing I will point out is the LLList collection and the for loop. A problem arises when an object with a scope outside of the immediate function is used to populate the ShapePoints of the MQPolygonOverlay. If that object is then cleared (which is necessary to allow drawing multiple overlays) the ShapePoints for the MQPolygonOverlay object are also cleared, causing the overlay to disappear. Assigning the contents of the UltimateLL collection to a new collection one by one seems to eliminate this problem. Other than that, Draw.finish is fairly straightforward. When the polygon has been added to the map, the Utilities.cancelDrawing method is called, which is the universal method within this application for cleaning up loose ends. Before I discuss that method, though, I'm going to take a step back and talk about events within the API.

The MQEventManager

All of the events within the MapQuest JavaScript API are handled by the MQEventManager. Within the Capture the Flag application, after the user selects what they want to draw and the color they want to draw it in, they click the Draw button in the toolbar. This button calls Draw.init, passing it a string representing the object the user would like to draw. For the purpose of this application, there are two choices. Draw.init is the method responsible for initiating the drawing process.

Listing 6 - Draw.init

            clean = false;
            if(draWhat == 'border'){
                MQEventManager.addListener(myMap, "click", Draw.borders);
            } else if(draWhat == 'flag'){
                MQEventManager.addListener(myMap, "click", Draw.flag);

The first thing this method does is check the clean variable. This is just an error-checking variable that is set to false while drawing is in progress. If it is false at this point, something is wrong, so the method calls Utilities.cancelDrawing to clean up before it continues. myMap.enableDragging accepts a Boolean argument and is used to prevent the user from dragging the map, making drawing a lot easier.

The biggest role that Draw.init plays is to add the appropriate event listener, depending on the user's selection. MQEventManager contains four methods, allowing you to add a listener, clear all of the listeners of a certain type, specify a single listener to remove, or trigger a custom event. Each of the first three methods are used at some point in this application. The arguments for the methods are fairly straightforward as well. The first argument is the object to attach the handler to, the second is the event to listen for, and the third is the callback function.

I have mentioned the Utilities.cancelDrawing method a number of times now, because it is called in a few different situations. Its main purpose is to provide a "clean slate" after an overlay has been drawn, or if something goes wrong. It does this by reenabling drawing, resetting the necessary variables and collections, and removing any outstanding lines from the map. This leaves the application in essentially the place that it started but obviously doesn't touch any polygons or POIs that the user has intentionally added. When Utilities.cancelDrawing has been called, the drawing process is complete. Thus, the minimum functionality to allow interactive drawing is contained within the following methods: Draw.init, Draw.borders, and Draw.finish.

	Listing 7 - Utilities.cancelDrawing

            MQEventManager.clearListeners(myMap, "click");
                startEnd = "start";
                ProcessLLFirst = ProcessLLSecond = null;
                for(var i = 0; i < Lines.getSize(); i++){
                clean = true;

Setting Up the Toolbox

The last thing I will discuss before I bring it all together is the toolbox. The code for the toolbox is contained in two main areas: InitFunc.toolbar and the ToolboxHandler object.

InitFunc.toolbar performs a simple task. It is called during the application's initialization sequence, and its sole purpose is to add event handlers to the various elements of the toolbox.

Listing 8 - InitFunc.toolbar

            var boxLinks =
            document.drawMenu.drawType[0].checked = true;
            for(var i = 0;i<boxLinks.length;i++){
                boxLinks[i].onclick =;
            document.getElementById('bt1').onclick =;
            document.getElementById('bt2').onclick =;
            document.getElementById('bt3').onclick =;
            document.getElementById('rb1').onclick =;
            document.getElementById('rb2').onclick =;


I've used three separate event-handling methods, all of which are properties of the ToolboxHandler object. handles all of the links in the toolbox as well as the two drawing buttons. It uses a switch statement and calls a method based on the ID of element that was clicked. The purpose of is to discover whether the user has selected the borders or flags radio button. If the user has selected flags, the handler causes the neutral color to be disabled in the menu. It also causes the information section at the bottom to update, displaying help information related to the current selection.

The following listing shows Using hard-coded coordinates, this method allows the user to select a city from a menu and uses MQTilemap.setCenter() to center the map on that location.

Listing 9 -

                case 'toronto':
                    var StartCoords = new MQLatLng(43.648366, -79.385019);
                case 'newyork':
                    var StartCoords = new MQLatLng(40.720409, -73.994637);
                case 'seattle':
                    var StartCoords = new MQLatLng(47.60629, -122.330624);
                case 'vancouver':
                    var StartCoords = new MQLatLng(49.260281, -123.113463);

Putting It All Together

As I said at the beginning of this article, the only thing we call directly from the HTML file is the jrtmq.initMap method. This method's primary responsibility is calling the initialization function, startUp, after the page has loaded and the required libraries are initialized. initializes the map and adds the zoom control and the map view control, all of which are covered thoroughly in the developer guide.

Listing 10 - Initialization Functions

    // Calls methods to initialize the map, the toolbar, and the text area
    // at the bottom of the page.

    function StartUp(){;

    // The public function that is called directly from the page.
    // It waits for the page 'load' event and the anonymous callback
    // function then uses the MQInitDojo method to call the startUp function
    // once the Dojo Library has been initialized.

    function InitMap(){
            window.addEventListener('load', function() {
              MQInitDojo(StartUp);}, true );
        } else{
            window.attachEvent("onload", function() {MQInitDojo(StartUp);});

    // Assign the public portion of our namespace to the jrtmq class.
    jrtmq.initMap = InitMap;

I haven't covered every aspect of the Capture the Flag application here. To make it more than just an example, I have included greater functionality than could be explained in a single article. Most of the remaining functionality, however, is complementary to the drawing capabilities of the application, and should be fairly straightforward to figure out. The code is commented and organized into objects that are fairly self-explanatory. If you haven't done so already, now is probably a good time to download the files and take a look inside. To bring this all together and provide a bit of context, I will summarize the initialization process of the application. This is a summary of what happens when a user first navigates to the index.html page:

The jrtmq.initMap method is called from the HTML document and starts the initialization sequence using the two main initialization methods, and InitFunc.toolbar). During that sequence, the map is set up and the MQTileMap object is passed to the variable myMap, event listeners are assigned to all of the components in the toolbox, and the information bar is populated with a welcome message. The main elements of the toolbox can be divided into three sections: the drawing section, the utilities section, and the help section. All of the functionality of the application is initiated from the toolbox and handled by,, and ToolboxHandler.cities. Each section of the toolbox has an object associated with it that contains most of the functionality for that section: InfoBarTextChange (used mostly for the help section), Utilities, and Draw. Drawing is accomplished primarily with three methods: Draw.init, Draw.borders, and Draw.finish.

Where to Go from Here

In this application, there are a lot of areas in which you could add functionality: geocoding specific locations, adding a better color selection system, or simply improving the UI. The modularity of this code lets you apply the principles to any number of contexts or add functionality quite painlessly. As an example of this flexibility, I'll be writing a couple of blog posts in coming weeks to demonstrate adding rollover windows to overlays by adding a module to this application.

And finally, here are a few links on urban gaming to get your imagination going: