xref: /plugin/openlayersmap/script.js (revision 97b4ffbb0888fe139b65645de3305d46db8a9532)
1/*
2 * Copyright (c) 2008-2013 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 <mprins@users.sf.net>
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 *            feature 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.warn("unable to get event position; reverting to boundingbox center.");
50			pPos = selectedFeature.geometry.getBounds().getCenterLonLat();
51		}
52	}
53
54	var pContent = '<div class="spacer">&nbsp;</div>';
55	if (feature.data.rowId !== undefined) {
56		pContent += '<span class="rowId">' + feature.data.rowId + ': </span>';
57	}
58	if (feature.data.name !== undefined) {
59		pContent += '<span class="txt">' + feature.data.name + '</span>';
60	}
61	if (feature.data.ele !== undefined) {
62		pContent += '<div class="ele">elevation: ' + feature.data.ele + '</div>';
63	}
64	if (feature.data.type !== undefined) {
65		pContent += '<div>' + feature.data.type + '</div>';
66	}
67	if (feature.data.time !== undefined) {
68		pContent += '<div class="time">time: ' + feature.data.time + '</div>';
69	}
70	if (feature.data.description !== undefined) {
71		pContent += '<div class="desc">' + feature.data.description + '</div>';
72	}
73
74	if (pContent.length > 0) {
75		// only show when there is something to show...
76		var popup = new OpenLayers.Popup.FramedCloud("olPopup", pPos, null, pContent, null, true, function() {
77			selectControl.unselect(selectedFeature);
78		});
79		feature.popup = popup;
80		feature.layer.map.addPopup(popup);
81	}
82}
83
84/**
85 * handle feature unselect event. remove & destroy the popup.
86 *
87 * @param {OpenLayers.Feature.Vector}
88 *            feature the un-selected feature
89 */
90function onFeatureUnselect(feature) {
91	if (feature.popup !== null) {
92		feature.layer.map.removePopup(feature.popup);
93		feature.popup.destroy();
94		feature.popup = null;
95	}
96}
97/**
98 * Test for css support in the browser by sniffing for a css class we added
99 * using javascript added by the action plugin; this is an edge case because
100 * browsers that support javascript generally support css as well.
101 *
102 * @returns {Boolean} true when the browser supports css (and implicitly
103 *          javascript)
104 */
105function olTestCSSsupport() {
106	return (jQuery('.olCSSsupported').length > 0);
107}
108
109/**
110 * Creates a DocumentFragment to insert into the dom.
111 *
112 * @param mapid
113 *            id for the map div
114 * @param width
115 *            width for the map div
116 * @param height
117 *            height for the map div
118 * @returns a {DocumentFragment} element that can be injected into the dom
119 */
120function olCreateMaptag(mapid, width, height) {
121	// TODO: use OpenLayers.i18n()
122	var mEl = '<div id="' + mapid + '-olContainer" class="olContainer olWebOnly">' + '<div id="' + mapid
123			+ '-olToolbar" class="olToolbar"></div>' + '<div class="clearer"></div>' + '<div id="' + mapid
124			+ '" tabindex="0" style="width:' + width + ';height:' + height + ';" class="olMap">'
125			+ '<a class="olAccesskey" href="" accesskey="1" onclick="document.getElementById(&quot;' + mapid
126			+ '&quot;).focus(); return false;" title="Activate map">Activate map</a>' + '</div>' + '<div id="' + mapid
127			+ '-olStatusBar" style="width:' + width + ';"class="olStatusBarContainer">' + '<div id="' + mapid
128			+ '-statusbar-scale" class="olStatusBar olStatusBarScale">scale</div>'
129			//+ '<div id="' + mapid	+ '-statusbar-link" class="olStatusBar olStatusBarPermalink">'
130			//+ '<a href="" id="' + mapid + '-statusbar-link-ref">link</a></div>'
131			+ '<div id="' + mapid + '-statusbar-mouseposition" class="olStatusBar olStatusBarMouseposition"></div>' + '<div id="' + mapid
132			+ '-statusbar-projection" class="olStatusBar olStatusBarProjection">proj</div>' + '<div id="' + mapid
133			+ '-statusbar-text" class="olStatusBar olStatusBarText">txt</div>' + '</div></div>',
134	// fragment
135	frag = document.createDocumentFragment(),
136	// temp node
137	temp = document.createElement('div');
138	temp.innerHTML = mEl;
139	while (temp.firstChild) {
140		frag.appendChild(temp.firstChild);
141	}
142	return frag;
143}
144
145/**
146 * Create the map based on the params given.
147 *
148 * @param {Object}
149 *            mapOpts MapOptions hash {id:'olmap', width:500px, height:500px,
150 *            lat:6710200, lon:506500, zoom:13, toolbar:1, statusbar:1,
151 *            controls:1, poihoverstyle:1, baselyr:'', kmlfile:'', gpxfile:'',
152 *            geojsonfile, summary:''}
153 * @param {Array}
154 *            OLmapPOI array with POI's [ {lat:6710300,lon:506000,txt:'instap
155 *            punt',angle:180,opacity:.9,img:'', rowId:n},... ]);
156 *
157 * @return {OpenLayers.Map} the created map
158 */
159function createMap(mapOpts, OLmapPOI) {
160	if (!olEnable) {
161		return;
162	}
163	if (!olTestCSSsupport()) {
164		olEnable = false;
165		return;
166	}
167
168	var DocBase = DOKU_BASE;
169
170	OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;
171	// OpenLayers.Layer.Vector.prototype.renderers = ["SVG", "VML"];
172
173	// find map element location
174	var cleartag = document.getElementById(mapOpts.id + '-clearer');
175	if (cleartag === null) {
176		return;
177	}
178	// create map element and add to document
179	var fragment = olCreateMaptag(mapOpts.id, mapOpts.width, mapOpts.height);
180	cleartag.parentNode.insertBefore(fragment, cleartag);
181
182	/** dynamic map extent. */
183	var extent = new OpenLayers.Bounds(),
184
185	/** map. */
186	m = new OpenLayers.Map({
187		div : mapOpts.id,
188		projection : 'EPSG:900913',
189		displayProjection : new OpenLayers.Projection("EPSG:4326"),
190		numZoomLevels : 22,
191		controls : [ new OpenLayers.Control.KeyboardDefaults({
192			observeElement : mapOpts.id
193		}), new OpenLayers.Control.Navigation(), new OpenLayers.Control.ScaleLine({
194			geodesic : true
195		}), /* new OpenLayers.Control.ArgParser() */],
196		theme : null
197	});
198
199	if (osmEnable) {
200		/* add OSM map layers */
201		m.addLayer(new OpenLayers.Layer.OSM("OpenStreetMap", null, {
202			transitionEffect : "resize",
203			visibility : mapOpts.baselyr === "OpenStreetMap"
204		}));
205
206		m.addLayer(new OpenLayers.Layer.OSM("transport", [
207				"http://a.tile2.opencyclemap.org/transport/${z}/${x}/${y}.png",
208				"http://b.tile2.opencyclemap.org/transport/${z}/${x}/${y}.png",
209				"http://c.tile2.opencyclemap.org/transport/${z}/${x}/${y}.png" ], {
210			transitionEffect : "resize",
211			attribution : 'Data CC-By-SA <a href="http://openstreetmap.org/" target="_blank">OpenStreetMap</a>, '
212					+ 'Tiles <a href="http://opencyclemap.org/" target="_blank">OpenCycleMap</a>'
213					+ '<img src="http://opencyclemap.org/favicon.ico" alt="OpenCycleMap logo"/>',
214			visibility : mapOpts.baselyr === "transport",
215			tileOptions : {
216				crossOriginKeyword : null
217			}
218		}));
219		m.addLayer(new OpenLayers.Layer.OSM("landscape", [
220				"http://a.tile3.opencyclemap.org/landscape/${z}/${x}/${y}.png",
221				"http://b.tile3.opencyclemap.org/landscape/${z}/${x}/${y}.png",
222				"http://c.tile3.opencyclemap.org/landscape/${z}/${x}/${y}.png" ], {
223			transitionEffect : "resize",
224			attribution : 'Data CC-By-SA <a href="http://openstreetmap.org/" target="_blank">OpenStreetMap</a>, '
225					+ 'Tiles <a href="http://opencyclemap.org/" target="_blank">OpenCycleMap</a>'
226					+ '<img src="http://opencyclemap.org/favicon.ico" alt="OpenCycleMap logo"/>',
227			visibility : mapOpts.baselyr === "transport",
228			tileOptions : {
229				crossOriginKeyword : null
230			}
231		}));
232		m.addLayer(new OpenLayers.Layer.OSM("cycle map", [ "http://a.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png",
233				"http://b.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png",
234				"http://c.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png" ], {
235			transitionEffect : "resize",
236			attribution : 'Data CC-By-SA <a href="http://openstreetmap.org/" target="_blank">OpenStreetMap</a>, '
237					+ 'Tiles <a href="http://opencyclemap.org/" target="_blank">OpenCycleMap</a>'
238					+ '<img src="http://opencyclemap.org/favicon.ico" alt="OpenCycleMap logo"/>',
239			visibility : mapOpts.baselyr === "cycle map",
240			tileOptions : {
241				crossOriginKeyword : null
242			}
243		}));
244		// CloudMade Fine Line
245		m.addLayer(new OpenLayers.Layer.OSM("cloudmade map", [
246				"http://a.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/2/256/${z}/${x}/${y}.png",
247				"http://b.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/2/256/${z}/${x}/${y}.png",
248				"http://c.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/2/256/${z}/${x}/${y}.png" ], {
249			transitionEffect : "resize",
250			attribution : 'Tiles &copy; 2012 <a target="_blank" href="http://cloudmade.com">CloudMade</a>'
251					+ '<img src="http://cloudmade.com/sites/default/files/favicon.ico" alt="CloudMade logo"/>'
252					+ ' Data CC-BY-SA <a href="http://openstreetmap.org/" target="_blank">OpenStreetMap</a>',
253			visibility : mapOpts.baselyr === "cloudmade map",
254			tileOptions : {
255				crossOriginKeyword : null
256			}
257		}));
258		m.addLayer(new OpenLayers.Layer.OSM("cloudmade fresh", [
259				"http://a.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/${z}/${x}/${y}.png",
260				"http://b.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/${z}/${x}/${y}.png",
261				"http://c.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/${z}/${x}/${y}.png" ], {
262			transitionEffect : "resize",
263			attribution : 'Tiles &copy; 2012 <a target="_blank" href="http://cloudmade.com">CloudMade</a>'
264					+ '<img src="http://cloudmade.com/sites/default/files/favicon.ico" alt="CloudMade logo"/>'
265					+ ' Data CC-BY-SA <a href="http://openstreetmap.org/" target="_blank">OpenStreetMap</a>',
266			visibility : mapOpts.baselyr === "cloudmade fresh",
267			tileOptions : {
268				crossOriginKeyword : null
269			}
270		}));
271
272		m.addLayer(new OpenLayers.Layer.OSM(
273				"hike and bike map", "http://toolserver.org/tiles/hikebike/${z}/${x}/${y}.png", {
274					transitionEffect : "resize",
275					visibility : mapOpts.baselyr === "hike and bike map",
276					tileOptions : {
277						crossOriginKeyword : null
278					}
279				}));
280	}
281	/*
282	 * add MapQuest map layers, see:
283	 * http://developer.mapquest.com/web/products/open/map
284	 */
285	if (mqEnable) {
286		m.addLayer(new OpenLayersMap.Layer.MapQuest());
287		m.addLayer(new OpenLayersMap.Layer.MapQuest("mapquest sat", [
288				"http://otile1.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.jpg",
289				"http://otile2.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.jpg",
290				"http://otile3.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.jpg",
291				"http://otile4.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.jpg" ], {
292			// note that global coverage is provided at zoom levels 0-11. Zoom
293			// Levels 12+ are provided only in the United States (lower 48).
294			numZoomLevels : 12,
295			tileOptions : {
296				crossOriginKeyword : null
297			}
298		}));
299	}
300
301	if (gEnable) {
302		/* load google maps */
303		try {
304			m.addLayer(new OpenLayers.Layer.Google("google relief", {
305				type : google.maps.MapTypeId.TERRAIN,
306				// transitionEffect : "resize",
307				numZoomLevels : 16,
308				animationEnabled : true,
309				visibility : mapOpts.baselyr === "google relief"
310			}));
311			m.addLayer(new OpenLayers.Layer.Google("google sat", {
312				type : google.maps.MapTypeId.SATELLITE,
313				// transitionEffect : "resize",
314				// numZoomLevels : 22,
315				animationEnabled : true,
316				visibility : mapOpts.baselyr === "google sat"
317			}));
318			m.addLayer(new OpenLayers.Layer.Google("google hybrid", {
319				type : google.maps.MapTypeId.HYBRID,
320				// transitionEffect : "resize",
321				// numZoomLevels : 20,
322				animationEnabled : true,
323				visibility : mapOpts.baselyr === "google hybrid"
324			}));
325			m.addLayer(new OpenLayers.Layer.Google("google road", {
326				// transitionEffect : "resize",
327				// numZoomLevels : 20,
328				animationEnabled : true,
329				visibility : mapOpts.baselyr === "google road"
330			}));
331		} catch (ol_err1) {
332			Openlayers.Console.userError('Error loading Google maps' + ol_err1);
333		}
334	}
335
336	if (bEnable && bApiKey !== '') {
337		try {
338			/* add Bing tiles */
339			m.addLayer(new OpenLayers.Layer.Bing({
340				key : bApiKey,
341				type : "Road",
342				name : "bing road",
343				transitionEffect : "resize",
344				visibility : mapOpts.baselyr === "bing road",
345				wrapDateLine : true,
346				attributionTemplate : '<a target="_blank" href="http://www.bing.com/maps/">'
347						+ 'Bing™</a><img src="http://www.bing.com/favicon.ico" alt="Bing logo"/> ${copyrights}'
348						+ '<a target="_blank" href="http://www.microsoft.com/maps/product/terms.html">Terms of Use</a>'
349			}));
350			m.addLayer(new OpenLayers.Layer.Bing({
351				key : bApiKey,
352				type : "Aerial",
353				name : "bing sat",
354				transitionEffect : "resize",
355				visibility : mapOpts.baselyr === "bing sat",
356				wrapDateLine : true,
357				attributionTemplate : '<a target="_blank" href="http://www.bing.com/maps/">'
358						+ 'Bing™</a><img src="http://www.bing.com/favicon.ico" alt="Bing logo"/> ${copyrights}'
359						+ '<a target="_blank" href="http://www.microsoft.com/maps/product/terms.html">Terms of Use</a>'
360			}));
361			m.addLayer(new OpenLayers.Layer.Bing({
362				key : bApiKey,
363				type : "AerialWithLabels",
364				name : "bing hybrid",
365				transitionEffect : "resize",
366				visibility : mapOpts.baselyr === "bing hybrid",
367				wrapDateLine : true,
368				attributionTemplate : '<a target="_blank" href="http://www.bing.com/maps/">'
369						+ 'Bing™</a><img src="http://www.bing.com/favicon.ico" alt="Bing logo"/> ${copyrights}'
370						+ '<a target="_blank" href="http://www.microsoft.com/maps/product/terms.html">Terms of Use</a>'
371			}));
372		} catch (ol_errBing) {
373			Openlayers.Console.userError('Error loading Bing maps: ' + ol_errBing);
374		}
375	}
376
377	m.setCenter(new OpenLayers.LonLat(mapOpts.lon, mapOpts.lat).transform(m.displayProjection, m.projection),
378			mapOpts.zoom);
379	extent.extend(m.getExtent());
380
381	// change/set alternative baselyr
382	try {
383		m.setBaseLayer(((m.getLayersByName(mapOpts.baselyr))[0]));
384	} catch (ol_err4) {
385		m.setBaseLayer(m.layers[0]);
386	}
387
388	if (mapOpts.controls === 1) {
389		/* add base controls to map */
390		m.addControl(new OpenLayers.Control.LayerSwitcher());
391		m.addControl(new OpenLayers.Control.PanZoomBar());
392		m.addControl(new OpenLayers.Control.Graticule({
393			visible : false
394		}));
395		m.addControl(new OpenLayers.Control.OverviewMap({
396			size : new OpenLayers.Size(140, 140),
397			minRectSize : 10
398		}));
399		// m.addControl(OpenLayersMap.Control.OverviewMap());
400
401		// add hillshade, since this is off by default only add when we have a
402		// layerswitcher
403		m.addLayer(new OpenLayers.Layer.OSM("Hillshade", "http://toolserver.org/~cmarqu/hill/${z}/${x}/${y}.png", {
404			transitionEffect : "resize",
405			isBaseLayer : false, // false
406			transparent : true, // true
407			visibility : false,
408			displayOutsideMaxExtent : true,
409			attribution : '',
410			tileOptions : {
411				crossOriginKeyword : null
412			}
413		}));
414	}
415
416	if (mapOpts.statusbar === 1) {
417		// statusbar control: permalink
418		// m.addControl(new OpenLayers.Control.Permalink(mapOpts.id + '-statusbar-link-ref'));
419
420		// statusbar control: mouse pos.
421		m.addControl(new OpenLayers.Control.MousePosition({
422			'div' : OpenLayers.Util.getElement(mapOpts.id + '-statusbar-mouseposition')
423		}));
424		// statusbar control: scale
425		m.addControl(new OpenLayers.Control.Scale(mapOpts.id + '-statusbar-scale'));
426		// statusbar control: attribution
427		m.addControl(new OpenLayers.Control.Attribution({
428			'div' : OpenLayers.Util.getElement(mapOpts.id + '-statusbar-text')
429		}));
430		// statusbar control: projection
431		OpenLayers.Util.getElement(mapOpts.id + '-statusbar-projection').innerHTML = m.displayProjection;
432	} else {
433		OpenLayers.Util.getElement(mapOpts.id + '-olStatusBar').display = 'none';
434	}
435
436	if (mapOpts.toolbar === 1) {
437		// add buttons + panel
438		var /* zoom in btn */
439		zoomin = new OpenLayers.Control.ZoomBox({
440			title : "Zoom in"
441		}), /* zoom out btn */
442		zoomout = new OpenLayers.Control.ZoomBox({
443			out : true,
444			title : "Zoom uit",
445			displayClass : "olControlZoomOut"
446		}), /* pan btn */
447		pan = new OpenLayers.Control.DragPan({
448			title : "Verschuif"
449		}), /* do "nothing" button... */
450		info = new OpenLayers.Control.Button({
451			type : OpenLayers.Control.TYPE_TOOL,
452			displayClass : "olControlFeatureInfo",
453			title : "Info"
454		}), /* navigation history btns */
455		nav = new OpenLayers.Control.NavigationHistory();
456		m.addControl(nav);
457		var panel = new OpenLayers.Control.Panel({
458			defaultControl : pan,
459			displayClass : "olToolbar",
460			"div" : OpenLayers.Util.getElement(mapOpts.id + "-olToolbar")
461		});
462		panel.addControls([ zoomin, zoomout, pan, info, nav.next, nav.previous ]);
463		m.addControl(panel);
464	} else {
465		OpenLayers.Util.getElement(mapOpts.id + '-olToolbar').display = 'none';
466	}
467
468	if (OLmapPOI.length > 0) {
469		var markers = new OpenLayers.Layer.Vector("POI", {
470			styleMap : new OpenLayers.StyleMap({
471				"default" : {
472					externalGraphic : "${img}",
473					graphicHeight : 16,
474					graphicWidth : 16,
475					graphicXOffset : 0,
476					graphicYOffset : -8,
477					graphicOpacity : "${opacity}",
478					rotation : "${angle}",
479					backgroundGraphic : DocBase + "lib/plugins/openlayersmap/icons/marker_shadow.png",
480					backgroundXOffset : 0,
481					backgroundYOffset : -4,
482					backgroundRotation : "${angle}",
483					pointRadius : 10,
484					labelXOffset : 8,
485					labelYOffset : 8,
486					labelAlign : "lb",
487					label : "${label}",
488					// fontColor : "",
489					fontFamily : "monospace",
490					fontSize : "12px",
491					fontWeight : "bold"
492				},
493				"select" : {
494					cursor : "crosshair",
495					externalGraphic : DocBase + "lib/plugins/openlayersmap/icons/marker-red.png",
496					graphicHeight : 16,
497					graphicWidth : 16,
498					graphicXOffset : 0,
499					graphicYOffset : -8,
500					graphicOpacity : 1.0,
501					rotation : "${angle}"
502				}
503			}),
504			isBaseLayer : false,
505			rendererOptions : {
506				yOrdering : true
507			}
508		});
509		m.addLayer(markers);
510		var features = [];
511		for ( var j = 0; j < OLmapPOI.length; j++) {
512			var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(OLmapPOI[j].lon, OLmapPOI[j].lat)
513					.transform(m.displayProjection, m.projection), {
514				angle : OLmapPOI[j].angle,
515				opacity : OLmapPOI[j].opacity,
516				img : DocBase + "lib/plugins/openlayersmap/icons/" + OLmapPOI[j].img,
517				label : OLmapPOI[j].rowId
518			});
519			feat.data = {
520				name : OLmapPOI[j].txt,
521				rowId : OLmapPOI[j].rowId
522			};
523			features.push(feat);
524		}
525		markers.addFeatures(features);
526		extent.extend(markers.getDataExtent());
527		m.zoomToExtent(extent);
528	}
529
530	/* GPX layer */
531	if (mapOpts.gpxfile.length > 0) {
532		var layerGPX = new OpenLayers.Layer.Vector("GPS route", {
533			protocol : new OpenLayers.Protocol.HTTP({
534				url : DocBase + "lib/exe/fetch.php?media=" + mapOpts.gpxfile,
535				format : new OpenLayers.Format.GPX({
536					extractWaypoints : true,
537					extractTracks : true,
538					extractStyles : true,
539					extractAttributes : true,
540					handleHeight : true,
541					maxDepth : 3
542				})
543			}),
544			style : {
545				strokeColor : "#0000FF",
546				strokeWidth : 3,
547				strokeOpacity : 0.7,
548				pointRadius : 4,
549				fillColor : "#0099FF",
550				fillOpacity : 0.7
551			// , label:"${name}"
552			},
553			projection : new OpenLayers.Projection("EPSG:4326"),
554			strategies : [ new OpenLayers.Strategy.Fixed() ]
555		});
556		m.addLayer(layerGPX);
557		layerGPX.events.register('loadend', m, function() {
558			extent.extend(layerGPX.getDataExtent());
559			m.zoomToExtent(extent);
560		});
561	}
562
563	/* GeoJSON layer */
564	if (mapOpts.geojsonfile.length > 0) {
565		var layerGJS = new OpenLayers.Layer.Vector("json data", {
566			protocol : new OpenLayers.Protocol.HTTP({
567				url : DocBase + "lib/exe/fetch.php?media=" + mapOpts.geojsonfile,
568				format : new OpenLayers.Format.GeoJSON({
569					ignoreExtraDims : true
570				})
571			}),
572			style : {
573				strokeColor : "#FF00FF",
574				strokeWidth : 3,
575				strokeOpacity : 0.7,
576				pointRadius : 4,
577				fillColor : "#FF99FF",
578				fillOpacity : 0.7
579			// , label:"${name}"
580			},
581			projection : new OpenLayers.Projection("EPSG:4326"),
582			strategies : [ new OpenLayers.Strategy.Fixed() ]
583		});
584		m.addLayer(layerGJS);
585		layerGJS.events.register('loadend', m, function() {
586			extent.extend(layerGJS.getDataExtent());
587			m.zoomToExtent(extent);
588		});
589	}
590
591	/* KML layer */
592	if (mapOpts.kmlfile.length > 0) {
593		var layerKML = new OpenLayers.Layer.Vector("KML file", {
594			protocol : new OpenLayers.Protocol.HTTP({
595				url : DocBase + "lib/exe/fetch.php?media=" + mapOpts.kmlfile,
596				format : new OpenLayers.Format.KML({
597					extractStyles : true,
598					extractAttributes : true,
599					maxDepth : 3
600				})
601			}),
602			style : {
603				label : "${name}"
604			},
605			projection : new OpenLayers.Projection("EPSG:4326"),
606			strategies : [ new OpenLayers.Strategy.Fixed() ]
607		});
608		m.addLayer(layerKML);
609		layerKML.events.register('loadend', m, function() {
610			extent.extend(layerKML.getDataExtent());
611			m.zoomToExtent(extent);
612		});
613	}
614
615	// selectcontrol for layers
616	if ((m.getLayersByClass('OpenLayers.Layer.GML').length > 0)
617			|| m.getLayersByClass('OpenLayers.Layer.Vector').length > 0) {
618		selectControl = new OpenLayers.Control.SelectFeature((m.getLayersByClass('OpenLayers.Layer.Vector')).concat(m
619				.getLayersByClass('OpenLayers.Layer.GML')), {
620			hover : mapOpts.poihoverstyle,
621			onSelect : onFeatureSelect,
622			onUnselect : onFeatureUnselect
623		});
624		m.addControl(selectControl);
625		selectControl.activate();
626	}
627	return m;
628}
629
630var olTimerId = -1;
631
632/** init. */
633function olInit() {
634	// TODO: check is this is still needed now that we have jQuery
635	if (navigator.userAgent.indexOf('MSIE') !== -1) {
636		if (olTimerId === -1) {
637			olTimerId = setTimeout("olInit()", 3000);
638			olEnable = false;
639		} else {
640			clearTimeout(olTimerId);
641			olEnable = true;
642		}
643	}
644
645	if (olEnable) {
646		var _i = 0;
647		// create the maps in the page
648		for (_i = 0; _i < olMapData.length; _i++) {
649			olMaps[olMapData[_i].mapOpts.id] = createMap(olMapData[_i].mapOpts, olMapData[_i].poi);
650		}
651		// hide the table(s) with POI by giving it a print-only style
652		var tbls = jQuery('.olPOItableSpan');
653		for (_i = 0; _i < tbls.length; _i++) {
654			tbls[_i].className += ' olPrintOnly';
655		}
656		// hide the static map image(s) by giving it a print only style
657		var statImgs = jQuery('.olStaticMap');
658		for (_i = 0; _i < statImgs.length; _i++) {
659			statImgs[_i].className += ' olPrintOnly';
660		}
661	}
662}
663
664/**
665 * ol api flag.
666 *
667 * @type {Boolean}
668 */
669var olEnable = false,
670/**
671 * An array with data for each map in the page.
672 *
673 * @type {Array}
674 */
675olMapData = [],
676/**
677 * Holds a reference to all of the maps on this page with the map's id as key.
678 * Can be used as an extension point.
679 *
680 * @type {Object}
681 */
682olMaps = new Object(),
683/**
684 * MapQuest tiles flag.
685 *
686 * @type {Boolean}
687 */
688mqEnable = false,
689/**
690 * google map api flag.
691 *
692 * @type {Boolean}
693 */
694gEnable = false,
695/**
696 * Bing tiles flag.
697 *
698 * @type {Boolean}
699 */
700bEnable = false,
701/**
702 * Bing API key.
703 *
704 * @type {String}
705 */
706bApiKey = '',
707/**
708 * OSM tiles flag.
709 *
710 * @type {Boolean}
711 */
712osmEnable = true,
713/**
714 * CSS support flag.
715 *
716 * @type {Boolean}
717 */
718olCSSEnable = true;
719/**
720 * yahoo map api flag.
721 *
722 * @type {Boolean}
723 */
724// yEnable = false;
725/* register olInit to run with onload event. */
726jQuery(olInit);
727