
JavaScript API
Developer’s Guide
Version 5.3.0.1
Copyrights, Trademarks, and Legal Information
Copyright 2008 MapQuest, Inc. All rights reserved. The use of this documentation and the product with which it is provided are governed by the product license agreement and applicable intellectual property laws. No part of the product or this documentation may be reproduced in any form by any means without prior written authorization from MapQuest, Inc. MapQuest may revise this documentation from time to time without notice.
THIS DOCUMENTATION IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND. IN NO EVENT SHALL MAPQUEST, ITS PARENT OR ITS LICENSORS BE LIABLE FOR INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY KIND ARISING FROM ANY ERROR IN THIS DOCUMENTATION, INCLUDING WITHOUT LIMITATION ANY LOSS OR INTERRUPTION OF BUSINESS, PROFITS, USE, OR DATA.
The downloading, exporting, or reexporting of MapQuest products or any underlying information or technology must be in full compliance with all United States and other applicable laws and regulations. Any provision of a MapQuest product or documentation to the U.S. government is with restricted rights as described in the license agreement for that product.
MapQuest, MapQuest.com, the MapQuest logo, Advantage, Site Advantage, Advantage API, and Advantage Enterprise are trademarks of MapQuest, Inc. or its parent AOL LLC. Other product and brand names are trademarks of their respective owners.
Companies, names, and data used in examples are fictitious unless otherwise noted. MapQuest may have patents or pending patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. The furnishing of this document does not give you license to these patents, trademarks, copyrights, or other intellectual property except as expressly provided in any written license agreement from MapQuest. This document and the software described in it are copyrighted, with all rights reserved.
Welcome to the JavaScript 5.3 Developer Guide. The goal of this document is to provide information and procedures about how to use the main features of the Tile Map Toolkit and the JavaScript API samples that utilize the XML over HTTP communication protocol.
This guide assumes the following:
| • | You understand the basics of the JavaScript language. |
| • | You understand the concepts of the MapQuest Platform APIs. |
| • | You will use this guide in combination with a Developer Guide from one of the other languages (for example: Java) that will explain a lot of the usage of the objects contained within the sample JavaScript. |
| • | You understand the limitations of DOCTYPEs. |
Windows
| • | Internet Explorer 6.0 and 7.0 |
This release contains many new enhancements. Refer to MapQuest Platform 5.3 Release Notes for complete information. However, there are features that are important to the JavaScript API. These include:
IMPORTANT
MQA Namespacing
The TileMap toolkit portion of the API has been namespaced to MQA and all MQ leading characters have been removed. For example, it would now be MQA.Tilemap instead of MQTilemap.
| • | 3rd Party Libraries
All 3rd party libraries have been removed from the API (Prototype and Dojo).
|
| • | ShapeCollections
To make it easier to handle multiple shape collections on the map, MQA.ShapeCollection and MQW.ShapeCollection (FUJAX), replace PoiCollection and overlayCollection. POIs and overlays now go into the same collection. Adding, removing, replacing, and appending include new methods. See the documentation for a complete list and examples.
|
| • | Custom Tile Layers
Custom tile layers can now be added to maps which may include your own tiles.
|
| • | Multiple Collections
Multiple shape collections can now be added to the map. A collection can include POIs and Overlays. Once a collection is attached to the map, adding shapes to and/or removing shapes from the collection will be automatically reflected on the map. Decluttering can also be done by collection.
|
| • | Minimum and Maximum Zoom Levels on POIs
Minimum and maximum zoom levels can be set on any POI. The POI would then be visible on the map between the set zoom levels.
|
| • | Retrieving an item by key
A shape (POI or overlay) can now be retrieved from the map or any collection by its key.
|
| • | Remote Collections
KML and GeoRSS support has been built into the API. When creating a RemoteCollection, tell it the location of the feed and its format, and add the Remote Collection using the shapeCollection.add(RemoteCollection) method. (Remote Collections are not currently supported in FUJAX.)
Note
The remote feeds need to be in the same domain as your application – standard XMLHttpRequest (XHR) rules apply. If using ActionScript 3, a crossdomain.xml file with appropriate permissions needs to be at the feed domain.
|
| • | Traffic Flow, Incidents, and Market Data
Traffic information can now be displayed on the map in the form of market data, incident data (construction, incidents, events), and a traffic flow overlay. See the documentation for further information and sample code.
|
| • | Reference to parent collection
A reference to the shape’s (POI or overlay) parent collection can be returned. Because a shape can be in multiple collections, it is important to note that this function returns an array, which will contain one or more ShapeCollection objects.
|
| • | MQMapIcon
The MQMapIcon is now MQA.Icon and is purely an interface, taking the image URL and the setup values in the constructor. For example:
myIcon = new MQA.Icon(imageURL, width, height);
|
| • | Drop Shadow
A visual drop-shadow graphic has been added to the map and can be turned on by calling map.setMapShadowState(Boolean). The shadow is off by default.
|
| • | Declutter Icon
The Poi object now contains a separate declutterIcon for display if the icon is decluttered, instead of using the altIcon.
|
| • | POIs & Overlays Overhaul
These are both now extended off of the same base object and their getters & setters have changed. Examples:
myPoi.setValue(propertyNameAsString, valueObject);
returnedValue = myPoi.getValue(NameAsString);
| – | A .setValues(); method exists that takes literal notation to set as many properties at once as you want. Refer to the documentation for a complete list of property names and examples. |
| – | Existing getters and setters will still function, but are deprecated. Effort should be made to convert these to the new methods. |
|
| 1.5 | Downloading Specific Packages / Modules |
With this release, you now have the ability to request specific packages/modules. By specifying on the URL, you can choose the specific packages to include. This allows you to optimize the size of your download because you specify only the packages you require for your application.
For example, if you want your application to have a traffic control, you can specify to include this package using the &ipkg=controls1,traffic URL name/value pair. However, if your application does not need the traffic control, simply use &ipkg=controls1 and you will save about 12k of download. This concept will be used going forward in order to optimize download sizes and speed.
Note
We have separated out the map controls as a modular package. If you are using our default controls (Zoom Control, View Control, etc.), you will want &pkg=controls1 on the string. If you are using fully customized map controls, you can now eliminate ours from the script download.
ipkg Parameter
| • | controls1 - will bring down all 4 controls (largezoom, zoom, pan, and view). |
| • | traffic - will bring down the traffic package. |
Examples
| • | &ipkg=controls1 - will bring down just the controls package |
| • | &ipkg=traffic - will bring down just the traffic package |
| • | &ipkg=controls1,traffic - will bring down both the controls and traffic packages |
| • | &ipkg=controls1,traffic,package1 - will bring down all packages listed by commas |
| 1.6 | Additional References |
In addition to this document, the following references are available:
| • | Tiled Map Toolkit Developer Reference |
| • | JS-API Developer Reference |
| • | XML Developer Reference |
| • | Sample code HTML pages contained with this guide
|
| 2 | Upgrading from Version 5.2 to Version 5.3 |
To migrate your application to version 5.3, you will need to make some modifications. If you require further assistance after reading this chapter, refer to the API Reference Guide or contact customer support.
The following sections detail each of the changes that require modifications to your code.
| 2.1 | Removal of 3rd Party Libraries |
Prior to 5.3, in order to utilize overlays, a callback function was needed in the form of MQInitOverlays(callback function);. This callback function is no longer needed for 5.3 as the Dojo libraries have been removed and all overlay support is handled by MapQuest.
The TileMap toolkit portion of the API has been namespaced to MQA and all MQ leading characters have been removed. Using any of the following objects will require you to make this change.
| Table 2–1 | Old-to-New Object Comparisons |
| Old Object Name | New Object Name |
|
MQObject
|
MQA.Object
|
|
MQPoint
|
MQA.Point
|
|
MQALatLng
|
MQA.LatLng
|
|
MQObjectCollection
|
MQA.ObjectCollection
|
|
MQLatLngCollection
|
MQA.LatLngCollection
|
|
MQDeclutter
|
MQA.Declutter
|
|
MQEvent
|
MQA.Event
|
|
MQEventManager
|
MQA.EventManager
|
|
MQTileMap
|
MQA.TileMap
|
|
MQInfoWindow
|
MQA.InfoWindow
|
|
MQPoiCollection
|
MQA.ShapeCollection
|
|
MQOverlayCollection
|
MQA.ShapeCollection
|
|
MQMapCorner
|
MQA.MapCorner
|
|
MQMapCornerPlacement
|
MQA.MapCornerPlacement
|
|
MQRectLL
|
MQA.RectLL
|
|
MQRectXY
|
MQA.RectXY
|
|
MQSize
|
MQA.Size
|
|
MQCopyright
|
MQA.Copyright
|
|
MQCopyrightCollection
|
MQA.CopyrightCollection
|
|
MQMapInit
|
MQA.MapInit
|
|
MQPoi
|
MQA.Poi
|
|
MQMapIcon
|
MQA.Icon
|
|
MQRolloverWindow
|
MQA.RolloverWindow
|
|
MQShapeOverlay
|
MQA.ShapeOverlay
|
|
MQRectangleOverlay
|
MQA.RectangleOverlay
|
|
MQLineOverlay
|
MQA.LineOverlay
|
|
MQPolyOverlay
|
MQA.PolyOverlay
|
|
MQEllipseOverlay
|
MQA.EllipseOverlay
|
|
MQImageOverlay
|
MQA.ImageOverlay
|
|
MQImageLevel
|
MQA.ImageLevel
|
Sample Code Snippets:
5.2
myMap = new MQTileMap(document.getElementById(’mapWindow’));
|
5.3
myMap = new MQA.TileMap(document.getElementById(’mapWindow’));
|
5.2
center = new MQALatLng(38.892046,-77.036175);
|
5.3
center = new MQA.LatLng(38.892046,-77.036175);
|
For Poi optimization, the MQMapIcon has been removed and replaced by MQA.Icon. All instances of MQMapIcon will need to be updated.
Note
MQA.Icon has no getters and setters. It is only a constructor. MQMapIcon and its associated functions do not exist any more.
Sample Code Snippets:
5.2
myIcon = new MQMapIcon();
myIcon.setImage("images/Skyscrapers.gif",32,32,true,false);
|
5.3
myIcon = new MQA.Icon("images/Skyscrapers.gif",32,32);
|
| 2.4 | New DeclutterIcon Object |
During POI optimization, we added another icon possibility when utilizing Declutter. A total of three possible icons can display for a POI.
| • | icon: The icon that is displayed upon placing a POI on the map |
| • | declutterIcon: This icon will display when POIs are decluttered |
| • | altIcon: This icon will display for a POI when the altstate is enabled |
| 2.5 | POI and Overlay Changes |
POIs and Overlays are now extended off of the same base object. While the current setters and getters still function, they are deprecated and effort should be made to convert these to the newer methods.
The following are the new property names for POIs that are passed using the setValue and getValue methods.
| Table 2–2 | POI Property Names |
|
key
|
visible
|
|
icon
|
infoContentHTML
|
|
iconOffset
|
infoTitleHTML
|
|
infoWindowOffset
|
maxInfoWindowWidth
|
|
altIcon
|
titleBackgroundColor
|
|
altIconOffset
|
infoWindowTitleText
|
|
altShadow
|
rolloverEnabled
|
|
altShadowOffset
|
labelText
|
|
altInfoWindowOffset
|
labelClass
|
|
declutterIcon
|
labelVisible
|
|
declutterIconOffset
|
draggable
|
|
declutterShadow
|
snapback
|
|
declutterShadowOffset
|
keepRolloverOnDrag
|
|
declutterInfoWindowOffset
|
leaderLineColor
|
|
HTMLContent
|
leaderLineDotImage
|
|
HTMLInfoWindowOffset
|
minZoomLevel
|
|
altStateFlag
|
maxZoomLevel
|
The following are the new property names for Shape Overlays that are passed using the setValue and getValue methods.
| Table 2–3 | Shape Overlay Property Names |
|
key
|
altBorderWidth
|
|
color
|
altStateFlag
|
|
altColor
|
visible
|
|
colorAlpha
|
shapePoints
|
|
altColorAlpha
|
maxZoomLevel
|
|
fillColor
|
minZoomLevel
|
|
altFillColor
|
imageURL
|
|
fillColorAlpha
|
imageLevels
|
|
altFillColorAlpha
|
imageOpacity
|
|
borderWidth
|
|
In versions prior to 5.3, if you wanted to remove all POIs or Overlays from the map, the .removePois or .removeOverlays functions from the TileMapobject were executed. These methods have been removed and should be changed to .removeShapes.
Sample Code Snippets
5.2
myPoi.setInfoTitleHTML(’NEW YORK, NEW YORK’);
myPoi.setInfoContentHTML(’The City So Nice, They Named it Twice!’);
|
5.3
myPoi.setValue(‘InfoTitleHTML’,’NEW YORK, NEW YORK’);
myPoi.setValue(‘InfoContentHTML’,’The City So Nice, They Named it Twice!’);
|
Note
Using the .setValues method allows you to pass multiple properties on one line. The example below demonstrates this for the above two lines.
myPoi.setValues({InfoTitleHTML:’NEW YORK, NEW YORK’,InfoContentHTML:
’The City So Nice, They Named it Twice!’});
|
5.2
OR
5.3
| 2.6 | ShapeCollection Object Replaces PoiCollection and OverlayCollection |
To make it easier to handle multiple shape collections on the map, MQA.ShapeCollection replaces both MQPoiCollection and MQOverlayCollection. Any references to MQPoiCollection or MQOverlayCollection should now be MQA.ShapeCollection. POIs and Overlays can now reside within the same collection. If it becomes necessary to determine what the type of object is within the collection, the getClassName method will return the text name of the class for that object.
| Table 2–4 | Shape Collection Methods |
|
setName
|
Sets the name of the collection.
|
|
getName
|
Returns the name of the collection
|
|
add
|
Adds an object to the collection.
|
|
getSize
|
Returns the size of the collection.
|
|
getAt
|
Returns an object at the specified index.
|
|
remove
|
Removes an object at specified index.
|
|
removeAll
|
Remove all elements from collection.
|
|
contains
|
Function to test if object is in collection.
|
|
removeItem
|
Remove an item by it’s pointer.
|
|
append
|
Appends the specified TKObjectCollection to this TKObjectCollection.
|
|
getItemIndex
|
Returns the index of the specified item in the collection If the item is not found, returns false.
|
Sample Code Snippets
5.2
myPoi = new MQPoi();
myPoiCollection = new MQPoiCollection();
myPoiCollection.add(myPoi);
or
myPoiCollection.remove(myPoi);
|
5.3
myPoi = new MQA.Poi();
myPoiCollection = new MQA.ShapeCollection();
myPoiCollection.add(myPoi);
or
myPoiCollection.remove(myPoi);
|
The following sections provide the basic information and procedures for creating your map.
| 3.1 | Installing the Map Toolkit (Customizing the Include String) |
The Map Tookit needs to be installed before you can do any mapping. As part of this installation, you will need to customize your include string.
After sign up, you receive a unique JavaScript key in your welcome e-mail. You will need to add this key to the <SCRIPT> tag that integrates the Tiled Map Toolkit JavaScript library into your page. If you have lost this key, you can find it on the “My Account” page inside the Developer Network web site. The <SCRIPT> tag, including your key, can also be found on the My Account page for you to copy and paste.

