xref: /plugin/openlayersmap/script.js (revision 6d91d4f8b267ee47299c8ec2c25ac3400772dd12)
1/*
2 * Copyright (c) 2008-2011 Mark C. Prins <mc.prins@gmail.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/**
18 * @fileoverview Javascript voor OpenLayers plugin.
19 *
20 * @requires {lib/OpenLayers.js} or a full openlayers build
21 * @author Mark C. Prins <mc.prins@gmail.com>
22 *
23 */
24
25/**
26 * Openlayers selectcontrol.
27 *
28 * @type {OpenLayers.Control.SelectFeature}
29 * @private
30 */
31var selectControl;
32
33/**
34 * handle feature select event.
35 *
36 * @param {OpenLayers.Feature.Vector}
37 *            the selected feature
38 */
39function onFeatureSelect(feature) {
40	var selectedFeature = feature;
41	// 'this' is selectFeature control
42	var pPos = selectedFeature.geometry.getBounds().getCenterLonLat();
43	// != OpenLayers.Geometry.Point
44	if (selectedFeature.geometry.CLASS_NAME === "OpenLayers.Geometry.LineString") {
45		try {
46			// for lines make the popup show at the cursor position
47			pPos = feature.layer.map
48					.getLonLatFromViewPortPx(this.handlers.feature.evt.xy);
49		} catch (anErr) {
50			OpenLayers.Console
51					.warn("unable to get event position; reverting to boundingbox center.");
52			pPos = selectedFeature.geometry.getBounds().getCenterLonLat();
53		}
54	}
55
56	var pContent = '<div clas="spacer">&nbsp;</div>';
57	if (feature.data.rowId !== undefined) {
58		pContent += '<span class="rowId">' + feature.data.rowId + ': </span>';
59	}
60	if (feature.data.name !== undefined) {
61		pContent += '<span class="txt">' + feature.data.name + '</span>';
62	}
63	if (feature.data.ele !== undefined) {
64		pContent += "<div>elevation: " + feature.data.ele + "</div>";
65	}
66	if (feature.data.type !== undefined) {
67		pContent += "<div>" + feature.data.type + "></div>";
68	}
69	if (feature.data.time !== undefined) {
70		pContent += "<div>time: " + feature.data.time + "</div>";
71	}
72	if (feature.data.description !== undefined) {
73		pContent += "<div>" + feature.data.description + "</div>";
74	}
75
76	if (pContent.length > 0) {
77		// only show when there is something to show...
78		var popup = new OpenLayers.Popup.FramedCloud("olPopup", pPos, null,
79				pContent, null, true, function() {
80					selectControl.unselect(selectedFeature);
81				});
82		feature.popup = popup;
83		feature.layer.map.addPopup(popup);
84	}
85}
86
87/**
88 * handle feature unselect event. remove & destroy the popup.
89 *
90 * @param {OpenLayers.Feature.Vector}
91 *            the un-selected feature
92 */
93function onFeatureUnselect(feature) {
94	if (feature.popup !== null) {
95		feature.layer.map.removePopup(feature.popup);
96		feature.popup.destroy();
97		feature.popup = null;
98	}
99}
100/**
101 * Test for css support in the browser by sniffing for a css class we added using
102 * javascript added by the action plugin; this is an edge case because browsers
103 * that support javascript generally support css as well.
104 *
105 * @returns {Boolean} true when the browser supports css (and implicitly
106 *          javascript)
107 */
108function olTestCSSsupport() {
109	return (((getElementsByClass('olCSSsupported', null, null))).length > 0);
110}
111
112/**
113 * creates a DocumentFragment to insert into the dom.
114 *
115 * @param mapid
116 *            id for the map div
117 * @param width
118 *            width for the map div
119 * @param height
120 *            height for the map div
121 * @returns a {DocumentFragment} element that can be injected into the dom
122 */
123function olCreateMaptag(mapid, width, height) {
124	var mEl = '<div id="'
125			+ mapid
126			+ '-olContainer" class="olContainer olWebOnly">'
127			+ '<div id="'
128			+ mapid
129			+ '-olToolbar" class="olToolbar"></div>'
130			+ '<div class="clearer"></div>'
131			+ '<div id="'
132			+ mapid
133			+ '" style="width:'
134			+ width
135			+ ';height:'
136			+ height
137			+ ';" class="olMap"></div>'
138			+ '<div id="'
139			+ mapid
140			+ '-olStatusBar" class="olStatusBarContainer">'
141			+ '<div id="'
142			+ mapid
143			+ '-statusbar-scale" class="olStatusBar olStatusBarScale">scale</div>'
144			+ '<div id="'
145			+ mapid
146			+ '-statusbar-link" class="olStatusBar olStatusBarPermalink"><a href="" id="'
147			+ mapid
148			+ '-statusbar-link-ref">map link</a></div>'
149			+ '<div id="'
150			+ mapid
151			+ '-statusbar-mouseposition" class="olStatusBar olStatusBarMouseposition"></div>'
152			+ '<div id="'
153			+ mapid
154			+ '-statusbar-projection" class="olStatusBar olStatusBarProjection">proj</div>'
155			+ '<div id="' + mapid
156			+ '-statusbar-text" class="olStatusBar olStatusBarText">txt</div>'
157			+ '</div>\n</div>',
158	// fragment
159	frag = document.createDocumentFragment(),
160	// temp node
161	temp = document.createElement('div');
162	temp.innerHTML = mEl;
163	while (temp.firstChild) {
164		frag.appendChild(temp.firstChild);
165	}
166	return frag;
167}
168
169/**
170 * create the map based on the params given.
171 *
172 * @param {Object}mapOpts
173 *            MapOptions hash {id:'olmap', width:500px, height:500px,
174 *            lat:6710200, lon:506500, zoom:13, toolbar:1, statusbar:1,
175 *            controls:1, poihoverstyle:1, baselyr:'', kmlfile:'', gpxfile:'',
176 *            summary:''}
177 * @param {Array}OLmapPOI
178 *            array with POI's [ {lat:6710300,lon:506000,txt:'instap
179 *            punt',angle:180,opacity:.9,img:'', rowId:n},... ]);
180 *
181 */
182function createMap(mapOpts, OLmapPOI) {
183	if (!olEnable) {
184		return;
185	}
186	if (!olTestCSSsupport()) {
187		olEnable = false;
188		return;
189	}
190
191	var DocBase = DOKU_BASE;
192
193	OpenLayers.IMAGE_RELOAD_ATTEMPTS = 4;
194	OpenLayers.Util.onImageLoadErrorColor = 'pink';
195	OpenLayers.Util.onImageLoadError = function() {
196		/* transparent gif */
197		// IE 8 complains w/ stack overflow... this.src =
198		// "data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";
199		this.src = DocBase + "lib/plugins/openlayersmap/lib/img/blank.gif";
200	};
201
202	// OpenLayers.Layer.Vector.prototype.renderers = ["SVG2", "VML", "Canvas"];
203
204	// find map element location
205	var cleartag = document.getElementById(mapOpts.id + '-clearer');
206	if (cleartag === null) {
207		return;
208	}
209	// create map element and add to document
210	var fragment = olCreateMaptag(mapOpts.id, mapOpts.width, mapOpts.height);
211	cleartag.parentNode.insertBefore(fragment, cleartag);
212
213	/** dynamic map extent. */
214	var extent = new OpenLayers.Bounds(),
215
216	/** map. */
217	m = new OpenLayers.Map(mapOpts.id, {
218		projection : new OpenLayers.Projection('EPSG:900913'),
219		displayProjection : new OpenLayers.Projection('EPSG:4326'),
220		units : 'm',
221		maxResolution : 156543.0339,
222		maxExtent : new OpenLayers.Bounds(-20037508.34, -20037508.34,
223				20037508.34, 20037508.34),
224		numZoomLevels : 19,
225		// panDuration : 100,
226		controls : [ /* new OpenLayers.Control.LoadingPanel(), */
227		new OpenLayers.Control.KeyboardDefaults(),
228				new OpenLayers.Control.Navigation({
229					dragPanOptions : {
230						enableKinetic : true
231					}
232				}), new OpenLayers.Control.ScaleLine({
233					geodesic : true
234				}) ],
235		theme : null
236	});
237	if (osmEnable) {
238		/* add OSM map layers */
239		m.addLayer(new OpenLayers.Layer.OSM("OpenStreetMap"), {
240			transitionEffect : 'resize',
241			visibility : false
242		});
243
244		m
245				.addLayer(
246						new OpenLayers.Layer.OSM(
247								"t@h",
248								[
249										"http://a.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png",
250										"http://b.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png",
251										"http://c.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png" ]),
252						{
253							transitionEffect : 'resize',
254							visibility : false
255						});
256
257		m
258				.addLayer(
259						new OpenLayers.Layer.OSM(
260								"cycle map",
261								[
262										// "http://andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png",
263										"http://a.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png",
264										"http://b.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png",
265										"http://c.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png" ]),
266						{
267							transitionEffect : 'resize',
268							attribution : 'Data CC-By-SA <a href="http://openstreetmap.org/" target="_blank">OpenStreetMap</a>, '
269									+ 'Tiles <a href="http://opencyclemap.org/" target="_blank">OpenCycleMap</a>'
270									+ '<img src="http://opencyclemap.org/favicon.ico" heigth="16" width="16"/>',
271							visibility : false
272						});
273
274		m
275				.addLayer(new OpenLayers.Layer.OSM(
276						"cloudmade map",
277						"http://tile.cloudmade.com/2f59745a6b525b4ebdb100891d5b6711/3/256/${z}/${x}/${y}.png",
278						{
279							transitionEffect : 'resize',
280							visibility : false
281						}));
282
283		m.addLayer(new OpenLayers.Layer.OSM("hike and bike map",
284				"http://toolserver.org/tiles/hikebike/${z}/${x}/${y}.png", {
285					transitionEffect : 'resize',
286					visibility : false
287				}));
288	}
289	/*
290	 * add MapQuest map layers, see:
291	 * http://developer.mapquest.com/web/products/open/map
292	 */
293	if (mqEnable) {
294		m
295				.addLayer(new OpenLayers.Layer.OSM(
296						"mapquest road",
297						[
298								"http://otile1.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
299								"http://otile2.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
300								"http://otile3.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
301								"http://otile4.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png" ],
302						{
303							transitionEffect : 'resize',
304							attribution : 'Data CC-By-SA <a href="http://openstreetmap.org/" target="_blank">OpenStreetMap</a>, '
305									+ 'Tiles <a href="http://www.mapquest.com/" target="_blank">MapQuest</a>'
306									+ '<img src="http://developer.mapquest.com/content/osm/mq_logo.png" heigth="14" width="14" alt="logo"/>',
307							visibility : false
308						}));
309		// note that global coverage is provided at zoom levels 0-11. Zoom
310		// Levels 12+ are provided only in the United States (lower 48).
311		m
312				.addLayer(new OpenLayers.Layer.OSM(
313						"mapquest sat",
314						[
315								"http://oatile1.mqcdn.com/naip/${z}/${x}/${y}.jpg",
316								"http://oatile2.mqcdn.com/naip/${z}/${x}/${y}.jpg",
317								"http://oatile3.mqcdn.com/naip/${z}/${x}/${y}.jpg",
318								"http://oatile4.mqcdn.com/naip/${z}/${x}/${y}.jpg" ],
319						{
320							transitionEffect : 'resize',
321							attribution : 'Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a>'
322									+ '<img src="http://developer.mapquest.com/content/osm/mq_logo.png" heigth="16" width="16">',
323							visibility : false,
324							numZoomLevels : 12
325						}));
326	}
327
328	/* open aerial map layers */
329	/*
330	 * turn this off; project is asleep:
331	 * https://sourceforge.net/tracker/?func=detail&aid=2897327&group_id=239475&atid=1110186
332	 * m.addLayer(new OpenLayers.Layer.XYZ("OpenAerialMap",
333	 * "http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/${z}/${x}/${y}.jpg",
334	 * {name: "OpenStreetMap", attribution: "Data CC-By by <a
335	 * href='http://www.openaerialmap.org/licensing/'>OpenAerialMap</a>",
336	 * sphericalMercator: true, transitionEffect: 'resize'} ));
337	 */
338
339	if (gEnable) {
340		/* load google maps */
341		try {
342			m.addLayer(new OpenLayers.Layer.Google("google relief", {
343				type : google.maps.MapTypeId.TERRAIN,
344				// transitionEffect : 'resize',
345				numZoomLevels : 16,
346				animationEnabled : true,
347				visibility : false
348			}));
349			m.addLayer(new OpenLayers.Layer.Google("google sat", {
350				type : google.maps.MapTypeId.SATELLITE,
351				// transitionEffect : 'resize',
352				// numZoomLevels : 22,
353				animationEnabled : true,
354				visibility : false
355			}));
356			m.addLayer(new OpenLayers.Layer.Google("google hybrid", {
357				type : google.maps.MapTypeId.HYBRID,
358				// transitionEffect : 'resize',
359				// numZoomLevels : 20,
360				animationEnabled : true,
361				visibility : false
362			}));
363			m.addLayer(new OpenLayers.Layer.Google("google road", {
364				// transitionEffect : 'resize',
365				// numZoomLevels : 20,
366				animationEnabled : true,
367				visibility : false
368			}));
369		} catch (ol_err1) {
370			Openlayers.Console.userError('Error loading Google maps' + ol_err1);
371		}
372	}
373
374	// if (yEnable) {
375	// try {
376	// m.addLayer(new OpenLayers.Layer.Yahoo("yahoo", {
377	// 'type' : YAHOO_MAP_HYB,
378	// 'sphericalMercator' : true,
379	// transitionEffect : resize
380	// }));
381	// } catch (ol_err2) {
382	// }
383	// }
384
385	if (veEnable) {
386		try {
387			m.addLayer(new OpenLayers.Layer.VirtualEarth("ve", {
388				type : VEMapStyle.Hybrid,
389				sphericalMercator : true,
390				transitionEffect : 'resize',
391				visibility : false
392			}));
393		} catch (ol_err3) {
394			Openlayers.Console.userError('Error loading Virtual Earth maps: '
395					+ ol_err3);
396		}
397	}
398
399	if (bEnable && bApiKey !== '') {
400		try {
401			/* add Bing tiles */
402			m.addLayer(new OpenLayers.Layer.Bing({
403				key : bApiKey,
404				type : "Road",
405				name : 'bing road',
406				transitionEffect : 'resize',
407				visibility : false
408			}));
409			m.addLayer(new OpenLayers.Layer.Bing({
410				key : bApiKey,
411				type : "Aerial",
412				name : 'bing sat',
413				transitionEffect : 'resize',
414				visibility : false
415			}));
416			m.addLayer(new OpenLayers.Layer.Bing({
417				key : bApiKey,
418				type : "AerialWithLabels",
419				name : "bing hybrid",
420				transitionEffect : 'resize',
421				visibility : false
422			}));
423		} catch (ol_errBing) {
424			Openlayers.Console.userError('Error loading Bing maps: '
425					+ ol_errBing);
426		}
427	}
428
429	m.setCenter(new OpenLayers.LonLat(mapOpts.lon, mapOpts.lat).transform(
430			m.displayProjection, m.projection), mapOpts.zoom);
431	extent.extend(m.getExtent());
432
433	// change/set alternative baselyr
434	try {
435		m.setBaseLayer(((m.getLayersByName(mapOpts.baselyr))[0]));
436	} catch (ol_err4) {
437		m.setBaseLayer(m.layers[0]);
438	}
439
440	if (mapOpts.controls === 1) {
441		/* add base controls to map */
442		m.addControl(new OpenLayers.Control.LayerSwitcher({
443			roundedCorner : false,
444			roundedCornerColor : null
445		}));
446		m.addControl(new OpenLayers.Control.PanZoomBar());
447		m.addControl(new OpenLayers.Control.Graticule({
448			visible : false
449		}));
450
451		// add hillshade, since this is off by default only add when we have a
452		// layerswitcher
453		m.addLayer(new OpenLayers.Layer.OSM("Hillshade",
454				"http://toolserver.org/~cmarqu/hill/${z}/${x}/${y}.png", {
455					transitionEffect : 'resize',
456					isBaseLayer : false,
457					transparent : true,
458					visibility : false,
459					displayOutsideMaxExtent : true,
460					attribution : ''
461				}));
462
463		m.addControl(new OpenLayers.Control.OverviewMap({
464			size : new OpenLayers.Size(140, 140),
465			mapOptions : {
466				theme : null
467			},
468			layers : [ m.baseLayer.clone() ],
469			minRectSize : 10
470		}));
471	}
472
473	if (mapOpts.statusbar === 1) {
474		// statusbar control: permalink
475		m.addControl(new OpenLayers.Control.Permalink(mapOpts.id
476				+ '-statusbar-link-ref'));
477		// statusbar control: mouse pos.
478		// TODO kijken naar afronding met aNumber.toFixed(0)
479		m.addControl(new OpenLayers.Control.MousePosition({
480			'div' : OpenLayers.Util.getElement(mapOpts.id + '-statusbar-mouseposition')
481		}));
482		// statusbar control: scale
483		m.addControl(new OpenLayers.Control.Scale(mapOpts.id + '-statusbar-scale'));
484		// statusbar control: attribution
485		m.addControl(new OpenLayers.Control.Attribution({
486			'div' : OpenLayers.Util.getElement(mapOpts.id + '-statusbar-text')
487		}));
488		// statusbar control: projection
489		OpenLayers.Util.getElement(mapOpts.id + '-statusbar-projection').innerHTML = m.displayProjection;
490	} else {
491		OpenLayers.Util.getElement(mapOpts.id + '-olStatusBar').display = 'none';
492	}
493
494	if (mapOpts.toolbar === 1) {
495		// add buttons + panel
496		var /* zoom in btn */
497		zoomin = new OpenLayers.Control.ZoomBox({
498			title : "Zoom in"
499		}), /* zoom out btn */
500		zoomout = new OpenLayers.Control.ZoomBox({
501			out : true,
502			title : "Zoom uit",
503			displayClass : "olControlZoomOut"
504		}), /* pan btn */pan = new OpenLayers.Control.DragPan({
505			title : "Verschuif"
506		}), /* do "nothing" button... */info = new OpenLayers.Control.Button({
507			type : OpenLayers.Control.TYPE_TOOL,
508			displayClass : "olControlFeatureInfo",
509			title : "Info"
510		}), /* navigation history btns */
511		nav = new OpenLayers.Control.NavigationHistory();
512		m.addControl(nav);
513		var panel = new OpenLayers.Control.Panel({
514			defaultControl : pan,
515			displayClass : "olToolbar",
516			"div" : OpenLayers.Util.getElement(mapOpts.id + "-olToolbar")
517		});
518		panel
519				.addControls([ zoomin, zoomout, pan, info, nav.next,
520						nav.previous ]);
521		// panel.addControls([ nav.next, nav.previous ]);
522		m.addControl(panel);
523	} else {
524		OpenLayers.Util.getElement(mapOpts.id + '-olToolbar').display = 'none';
525	}
526
527	if (OLmapPOI.length > 0) {
528		var markers = new OpenLayers.Layer.Vector(
529				"POI",
530				{
531					styleMap : new OpenLayers.StyleMap(
532							{
533								"default" : {
534									externalGraphic : "${img}",
535									graphicHeight : 16,
536									graphicWidth : 16,
537									graphicXOffset : 0,
538									graphicYOffset : -8,
539									graphicOpacity : "${opacity}",
540									rotation : "${angle}",
541									backgroundGraphic : DocBase
542											+ "lib/plugins/openlayersmap/icons/marker_shadow.png",
543									backgroundXOffset : 0,
544									backgroundYOffset : -4,
545									backgroundRotation : "${angle}",
546									pointRadius : 10,
547									labelXOffset : 8,
548									labelYOffset : 8,
549									labelAlign : "lb",
550									label : "${label}",
551									// fontColor : "",
552									fontFamily : "monospace",
553									fontSize : "12px",
554									fontWeight : "bold"
555								},
556								"select" : {
557									cursor : "crosshair",
558									externalGraphic : DocBase
559											+ "lib/plugins/openlayersmap/icons/marker-red.png",
560									graphicHeight : 16,
561									graphicWidth : 16,
562									graphicXOffset : 0,
563									graphicYOffset : -8,
564									graphicOpacity : 1.0,
565									rotation : "${angle}"
566								}
567							}),
568					isBaseLayer : false,
569					rendererOptions : {
570						yOrdering : true
571					}
572				});
573		m.addLayer(markers);
574		var features = [];
575		var lonLat;
576		for ( var j = 0; j < OLmapPOI.length; j++) {
577			var feat = new OpenLayers.Feature.Vector(
578					new OpenLayers.Geometry.Point(OLmapPOI[j].lon,
579							OLmapPOI[j].lat).transform(m.displayProjection,
580							m.projection), {
581						angle : OLmapPOI[j].angle,
582						opacity : OLmapPOI[j].opacity,
583						img : DocBase + "lib/plugins/openlayersmap/icons/"
584								+ OLmapPOI[j].img,
585						label : OLmapPOI[j].rowId
586					});
587			feat.data = {
588				name : OLmapPOI[j].txt,
589				rowId : OLmapPOI[j].rowId
590			};
591			features.push(feat);
592		}
593		markers.addFeatures(features);
594		extent.extend(markers.getDataExtent());
595		m.zoomToExtent(extent);
596	}
597
598	/* GPX layer */
599	if (mapOpts.gpxfile.length > 0) {
600		var layerGPX = new OpenLayers.Layer.GML("GPS route", DocBase
601				+ "lib/exe/fetch.php?media=" + mapOpts.gpxfile, {
602			format : OpenLayers.Format.GPX,
603			formatOptions : {
604				extractWaypoints : true,
605				extractTracks : true,
606				extractStyles : true,
607				extractAttributes : true,
608				handleHeight : true,
609				maxDepth : 3
610			},
611			style : {
612				strokeColor : "#0000FF",
613				strokeWidth : 3,
614				strokeOpacity : 0.7,
615				pointRadius : 4,
616				fillColor : "#0099FF",
617				fillOpacity : 0.7
618			/*
619			 * , label:"${name}"
620			 */},
621			projection : new OpenLayers.Projection("EPSG:4326")
622		});
623		m.addLayer(layerGPX);
624		layerGPX.events.register('loadend', m, function() {
625			extent.extend(layerGPX.getDataExtent());
626			m.zoomToExtent(extent);
627		});
628
629	}
630
631	/* KML layer */
632	if (mapOpts.kmlfile.length > 0) {
633		var layerKML = new OpenLayers.Layer.GML("KML file", DocBase
634				+ "lib/exe/fetch.php?media=" + mapOpts.kmlfile, {
635			format : OpenLayers.Format.KML,
636			formatOptions : {
637				extractStyles : true,
638				extractAttributes : true,
639				maxDepth : 3
640			},
641			style : {
642				label : "${name}"
643			},
644			projection : new OpenLayers.Projection("EPSG:4326")
645		});
646		m.addLayer(layerKML);
647		layerKML.events.register('loadend', m, function() {
648			extent.extend(layerKML.getDataExtent());
649			m.zoomToExtent(extent);
650		});
651	}
652
653	// selectcontrol for layers
654	if ((m.getLayersByClass('OpenLayers.Layer.GML').length > 0)
655			|| m.getLayersByClass('OpenLayers.Layer.Vector').length > 0) {
656		selectControl = new OpenLayers.Control.SelectFeature((m
657				.getLayersByClass('OpenLayers.Layer.Vector')).concat(m
658				.getLayersByClass('OpenLayers.Layer.GML')), {
659			hover : mapOpts.poihoverstyle,
660			onSelect : onFeatureSelect,
661			onUnselect : onFeatureUnselect
662		});
663		m.addControl(selectControl);
664		selectControl.activate();
665	}
666
667	return m;
668}
669
670var olTimerId = -1;
671/** init. */
672function olInit() {
673	if(navigator.userAgent.indexOf('MSIE')!= -1){
674		//console.log("need to sleep");
675		if(olTimerId==-1){
676			olTimerId = setTimeout ( "olInit()", 3000 );
677			olEnable = false;
678		} else {
679			//console.log("done sleeping");
680			clearTimeout ( olTimerId );
681			olEnable = true;
682		}
683	}
684
685	if (olEnable) {
686		var _i = 0;
687		// create the maps in the page
688		for(_i = 0; _i < olMapData.length; _i++){
689			//console.log(olMapData);
690			createMap(olMapData[_i].mapOpts,olMapData[_i].poi);
691		}
692
693		// hide the table(s) with POI by giving it a print-only style
694		var tbls = getElementsByClass('olPOItableSpan', null, null);
695		for (_i = 0; _i < tbls.length; _i++) {
696			tbls[_i].className += ' olPrintOnly';
697		}
698		// hide the static map image(s) by giving it a print only style
699		var statImgs = getElementsByClass('olStaticMap', null, null);
700		for (_i = 0; _i < statImgs.length; _i++) {
701			statImgs[_i].className += ' olPrintOnly';
702		}
703	}
704}
705
706/**
707 * ol api flag.
708 *
709 * @type {Boolean}
710 */
711var olEnable = false,
712/**
713 * array with data for each map in the page.
714 * @type {Array}
715 */
716olMapData = new Array(),
717/**
718 * MapQuest tiles flag.
719 *
720 * @type {Boolean}
721 */
722mqEnable = false,
723/**
724 * google map api flag.
725 *
726 * @type {Boolean}
727 */
728gEnable = false,
729/**
730 * virtual earth map api flag.
731 *
732 * @type {Boolean}
733 */
734veEnable = false,
735/**
736 * Bing tiles flag.
737 *
738 * @type {Boolean}
739 */
740bEnable = false,
741/**
742 * Bing API key.
743 *
744 * @type {String}
745 */
746bApiKey = '',
747/**
748 * OSM tiles flag.
749 *
750 * @type {Boolean}
751 */
752osmEnable = true,
753/**
754 * CSS support flag.
755 *
756 * @type {Boolean}
757 */
758olCSSEnable = true;
759/**
760 * yahoo map api flag.
761 *
762 * @type {Boolean}
763 */
764// yEnable = false;
765
766
767/* register olInit to run with onload event. */
768addInitEvent(olInit);
769