The MapAPI 1.0 is deprecated. Please use the new MapAPI 1.1.





« Previous chapter 4: Routing   Back to Index   Next chapter 6: Overlays »

Chapter 5: Controls

5.1 Adding controls to the map

To make the handling of the map more comfortable for the user, we have to add some controls to it. The Api provides a comfortable way for adding elements as well as predefined controls. In this chapter, we will explain how the positioning works, then we will add some predefined controls to our map and finally we will make an own control element which we want to use in our map.

5.1.1 The LayoutManager

The API provides a IWLayoutManager for easy positioning of the controls. It uses a so-called "Docking-Layout". If you want to add an element, you just have to specify the direction. The element will be "shoved" to this side, and docks either to the border of the map, or, if there is another element already, it docks to that element. A simple example will show you how it works theoretically.

There are always two docking commands necessary to add an element to the map. If we want to see our control element in the upper right corner, we can to dock it at first to the top border, and then to the right. (Notice: As there is no other element on the map, it would make no difference if we dock it at first to the right, and then to the top border.) For docking the element to the top we use the constant IWAlignment.TOP. Similar to this constant there are IWAlignment.BOTTOM, IWAlignment.LEFT, IWAlignment.RIGHT and IWAlignment.CENTER.

Now, we want to add another control element at the top beside the existing one. The order we are docking is important here. We have to dock it at first to the top, and then to the right.

If we change the order, the new control element will be added at the right side below the existing control element.

And of course, if we dock an element to the center of a side, the elements will be centered automatically.

For the exceptional case that you want to add elements to the center of the map, just use IWAlignment.CENTER as first docking command. The first element will always be set in the center of the map. Following elements will be docked according to the second command.

You can define a global spacing to the borders of the map as well as for each element a local one.

5.1.2 A Map with some controls