How to Customize the Include String
| 1) | Inside the <HEAD> area, paste in the following snippet to include the Map Toolkit JavaScript library.
<script src="http://btilelog.access.mapquest.com/tilelog/
transaction?transaction=script&key=YOUR_KEY_HERE&itk=true
&v=5.3.s&ipkg=controls1></script>
|
|
| 2) | Update the Key variable (the bit highlighted in bold) that you received in your Welcome letter. |
| 4) | Do not change the itk=true value. This parameter is what integrates the Tiled Map Toolkit into your page. |
Note
You will also need to configure your referer – the referer is the path on your web server from which the pages will be served. This referer can also be edited under the My Account section of the Developer Network web site.
To add a map to your page, follow this procedure.

How to Generate a Map
| 1) | Create a basic HTML page. |
| 2) | Create the customized include string as previously defined. |
| 3) | Create a DIV tag to house the map control. |
| 4) | In JavaScript, create a MQA.TileMap object and pass in the ID of the DIV tag
Note
Do NOT name your DIV the same as your JavaScript object – this causes some problems in IE 6.
The Best Practices with IE 6 are:
| • | Use the <META HTTP-EQUIV="imagetoolbar" CONTENT="no"> in the head. |
| • | It is best to wrap the map start up in a function that is called from BODY onLoad. |
The following code snippet demonstrates these steps (remember to replace the key!) (Page can be seen HERE).
WARNING
Creating a TileMap without setting a center LatLng, as shown below, is not recommended. This behavior has the potential to cause multiple transactions to be charged to your account. To avoid this, ensure your TileMap constructor takes a valid LatLng object as its center.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Quick Map</title>
<!-- THE JS INCLUDE Tag that gets Map Toolkit -
Change Key value to one provided on signup -->
<script src="http://btilelog.access.mapquest.com/tilelog/
transaction?transaction=script&key=YOUR_KEY_HERE&itk=true
&v=5.3.s&ipkg=controls1></script>
</head>
<body>
<!-- The DIV to hold the Map itself -->
<div id="mapWindow" style="width:900px; height:520px;"></div>
<!-- Create the base MQA.TileMap object and pass in the id of
the DIV you
want to hold the map -->
<script language="javascript">
myMap = new MQA.TileMap(document.getElementById(’mapWindow’));
</script>
</body>
</html>
|
This example will give you a map that is at the farthest possible zoom, centered on the geographic center of the United States. Grab and Pan are enabled, but no controls are added.
Note
The functionality that re-centered your map when the user double-clicked on your map has been removed from the JavaScript API so that you can now set the double-click event to do anything you want. If you would like to re-enable this feature, use the following code in your application.
// Add the following listener to the map.
MQA.EventManager.addListener(myMap, ’dblclick’, recenterOnClick);
// Function to call when recentering map on double-click
function recenterOnClick(e)
{
// To animate the map panning to the new center point, use...
myMap.panToLatLng(e.ll);
// To instantly move the map to the new center point, use...
// myMap.setCenter(e.ll);
};
|
|
| 5) | Instantiate the map at a given location and zoom level (and even map type) using the MQA.TileMap constructor. The following is a replacement snippet that sets up a map to be a satellite map at zoom level 9, at a particular latitude & longitude.
<!-- Create the base MQA.TileMap object and pass in the id of the
DIV you want to hold the map -->
<script language="javascript">
myMap=new MQA.TileMap(document.getElementById(’mapWindow’),9,new MQALatLng(40.0446,-76.4131),"sat");
</script>
|
The constructor breaks down to the following:
| • | DIV element to contain the map |
| • | Zoom Level to start at (1 is farthest out, 16 is most zoomed in) |
| • | An MQALatLng object, which takes a latitude and a longitude as its two constructor parameters, which becomes the center of the map |
| • | The type of map displayed – Optional parameter, leave it off for regular map. Options are: map, sat, hyb |
|

How to Change the Center of the Map Programmatically
| 1) | Create a new MQALatLng object and populate it with the Latitude & longitude you want to be the new center. |
| 2) | Call the MQA.TileMap.setCenter function and pass in the MQALatLng (you can also optionally pass in a zoom level too).
(Page can be seen HERE)
Note
A function called from onLoad has been included in this map start to better support IE 6.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Map Constructor</title>
<!-- THE JS INCLUDE Tag that gets Map Toolkit - Change Key value to one
provided on signup -->
<script src="http://btilelog.access.mapquest.com/tilelog/
transaction?transaction=script&key=YOUR_KEY_HERE&itk=true
&v=5.3.s&ipkg=controls1></script>
<script language="javascript">
//Create the base MQA.TileMap object and pass in the id of the DIV you
want to hold the map
function startMap(){
myMap = new MQA.TileMap(document.getElementById(’mapWindow’),9,new
MQALatLng(40.0446,-76.4131),"map");
}
</script>
</head>
<body onload="startMap();">
<!-- The DIV to hold the Map itself -->
<div id="mapWindow" style="width:900px; height:520px:"></div>
<br>
<!-- clickable link to trigger recenter -->
<a href="#" onclick="reCenter();">Recenter on New York</a>
</body>
</html>
|
|

How to Add Controls to the Map
The following default controls are available within the optional Controls1 package. Make sure you have ipkg=controls1 on your API script src tag:
|
ZoomControl
|
A simple +/- control for zooming in and out one level at a time.
|
|
PanControl
|
A compass rose control allowing uses to click arrows to pan.
|
|
ViewControl
|
A map display-type control to allow users to switch to different map types (aerial, hybrid, etc.).
|
|
LargeZoomControl
|
A large zoom control that includes buttons for each of the available zoom levels.
|
| 1) | Create a new control object of the type of control you want, passing in the map object it is to be attached to. |
| 2) | Tell the map to display the control.
Things can get a little more advanced with the optional objects for specifying where you want to the control to show up, instead of its default position. An example of that is shown as follows with the map type control.
| a) | When you tell the map to display the control, also pass in an MQA.MapCornerPlacement() object. |
| b) | The MQA.MapCornerPlacement() object itself takes two parameters:
| • | For example, in the example following, the BOTTOM RIGHT corner of the view control is 20 pixels IN and 20 pixels UP from the bottom-right corner of the map. |
| • | For example, MQA.MapCornerPlacement(MQA.MapCorner.TOP_LEFT, new MQA.Size(10,30)) would place the TOP LEFT corner of the view control 10 pixels IN and 30 pixels DOWN from the top-left corner of the map. |
|
|
| 3) | Replace the startMap function from before with the one below. (Page can be seen HERE)
function startMap(){
//Create the base MQA.TileMap object and pass in the id of the DIV you want to hold the map
myMap = new MQA.TileMap(document.getElementById
(’mapWindow’),9,new MQALatLng(40.0446,-76.4131),
"hyb");
// Create a new Large Zoom control
myLZControl = new MQA.LargeZoomControl;
//tell the map to display the control we just attached
myMap.addControl(myLZControl);
//Create a map view type control
myVControl = new MQA.ViewControl(myMap);
/*
Display control - use the Corner placement constant to specify
which corner, plus an MQA.Size object to specify X and Y "indent"
offset
*/
myMap.addControl(myVControl, new MQA.MapCornerPlacement
(MQA.MapCorner.BOTTOM_RIGHT, new MQA.Size(20,20)));
}
|
|

How to Create a Printer Friendly Map
When you create a printer friendly map, the map is turned into a static image. That is, you can no longer drag and pan or zoom the map while the map is in the printer friendly mode (showStaticMap). Once the printer friendly map is turned off (hideStaticMap), these controls are re-enabled.
| 1) | Create the doPrint function. |
| 2) | Set the view to showStaticMap(); to create the image of the printer friendly map. |
| 3) | To turn off the printer friendly map set the view hideStaticMap.
function doPrint(mode)
{
var myURL = myMap.generatePFUrl(myMap.getSize());
myMap.showStaticMap(myMapInit);
document.getElementById(’results’).innerHTML = myURL;
document.getElementById(’results’).style.visibility = "visible";
//HidePrinterFriendly
myMap.hideStaticMap(myMapInit);
}
|
|

How to Add a Drop Shadow to Your Map
You can now turn a shadow on behind your map that appears off the top and left of the map. You can turn on the map shadow by calling:
map.setMapShadowState(boolean)
|
The shadow is off by default and the boolean values are: True to show shadow and False to hide shadow.
| 4 | Geocoding, Routing, and Searching |
Now that you have created a map, you can use the JavaScript (JS) API to add geocoding, routing, and searching to your map. Before you can do that, however, you need to install the JS API. This installation requires that you complete two procedures: Installing the proxy code and the JS-API files.
There are currently five flavors of sample proxy code available:
| • | Client-side Flash "proxy" |
The purpose of the proxy is twofold:
| • | Circumvent the XML cross domain security issue. A browser can currently only request XML from the same domain as the HTML page arrived from. In other words, you cannot serve a page that requests XML directly from us, it has to come from you, so the Proxy is therefore a routing mechanism to make that happen. |
| • | Secondly, the Proxy also adds in your clientID and password on the way through, so that your authorization credentials are not exposed in any manner within the web browser. |
The proxy code is merely a sample that also works with the sample JavaScript files provided. Once you see how small and simple it is internally, you will realize the extent to which you could customize and transform this component if you wanted to. If you need a proxy in a different language please use one of the existing samples as a basis for creating your own.
Regardless of the version you choose to use, the goal is to get the proxy pages up and running as a web application on your server, in the same domain as you will serve the rest of your application from. Refer to the additional Proxy Pages Configuration Guide, available from the Developer Network
http://developer.mapquest.com.
The following provides an example procedure about installing this proxy code.

