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