As we now know how the Layoutmanager works, we will create a map and add some predefined control elements.

 Controls example 5a (view example):

 Source code example 5a:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>
	<head>
		<title>Chapter 5: Controls example 5a</title>
		
		<script type="text/javascript" src="http://iw.mapandroute.de/MapAPI-1.0/js/mapping.js"></script>
		
		<script type="text/javascript" >
		
			var map = null;
			
			function initialize()
			{
				map = new IWMap(document.getElementById('map'));
				
				IWEventManager.addListener(map, 'oninitialize', 
					function()
					{
						// add some controls
						map.getLayoutManager().getLayer(0).setBorder(5, 5);																	
						map.getLayoutManager().getLayer(0).addControl(new IWScalarControl(map), IWAlignment.LEFT, IWAlignment.BOTTOM, 0, 0);
						map.getLayoutManager().getLayer(0).addControl(new IWNavigationControl(map), IWAlignment.RIGHT, IWAlignment.TOP, 0, 0);
						map.getLayoutManager().getLayer(0).addControl(new IWSliderControl(map), IWAlignment.RIGHT, IWAlignment.TOP, 0, 0);

						// create a toolbar control and add it to the map
						var toolbar = createToolbar(map);
						map.getLayoutManager().getLayer(0).addControl(toolbar, IWAlignment.TOP, IWAlignment.CENTER);

						// add a overview map						
						map.getLayoutManager().getLayer(1).setBorder(0, 0);
						map.getLayoutManager().getLayer(1).addControl(new IWOverviewMapControl(map, 'bing_mapdispatcher'), IWAlignment.LEFT, IWAlignment.TOP, 0, 0);
					}
				);
				
				map.setCenter(new IWCoordinate(7.096311, 50.732705, IWCoordinate.WGS84), 5);
			}
			
			//********************************************************************
			//* Helper functions for a user defined toolbar control
			//********************************************************************
			
			/**
			 * Creates a user defined toolbar and returns it.
			 *
			 * This is only an example implementation of the toolbar control. 
			 *
			 * @return {IWToolbarControl}
			 */
			function createToolbar(map)
			{
				var toolbar = new IWToolbarControl(map);
		
				var leftBorder = new IWToolbarItem('leftBorder');
				var spacer = new IWToolbarItem('spacer');
				var rightBorder = new IWToolbarItem('rightBorder');

				var item1 = new IWToolbarItem('address');
				var item2 = new IWToolbarItem('search');
				var item3 = new IWToolbarItem('print');

				IWEventManager.addListener(toolbar, 'onappendstart', function(e) { formatToolbarItem(e.item); });
				IWEventManager.addListener(toolbar, 'onmouseover', function(e) { formatOnMouseOver(e.item); });
				IWEventManager.addListener(toolbar, 'onmouseout', function(e) { formatOnMouseOut(e.item); });
				IWEventManager.addListener(toolbar, 'onclick', function(e) { alert('user clicked: ' + e); });
		
				toolbar.addItem(leftBorder);
				toolbar.addItem(item1);
				toolbar.addItem(item2);
				toolbar.addItem(spacer);
				toolbar.addItem(item3);
				toolbar.addItem(rightBorder);
				
				return toolbar;
			}

			/**
			 * Formats a toolbar item.
			 * 
			 * @param {IWToolbarItem} item
			 * @return {void}
			 */			 
			function formatToolbarItem(item)
			{
				if (item.getName() == 'leftBorder')
				{
					var img = iw.create('img');
					img.style.position = 'absolute';
					img.style.top = '21px';
					img.style.width = '3px';
					
					img.src = 'http://iw.mapandroute.de/MapAPI-1.0/img/controls/toolbar/left.gif';
		
					item.setNode(img);
				}
				else if (item.getName() == 'rightBorder')						
				{
					var img = iw.create('img');
					img.style.position = 'absolute';		
					img.style.top = '21px';
					img.style.width = '3px';
					
					img.src = 'http://iw.mapandroute.de/MapAPI-1.0/img/controls/toolbar/right.gif';

					item.setNode(img);
				}
				else if (item.getName() == 'spacer')
				{
					var div = document.createElement('div');
					div.style.position = 'absolute';
					div.style.top = '21px';
					div.style.height = '37px';
					div.style.width = '1px';
				
					var image = document.createElement('img');					
					div.appendChild(image);

					image.src = 'http://iw.mapandroute.de/MapAPI-1.0/img/controls/toolbar/spacer.gif';
					
					image.style.width = '1px';
					image.style.height = '37px';	

					item.setNode(div)					
				}
				else
				{
					var div = document.createElement('div');
					div.style.position = 'absolute';
					div.style.top = '0px';
					div.style.height = '58px';
					div.style.width = '50px';
				
					var image = document.createElement('img');
					div.appendChild(image);

					image.style.width = '50px';
					image.style.height = '58px';

					var label = document.createElement('div');
					div.appendChild(label);

					label.style.position = 'absolute';
					label.style.left = '0px';
					label.style.top = '37px';
					label.style.width = '50px';
					label.style.height = '21px';

					item.setNode(div);

					formatOnMouseOut(item);
				}
			}	
			
			/**
			 * Eventhandler for onMouseOut events.
			 * 
			 * This method is registered on 'onmouseout' events from the toolbox. If the event is catched we 
			 * change the url of the image. 
			 *
			 * @return {void}
			 */
			function formatOnMouseOut(item)
			{
				var image = item.getNode().firstChild;
				var label = image.nextSibling;
				label.innerHTML = '';

				switch(item.getName())
				{
					case 'address':
						image.src = 'http://iw.mapandroute.de/MapAPI-1.0/img/controls/toolbar/address_normal.gif';
						break;
						
					case 'search':
						image.src = 'http://iw.mapandroute.de/MapAPI-1.0/img/controls/toolbar/search_normal.gif';
						break;

					case 'print':
						image.src = 'http://iw.mapandroute.de/MapAPI-1.0/img/controls/toolbar/print_normal.gif';
						break;
				}		
			}
			
			/**
			 * Eventmethod for onMouseOver events.
			 * 
			 * This method is registered on 'onmouseover' events from the toolbox. If the event is catched we
			 * change the url of the image.
			 *
			 * @return {void}
			 */
			function formatOnMouseOver(item)
			{
				var image = item.getNode().firstChild;
				var label = image.nextSibling;
									
				switch(item.getName())
				{
					case 'address':
						image.src = 'http://iw.mapandroute.de/MapAPI-1.0/img/controls/toolbar/address_hover.gif';
						label.innerHTML = '<p class="iwtoolbaritem">LOCATE<br>ADDRESS</p>';
						break;
						
					case 'search':
						image.src = 'http://iw.mapandroute.de/MapAPI-1.0/img/controls/toolbar/search_hover.gif';
						label.innerHTML = '<p class="iwtoolbaritem">POINTS OF<br>INTEREST</p>';
						break;

					case 'print':
						image.src = 'http://iw.mapandroute.de/MapAPI-1.0/img/controls/toolbar/print_hover.gif';
						label.innerHTML = '<p class="iwtoolbaritem">PRINT</p>';
						break;
				}
			}
		</script>
		
	</head>
	<body onload="initialize();">
		<div id="map" style="background-color: #dddddd; width: 450px; height: 300px"></div>
	</body>