How to Install the Proxy Code
This procedure uses .Net as an example.
| 1) | Make sure you have .Net framework 2.0 running. |
| 2) | Unzip the proxy package and copy the JSAPIProxyPage folder to C:\inetpub\wwwroot. |
| 3) | Use IIS to configure the C:\InetPub\wwwroot\JSAPIProxyPage folder as an application. |
| 4) | Each Proxy sample needs to have its configuration edited for your own ClientID and Password (found in your Welcome Letter).
For the .Net version, you will find it in the web.config file, at the bottom – edit the ClientID and Password parameters to be yours.
|
| 5) | You can test it is now working by calling http://<yourwebaddress>/JSAPIProxyPage/TestXML.html in a web browser. |
| 6) | Edit the “Server to send request to” to make sure it is calling YOUR server (http://<yourwebaddress>/JSAPIProxyPage/proxy.aspx?). |
| 7) | Leave the rest of the query string parameters – those define the MapQuest server name, port, and directory that the proxy server will forward requests on to. |

How to Install the JS-API Files
| 1) | Locate the JS-API files inside the API clients package downloadable from the Developer Network web site.
On the download site, you will find three directories: - : - : - :
| • | CompactJS
Use this version if you do not intend to make any changes to the JS files. All comments and whitespace have been stripped to save space.
|
| • | CommentedJS
A commented and more readable form of the JS files, that are easier to modify if, for instance, you wanted to remove unwanted functions to save space.
|
| • | FlashProxyJS
A separate version of the JS files for use specifically with the Flash Proxy. The Flash Proxy requires event handlers to be passed into each EXEC call, because it is asynchronous.
|
|
| 2) | Place these JavaScript files on your server within the same domain as the proxy and web page. Locating them in a different domain will cause you to run into the XML cross-domain permissions issue.
For example, create a subdirectory inside your web application called JS and place them in there.
|
| 3) | Include the following lines in the <HEAD>section of your web page, and edit them to point to the location of the JS files relative to your web page on your server. This assumes you placed them in a subdirectory called JS. Edit the locations as appropriate.
<script src=’js/mqcommon.js’ type=’text/javascript’></script>
<script src=’js/mqutils.js’ type=’text/javascript’></script>
<script src=’js/mqobjects.js’ type=’text/javascript’></script>
<script src=’js/mqexec.js’ type=’text/javascript’></script>
|
Note
| • | The mqcommon.js file should be included before the others. |
| • | The mqcommon.js file should only be included if you are not using the tiled Map Toolkit include. Because at first we are not using the toolkit here, we will initially include it, then remove it when we start using the mapping toolkit again. |
|

How to Geocode an Address
With the sample JS-API, steps have been taken to make sure the structure and usage is as similar as possible to the server-side client APIs that you are already familiar with. One very important item to note is that there are objects in the JS-API that look similar to objects in the Mapping Toolkit. They are not the same, and are different for some very good reasons. An obvious example is MQPointFeature (JSAPI) vs MQA.Poi (Toolkit).
| 1) | Create an MQExec() object that handles connection to the proxy sample, and then on to the MapQuest server.
| a) | The MapQuest servers in production will be the same servers you are used to, so the same process of functionality being split across servers still applies – there are separate Geocode servers, Routing Servers, and Search Servers. |
| b) | You need to configure both the location of the MapQuest server, and the location of your proxy sample. Notice that since I am returning to the same server for proxy as the web pages are being pulled from, all I really need to configure for the proxy server is the Path as a relative value. |
|
| 2) | Create an MQAddress() object and populate it with the address to be geocoded. |
| 3) | Create an empty MQLocationCollection(“MQGeoAddress”) to hold the results when they come back. |
| 4) | Make the geocode call off the MQExec() object, passing in the MQAddress and the empty MQLocationCollection. |
| 5) | Extract the first result in the array of MQGeoAddress objects that get populated into the MQLocationCollection.
The MQALatLng object attached to the MQGeoAddress holds the all important latitude and longitude.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<META HTTP-EQUIV="imagetoolbar" CONTENT="no">
<title>Simple Geocode</title>
<!-- The JSAPI Source files -->
<script src=’js/mqcommon.js’ type=’text/javascript’></script>
<script src=’js/mqutils.js’ type=’text/javascript’></script>
<script src=’js/mqobjects.js’ type=’text/javascript’></script>
<script src=’js/mqexec.js’ type=’text/javascript’></script>
<script language="javascript">
//My Geocode Function
function doGeocode(frm) {
/*
The proxy variables describe to the JSAPI both where my .Net
proxy server is, as the server name, path, and port of the
MapQuest server that gets proxied
*/
//Since it is my server, I can leave these blank, it’s
relative to the page
var proxyServerName = "";
var proxyServerPort = "";
/*
This is the important one. It tells the JSAPI where to
send the XML request (the location of the proxy on my own
server).
*/
var ProxyServerPath = "/JSAPIProxyPage/proxy.aspx";
/* These ones are the location of the MapQuest Server -
in this case, the geocoding server.
*/
var serverName = "geocode.access.mapquest.com";
var serverPort = "80";
var serverPath = "mq";
//This object is the EXEC object, just like you should all
know and love from your server code, with a nice shiny
constructor
var geoExec = new MQExec(serverName, serverPath,
serverPort, proxyServerName, ProxyServerPath,
proxyServerPort );
//An address object, just like in server-side, except
now it has an MQ on the front
var address = new MQAddress();
/*
create a locationCollection object to hold the GeoAddress
objects returned as geocode results. Note that a
locationcollection can contain either address or geoaddress
objects, but not both at once, so you need to tell the
locationcollection which type it will hold in its constructor
*/
var gaCollection = new MQLocationCollection("MQGeoAddress");
//populate the address object with the information from the form
address.setStreet(document.getElementById("street1").value);
address.setCity(document.getElementById("city").value);
address.setState(document.getElementById("state").value);
address.setPostalCode(document.getElementById
("postalcode").value);
address.setCountry(document.getElementById("country").value);
/* Call the geocode function of the exec object - give it
the address object to be geocoded, and the locationcollection to
hold the results
*/
geoExec.geocode(address, gaCollection);
//Get the first geoaddress result out of the collection
var geoAddr = gaCollection.get(0);
//pop-up alert to test the result that came back
alert("Lat: "+geoAddr.getMQALatLng().getLatitude()+" Lng:
"+geoAddr.getMQALatLng().getLongitude()+" Resultcode:
"+geoAddr.getResultCode());
return false;
}
</script>
</head>
<body>
<!--Simple Address interface for geocoding -->
<label>Street</label>
<input size=25 id=street1 type=text value="3710 Hempland Road"
SIZE=50>
<label>City:</label>
<input size=15 id=city type=text value="Mountville" SIZE=25>
<label>State</label>
<input size=5 id=state type=text value=PA SIZE=2>
<label>Zip/Postal:</label>
<input size=10 id=postalcode type=text value=17554 SIZE=5>
<label>Country:</label>
<input size=5 id=country type=text value=US SIZE=2>
<input type="button" onclick="doGeocode()" VALUE="Geocode it">
</body>
</html>
|
|

How to Geocode an Address and Add It to the Map
| 1) | Add the Tiled Map Toolkit JavaScript source tag (remember your key). |
| 2) | Add the JS-API JavaScript source tags MINUS the mqcommon.js. |
| 3) | Add the DIV, the startMap() function, and the onLoad to the BODY tag. |
| 4) | Add the simple geocode form, and link to call the doGeocode function. |
| 5) | Set up the exec object to connect to the geocode server. |
| 6) | Grab the address from the form, populate an MQaddress object, hand it in to the geocode function with an empty MQLocationCollection. |
| 7) | Extract the returning latitude and longitude and add it to an MQLatLng or MQALatLng object. (The JS API MQLatLng and the Map Toolkit MQA.LatLng are the same object. One is merely a namespaced version of the other. |
| 8) | Use that MQALatLng object as the point of both an MQA.Poi and to recenter the map.
<!DOCTYPE HTML PUBLIC "-//Wc3//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<META HTTP-EQUIV="imagetoolbar" CONTENT="no">
<title>Simple Geocode and Map</title>
<!-- THE JS INCLUDE Tag that gets Map Toolkit - Change
Key value to one provided on signup -->
<script src="http://btilelog.access.mapquest.com/tilelog/
transaction?transaction=script&key=YOUR_KEY_HERE&itk=true
&v=5.3.s&ipkg=controls1></script>
<!-- The JSAPI Source files -->
<script src=’js/mqutils.js’type=’text/javascript’></script>
<script src=’js/mqobjects.js’type=’text/javascript’></script>
<script src=’js/mqexec.js’ type=’text/javascript’></script>
<script language="javascript">
//Start the map, add the controls
function startMap(){
myMap = new MQA.TileMap(document.getElementById
(’mapWindow’));
myLZControl = new MQA.LargeZoomControl(myMap);
myMap.addControl(myLZControl, new
MQA.MapCornerPlacement(MQA.MapCorner.TOP_LEFT,
new MQA.Size(20,20)));
myVControl = new MQA.ViewControl(myMap);
myMap.addControl(myVControl, new
MQA.MapCornerPlacement(MQA.MapCorner.TOP_RIGHT,
new MQA.Size(20,20)));
}
//My Geocode Function
function doGeocode() {
//set up the connection to the geocode server
var proxyServerName = "";
var proxyServerPort = "";
var ProxyServerPath = "/JSAPIProxyPage/proxy.aspx";
var serverName = "geocode.access.mapquest.com";
var serverPort = "80";
var serverPath = "mq";
var geoExec = new MQExec(serverName, serverPath,
serverPort, proxyServerName, ProxyServerPath,
proxyServerPort );
var address = new MQAddress();
var gaCollection = new MQLocationCollection("MQGeoAddress");
//populate the address object with the information
from the form
address.setStreet(document.getElementById("street1").value);
address.setCity(document.getElementById("city").value);
address.setState(document.getElementById("state").value);
address.setPostalCode(document.getElementById
("postalcode").value);
address.setCountry(document.getElementById("country").value);
geoExec.geocode(address, gaCollection);
var geoAddr = gaCollection.get(0);
//Put the result on the map with a custom icon
origin = gaCollection.get(0).getMQALatLng();
myIcon=new MQA.Icon("images/Skyscrapers.gif",32,32);
var myPoint = new MQA.Poi(origin,myIcon);
myPoint.setValue("infoTitleHTML",geoAddr.getStreet());
myPoint.setValue("InfoContentHTML",geoAddr.getResultCode());
myMap.addShape(myPoint);
myMap.setCenter(origin,7);
}
</script>
</head>
<body onload="startMap();">
<div id="mapWindow" style="width:900px; height:520px;"></div>
<br>
<label>Street</label>
<input size=25 id=street1 type=text value="3710 Hempland
Road" SIZE=50>
<label>City:</label>
<input size=15 id=city type=text value="Mountville"
SIZE=25>
<label>State:</label>
<input size=5 id=state type=text value=PA SIZE=2>
<label>Zip/Postal:</label>
<input size=10 id=ppostal/code type=text value=17554
SIZE=5>
<label>Country:</label>
<input size=5 id=country type=text value=US SIZE=2>
<input type="button" onclick="doGeocode()"
VALUE="Geocode it">
</body>
</html>
|
|

