« Previous Chapter 6: Overlays    Back to Index    Next Chapter 8: Projection »

Chapter 7: Shapes and Layers

With shapes you can add more information to the map. You can create your own shapes for the mapserver and add them to your map when you need them. In addition you can use layers (and shapes) which are provided by MapCms. This is a tool to group pois into catalogs, change their presentation (logo, legend, etc.) and make it accessible for your product. How you can use these layer is described in part ??????. (For more information about products and MapCms contact us!)

7.1 Adding a layer

7.1.1 IWPoiUtils

Managing of POI types and formatting of tool tips and bubbles can be quite complex. To help you with this task the API provides the class IWPoiUtils and the concept of POI formatters.

The class IWPoiUtils gives you an easy way to add layers to your map and give them default functions to show a tooltip (mouseover) and an infoballoon (click). For standard POIs you can use the default formatters (see POI formatters for further information).

The classes IWPoiUtils and the formatters are part of the module poi. Call IWLoader.loadModules(['poi']); to use IWPoiUtils.

Shapes and Layers example 7a Source code example 7a:
<!DOCTYPE html>
<html>
	<head>		
		<title>Chapter 7: Shapes and Layers example 7d</title>
		<script type="text/javascript" src="http://iw.mapandroute.de/MapAPI-1.1/js/core.js?vnr=0&pnr=0"></script>

		<script type="text/javascript">
			
			var map = null;

			// Initializes the map object after the body element has been loaded.
			function initialize()
			{
				map = new IWMap(document.getElementById('divMap'));
				map.setCenter(new IWCoordinate(7.1408879, 50.70150837, IWCoordinate.WGS84), 13);
				
				IWEventManager.addListener(IWLoader, 'onmoduleload', function(event)
				{
					if (event.name == 'poi')
					{
						// Use the default Formatters
						IWPoiUtils.initFormatters(IWPoiUtils.DEFAULT_FORMATTERS);
						
						// add a single layer to the map
						map.addLayer(IWPoiUtils.makeLayer(map, 'Tankstelle', 'POITA1', 'Tankstelle', 'POITA1'));
					}
				});
				
				IWLoader.loadModules(['poi']);
			}
		</script>	
	</head>

	<body onload="initialize();">
		<div id="divMap" style="position: absolute; background-color: #dddddd; width: 450px; height: 300px"></div>			
	</body>
</html>

The line of interest is:

map.addLayer(IWPoiUtils.makeLayer(map, 'Tankstelle', 'POITA1', 'Tankstelle', 'POITA1'))

The function makeLayer() creates an IWLayer, which can be placed on the map with map.addLayer.

7.1.2 Full control

If you want to have full control of your layer and formatting you can do all the things manually.

Shapes and Layers example 7b Source code example 7b:
// (1) create and add layer
layer = new IWLayer(map, 'Tankstelle', 'POITA1');
layer.addShape(new IWShape('Tankstelle', new IWRange(6, 19)));
map.addLayer(layer);

// (2) create new request layer for our layer
requestLayer = new IWRequestLayer(layer);
// (3) we register two events
requestLayer.registerEvent('onmousestop');
requestLayer.registerEvent('onclick');

// add the request layer to the infomanager of the map.
var infoManager = map.getLayerInfoManager();										
infoManager.addRequestLayer(requestLayer);
					
IWEventManager.addListener(requestLayer, 'ondatareceive', 
	function(e)
	{
		// test if the event contains an none empty recordset						
		if (e.records > 0)
		{
			if (e.requestedEvent == 'onclick')
			{
				var content = document.createElement('div');

				for (var i=0; i < e.records; i++)
				{
					//format your record
					var div = formatContent(e.json.record[i]);
					content.appendChild(div);
				}
				//create an infoballoon with this content
				map.openInfoBalloon(e.mouseCoordinate, content);
			}
			else if (e.requestedEvent == 'onmousestop')
			{
				// create a new tooltip with the 'tooltip text' from the first record.
				map.openTooltip(e.mouseCoordinate, '<nobr>' + e.json.record[0].NAME + '</nobr>');
																	
				// close the tooltip after 5 seconds automatically
				window.setTimeout(function () { map.removeTooltip(); }, 5000);
			}
		}
	}
);

First we instantiate a IWLayer with a corresponding shapefile and add it to the map.

With IWRequestLayer you can receive data from the layer and show it for example in a tooltip/popup.

With IWRequestLayer.registerEvent() you can add every possible event. You could also make your own events (that you are triggering elsewhere) and catch them with the request layer. The only condition is that you have to provide an attribute position for the mouse coordinate in the event (which has to be an IWPoint). The request layer will send an request to the server. If data is available for this position, the request layer triggers an event ondatareceive. As you can see in the code above, we registered the two events onclick and onmousestop. The onmousestop is made by the API and will be triggered whe the mouse stops for a certain period on the map, feel free to use it. We have to set a listener on the request layer to catch and handle the information.