</html>

As you can see, adding controls is very simple. A new concept we introduced here are the layers. With the method getLayer() you can get specific layers. The higher the number for the parameter is, the more in front are the controls on the map. Each layer is completely independent to each other. Therefore each layer has its own global padding, and controls cannot be docked to controls in other layers.

map.getLayoutManager().getLayer(0).setBorder(5, 5);

With this code we set the global padding for layer 0 horizontal and vertical to 5 pixel.

map.getLayoutManager().getLayer(0).addControl(new IWScalarControl(map), IWAlignment.LEFT, IWAlignment.BOTTOM, 0, 0);

Here we add a new scalar control. The control takes the map as parameter, because it wants to communicate with it. The last two parameters define the local padding for this control.

5.1.3 Customize the toolbar control

The example above demonstrates the use of the IWLayoutManager and its IWLayer`s. To allow user interactions we prefer a user defined toolbar control which contains items e.g. for switching the map type, printing the map or opening the routing window. Its up to the user to build the graphical and logical part of this control. The API contains two classes and several images to realize the implementation of this control in a few steps. The following example gives you a short summary of the required steps.

First we instantiate an empty IWToolbarControl where we can add the toolbar items later.

var toolbar = new IWToolbarControl(map);

The toolbar control triggers the following events:

Event Description
onappendstart This event is triggerd before a item is added to the toolbar. Use this event to realize your own layout.
onmouseover This event is triggered when the mouse pointer is over a toolbar item. You can use this event e.g. to realiue a hover effect.
onmouseout This event is triggered when the mouse point has leave the area of the toolbar item.
onclick This event is triggered when the user clicked a toolbar item.
onremove This event is triggered after a item has been removed from the toolbar.

After we have create the toolbar control we can create several items by instantiating the IWToolbarItem class. At this point we do not make a difference between functional and non-functional toolbar items such as borders and spacers. We use a unique name for each toolbar item so that we can refer the item later by its name.

var spacer = new IWToolbarItem('spacer);
var item1 = new IWToolbarItem('address');
var item2 = new IWToolbarItem('search');
var item3 = new IWToolbarItem('print');

Before we add a item to the toolbar control we have to define an event listener which is triggered when a item is appended. This handler method is required to realize a user defined toolbar layout.

IWEventManager.addListener(toolbar, 'onappendstart', formatToolbarItem);

When the event is triggered the handler method formatToolbarItem() is called. The user can use this method to realize his own toolbar item layout. The layout of the item is set by his item.setNode(layout) method. Here is an example:

...
var div = document.createElement('div');  
div.style.position = 'absolute';  
div.style.top = '0px';  
div.style.height = '58px';  
div.style.width = '50px';  
                   
var image = document.createElement('img');  
div.appendChild(image);  

image.style.width = '50px';  
image.style.height = '58px';  

var label = document.createElement('div');  
div.appendChild(label);  

label.style.position = 'absolute';  
label.style.left = '0px';  
label.style.top = '37px';  
label.style.width = '50px';  
label.style.height = '21px';  
 
item.setNode(div);  

formatOnMouseOut(item);
...  	
	

We create a div element with an underlaying image and a div container. The second div container is used for the description text of the image. The formatOnMouseOut() does additional formations. Important is the item.setNode(div) call where we set the specific item layout. After we have specified the handler methods for the onappend and onclick event we can add the items the the toolbar control.

toolbar.addItem(item1);
toolbar.addItem(item2);			
	

The following table contains a list of images that you can use to create your own toolbar control. Certainly you can use also your own images.

Name Images
address
aerialview
birdsview
hybrid
measure
move
search
print
resize
roadmap
route
traffic
zoom
Name Image
spacer
left border
right border

5.2 Removing controls from the map

To remove a control from the map, you can use the removeControl method from the layer where the control has been appended.

Please notice that the removeControl method requires the control reference as an parameter. So if you want to remove a control, you should use the addControl and removeControl method in the following way:

			
			var scalarControl = new IWScalarControl(map);
			map.getLayoutManager().getLayer(0).addControl(scalarControl, IWAlignment.TOP, IWAlignment.CENTER, 0, 0);
			...
			map.getLayoutManager().getLayer(0).removeControl(scalarControl);

We know that in some cases it is very important to inform a control element that it was removed from the map. So the removeControl method calls two callback methods on the control. The beforeRemove method is directly called before the control element is removed from the map and the afterRemove method will be called when the control has been removed. Overwrite this two methods if you require some special behaviour when the control is removed.

5.3 Create your own controls

Adding custom controls to the map is easy. You just have to regard two points:

  • You have to inherit from the main interface IWControl.
  • You have to set the correct size of your control in the DOM style parameter.
  • In the next example we will create a simple control. It will just contain a simple link which sets the center of the map to Bonn, Germany.

     Controls example 5b (view example):

     Source code example 5b:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    
    <html>
    	<head>
    		<title>Chapter 5: Controls example 5b</title>
    		<script type="text/javascript" src="http://iw.mapandroute.de/MapAPI-1.0/js/mapping.js"></script>
    		
    		<script type="text/javascript" >
    		
    			function MyControl(map)
    			{
    				//********************************************************************
    				//* Calls the super class constructor
    				//********************************************************************
    				IWControl.call(this, map);
    
    				//********************************************************************
    				//* Getting the DIV Container we can work with
    				//********************************************************************
    				var div = this.getContainer();
    
    				//********************************************************************
    				// Setting the size 
    				//********************************************************************
    				div.style.width = '50px';
    				div.style.height = '20px';
    				
    				div.style.backgroundColor = '#eeeeee';
    
    				//********************************************************************
    				// Creates the text node 
    				//********************************************************************
            		div.appendChild(document.createTextNode('To Bonn'));
    				div.style.cursor = 'pointer';
    				
    				IWEventManager.addDomListener(div, 'onclick', 
    					function() 
    					{
    						map.setCenter(new IWCoordinate(278233.27, 193335.85));
    					}
    				);
    			}
    			
    			function initialize() 
    			{
    				var map = new IWMap(document.getElementById('map'));
    				map.setCenter(new IWCoordinate(7.096311, 50.732705, IWCoordinate.WGS84));
    
    				//********************************************************************
    				//* Sets global padding
    				//********************************************************************
    				map.getLayoutManager().getLayer(0).setBorder(5, 5);
    				map.getLayoutManager().getLayer(1).setBorder(50, 50);
    
    				//********************************************************************
    				//* Adds the new control element to map
    				//********************************************************************
    				var myControl = new MyControl(map);
    				map.getLayoutManager().getLayer(1).addControl(myControl, IWAlignment.BOTTOM, IWAlignment.CENTER, 0, 0);
    			}
    		</script>
    		
    	</head>
    	<body onload="initialize();">
    		<div id="map" style="background-color: #dddddd; width: 450px; height: 300px"></div>
    	</body>
    </html>
    

    As usual we will have a closer look at the important lines of code:

    		function MyControl(map)
    		{

    Here we define a class for our new control. As we want to work with the map, we require a reference for it.

    		//********************************************************************
    		//* Calls the super class constructor
    		//********************************************************************
    		IWControl.call(this, map);
    
    		//********************************************************************
    		//* Getting the DIV Container we can work with
    		//********************************************************************
    		var div = this.getContainer();

    Each control has to implement the interface IWControl. Once this is done, we get the div we can use for creating our control with the method getContainer().

    		//********************************************************************
    		// Setting the size 
    		//********************************************************************
    		div.style.width = '50px';
    		div.style.height = '20px';

    It is important to set the correct size here. Otherwise the IWLayoutManager isn't able to place the controls correctly.

    //********************************************************************
    // Creates the text node 
    //********************************************************************
    div.appendChild(document.createTextNode('To Bonn'));
    div.style.cursor = 'pointer';
    				
    IWEventManager.addDomListener(div, 'onclick', 
    	function() 
    	{
    		map.setCenter(new IWCoordinate(7.096311, 50.732705, IWCoordinate.WGS84));
    	}
    );

    In our little example we just create a link that sets the center of the map to Bonn. We use the IWEventManager to catch the onclick event from the div container. If the event is triggered by the div container our EventManager executes the anonymous callback function for setting the new map center.

    5.4 Customize existing controls

    The following example demonstrates how you can customize the layout of the existing controls.

     Controls example 5c (view example):

     Source code example 5c:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    
    <html>
    	<head>
    		<title>Chapter 5: Controls example 5c</title>
    		<script type="text/javascript" src="http://iw.mapandroute.de/MapAPI-1.0/js/mapping.js"></script>
    		
    		<style type="text/css">
    		
    			/* Here we override the CSS Sytles for the IWScalarControl */
    		
    			.IWScalarControl .separator {
    				border-bottom:1px solid #8c8c8c;
    			}
    			.IWScalarControl .dark {
    				border-bottom:1px solid #8c8c8c;
    			}
    			.IWScalarControl .bright {
    				border-bottom:1px solid #8c8c8c;
    			}
    			
    			/* Here we override the CSS Sytles for the IWSliderControl */
    			
    			.IWSliderControl {
    				height:144px; 
    				width:24px;
    			}
    
    			.IWSliderControl .zoomIn {
    				left:0px;
    				width:23px;
    				height:23px;
    				/* border:1px solid red; */
    			}
    
    			.IWSliderControl .zoomOut {
    				left:0px;
    				width:23px;
    				height:23px;
    				cursor:pointer;
    				z-index:1;
    				/* border:1px solid red; */
    			}
    
    			.IWSliderControl .zoomClick {
    				top:24px;
    				left:5px;
    				width:14px;
    				height:98px;
    				/* border:1px solid red; */
    			}		
    
    			.IWSliderControl .button {
    				width:24px;
    				height:14px;
    				left:0px;
    				top:24px;
    			}
    			
    			/* Here we override the CSS Sytles for the IWNavigationControl */
    
    			.IWNavigationControl {
    				position:absolute;
    				width:58px;
    				height:55px;	
    			}
    			
    			.IWNavigationControl .navigationImage {
    				width:58px;
    				height:55px;
    			}
    			
    			.IWNavigationControl .areaUp {
    				position:absolute;
    				left:18px;
    				top:4px;
    				height:12px;
    				width:22px;
    				cursor:pointer;
    				/* border:1px solid yellow; */
    			}
    			
    			.IWNavigationControl .areaDown {
    				position:absolute;
    				left:18px;
    				top:37px;
    				height:12px;
    				width:22px;
    				cursor:pointer;
    				/* border:1px solid blue; */
    			}
    			
    			.IWNavigationControl .areaLeft {
    				position:absolute;
    				left:5px;
    				top:16px;
    				height:23px;
    				width:13px;
    				cursor:pointer;
    				/* border:1px solid orange; */
    			}
    			
    			.IWNavigationControl .areaRight {
    				position:absolute;
    				left:39px;
    				top:16px;
    				height:23px;
    				width:13px;
    				cursor:pointer;
    				/* border:1px solid green; */
    			}
    			
    			
    		</style>		
    		
    		<script type="text/javascript" >
    			
    			function initialize() 
    			{
    				var map = new IWMap(document.getElementById('map'));
    				map.setCenter(new IWCoordinate(6.951698, 50.922106, IWCoordinate.WGS84));
    
    				//********************************************************************
    				//* Sets global padding
    				//********************************************************************
    				map.getLayoutManager().getLayer(0).setBorder(5, 5);
    
    				//********************************************************************
    				//* Customize the IWScalarControl
    				//********************************************************************
    
    				var scalarControl = new IWScalarControl(map);
    				scalarControl.setDarkImage('http://iw.mapandroute.de/MapAPI-1.0/examples/tutorial/img/8c8c8c.gif');
    				scalarControl.setBrightImage('http://iw.mapandroute.de/MapAPI-1.0/examples/tutorial/img/e8e8e8.gif');
    				scalarControl.setSeparatorImage('http://iw.mapandroute.de/MapAPI-1.0/examples/tutorial/img/8c8c8c.gif');
    
    				map.getLayoutManager().getLayer(0).addControl(scalarControl, IWAlignment.BOTTOM, IWAlignment.LEFT, 0, 0);
    
    				//********************************************************************
    				//* Customize the IWNavigationControl
    				//********************************************************************
    
    				var navigationControl = new IWNavigationControl(map);
    				navigationControl.setNavigationImage('http://iw.mapandroute.de/MapAPI-1.0/examples/tutorial/img/navicross-gray.png');
    				
    				map.getLayoutManager().getLayer(0).addControl(navigationControl, IWAlignment.RIGHT, IWAlignment.TOP, 0, 5);
    				
    				//********************************************************************
    				//* Customize the IWSliderControl
    				//********************************************************************
    				
    				var sliderControl = new IWSliderControl(map);
    				sliderControl.setSliderImage('http://iw.mapandroute.de/MapAPI-1.0/examples/tutorial/img/slider-gray.gif');
    				sliderControl.setSliderButtonImage('http://iw.mapandroute.de/MapAPI-1.0/examples/tutorial/img/slider-button-gray.gif');
    
    				map.getLayoutManager().getLayer(0).addControl(sliderControl, IWAlignment.RIGHT, IWAlignment.TOP, 16, 5);
    				
    				
    				
    			}
    		</script>
    		
    	</head>
    	<body onload="initialize();">
    		<div id="map" style="background-color: #dddddd; width: 450px; height: 300px"></div>
    	</body>

    « Previous chapter 4: Routing   Back to Index   Next chapter 6: Overlays »