How to Perform a Search and Add It to the Map
This sample builds on the Geocode and Map sample, adding an extra search function to the overall process. Without stepping through every single line of code, the basic steps to perform a search are:
| 1) | Setup your search criteria object. Depending on the type of spatial search you want to do will decide the specific searchcriteria object you use. Available objects are:
| • | MQRadiusSearchCriteria – for radius searches around a center point |
| • | MQRectangleSearchCriteria – searches a box from an upper left LL to a lower right LL |
| • | MQCorridorSearchCriteria – for searching around a route for example |
| • | MQPolygonSearchCriteria – for searching inside a MQLatLngCollection defining an irregular polygon |
|
| 2) | Define your search source. Normally this is a table of locations uploaded through the Data Manager in the Developer Network web site, so you create a MQDBLayerQuery and a MQDBLayerQueryCollection, just like you were using the server-based API clients. |
| 3) | Define a connection to the spatial server using an Exec object, and perform the search function. You hand in an empty MQFeatureCollection which is populated with the return results – just like the server-based APIs. |
| 4) | To get the results on to the map, you then loop through the MQFeatureCollection, extracting each resulting MQPointFeature object in the collection, and using the data in the object to construct a Tiled Map Toolkit MQA.Poi object. Add each MQA.Poi object to the map. |
| 5) | Call bestFit() on the map to best-fit it around all the search results you have added.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<META HTTP-EQUIV="imagetoolbar" CONTENT="no">
<title>Simple Search and map</title>
<script src="http://btilelog.access.mapquest.com/tilelog/
transaction?transaction=script&key=YOUR_KEY_HERE&itk=true
&v=5.3.s&ipkg=controls1></script>
<!--The JSAPI Source files -->
<script src=’js/mqutils.js’ type=’text/javascript’></script>
<script src=’js/mqobjects.js’ type=’text/javascript’></script>
<script src=’js/mqexec.js’ type=’text/javascript’></script>
<script language=’javascript">
//Set up global vars
//Proxy server variables
var proxyServerName = "";
var proxyServerPort = "";
var ProxyServerPath = "/JSAPIProxyPage/proxy.aspx";
//set up the connection to the geocode server
var geoServerName = "geocode.access.mapquest.com";
var geoServerPort = "80";
var geoServerPath = "mq";
var geoExec = new MQExec(geoServerName, geoServerPath,
geoServerPort, proxyServerName, ProxyServerPath,
proxyServerPort );
//set up the connection to the Spatial search server
var spatServerName = "spatial.access.mapquest.com";
var spatServerPort = "80";
var spatServerPath = "mq";
var searchExec = new MQExec(spatServerName,
spatServerPath, spatServerPort, proxyServerName,
ProxyServerPath, proxyServerPort );
//custom icon used for search origin
var myIcon=new MQA.Icon("images/Skyscrapers.gif",32,32);
//global use objects
var resultPoint = null;
var myMap = null;
//function called onLoad to start the map with a zoom control
function startMap(){
myMap = new MQA.TileMap(document.
getElementById(’mapWindow’));
myLZControl = new MQA.LargeZoomControl(myMap);
myMap.addControl(myLZControl, new
MQA.MapCornerPlacement(MQA.MapCorner.TOP_LEFT,
new MQA.Size(20,20)));
}
function getResults() {
//clear the map
myMap.removeAllShapes();
//geocode the address
var address = new MQAddress();
var gaCollection = new MQLocationCollection();
address.setStreet(document.getElementById
("street1").value);
address.setCity(document.getElementById
("city").value);
address.setState(document.getElementById
("state").value);
address.setPostalCode(document.getElementById
("postalcode").value);
address.setCountry(document.getElementById
("country").value);
geoExec.geocode(address, gaCollection);
var geoAddr = gaCollection.get(0);
origin = gaCollection.get(0).getMQALatLng();
//call search function, get back a
FeatureCollection of results
var searchRes = new doSearch(geoAddr.getMQALatLng());
|
|

How to Perform Single Line Geocoding
Single line geocoding enables you to pass in all of your address in one string, versus breaking it into four pieces as in the past.
| 1) | Select your address you want to geocode. |
| 2) | Enter the single string as shown in the following example.
//create exe object for singleline geocoding request
var myGcExec = new MQExec(mqServer,mqPath,mqPort,myPxyServer,
myPxyPath,myPxyPort);
//create empty string to display results
var strOut = ’’;
//create locationcollection for results
var myLocColl = new MQLocationCollection("MQGeoAddress");
//create a new MQSingleLineAddress object to handle the input address
var mySLA = new MQSingleLineAddress();
//get the address from a textbox on the page
mySLA.setAddress(document.getElementById("selAddress").value);
//call geocode, passing in the single line address to be geocoded
and the empty location collection to hold the reuslts
myGcExec.geocode(mySLA,myLocColl);
//loop through the location collection extracting each address
for (var intA = 0; intA < myLocColl.getSize();intA ++) {
myGeoAddress = myLocColl.get(intA);
myStrOut += "<br/>-----------Location " + intA + "---------
--<br/>";
myStrOut += "LatLng: " + myGeoAddress.getMQALatLng() + "<br/>";
myStrOut += "Result Code: " + myGeoAddress.getResultCode() +
"<br/>";
myStrOut += "Source ID: " + myGeoAddress.getSourceId() + "<br/>";
myStrOut += "Address: <br/>";
myStrOut += myGeoAddress.getStreet() + "<br/>";
myStrOut += myGeoAddress.getCity() + ", " +
myGeoAddress.getState() + "<br/>";
myStrOut += myGeoAddress.getPostalCode() + "<br/>";
myStrOut += myGeoAddress.getCountry() + "<br/>";
}
//output the results in an alert box
alert(mystrOut);
|
|

How to Perform Batch Geocoding
Batch Geocoding enables you to send in multiple addresses in at one time (up to 100 addresses).
| 1) | Select your addresses that you want to geocode. |
| 2) | Pass in the multiple addresses using a single line as shown in the following example.
//add addreses to the location collection for batch geocoding
var myAddr = new MQAddress();
myAddr.setStreet("Centerville Rd. @ 462");
myAddr.setCity("Lancaster");
myAddr.setState("PA");
myAddr.setCountry("US");
myAddressColl.add(myAddr);
myAddr = new MQAddress();
myAddr.setStreet("300 Granite Run Drive");
myAddr.setCity("Lancaster");
myAddr.setState("PA");
myAddr.setPostalCode("17601");
myAddr.setCountry("US");
myAddressColl.add(myAddr);
myAddr = new MQAddress();
myAddr.setStreet("100 Hershey Park Drive");
myAddr.setCity("Hershey");
myAddr.setState("PA");
myAddr.setPostalCode("17033");
myAddr.setCountry("US");
myAddressColl.add(myAddr);
//call batchgeocode, passing in the location collection to
be geocoded and the empty locationcollcoll for the results
myGcExec.batchGeocode(myAddressColl,myGcResultCollColl);
//location collection to be used to get results
var myLocColl = new MQLocationCollection();
//geoaddress for each result in the location collection
var myGeoAddress = new MQGeoAddress();
//empty string for output
var myStrOut = ’’;
//loop through each locationcollection in the
locationcollectioncollection
for (var intB = 0;intB < myGcResultCollColl.getSize();intB ++) {
myLocColl = myGcResultCollColl.get(intB);
myStrOut += "
<br>=========== LOCATION COLLECTION # " + intB + " ======
=============</br>";
//loop throgh the locationcollection extracting
address information
for (var intA = 0; intA < myLocColl.getSize();intA ++) {
myGeoAddress = myLocColl.get(intA);
myStrOut += "<br/>-----------Location " + intA + "-
----------<br/>";
myStrOut += "LatLng: " + myGeoAddress.getMQALatLng()
+ "";<br/>
myStrOut += "Result Code: " + myGeoAddress.getResultCode()
+ "";<br/>
myStrOut += "Source ID: " + myGeoAddress.getSourceId()
+ "";<br/>
myStrOut += "<br/>Address:<br/> ";
myStrOut += myGeoAddress.getStreet() + "<br/>";
myStrOut += myGeoAddress.getCity() + ", " +
myGeoAddress.getState() + "<br/>";
myStrOut += myGeoAddress.getPostalCode() + "<br/>";
myStrOut += myGeoAddress.getCountry() + "<br/>";
myStrOut += "<br/><textarea cols=’75’ rows=’8’>"+
myGeoAddress.saveXml() + "</textarea><br/>";
}
}
//output the results string
alert(myStrOut);
|
|

How to Perform a Route
First we will calculate a route and display the narrative, using just the JSAPI. The full page will contain all the code necessary to complete the entire set of steps below, but the code snippets added here will focus only on those things not previously covered under geocoding.
| 1) | Capture the origin and destination addresses for the route, usually with some form on the page for user-entered addresses. |
| 2) | Geocode these addresses. Each geocode will result in a returned MQGeoAddress object. We need MQGeoAddress objects to set up the routing, so we will preserve these two results (remember each comes inside a MQLocationcollection, so pull them out). |
| 3) | To do a routing call, you need to use several objects:
| a) | A MQLocationCollection containing the MQGeoAddresses of where you want to route between – once you create this, populate it with the two MQGeoAddress objects from our geocode calls. |
| b) | A MQRouteOptions object – in this example we will use default route options, so just need an empty object. |
| c) | An empty MQRouteResults object, which will hold the narrative steps of the route maneuvers. |
|
| 4) | Set up an MQExec() object that points to the route.access.mapquest.com server (or provided route server address that is appropriate for your account type, such as route.dev.mapquest.com or route.free.mapquest.com), then perform the doRoute call from that object. |
| 5) | The MQRouteResults object is now populated with a hierarchical collection that breaks down in the following manner:
| a) | MQRouteResults object contains a collection of MQTrekRoutes
(myRtResults.getTrekRoutes()) – each TrekRoute is a journey or “leg” between two points entered in the locationCollection you passed into the doRoute call. If you only have two addresses (an origin and a destination) then there is only one TrekRoute. The MQRouteResults object contains the time and distance for the entire route. |
| b) | Each MQTrekRoute contains a collection of maneuvers (an MQManeuverCollection) (myRtResults.getTrekRoutes().get(0).getManeuvers()) – A maneuver is a single text driving direction to make a turn or change road, and get to the next maneuver. The MQTrekRoute object contains the time and distance for this particular leg of the journey. |
| c) | Each MQManeuver object contains the time and distance of that particular maneuver, plus a narrative describing the maneuver So, to get the full route maneuvers, first you loop through the MQTrekRoutes (if you have more than two waypoints), then inside of each MQTrekRoute, you grab the MQManeuverCollection and loop through that, grabbing each MQManeuver, and use MQManeuver.getNarrative() to get the text. |
Remember to view the page located HERE for the full source code.
Note
This snippet assumes that you already have a form to capture the two input addresses, as well as having already instantiated certain variables. This code is all found on the actual page.
//---geocodes addresses-----------------------------------------------
function geocodeThem() {
myGExec.geocode(myFAddress, myGcColl);
myRtColl.add(myGcColl.get(0));
myGExec.geocode(myTAddress, myGcColl);
myRtColl.add(myGcColl.get(0));
getRoute();
} //end geocodeThem()
//---performs routing-----------------------------------------------
function getRoute() {
//you need several objects:
//a) the MQLocationCollection containing the waypoint MQGeoAddress
objects
//b) the MQRouteOptions object - default options still require a
blank one
//c) the MQRouteResults object to hold the resulting narrative
myRExec.doRoute(myRtColl,myOptions,myRtResults);
displayIt();
}//end getRoute()
//---displays results-----------------------------------------------
function displayIt() {
// CODE REMOVED FOR CLARITY – CHECK THE PAGE SOURCE
// we want to loop through all the maneuvers in the
maneuvercollection for our trekroute
//we only have one trekroute (only 2 addresses), so we can go
straight to the maneuvercollection
//we loop thru the maneuvercollection - remember it is a
zero-based array, so there is one less than the count
for (intX = 0; intX < myRtResults.getTrekRoutes().get(0).
getManeuvers().getSize(); intX ++){
myManDist = Math.round(myRtResults.getTrekRoutes().
get(0).getManeuvers().get(intX).getDistance()*100)/100;
myManStr = (intX +1) + ". " + myRtResults.getTrekRoutes().
get(0).getManeuvers().get(intX).getNarrative() +
"(DISTANCE:
" + myManDist + " mi)";
myTrkStr = myTrkStr + myManStr + "\n\n";
}
document.getElementById("DDIRResults").value = myTrkStr;
} //end displayIt()
|
|

