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