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