How to Put the Route on the Map
For this sample we will concentrate only on how to get the route ribbon onto the map itself. Once again, the code snippets in this document only relate to that task. For the complete code sample, refer to the actual page itself.
We are ignoring such niceties as displaying the maneuvers or placing “start” and “end” icons on the map as well – those should be easily accomplishable tasks based on the previous mapping samples in this guide.
To add the route ribbon, the steps are:
| 1) | Make sure both the Toolkit AND the JSAPI are installed on the page (that means you do not need the mqcommon.js file). |
| 2) | Make sure you have an MQLocationCollection object with at least two MQGeoAddress objects in it, with LatLngs on them. |
| 3) | You need all the same objects as before, plus two extra parameters:
| a) | A server-side Session ID. You obtain one by creating a basic server-side MQSession object on the route server, which will hand back a session ID. You need this because we are going to create a special map image that contains nothing but the route overlay, and then ship it to the Map to be overlayed by telling the MQA.TileMap the sessionID to ask for. |
| b) | A blank MQA.RectLL bounding box. The routing engine will populate this with the bounding box coordinates to tell the map the image overlay size and placing. |
|
| 4) | Call the doRoute, including the two extra parameters. |
| 5) | Call MQA.TileMap.addRouteHighlight() passing in the MQA.RectLL bounding box, the location of the MapQuest map server (http://map.access.mapquest.com), or address appropriate for your account, such as map.dev.mapquest.com or map.free.mapquest.com, the sessionID string, and whether or not you want the map best-Fitted to the route ribbon.
Remember to view the page located HERE for the full source code.
This snippet assumes that you already have a form to capture the two input addresses, as well as having already instantiated certain variables – this code is all found on the actual page.
var session = new MQSession();
var routeRes = new MQRouteResults();
var wayPoints = new MQLocationCollection();
var myBB = new MQA.RectLL(new MQALatLng(),new MQALatLng());
wayPoints.add(geoAddr1);
wayPoints.add(geoAddr2);
var routeOpt = new MQRouteOptions();
//create sessionID from the route server
var sessId = routeExec.createSessionEx(session);
routeExec.doRoute(wayPoints,routeOpt,routeRes,sessId,myBB);
myMap.addRouteHighlight(myBB,"http://map.access.mapquest.com",
sessId,true);
|
|
| 5 | Using Remote Collections |
The JavaScript API now has the ability to receive KML and GeoRSS feeds. This feature is implemented by creating a RemoteCollection and then telling the RemoteCollection the location of the feed and its format. You then add the Remote Collection to your map. (Remote Collections are not currently supported in FUJAX.)
Note
The remote feeds need to be in the same domain as your application – standard XMLHttpRequest (XHR) rules apply.
The following procedure provides the basic information for using Remote Collections. For a complete code sample, click
Here.

How to Implement a Remote Collection for a KML File
| 1) | Define the Remote Collection. |
| 2) | Pass in the KML file or URL. |
| 3) | Create the deserialized object.
myRC = new MQA.RemoteCollection("MetroLines3.kml",new
MQA.KMLDeserializer());
|
|
| 4) | Add the Remote Shape Collection to the map.
|

How to Implement a Remote Collection for a GeoRss File
| 1) | Define the Remote Collection. |
| 2) | Pass in the GeoRss file or URL. |
| 3) | Create the deserialized object.
myRC = new MQA.RemoteCollection("hurricaneivan.xml",new
MQA.GeoRSSDeserializer());
|
|
| 4) | Add the Remote Shape Collection to the map.
|
| 6 | Using Multiple Collections |
To make it easier to handle multiple shape collections on the map, MQA.ShapeCollection replaces both PoiCollection and OverlayCollection. POIs and overlays now go into the same collection. Adding, removing, replacing, and appending include new methods.
Note
You do not need to actually use multiple collections if you are making a simple application. The map itself still has a default ShapeCollection, which you can add to and remove from by calling myMap.addShape() and myMap.removeShape().
Some things to consider when using shapeCollection functions:
| • | If a shape gets added to a shapeCollection that is on the map, the shape will be added to the map as well. |
| • | If a shape gets removed from a shapeCollection that is on the map, the shape will be removed from the map as well. |
Click
HERE for a sample and full source code.

How to Use a ShapeCollection on a Map
ShapeCollections can be added to a MapQuest TileMap that allows you to place a variety of items such as POI locations and / or overlays on a map. These layers of information can be added, changed or removed from the map easily. Currently no limit exists to the number of ShapeCollections that can be placed on a map.
The following steps are samples of the steps necessary to create and add ShapeCollections to a map.
Note
These steps assume that the POIs and overlays have already been created.
| 1) | Create an MQA.ShapeCollection object for each collection using the following command:
var myShapeCollection = new MQA.ShapeCollection
|
|
| 2) | Name the newly created collection. This name can be used later to reference a collection on the map.
myShapeCollection.Name = “myPois”
|
|
| 3) | To add elements to the newly created ShapeCollection, use the following:
myShapeCollection.add(poi or overlay object)
|
Note
If a collection is already on the map and an addition or deletion is made to the collection, that change will be instantly visible.
|
| 4) | Issue the following function to place MQA.ShapeCollection objects on the map:
myMap.addShapeCollection(collectionobject)
|
Note
Remove MQA.ShapeCollection objects from the map using the following:
myMap.removeShapeCollection(collectionName)
|
|
| 5) | Retrieve information about the collections currently on the map using the following:
myMap.getShapeCollections (returns an array of collections on the map)
|
Or:
myMap.getShapeCollectionNames (returns an array of the names of
all the collections on the map)
|
Note
Neither of these functions will include the default collection that may or may not be on the map. Maintaining the default shape collection of the map is done through different functions.
|
| 6) | To replace one collection on the map with another collection (if necessary), issue the following function:
myMap.replaceShapeCollection(sourcecollection,targetcollectionname)
|
|
| 7) | To declutter a particular ShapeCollection that is on the map, use the following function:
Note
When many collections are placed on the map, it can become quite cluttered. Declutter functionality exists for each collection.
| • | By default, the declutter flag for each ShapeCollection is set to true. |
| • | When decluttering, the collection object will use the current declutter type on the map, either 1 or 2. |
collectionobject.setDeclutter(true);
|
|
A variety of options are available for adding POIs to your map, including setting the zoom levels and alternate and declutter icons.
getters and setters
With the 5.3 release, the getters and setters have been changed. Now, a .setValues(); method exists that takes literal notation to set as many properties at once as you want.
Note
Existing getters and setters will still function, but are deprecated. You should make an effort to convert these to the new methods.
Zoom Levels
The MQA.Poi object now has functions to handle at which zoom level the items will appear on the map, including the following:
| • | MQA.Poi.setValue(“minZoomLevel”,zoomlevel);
Sets the minimum zoom level at which the POI will be displayed.
Example:
myPoi.setValue(“minZoomLevel”,6);
|
|
| • | MQA.Poi.setValue(“maxZoomLevel”,zoomlevel);
Sets the maximum zoom level at which the POI will be displayed.
Example:
myPoi.setValue(“minZoomLevel”,9);
|
|
Note
Valid zoom levels can be set between 1 and 16.
POI Icons
Three types of POI icons are available (MQA.Icon):
| • | altIcon
Alternate icon (defaults to primary icon if not explicitly set).
|
| • | declutterIcon
Declutter icon (defaults to primary icon if not explicitly set).
|
Additional settings are available for POIs, such as the ability to set the offset, shadow, shadow offset, and infowindow offset for each type of POI icons. Refer to the API Reference for more details of each setting.

How to Add Points of Interest (POIs) to the Map
| 1) | Create an MQA.Poi() object and hand it an MQALatLng() object to specify its location. |
| 2) | Add any additional display text for the infoWindow.
| a) | infoTitle shows up on rollover |
| b) | infoContent shows up below the title text on clicking the POI |
| c) | Other parameters are available, such as setLabel, setLabelVisible, and setRolloverEnabled that are not covered in this document. |
|
| 3) | Add the POI to the map using the MQA.TileMap.addShape() function.
function startMap(){
//Create the MQA.TileMap
myMap = new MQA.TileMap(document.getElementById(’mapDiv’),9,new
MQA.LatLng(40.0446,-76.4131),"hyb");
var newCenterLL = new MQA.LatLng(40.720409,-73.994637);
myMap.setCenter(newCenterLL);
//Create a new MQA.Poi object and set its location
myPoint = new MQA.Poi(newCenterLL);
//set any rollover and pop-up text
myPoint.setValue(’infoTitleHTML’,’NEW YORK, NEW YORK’);
myPoint.setValue(’infoContentHTML’,’The City So Nice,
They Named it Twice!’);
//you can set a Key value to help keep track of the POIs
you put on the map
myPoint.setValue(’key’,’1A’);
//Add the POI to the map
myMap.addShape(myPoint);
|
|
| 4) | Replace the reCenter() function from before with the one below. (Page can be seen HERE)
//Recenter function - hardcoded to NY,NY lat/Lng
function reCenter(){
newCenter = new MQALatLng(40.720409,-73.994637);
myMap.setCenter(newCenter,7);
//Create a new MQA.Poi object and set its location
myPoint = new MQA.Poi(newCenter);
//set any rollover and pop-up text]
myPoint.setValue("infoTitleHTML","NEW YORK, NEW YORK");
myPoint.setValue("infoContentHTML","The City Is So
Nice, They Named it Twice!");
//you can set a Key value to help keep track of
the POIs you put on the map
myPoint.setValue("key","1A");
//Add the POI to the map
myMap.addShape(myPoint);
}
|
|

How to Use a Custom Icon with Your Points
Quite a few functions and objects can be involved in setting up a custom icon, including being able to add shadows and change around the infowindow offsets, etc. However, for the Developer Guide, the goal is the bare minimum to add a custom icon.
Note
Instead of setting a specific icon, you can now pass in an image URL and the setup values in the constructor. For example:
myIcon = new MQA.Icon(imageURL, width, height);
| 1) | Create an MQA.Icon() object, passing the custom image path, filename, width, and height.
myIcon = new MQA.Icon("imagePath/myImage.bmp",20,20);
|
|
| 2) | On the POI that will use it, call MQA.Poi.setValue("icon",myIcon); to assign the icon to the POI. |
| 3) | Replace the reCenter() function from before with the one below.
//Recenter function - hardcoded to NY,NY lat/Lng
function reCenter(){
newCenter = new MQALatLng(40.720409,-73.994637);
myMap.setCenter(newCenter,7);
//create a new icon object and assign image
myIcon = new MQA.Icon("images/Skyscrapers.gif",32,32);
//Create a new MQA.Poi object and set its location
myPoint = new MQA.Poi(newCenter);
//set any rollover and pop-up text
myPoint.setValue("infoTitleHTML","NEW YORK, NEW YORK");
myPoint.SetValue("infoContentHTML","The City So Nice, They Named it Twice!");
//Set the custom icon for the POI
myPoint.setValue("icon",myIcon);
//you can set a Key value to help keep track of the POIs
you put on the map
myPoint.setValue("key","1A");
//Add the POI to the map
myMap.addShape(myPoint);
}
|
|
| 8 | Using Declutter Modes 1 and 2 |
Declutter enables you to clean up your map image when multiple points of interest (POIs) intersect. You have the option of three POI decluttering modes:
| • | 0 = none (no decluttering will occur) |
| • | 2 = leader line decluttering |
To use the declutter feature, you use the following function: MQA.TileMap.getDeclutter().setDeclutterMode(<mode>);. Within this function, you can set these properties for each mode. In addition, you can set a global icon for decluttered POIs using setDeclutterIcon(). Refer to the Toolkit Developer Reference documentation for more information about this implementation.
Note
When in Declutter mode, a decluttered icon will always show its declutterIcon image. By specifically setting a declutterIcon for a POI, you can override the global Declutter icon for that specific POI.
Refer to the following subsections for further information about each mode.
Declutter Mode 1 is Stack Decluttering. provides a linear layout that has the ability to allow the user to page through the POI icons. Declutter Mode 1 offers these capabilities:
| • | Custom Next and Previous Page Images |
| • | Custom Stack Height and Width |
You can set the following properties:
| • | Set Stack Height and Width |
The following graphic shows an example of Decluttering Mode 1.
Decluttering Mode 1 Example
As indicated in this example, the dots indicate multiple POIs. When you click each dot, it indicates where the POI was originally before decluttering it. The red bar across the top indicates the progress of paging through each POI.
This mode is relatively static. That is, you can not move the dots around to rearrange the POIs.
Declutter Mode 2 is Leader Line Decluttering which provides the user the option to do a number of actions with the arrangement of the POIs. Declutter Mode 2 offers the following capabilities:
| • | Custom Leader Line Color |
| • | Custom Dot Mode (0 = no dot, 1 = drawn dot, 2 = dot image)
|
You can set the following properties:
| • | Drag open Rollovers with POIs |
As shown by this example, the POIs are decluttered in a more radial fashion than in Declutter Mode 2. This mode allows the user to drag each icon to arrange them for easier reading. You can set the POI image, the line color, and the anchor dot style.
Overlays enable the user to draw shapes on the map.
The following object types are available for overlays:
For each of these objects, you can set shape points that allow the shape to appear on the map. For each of these, you can zoom in and zoom out, while setting the minimum and maximum zoom levels. In addition, each of these objects have multiple properties that can be set for each of them, such as the border width, color, fill color, minimum and maximum zoom levels, and so on. All properties are derived from the MQA.ShapeOverlay method. Refer to the Tiled Map Toolkit Developer Reference for more information about each of these properties.
Note
With the 5.3 release, the getters and setters have been changed. Now, a .setValues(); method exists that takes literal notation to set as many properties at once as you want.
Existing getters and setters will still function, but are deprecated. You should make an effort to convert these to the new methods.

