xref: /plugin/openlayersmap/script.js (revision 85e32b858937787c823ef75fccd33a8c769aeae5)
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 = 4;
173	OpenLayers.Util.onImageLoadErrorColor = 'transparent';
174	OpenLayers.Util.onImageLoadError = function() {
175		/* transparent gif */
176		// IE 8 complains w/ stack overflow... this.src =
177		// "data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";
178		this.src = DocBase + "lib/plugins/openlayersmap/lib/img/blank.gif";
179	};
180
181	// OpenLayers.Layer.Vector.prototype.renderers = ["SVG2", "VML", "Canvas"];
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 : false
234					visibility : mapOpts.baselyr == "OpenStreetMap"
235				}));
236
237		m.addLayer(new OpenLayers.Layer.OSM(
238				"t@h", "http://tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png", {
239					transitionEffect : 'resize',
240					visibility : mapOpts.baselyr == "t@h",
241					tileOptions : {
242						crossOriginKeyword : null
243					}
244				}));
245
246		m
247				.addLayer(new OpenLayers.Layer.OSM(
248						"cycle map",
249						[// "http://andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png",
250								"http://a.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png",
251								"http://b.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png",
252								"http://c.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png" ],
253						{
254							transitionEffect : 'resize',
255							attribution : 'Data CC-By-SA <a href="http://openstreetmap.org/" target="_blank">OpenStreetMap</a>, '
256									+ 'Tiles <a href="http://opencyclemap.org/" target="_blank">OpenCycleMap</a>'
257									+ '<img src="http://opencyclemap.org/favicon.ico" heigth="16" width="16"/>',
258							visibility : mapOpts.baselyr == "cycle map",
259							tileOptions : {
260								crossOriginKeyword : null
261							}
262						}));
263
264		m
265				.addLayer(new OpenLayers.Layer.OSM(
266						"cloudmade map",
267						"http://tile.cloudmade.com/2f59745a6b525b4ebdb100891d5b6711/3/256/${z}/${x}/${y}.png",
268						{
269							transitionEffect : 'resize',
270							visibility : mapOpts.baselyr == "cloudmade map",
271							tileOptions : {
272								crossOriginKeyword : null
273							}
274						}));
275
276		m.addLayer(new OpenLayers.Layer.OSM(
277				"hike and bike map", "http://toolserver.org/tiles/hikebike/${z}/${x}/${y}.png", {
278					transitionEffect : 'resize',
279					visibility : mapOpts.baselyr == "hike and bike map",
280					tileOptions : {
281						crossOriginKeyword : null
282					}
283				}));
284	}
285	/*
286	 * add MapQuest map layers, see:
287	 * http://developer.mapquest.com/web/products/open/map
288	 */
289	if (mqEnable) {
290		m
291				.addLayer(new OpenLayers.Layer.OSM(
292						"mapquest road",
293						[
294								"http://otile1.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
295								"http://otile2.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
296								"http://otile3.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
297								"http://otile4.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png" ],
298						{
299							transitionEffect : 'resize',
300							attribution : 'Data CC-By-SA <a href="http://openstreetmap.org/" target="_blank">OpenStreetMap</a>, '
301									+ 'Tiles <a href="http://www.mapquest.com/" target="_blank">MapQuest</a>'
302									+ '<img src="http://developer.mapquest.com/content/osm/mq_logo.png" heigth="14" width="14" alt="logo"/>',
303							visibility : mapOpts.baselyr == "mapquest road",
304							tileOptions : {
305								crossOriginKeyword : null
306							}
307						}));
308		// note that global coverage is provided at zoom levels 0-11. Zoom
309		// Levels 12+ are provided only in the United States (lower 48).
310		m
311				.addLayer(new OpenLayers.Layer.OSM(
312						"mapquest sat",
313						[
314								"http://oatile1.mqcdn.com/naip/${z}/${x}/${y}.jpg",
315								"http://oatile2.mqcdn.com/naip/${z}/${x}/${y}.jpg",
316								"http://oatile3.mqcdn.com/naip/${z}/${x}/${y}.jpg",
317								"http://oatile4.mqcdn.com/naip/${z}/${x}/${y}.jpg" ],
318						{
319							transitionEffect : 'resize',
320							attribution : 'Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a>'
321									+ '<img src="http://developer.mapquest.com/content/osm/mq_logo.png" heigth="16" width="16">',
322							visibility : mapOpts.baselyr == "mapquest sat",
323							numZoomLevels : 12,
324							tileOptions : {
325								crossOriginKeyword : null
326							}
327						}));
328	}
329
330	/* open aerial map layers */
331	/*
332	 * turn this off; project is asleep:
333	 * https://sourceforge.net/tracker/?func=detail&aid=2897327&group_id=239475&atid=1110186
334	 * m.addLayer(new OpenLayers.Layer.XYZ("OpenAerialMap",
335	 * "http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/${z}/${x}/${y}.jpg",
336	 * {name: "OpenStreetMap", attribution: "Data CC-By by <a
337	 * href='http://www.openaerialmap.org/licensing/'>OpenAerialMap</a>",
338	 * sphericalMercator: true, transitionEffect: 'resize'} ));
339	 */
340
341	if (gEnable) {
342		/* load google maps */
343		try {
344			m.addLayer(new OpenLayers.Layer.Google(
345					"google relief", {
346						type : google.maps.MapTypeId.TERRAIN,
347						// transitionEffect : 'resize',
348						numZoomLevels : 16,
349						animationEnabled : true,
350						visibility : mapOpts.baselyr == "google relief"
351					}));
352			m.addLayer(new OpenLayers.Layer.Google(
353					"google sat", {
354						type : google.maps.MapTypeId.SATELLITE,
355						// transitionEffect : 'resize',
356						// numZoomLevels : 22,
357						animationEnabled : true,
358						visibility : mapOpts.baselyr == "google sat"
359					}));
360			m.addLayer(new OpenLayers.Layer.Google(
361					"google hybrid", {
362						type : google.maps.MapTypeId.HYBRID,
363						// transitionEffect : 'resize',
364						// numZoomLevels : 20,
365						animationEnabled : true,
366						visibility : mapOpts.baselyr == "google hybrid"
367					}));
368			m.addLayer(new OpenLayers.Layer.Google(
369					"google road", {
370						// transitionEffect : 'resize',
371						// numZoomLevels : 20,
372						animationEnabled : true,
373						visibility : mapOpts.baselyr == "google road"
374					}));
375		} catch (ol_err1) {
376			Openlayers.Console.userError('Error loading Google maps' + ol_err1);
377		}
378	}
379
380	// if (yEnable) {
381	// try {
382	// m.addLayer(new OpenLayers.Layer.Yahoo("yahoo", {
383	// 'type' : YAHOO_MAP_HYB,
384	// 'sphericalMercator' : true,
385	// transitionEffect : resize
386	// }));
387	// } catch (ol_err2) {
388	// }
389	// }
390
391	/*
392	 * TODO! if (veEnable) { try { m.addLayer(new
393	 * OpenLayers.Layer.VirtualEarth("ve", { type : VEMapStyle.Hybrid,
394	 * sphericalMercator : true, transitionEffect : 'resize', visibility : false
395	 * })); } catch (ol_err3) { Openlayers.Console.userError('Error loading
396	 * Virtual Earth maps: ' + ol_err3); } }
397	 */
398	if (bEnable && bApiKey !== '') {
399		try {
400			/* add Bing tiles */
401			m.addLayer(new OpenLayers.Layer.Bing(
402					{
403						key : bApiKey,
404						type : "Road",
405						name : 'bing road',
406						transitionEffect : 'resize',
407						visibility : mapOpts.baselyr == "bing road",
408						wrapDateLine : true
409					}));
410			m.addLayer(new OpenLayers.Layer.Bing(
411					{
412						key : bApiKey,
413						type : "Aerial",
414						name : 'bing sat',
415						transitionEffect : 'resize',
416						visibility : mapOpts.baselyr == "bing sat",
417						wrapDateLine : true
418					}));
419			m.addLayer(new OpenLayers.Layer.Bing(
420					{
421						key : bApiKey,
422						type : "AerialWithLabels",
423						name : "bing hybrid",
424						transitionEffect : 'resize',
425						visibility : mapOpts.baselyr == "bing hybrid",
426						wrapDateLine : true
427					}));
428		} catch (ol_errBing) {
429			Openlayers.Console.userError('Error loading Bing maps: ' + ol_errBing);
430		}
431	}
432
433	m.setCenter(
434			new OpenLayers.LonLat(
435					mapOpts.lon, mapOpts.lat).transform(
436					m.displayProjection, m.projection), mapOpts.zoom);
437	extent.extend(m.getExtent());
438
439	// change/set alternative baselyr
440	try {
441		m.setBaseLayer(((m.getLayersByName(mapOpts.baselyr))[0]));
442	} catch (ol_err4) {
443		m.setBaseLayer(m.layers[0]);
444	}
445
446	if (mapOpts.controls === 1) {
447		/* add base controls to map */
448		m.addControl(new OpenLayers.Control.LayerSwitcher(
449				{
450					roundedCorner : false,
451					roundedCornerColor : null
452				}));
453		m.addControl(new OpenLayers.Control.PanZoomBar());
454		m.addControl(new OpenLayers.Control.Graticule(
455				{
456					visible : false
457				}));
458
459		// add hillshade, since this is off by default only add when we have a
460		// layerswitcher
461		m.addLayer(new OpenLayers.Layer.OSM(
462				"Hillshade", "http://toolserver.org/~cmarqu/hill/${z}/${x}/${y}.png", {
463					transitionEffect : 'resize',
464					isBaseLayer : false,
465					transparent : true,
466					visibility : false,
467					displayOutsideMaxExtent : true,
468					attribution : '',
469					tileOptions : {
470						crossOriginKeyword : null
471					}
472				}));
473
474		m.addControl(new OpenLayers.Control.OverviewMap(
475				{
476					size : new OpenLayers.Size(
477							140, 140),
478					mapOptions : {
479						theme : null
480					},
481					layers : [ m.baseLayer.clone() ],
482					minRectSize : 10
483				}));
484	}
485
486	if (mapOpts.statusbar === 1) {
487		// statusbar control: permalink
488		m.addControl(new OpenLayers.Control.Permalink(
489				mapOpts.id + '-statusbar-link-ref'));
490		// statusbar control: mouse pos.
491		// TODO kijken naar afronding met aNumber.toFixed(0)
492		m.addControl(new OpenLayers.Control.MousePosition(
493				{
494					'div' : OpenLayers.Util.getElement(mapOpts.id + '-statusbar-mouseposition')
495				}));
496		// statusbar control: scale
497		m.addControl(new OpenLayers.Control.Scale(
498				mapOpts.id + '-statusbar-scale'));
499		// statusbar control: attribution
500		m.addControl(new OpenLayers.Control.Attribution(
501				{
502					'div' : OpenLayers.Util.getElement(mapOpts.id + '-statusbar-text')
503				}));
504		// statusbar control: projection
505		OpenLayers.Util.getElement(mapOpts.id + '-statusbar-projection').innerHTML = m.displayProjection;
506	} else {
507		OpenLayers.Util.getElement(mapOpts.id + '-olStatusBar').display = 'none';
508	}
509
510	if (mapOpts.toolbar === 1) {
511		// add buttons + panel
512		var /* zoom in btn */
513		zoomin = new OpenLayers.Control.ZoomBox(
514				{
515					title : "Zoom in"
516				}), /* zoom out btn */
517		zoomout = new OpenLayers.Control.ZoomBox(
518				{
519					out : true,
520					title : "Zoom uit",
521					displayClass : "olControlZoomOut"
522				}), /* pan btn */pan = new OpenLayers.Control.DragPan(
523				{
524					title : "Verschuif"
525				}), /* do "nothing" button... */info = new OpenLayers.Control.Button(
526				{
527					type : OpenLayers.Control.TYPE_TOOL,
528					displayClass : "olControlFeatureInfo",
529					title : "Info"
530				}), /* navigation history btns */
531		nav = new OpenLayers.Control.NavigationHistory();
532		m.addControl(nav);
533		var panel = new OpenLayers.Control.Panel(
534				{
535					defaultControl : pan,
536					displayClass : "olToolbar",
537					"div" : OpenLayers.Util.getElement(mapOpts.id + "-olToolbar")
538				});
539		panel.addControls([
540				zoomin, zoomout, pan, info, nav.next, nav.previous ]);
541		// panel.addControls([ nav.next, nav.previous ]);
542		m.addControl(panel);
543	} else {
544		OpenLayers.Util.getElement(mapOpts.id + '-olToolbar').display = 'none';
545	}
546
547	if (OLmapPOI.length > 0) {
548		var markers = new OpenLayers.Layer.Vector(
549				"POI", {
550					styleMap : new OpenLayers.StyleMap(
551							{
552								"default" : {
553									externalGraphic : "${img}",
554									graphicHeight : 16,
555									graphicWidth : 16,
556									graphicXOffset : 0,
557									graphicYOffset : -8,
558									graphicOpacity : "${opacity}",
559									rotation : "${angle}",
560									backgroundGraphic : DocBase
561											+ "lib/plugins/openlayersmap/icons/marker_shadow.png",
562									backgroundXOffset : 0,
563									backgroundYOffset : -4,
564									backgroundRotation : "${angle}",
565									pointRadius : 10,
566									labelXOffset : 8,
567									labelYOffset : 8,
568									labelAlign : "lb",
569									label : "${label}",
570									// fontColor : "",
571									fontFamily : "monospace",
572									fontSize : "12px",
573									fontWeight : "bold"
574								},
575								"select" : {
576									cursor : "crosshair",
577									externalGraphic : DocBase
578											+ "lib/plugins/openlayersmap/icons/marker-red.png",
579									graphicHeight : 16,
580									graphicWidth : 16,
581									graphicXOffset : 0,
582									graphicYOffset : -8,
583									graphicOpacity : 1.0,
584									rotation : "${angle}"
585								}
586							}),
587					isBaseLayer : false,
588					rendererOptions : {
589						yOrdering : true
590					}
591				});
592		m.addLayer(markers);
593		var features = [];
594		var lonLat;
595		for ( var j = 0; j < OLmapPOI.length; j++) {
596			var feat = new OpenLayers.Feature.Vector(
597					new OpenLayers.Geometry.Point(
598							OLmapPOI[j].lon, OLmapPOI[j].lat).transform(
599							m.displayProjection, m.projection), {
600						angle : OLmapPOI[j].angle,
601						opacity : OLmapPOI[j].opacity,
602						img : DocBase + "lib/plugins/openlayersmap/icons/" + OLmapPOI[j].img,
603						label : OLmapPOI[j].rowId
604					});
605			feat.data = {
606				name : OLmapPOI[j].txt,
607				rowId : OLmapPOI[j].rowId
608			};
609			features.push(feat);
610		}
611		markers.addFeatures(features);
612		extent.extend(markers.getDataExtent());
613		m.zoomToExtent(extent);
614	}
615
616	/*
617	 * map.addLayer(new OpenLayers.Layer.Vector("GML", { protocol: new
618	 * OpenLayers.Protocol.HTTP({ url: "gml/polygon.xml", format: new
619	 * OpenLayers.Format.GML() }), strategies: [new OpenLayers.Strategy.Fixed()]
620	 * }));
621	 */
622
623	/* GPX layer */
624	if (mapOpts.gpxfile.length > 0) {
625		var layerGPX = new OpenLayers.Layer.Vector(
626				"GPS route", {
627					protocol : new OpenLayers.Protocol.HTTP(
628							{
629								url : DocBase + "lib/exe/fetch.php?media=" + mapOpts.gpxfile,
630								format : new OpenLayers.Format.GPX(
631										{
632											extractWaypoints : true,
633											extractTracks : true,
634											extractStyles : true,
635											extractAttributes : true,
636											handleHeight : true,
637											maxDepth : 3
638										})
639							}),
640					style : {
641						strokeColor : "#0000FF",
642						strokeWidth : 3,
643						strokeOpacity : 0.7,
644						pointRadius : 4,
645						fillColor : "#0099FF",
646						fillOpacity : 0.7
647					/*
648					 * , label:"${name}"
649					 */
650					},
651					projection : new OpenLayers.Projection(
652							"EPSG:4326"),
653					strategies : [ new OpenLayers.Strategy.Fixed() ]
654				});
655		m.addLayer(layerGPX);
656		layerGPX.events.register(
657				'loadend', m, function() {
658					extent.extend(layerGPX.getDataExtent());
659					m.zoomToExtent(extent);
660				});
661
662	}
663
664	/* KML layer */
665	if (mapOpts.kmlfile.length > 0) {
666		var layerKML = new OpenLayers.Layer.Vector(
667				"KML file", {
668					protocol : new OpenLayers.Protocol.HTTP(
669							{
670								url : DocBase + "lib/exe/fetch.php?media=" + mapOpts.kmlfile,
671								format : new OpenLayers.Format.KML(
672										{
673											extractStyles : true,
674											extractAttributes : true,
675											maxDepth : 3
676										})
677							}),
678					style : {
679						label : "${name}"
680					},
681					projection : new OpenLayers.Projection(
682							"EPSG:4326"),
683					strategies : [ new OpenLayers.Strategy.Fixed() ]
684				});
685		m.addLayer(layerKML);
686		layerKML.events.register(
687				'loadend', m, function() {
688					extent.extend(layerKML.getDataExtent());
689					m.zoomToExtent(extent);
690				});
691	}
692
693	// selectcontrol for layers
694	if ((m.getLayersByClass('OpenLayers.Layer.GML').length > 0)
695			|| m.getLayersByClass('OpenLayers.Layer.Vector').length > 0) {
696		selectControl = new OpenLayers.Control.SelectFeature(
697				(m.getLayersByClass('OpenLayers.Layer.Vector')).concat(m
698						.getLayersByClass('OpenLayers.Layer.GML')), {
699					hover : mapOpts.poihoverstyle,
700					onSelect : onFeatureSelect,
701					onUnselect : onFeatureUnselect
702				});
703		m.addControl(selectControl);
704		selectControl.activate();
705	}
706	return m;
707}
708
709var olTimerId = -1;
710
711/** init. */
712function olInit() {
713	if (navigator.userAgent.indexOf('MSIE') != -1) {
714		//console.log("need to sleep");
715		if (olTimerId == -1) {
716			olTimerId = setTimeout(
717					"olInit()", 3000);
718			olEnable = false;
719		} else {
720			//console.log("done sleeping");
721			clearTimeout(olTimerId);
722			olEnable = true;
723		}
724	}
725
726	if (olEnable) {
727		var _i = 0;
728		// create the maps in the page
729		for (_i = 0; _i < olMapData.length; _i++) {
730			// console.log(olMapData);
731			createMap(
732					olMapData[_i].mapOpts, olMapData[_i].poi);
733		}
734
735		// hide the table(s) with POI by giving it a print-only style
736		// var tbls = getElementsByClass('olPOItableSpan', null, null);
737		var tbls = jQuery('.olPOItableSpan');
738		for (_i = 0; _i < tbls.length; _i++) {
739			tbls[_i].className += ' olPrintOnly';
740		}
741		// hide the static map image(s) by giving it a print only style
742		// var statImgs = getElementsByClass('olStaticMap', null, null);
743		var statImgs = jQuery('.olStaticMap');
744		for (_i = 0; _i < statImgs.length; _i++) {
745			statImgs[_i].className += ' olPrintOnly';
746		}
747	}
748}
749
750/**
751 * ol api flag.
752 *
753 * @type {Boolean}
754 */
755var olEnable = false,
756/**
757 * array with data for each map in the page.
758 *
759 * @type {Array}
760 */
761olMapData = new Array(),
762/**
763 * MapQuest tiles flag.
764 *
765 * @type {Boolean}
766 */
767mqEnable = false,
768/**
769 * google map api flag.
770 *
771 * @type {Boolean}
772 */
773gEnable = false,
774/**
775 * virtual earth map api flag.
776 *
777 * @type {Boolean}
778 */
779veEnable = false,
780/**
781 * Bing tiles flag.
782 *
783 * @type {Boolean}
784 */
785bEnable = false,
786/**
787 * Bing API key.
788 *
789 * @type {String}
790 */
791bApiKey = '',
792/**
793 * OSM tiles flag.
794 *
795 * @type {Boolean}
796 */
797osmEnable = true,
798/**
799 * CSS support flag.
800 *
801 * @type {Boolean}
802 */
803olCSSEnable = true;
804/**
805 * yahoo map api flag.
806 *
807 * @type {Boolean}
808 */
809// yEnable = false;
810/* register olInit to run with onload event. */
811// addInitEvent(olInit);
812jQuery(olInit);
813