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