How to Add an Overlay to a Map
This procedure shows the steps and code necessary to add an overlay (in this case, a polygon overlay).
| 1) | Set the overlay shape to the correct object type. |
| 2) | Define the border width. |
| 5) | Set the shape points to the latitude and longitude collection. |
| 6) | Set the shape points to specific latitude and longitude values. |
| 7) | Add the polygon to the map.
myPolygonOL = new MQA.PolygonOverlay();
myPolygonOL.setValue("borderWidth",2);
myPolygonOL.setValue("color","#00FF7F");
myPolygonOL.setValue("fillColor","#00FF7F");
var myShapePts = new MQALatLngCollection();
myShapePts.add(myMap.pixToLL(new MQA.Point(500,500)));
myShapePts.add(myMap.pixToLL(new MQA.Point(700,500)));
myShapePts.add(myMap.pixToLL(new MQA.Point(800,200)));
myShapePts.add(myMap.pixToLL(new MQA.Point(600,300)));
myPolygonOL.setValue("shapePoints",myShapePts);
myMap.addShape(myPolygonOL);
|
|
| 9.1 | Using the Image Overlay |
The Image overlay is a graphic (jpg, gif, png, and so on) that can be put on top of the map that is generated in a different program. The opacity of the overlaid image is a function of the MQA.ImageOverlay object. The placement of the Image overlay is determined by the top left corner at the designated Latitude/Longitude and the bottom right at the designated Latitude/Longitude levels.
You can also zoom in and out on this Image overlay, but at a certain point the image may distort. The Image Overlay object can accept an array of images that corresponds to the 16 zoom levels available within the API. The API will automatically select the nearest assigned image to the currently displayed zoom level. This allows for the use of higher resolution images when zoomed in to avoid pixilation.
You can clone overlays from a previously constructed overlay into a new overlay constructor. That new overlay inherits all of the properties of the cloned overlay. Cloned overlays must be the same type as the original (ellipses from ellipses, rectangles from rectangles).
To do this, you pass in the cloned overlay to the new overlay’s constructor. For example, you can use the following argument:
var newOverlay = MQA.PolygonOverlay(oldOverlay);
|
Note
The overlay objects also have a setValues method that accepts all properties at once. This function accepts Name / Value pairs for each property. For example:
myOverlay.setValues({key:document.getElementById("skey").value,color:
document.getElementById("scolor").value});
|
For more information about cloning, refer to the JavaScript API Developer Reference for more information.
Overlay objects also have a set of events associated with them. The following events are available for overlays:
Note
You can click on the map through an overlay and have them work as expected. If the map receives a click event that is through an overlay, the MQA.Event object will contain a .srcObject object that contains the overlay clicked on. By checking whether or not the .srcObject is NULL, you can determine whether the click was on a bare piece of the map or through an overlay.
| 10 | Using BestFit on Map Load |
This release includes an MQA.MapInit object that provides a BestFit on Map load. This enables you to BestFit your map around your POIs at moment of instantiation, which eliminates extra transactions and tile loads. You can create a BestFit rectangle based on what you know about your POIs. You can pass this information into the map when you start.

How to Use BestFit on Map Load
| 1) | Create an MQA.ShapeCollection. |
| 2) | Create MQA.Pois and add them to the MQA.ShapeCollection. |
| 3) | Get the MQA.ShapeCollection.getBoundingRect() (which is an MQA.RectLL) and pass it to the MQA.MapInit.setBestFitRect().
MQA.MapInit.setBestFitRect(MQA.ShapeCollection.getBoundingRect());
|
|
| 4) | Configure any further BestFit options you want on the MQA.MapInit object. For a map start, for example, if you want a pixel margin around the edge, you would use the following: (MQA.MapInit.setBestFitMargin()). |
| 5) | Start your map by passing the MQA.MapInit object into the constructor.
myMap = new MQA.TileMap( document.getElementById(’mapview’),
zoom, center,’map’,myMapInit );
|
This will start the map at the necessary zoom level and coordinates to fit your ShapeCollection on the map.
|
| 6) | Add your ShapeCollection. |
Your map can now display traffic market indicators, flow data, and incident data. Additionally, a traffic control can be added to your map that enables you to add the same traffic functionality that you see on www.mapquest.com to your maps.
| 11.1 | Adding Traffic to Your Map |
The simplest way to add traffic is to add the Traffic Control to your map using the following:
myMap.addControl(new MQA.TrafficControl());
|
The traffic control itself has a lot of configurable parameters to customize the legend. However, each part of the traffic functionality is available separately and is completely customizable.
The Traffic API is composed of three main items:
| • | Traffic Market Indicators:
Icons that will display on the map at zoom levels 2-6, showing that traffic is available for that area. Valid JSON traffic market data elements include:
An example of how these data elements would be implemented include:
function modifyMarketContent(data)
{
var s;
s = ’Latitude/Longitude: ’;
s += data.latitude + ’,’ + data.longitude;
return s;
}; // end modifyMarketContent
|
|
| • | Traffic Flow Data:
Image that is displayed on the map indicating whether or not the flow of a particular road is good (green), slow (yellow) or stopped (red). Traffic flow will display from zoom levels 7-16.
|
| • | Traffic Incident Data:
Incidents that are displayed on the map for construction, traffic incidents, and events. Valid JSON traffic incident data elements include:
An example of how these data elements would be implemented include:
function modifyMarketContent(data)
{
var s;
s = ’Latitude/Longitude: ’;
s += data.latitude + ’,’ + data.longitude;
return s;
}; // end modifyMarketContent
|
|
Note
To use the traffic API feature, you must include the traffic parameter in the query string. The parameter you must use is:
The following procedure provides the basic information for getting traffic on your map. For a complete code sample, click
Here.