The IWRequestLayerEvent has an attribute requestedEvent, there you can determine for which registered event you are getting your information and with the attribute mouseCoordinate you know where the information is located. The data itself is provided in JSON-format and stored in the attribute json. In example 7a you can see how to use and format the information for a IWTooltip or an IWInfoballoon.

7.1.3 Handling more layers

If you added two layers to the map and two different POIs are at the same position, you can fetch all information from an event thrown by the IWLayerInfoManager.

var infoManager = map.getLayerInfoManager();										
infoManager.addRequestLayer(requestLayer1);
infoManager.addRequestLayer(requestLayer2);

IWEventManager.addListener(infoManager, 'ondatareceive',
		function(e)
		{
		if (e.records > 0)
			{	
		  		if (e.requestedEvent == 'onclick')
		  		{
					var content = document.createElement('div');
											
					//fetch all records
					for (layer in e.json)
					{
						var records = e.json[layer].recordset.record;
						for (var i=0; i < records.length; i++)
						{
							//format the informations, e.g. in an infoballoon
							...
										
							

The main difference to example 7b is that we change the listener. The IWLayerInfoManager throws the event ondatareceive when data is on its way. It provides also an attribute json which contains the information from all registered RequestLayers. This way you can easily process the received data without adding a listener for each layer.

7.2 POI Formatters

Imagine you want to display several kinds of overlays in your map: Traffic information (with concrete information on traffic jams and road works), railway stations (with links to railway schedules) and standard POIs. For standard POIs there is nothing but a type, a name, an address and maybe a link to a website, but traffic information and railway stations both require a different formatting.

This is what formatters are used for: When a symbol in the map is clicked, a formatter decides if it is able to format this kind of POIs and generates a short (for tooltips) or complex (for bubbles) HTML representation of the POI. There are several formatters included in the API which will be sufficient in most cases and which will be used when IWPoiUtils.initFormatters(); is called as seen before.

7.2.1 Create your own POI Formatter

If you want to add your own layer with a special format, you can write your own POI formatter. Your formatter must implement 3 methods, in which the parameter record is a POI record from an identify request:

function MyPoiFormatter()
	{
		// your constructor code (if required)
	}
	
	// Checks a feature of the record to determine whether this formatter should be used or not. Returns true or false
	MyPoiFormatter.prototype.isSupported = function(record){};

	// a HTML string with a short description, e.g. for a tooltip
	MyPoiFormatter.prototype.formatCompact = function(record){};

	// a HTML string with a long description, e.g. for an infoballoon
	MyPoiFormatter.prototype.formatDetailed = function(record){};

To use this formatter for your layers, you must initialize the formatter engine as follows:


			IWPoiUtils.initFormatters([new MyPoiFormatter()]);
		
In this case all POIs are formatted by your custom formatter (or not displayed if isSupported() returns false). To use both your custom formatter and the default formatters of the API you can initialize the engine like this:

			IWPoiUtils.initFormatters([new MyPoiFormatter()].concat(IWPoiUtils.DEFAULT_FORMATTERS));
		

7.3 Layer groups

With IWLayerGroup you can create a hierachy. If you set a group to invisible for example, all layers and groups added in this group become invisible. The following example shows it in combination with an IWOverlaySelectionControl

 Source code example 7c:

var poitaGroup = new IWLayerGroup('Points of Interest');
						
var gastronomieGroup = new IWLayerGroup('Gastronomie');
gastronomieGroup.addLayer(makeLayer('Restaurant', 'POITA2', 'Restaurant'));
poitaGroup.addLayer(gastronomieGroup);

poitaGroup.addLayer(makeLayer('Tankstelle', 'POITA1', 'Tankstelle'));				

map.addLayer(poitaGroup);
Shapes and Layers example 7c Source code example 7c:

7.4 MapCms

To get actual or dynamic poi informations and if your product is registered by MapCms you can use the configured pois for this product.

Your product is defined by the parameters vnr and pnr> by calling the core.js library.

A simple way to do this, is to call IWPoiUtils.initLayers(). This adds all POI types of a POI catalogue (collection of pois, configured in MapCms) to the map.

Shapes and Layers example 7e Source code example 7e:
IWPoiUtils.initLayers(map, 'demo');

This line will add the catalogue 'demo' with all pois to the map.

In combination with a layergroup you can first insert the catalog into a layergroup and add them to the map (or an IWOverlaySelectionControl)

var demoGroup = new IWLayerGroup('Points of Interest');
IWPoiUtils.initLayers(map, 'demo', demoGroup);
map.addLayer(demoGroup);

   « Previous Chapter 6: Overlays    Back to Index    Next Chapter 8: Projection »