How to Add Traffic to Your Map
| 1) | Declare a new MQA.Traffic object.
myTraffic = new MQA.Traffic(myMap);
|
|
| 2) | Set the traffic call backs for incidents and markets.
myTraffic.setValue("incidentTitleCallback",incidentcallbacktitle);
myTraffic.setValue("incidentContentCallback",incidentcallbackcontent);
myTraffic.setValue("marketTitleCallback",marketcallbacktitle);
myTraffic.setValue("marketContentCallback",marketcallbackcontent);
|
|
| 3) | Check to see if traffic is available.
Or:
myTraffic.getValue("visible");
|
|
| 4) | Add traffic event listeners.
function addEvents()
{
//add traffic event listeners
MQA.EventManager.addListener(myTraffic,’flowadded’,addEventName);
MQA.EventManager.addListener(myTraffic,’flowremoved’,
addEventName);
MQA.EventManager.addListener(myTraffic,’marketsadded’,
addEventName);
MQA.EventManager.addListener(myTraffic,’marketsremoved’,
addEventName);
MQA.EventManager.addListener(myTraffic,’markettimeout’,
addEventName);
MQA.EventManager.addListener(myTraffic,’incidentsadded’,
addEventName);
MQA.EventManager.addListener(myTraffic,’incidentsremoved’,
addEventName);
MQA.EventManager.addListener(myTraffic,’incidenttimeout’,
addEventName);
document.getElementById("btnEvents").value =="Remove Events"
//remove traffic event listeners
MQA.EventManager.removeListener(myTraffic,’flowadded’,
addEventName);
MQA.EventManager.removeListener(myTraffic,’flowremoved’,
addEventName);
MQA.EventManager.removeListener(myTraffic,’marketsadded’,
addEventName);
MQA.EventManager.removeListener(myTraffic,’marketsremoved’,
addEventName);
MQA.EventManager.removeListener(myTraffic,’markettimeout’,
addEventName);
MQA.EventManager.removeListener(myTraffic,’incidentsadded’,
addEventName);
MQA.EventManager.removeListener(myTraffic,’incidentsremoved’,
addEventName);
MQA.EventManager.removeListener(myTraffic,’incidenttimeout’,
addEventName);
document.getElementById("btnEvents").value =="Add Events"
}
|
|
| 5) | Set the traffic properties. Refer to the available properties and code samples listed in the next section. |
| 6) | Add traffic market icons.
|
| 7) | Add traffic incidents to the map.
myTraffic.addIncidents();
|
|
| 8) | Add traffic flow to the map.
|
| 9) | Determine the contents of the Infowindow Title and the contents of the Infowindow that will be displayed for Market Data.
| • | The marketcallbacktitle function sets the title of the rollover window that displays when the mouse is moved over the market data icon. |
| • | The marketcallbackcontent function sets the contents of the window when the icon is clicked. |
function marketcallbacktitle(data) {
return data.city + ’, ’ + data.state;
}
function marketcallbackcontent(data) {
var s;
s = ’Click <a href="#" ’;
s += ’onclick="myMap.setCenter(new MQA.LatLng(’;
s += data.latitude + ’,’ + data.longitude;
s += ’), 7)">here</a> to zoom in.’;
return s;
}
|
|
| 10) | Determine the contents of the Infowindow Title and the contents of the Infowindow that will be displayed for Incident Data.
| • | The incidentcallbacktitle function sets the title of the rollover window that displays when the mouse is moved over the incident data icon. |
| • | The incidentcallbackcontent function sets the contents of the window when the incident icon is clicked. |
function incidentcallbacktitle(data) {
return data.incidentType + ’, ’ + data.title;
}
function incidentcallbackcontent(data) {
var s;
s = data.description;
return s;
}
|
|
| 11) | Set the timeout duration.
myTraffic.setTimeoutDuration(200);
|
This function sets the timeout duration in milliseconds before failing the request. If not set, the default is 10 seconds.
|
| 12) | Refresh the traffic data.
function doRefresh() {
myTraffic.refresh();
}
|
This function makes a new call to the traffic service which updates the map with the latest information.
|
The following properties are available for traffic:
Traffic Flow Image Opacity
The opacity is a float value from 0 to 1.
myTraffic.setValue("flowOpacity",0.5);
|
Timeout Duration
This function sets the timeout duration in milliseconds before failing the request. If not set, the default is 10 seconds.
myTraffic.setValue("timeoutDuration",5000);
|
Traffic Severity Colors
var scolor = new Array();
scolor.push("#FFFAB2","#FBD7A1","#F6B28F","#F0888A","#E3372E");
myTraffic.setValue("severityColors",scolor);
|
InfoWindow Width
This function sets the width of the InfoWindow that displays for a traffic incident. The default value is 285 pixels.
myTraffic.setValue("maxInfoWindowWidth",350);
|
Traffic Severity Text
var stext = new Array();
stext.push("Minimal0","Minimal1","Moderate2","Moderate3","Severe4");
myTraffic.setValue("severityText",stext);
|
Set Market Icon
myTraffic.setValue("marketIcon",new MQA.Icon
("http://www.aolcdn.com/mqapi/mq00204",20,20));
|
Set Incident Icons
var incIcons = new Array();
incIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00011",20,20));
incIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00012",20,20));
incIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00013",20,20));
incIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00014",20,20));
incIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00015",20,20));
myTraffic.setValue("incidentIcons",incIcons);
|
Set Construction Icons
var conIcons = new Array();
conIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00031",20,20));
conIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00032",20,20));
conIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00033",20,20));
conIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00034",20,20));
conIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00035",20,20));
myTraffic.setValue("constructionIcons",conIcons);
|
Event Icons
var evntIcons = new Array();
evntIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00231",20,20));
evntIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00232",20,20));
evntIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00233",20,20));
evntIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00234",20,20));
evntIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00235",20,20));
myTraffic.setValue("eventIcons",evntIcons);
|
Traffic events are handled the same as other events within the TileMap Toolkit. You need to utilize the MQA.EventManager to add or remove events.
| Table 11–1 | Traffic Events |
| Event Name | Returned Event Names |
|
flowadded
|
MQA.Traffic.flowadded
|
|
flowremoved
|
MQA.Traffic.flowremoved
|
|
marketsadded
|
MQA.Traffic.marketsadded
|
|
marketsremoved
|
MQA.Traffic.marketsremoved
|
|
markettimeout
|
MQA.Traffic.markettimeout
|
|
incidentsadded
|
MQA.Traffic.incidentsadded
|
|
incidentsremoved
|
MQA.Traffic.incidentsremoved
|
|
incidenttimeout
|
MQA.Traffic.incidenttimeout
|
| 11.4 | Traffic Control Button |
The traffic control button enables you to add the traffic functionality to your map. The following graphic shows an example of a map with the traffic control implemented.
The Traffic Control button at the top is the control’s main button that always goes in the upper left corner by default due to the construction of the graphic. It can be changed after construction by setting the position property. The “legend” is shown in the lower right hand corner. This placement can be set using the legendPosition property.
Traffic can be added to your map using the following:
myMap.addControl(new MQA.TrafficControl());
|
Note
This is the default method that gives you access to all the properties. If you want to make any modifications to the defaults, create the traffic control as a variable and then add it.
The placement and appearance or the traffic control and the legend can be set using properties as described in the next section.
The following properties are available for the traffic control button and the legend.
position
position: MQA.MapCornerPlacement
The position of the control’s main activation button.
The following sample code will place the activation button in the upper left corner of the map.
myTrafficCtrl.setValue(‘position’, new MQA.MapCornerPlacement
(MQA.MapCorner.TOP_LEFT, new MQA.Size(0,0)));
|
legendPosition
legendPosition: MQA.MapCornerPlacement
The position of the legend. Because the legend is draggable, this is best used for setting up the starting position of the legend.
The following sample code will initially place the legend in the lower left corner of the map.
myTrafficCtrl.setValue(’legendPosition’,new MQA.MapCornerPlacement
(MQA.MapCorner.BOTTOM_LEFT, new MQA.Size(0,0)));
|
legendIconImages
legendIconImages: Array of MQA.Icon
Maximum five-element array to specify what icons to use for the icon column of the legend.
Example:
var incIcons = new Array();
incIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00011",20,20));
incIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00012",20,20));
incIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00013",20,20));
incIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00014",20,20));
incIcons.push(new MQA.Icon("http://www.aolcdn.com/mqapi/mq00015",20,20));
myTrafficCtrl.setValue(’legendIconImages’,incIcons);
|
legendIconText
legendIconText: Array of Strings
Maximum five-element array to specify what text to use to label the icons set by legendIconImages. The array size must match the array set for legendIconImages.
Example:
var stext = new Array();
stext.push("Minimal0","Minimal1","Moderate2","Moderate3","Severe4");
myTrafficCtrl.setValue(’legendIconText’,stext);
|
legendIconsVisible
legendIconsVisible: Boolean
Specifies whether the icon part of the legend is visible.
Example:
myTrafficCtrl.setValue("legendIconsVisible",true);
|
legendFlowVisible
legendFlowVisible: Boolean
Specifies whether the flow color part of the legend is visible.
Example:
myTrafficCtrl.setValue("legendFlowVisible",true);
|
legendCheckboxes
legendCheckboxes: Array of Boolean
Three-element array to specify which check boxes to show for the control. The order is [Incident, Construction, Event]. True or False indicates which element to show.
The following example will enable all three check boxes for the control.
myTrafficCtrl.setValue(’legendCheckboxes’,[true,true,true]);
|
legendSliderVisible
legendSliderVisible: Boolean
Specifies whether the flow opacity slider is visible.
myTrafficCtrl.setValue("legendSliderVisible",true);
|
traffic
traffic:Traffic object
Used to access the Traffic object on the map that is associated with the Traffic Control.
Example:
var myTraffic = new MQA.Traffic();
myTraffic = myTrafficCtrl.getValue(’traffic’);
|
The Traffic Control events are handled the same as other events within the TileMap Toolkit. Utilize the MQA.EventManager to add or remove events.
| Table 11–2 | Traffic Control Events |
| Listener | Event Names |
|
activate
|
MQA.TrafficControl.activate
|
|
deactivate
|
MQA.TrafficControl.deactivate
|
|
legendclose
|
MQA.TrafficControl.legendClose
|
|
legendopen
|
MQA.TrafficControl.legendOpen
|
|
refreshclick
|
MQA.TrafficControl.refreshClick
|
|
incidentclick
|
MQA.TrafficControl.constructionClick
|
|
constructionclick
|
MQA.Traffic.incidentsremoved
|
|
eventclick
|
MQA.TrafficControl.eventClick
|
|
helpclick
|
MQA.TrafficControl.helpClick
|
| 12 | Using Custom Tile Layers |
Custom tile layers are tile layers that you can create on your own, that will appear as content on a MapQuest map. By creating a custom layer, that data now is subject to all map operations automatically, for example, dragging and panning. For example, weather applications can consist of many custom tiles with each layer depicting its own content. The individual tile size has to be 256 x 256 for the custom layer. One approach is to create several small tiles from one large image.
The following subsections detail the information necessary to create and add a custom tile layer to your map.
MQA.ImageTile Class
The base image tile class that constructs the new MQA.ImageTile object is the MQA.ImageTile class. This extends the MQA.BaseTile object.
| Parameter | Type | Description |
|
parent
|
object
|
DIV element to contain the tile
|
|
left
|
integer
|
Left position in XY coordinates of the upper left corner of the tile
|
|
top
|
integer
|
Top position in XY coordinates of the upper left corner of the tile
|
|
gridColumn
|
integer
|
The column number of the tile
|
|
gridRow
|
integer
|
The row number of the tile
|
|
scale
|
integer
|
The map scale of the tile
|
|
zoom
|
integer
|
The zoom level of the tile
|
|
size
|
integer
|
The length in pixels of each side of the tile
|
|
opacity
|
float
|
The opacity of the tile (0 to 1)
|
Projection
The type of projection used for the custom tile layers is the Lambert Equirectangular projection with a standard parallel of 37.5 degrees and a spherical earth (km= 6378.160187 & mi=3963.205). The closest known Datum that lines things up on our actual output is Australia 1984.
Tiling Coordinate System
Tile 0,0 is at -90 lag, -180 lng.
PIXELSPERLATDEGREE = 315552459.66191697
PIXELSPERLNGDEGREE = 250344597.90989706
TILESIZE = 256
def getRowTile(LAT, SCALE):
| • | y = (LAT + 90.0) * (PIXELSPERLATDEGREE / SCALE) |
| • | ROW = parseInt(y / TILESIZE) |
def getColTile(LNG, SCALE):
| • | x = (LNG + 180.0) * (PIXELSPERLNGDEGREE / SCALE) |
| • | COL = parseInt(x / TILESIZE) |
Column and Row Grid Scheme
To create the custom tile, you must be able to convert the latitude and longitude into a row and column scheme. The following describes that process and gives the details necessary to do this conversion.
Latitude/Longitude to Tile URL Row/Column
| • | The latitude transforms into a row (ROW). The longitude transforms into a column (COL). |
| • | The ROW is represented in URI space as two numerics: the first is the floor of the ROW divided by 1000, the second is the remainder. |
| • | The COL is treated similarly. For example, an aerial tile at SCALE=1000, ROW=142685 and COL=97653, is represented in the URL as /sat/Scale1000/142/685/97/653.jpg. |
Computations
| • | ROW = parseInt( ROW / 4 ) * 4 |
| • | y = ROW * TILESIZE + 511 |
| • | LAT = y / (PIXERSPERLATDEGREE / SCALE) - 90.0 |
| • | LAT = parseInt( LAT * 1000000 ) / 1000000.0 |
| • | COL = parseInt( COL / 4 ) * 4 x = COL * TILESIZE + 511 |
| • | LNG = x / (PIXERSPERLNGDEGREE / SCLE) - 180.0 |
| • | LNG = parseInt( LNG * 1000000 ) / 1000000.0 |
Zoom Levels & Zoom Scales
For each custom tile layer, you must set the zoom level.
Note
Scale is a factor of 1 to that number. For example, it could be 1 inch = 6000 inches or 1 mile = 6000 miles.
| Table 12–2 | Zoom Levels & Scales |
| Zoom Level | Zoom Scale |
|
1
|
88011773
|
|
2
|
29337258
|
|
3
|
9779086
|
|
4
|
3520471
|
|
5
|
1504475
|
|
6
|
701289
|
|
7
|
324767
|
|
8
|
154950
|
|
9
|
74999
|
|
10
|
36000
|
|
11
|
18000
|
|
12
|
9000
|
|
13
|
4700
|
|
14
|
2500
|
|
15
|
1500
|
|
16
|
1000
|

How to Add a Custom Tile Layer to a TileMap
Custom tile layers can be added to MapQuest TileMaps, providing developers the ability to integrate custom layer information within MapQuest tiles.
The following steps are required when adding an image tile layer. (See page
HERE.)
| 1) | Create an instance of a Tile class, defining the getUrl() function, and overriding the relevant methods of the MQA.ImageTile class, as shown below.
CustomTileClass = function( parent, left, top, gridColumn, gridRow,
scale, zoom, size, opacity, options) {
this.gridColumn = gridColumn;
this.gridRow = gridRow;
this.url = ‘./image_dir/image.gif’;
this.tileImage = null;
MQA.ImageTile.call( this, parent, left, top, gridColumn, gridRow,
scale, zoom, size, opacity, options )
this.getUrl = function() {return this.url;}
}
|
|
| 2) | Create a TileLayer object, passing in arguments for the map, layer id, the Tile class created in the previous step, bounds (if undefined, the layer will apply to the whole map), minimum zoom level, maximum zoom level, opacity, z-index and copyright, as shown below.
myCustomLayer = new
MQA.TileLayer(myMap,"layer_id",CustomTileClass,null,null,1,
16,0.75,60,null);
|
|
| 3) | Call TileMap.addTileLayer(), passing the TileLayer object created in the previous step.
myMap.addTileLayer(myCustomLayer);
|
|

How to Access the Properties of Custom Tile Layers
After custom tile layers have been added to a map, they have various properties and methods that can be accessed to adjust their appearance and behavior.
The tile layer’s properties can be set using the setValue(‘property’,’value’) notation, as shown below.
myLayer. setValue(‘minZoom’,2);
|
The tile layer’s properties can be retrieved using the getValue(‘property’) notation, as shown below.
myIntMinZoom = myLayer. getValue(‘minZoom’);
|
Custom events exist for some of the objects (see list below). You can hook your own functions on these events using the MQA.EventManager object.
The basics are as follows:
| • | Create a function to do something. When you create the function:
| – | Have an input parameter – For example, function foo(inputParam) – it does not matter what you call it, but that input parameter will become the MQA.Event object inside your function. So if it was a map click, you would have access to inputParam.ll to get the latLng of where the map was clicked. |
| – | Inside your function, the "this" keyword will refer to the object that raised the event. So, if it was a map click, you would have access to this.getBounds();. If it was a POI click, you would have access to this.getKey();. |
|
| • | Call MQA.EventManager.addListener(sourceObject, ‘event name’, function_with_no_parens)
| – | For example, to call the function foo(inputParam) on a map click, and your MQA.TileMap object is called myMap would be: MQA.EventManager.addListener(myMap,’click’,foo).
Note
The MQA.EventManager object is static – you do not have to create it, it just exists.
|
|
| • | Inside of your function, do whatever you wanted to do if that event was raised. |
Following is an example that shows you how to add a custom event listener to the MQA.TileMap to handle click events, and report the latitude and longitude of where the mouse was clicked.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Add Event Listener </title>
<!-- THE JS INCLUDE Tag that gets Map Toolkit - Change Key value to
one provided on signup -->
<script src="http://btilelog.access.mapquest.com/tilelog/
transaction?transaction=script&key=YOUR_KEY_HERE&itk=true
&v=5.3.s&ipkg=controls1></script>
<!-- Create the base MQA.TileMap object and pass in the id of the DIV
you want to hold the map -->
<script language="javascript">
//function to show the latLng of where I clicked
function showLL(e) //e will become the event object passed in by
the event manager
{
//grabbing the DIV where I will display the Lat Lng
var resWin = document.getElementById(’resultBox’);
/*
the event object for a map click has a .ll object that is an
MQALatLng of where the click event was raised
for sake of clarity I am pulling it out to a separate object
*/
mLL = e.ll;
//because it is an MQALatLng object, I have access to getLat()
and getLng
resWin.innerHTML = mLL.getLat() + ’, ’ + mLL.getLng();
//I could have written that line purely as
//resWin.innerHTML = e.ll.getLat() + ’, ’ + e.ll.getLng();
}
function startMap(){
myMap = new MQA.TileMap(document.getElementById(’mapWindow’),9,new
MQALatLng(40.0446,-76.4131));
//here I add my function to my Map object, on the click event -
notice there are no parens on my function name
MQA.EventManager.addListener(myMap,"click",showLL);
}
</script>
|
</head>
<body onload="startMap();">
<!-- The DIV to hold the Map itself -->
<div id="mapWindow" style="WIDTH:900px; HEIGHT:520px"></div>
<!-- My results Div -->
<DIV id="resultBox" style="WIDTH:900px; HEIGHT:20px;
background-color: #CCCCCC">
Click on Map to display Lat/Lng
</DIV>
</body>
</html>
|
Consider the following with respect to these events:
| • | Inside of every handler you attach, the “this” object is the object that called your event handler. |
| • | Every (e)event has e.eventName property that returns the name of the triggering event. |
| • | Mouse clicks on POIs and Overlays “fall through” to the map object, with themselves as the e.srcObject property on the map click event. If MQA.TileMap.srcObject() is null, then only the map was clicked. |
| • | Mouse clicks on rollovers and InfoWindows do not “fall through” to objects below them. |
| • | The Z-ordering of the objects is:
| – | Rollovers are above InfoWindows |
| – | InfoWindows are above POIs |
| – | POIs are above overlays |
| – | Overlays are above the map |
|
Available Events by Object
| • | "click": e.eventName, e.domEvent, e.xy, e.button |
| • | "dblclick": e.poi, e.eventName, e.domEvent, e.xy, e.button |
| • | "mousedown": e.poi, e.eventName, e.domEvent, e.xy, e.button |
| • | "mouseup": e.poi, e.eventName, e.domEvent, e.xy, e.button |
| • | "mouseover": e.poi, e.eventName, e.domEvent, e.xy, e.button |
| • | "mouseout": e.poi, e.eventName, e.domEvent, e.xy, e.button |
| • | "infowindowopen": e.poi, e.eventName, e.domEvent, e.xy, e.button |
| • | "infowindowclose": e.poi, e.eventName, e.domEvent, e.xy, e.button |
| • | "rolloveropen": e.poi, e.eventName, e.domEvent, e.xy, e.button |
| • | "rolloverclose": e.poi, e.eventName, e.domEvent, e.xy, e.button |
| • | "removed": e.poi, e.eventName, e.domEvent, e.xy, e.button |
|
| • | "clickedclosed": e.eventName |
|
| Table 13–3 | Rollover Window |
|
Events that happen to the map (or events that fall through an object to the map)
Mouse Events
| • | "click": e.eventName, e.xy, e.ll, e.srcObject |
| • | "dblclick": e.eventName, e.xy, e.ll, e.srcObject, e.domEvent |
| • | "mouseup": e.eventName, e.button, e.clientX, e.clientY |
| • | "mousedown": e.eventName, e.button, e.clientX, e.clientY |
| • | "zoomStart": e.eventName, e.zoom |
| • | "zoomend": e.prevZoom=old zoom level, e.zoom=new zoom level |
| • | "dragstart": e.eventName |
| • | "dragend": e.eventName, e.clientX, e.clientY, e.dragDirection, e.dragPercentage |
|
|
Code Events
| • | "movestart": e.eventName |
| • | "maptypechanged": e.prevMapType, e.mapType |
| • | "mapcleared": e.eventName |
|
|
Events Other Objects Can Trigger on the Map
| • | "infowindowopen": e.eventName |
| • | "infowindowclose": e.eventName |
| • | "shapeadded": e.eventName, e.poi |
| • | "shaperemoved": e.eventName, e.poi |
|
| • | “click”: e.eventName, e.domEvent |
| • | "dblclick": e.eventName, e.domEvent |
| • | "mousedown": e.eventName, e.domEvent |
| • | "mouseup": e.eventName, e.domEvent |
| • | "mouseout": e.eventName, e.domEvent |
| • | "removed": e.eventName, e.domEvent |
|
After completing these basic tasks as described in this guide, you should be able to continue on with more advanced items. To do so, it would be helpful to refer to these reference materials:
| • | Map Toolkit Developer Reference |
| • | JavaScript API Developer Reference |
| • | Flash Map Under JavaScript-Nuances |
| • | Proxy Configuration Guide |
| A | Creating Custom Objects from MQA.Base |
You can create your own custom objects using the MQA.Base object. Before beginning, here are the basics.
Default Public Functions:
setValue(<key>, <value>)
setValues({<key>:<value>, <key>:<value>})
getValue(<key>)
|
All objects created using MQA.Base will automatically have the default functionality to set/get property values using the above functions.
Other private functions used to derive objects from MQA.Base:
facio(<key>, <value>)
duco(<key>)
draw()
dispose()
override(<key>)
|
The above functions do no processing by default. They are used to extend MQA.Base when creating custom objects. Details are described in the following sections.
| A.1 | Using MQA.Base as a Starting Point |
Before you can create a custom object, you need to start by creating an MQA.Base object that can be extended with additional functionality.

How to Use MQA.Base as the Starting Object
| 1) | Create the object function and use the call() function to use MQA.Base as the starting object.
CustomObject = function()
{
MQA.Base.call(this);
};
|
|
| 2) | Add any properties that are specific to your object.
CustomObject = function()
{
MQA.Base.call(this);
this.firstName = null;
this.lastName = null;
this.phone = null;
};
|
If your object is just to be used as a data store, this may be all you need to do. You can now create and use your object as in the following code.
myObject = new CustomObject();
myObject.setValue("firstName", "John");
myObject.setValue("lastName", "Smith");
myObject.setValue("phone", "800-555-1212");
var myPhone = myObject.getValue("phone");
|
|
| 3) | Pass parameters into the constructor using the following:
CustomObject = function(strFirstName, strLastName, strPhone)
{
MQA.Base.call(this);
this.firstName = strFirstName;
this.lastName = strLastName;
this.phone = strPhone;
};
|
Example usage:
myObject = new CustomObject("John", "Smith", "800-555-1212");
var myPhone = myObject.getValue("phone");
|
|
| 4) | Extend the draw() method and the dispose() method to create and destroy the objects if the custom object will create DOM objects.
The dispose() function should detach all the object’s DOM elements from their parents and destroy them. For the following example, the property objectDiv should be added to the property definitions of the object and set to null initially.
this.draw = function()
{
// Create the div with a "this" reference to access it later.
this.objectDiv = document.createElement("div");
// Set the div properties.
this.objectDiv.style.border = "1px solid red";
this.objectDiv.style.padding = "5px";
var s = this.getValue("firstName") + " ";
s += this.getValue("lastName") + "<br/>";
s += this.getValue("phone");
this.objectDiv.innerHTML = s;
// append the div to the desired parent element.
document.body.appendChild(this.objectDiv);
};
this.dispose = function()
{
// blank the contents.
this.objectDiv.innerHTML = "";
// remove the div from the parent element.
this.objectDiv.parentNode.removeChild(this.objectDiv);
// set the div variable to null.
this.objectDiv = null;
};
|
|
| A.2 | Expanding the MQ.Base Functionality |
At times, setting a property needs to do more than simply set the property. For instance, in the previous example, changing the value of firstName may need to update the div contents if the object has already been placed in the DOM. You would use the facio() function for this purpose. facio() takes a key / value pair as a parameter and consists of a switch statement, with a separate case statement for each property that needs special processing.
The example below checks to see if this.objectDiv has been created and, if so, redraws the object with the new property values. Keep in mind that when facio() gets called, the new property value has already been set. facio() is simply adding on any post-processing that needs to be done after the value is set.
this.facio = function(key, value)
{
switch (key) {
case "firstName":
if (this.objectDiv) this.draw();
break;
case "lastName":
if (this.objectDiv) this.draw();
break;
case "phone":
if (this.objectDiv) this.draw();
break;
};
};
|
Likewise, there may be times when a returned value needs to be calculated instead of returning the property value directly. In this situation, the duco() function is used. This is generally needed far less often than facio(). duco() takes a key (string) as a parameter and returns a calculated value of whatever type is appropriate.
In the following example, duco() is used to return capitalized first and last names regardless of the string case stored in the properties.
this.duco = function(key)
{
switch (key) {
case "firstName":
var s = this.firstName.substr(1).toLowerCase();
s = this.firstName.substr(0,1).toUpperCase() + s;
return s;
break;
case "lastName":
var s = this.lastName.substr(1).toLowerCase();
s = this.lastName.substr(0,1).toUpperCase() + s;
return s;
break;
};
};
|
The previous example will affect the properties as follows:
var myObject = new CustomObject();
myObject.setValue("firstName", "JOHN");
myObject.setValue("lastName", "SMITH");
var s = myObject.getValue("firstName") + " ";
s += myObject.getValue("lastName");
// s will equal "John Smith"
|
| A.3 | Overriding Default Behavior |
When deriving an object from a MapQuest (MQA.) object that has been derived from MQA.Base, there may be an instance where the default behavior of setting a property needs to be overridden.
For example, if creating a custom object which is derived from MQA.ShapeOverlay, perhaps setting the color to a dark color should make the border semi-transparent and setting it to a lighter color should make the border completely opaque.
Use the override() function to override the default functionality for the specified property or properties. override() takes a string (a single property) or an array of strings (for multiple properties) as a parameter.
CustomShape = new function()
{
MQA.ShapeOverlay.call(this);
this.override("color");
};
|
To attach the new desired behavior, create a facio() function to include the overridden properties. The following example will set the transparency of the border to 0.5 if the color is darker and 1.0 if the color is lighter.
this.facio = function(key, value)
{
switch (key) {
case "color":
if (value <= "#888888") {
this.setValue("colorAlpha", 0.5);
} else {
this.setValue("colorAlpha", 1.0);
};
// redraw the shape with the new color settings if the
// shape is already visible.
if (this.shape) this.draw();
break;
};
};
|