function googleMapKml(mapa,kmls,tipoMenu) {
	
	//	gx1 = new GeoXml("gx1", map, "/cgi-bin/apsesp/municipios/recursos.php?plxslt=mapa/rectur2kml.xsl&kml=1", {sidebarid:"the_side_bar", allfoldersopen:false, iconFromDescription:false, domouseover:false, nozoom: true});	
	var gestorKml = this;
	gestorKml.gestorMapa = mapa;
	gestorKml.docKmls = {};
	gestorKml.contadorMarcadores = 0;
	var tipoMenu = tipoMenu || 'lista';
	gestorKml.gestorBarraLateral = {};
	
	//nuymero de kmls que vamos a cargar en el mapa
	var numKmls = kmls.length;
	
	//es posible que el gestor del kml comience a enviar marcadoes al gestor de mapas
	//antes de que el mapa esté completamente cargado
	//para comunicar los estados del mapa de google, cuando carga o se actualiza,
	//usamos eventos propios, que disparamos desde el gestor de mapas
	//en este caso, una vez que el gestor detecta la carga del mapa,
	//va a disparar un evento denominado 'mapaCargado'
	//que 'escucharemos' gracias al siguiente metodo, y procederemos a cargar los recursos
	
	jQuery(gestorKml.gestorMapa).bind('mapaCargado',inicializarKmls);
	
	//gestorKml.gestorMapa.mapaCargado2(inicializarKmls);
	
	function inicializarKmls()
	{
		jQuery(kmls).each(function(i)
		{
			var parametrosKml = this;
			var docKml = {};
			
			docKml.nombre = parametrosKml.nombre;
			docKml.id = parametrosKml.id;
			docKml.desplegado = parametrosKml.desplegado;
			docKml.visible = parametrosKml.visible || 1;
			
			docKml.estilos = {};
			docKml.carpetasGrupo = [];
			docKml.numCarpetasGrupo = 0;
			docKml.carpetas = [];
			docKml.numCarpetas = [];
			docKml.marcadores = [];
			docKml.marcadoresPorCategoria = {};
			docKml.marcadoresPorGrupo = {};
			

			docKml.groundOverlays = [];	
			
			docKml.urlKml = parametrosKml.url;
			
			docKml.gestorMapa = gestorKml.gestorMapa;
			

			docKml.idContenedor = '#'+'doscol_col_der';
			docKml.formatoBarra = parametrosKml.formatoBarra;

			
			gestorKml.docKmls[docKml.id] = docKml;
			
			cargarKml(docKml.urlKml,docKml.id);
		});
			
		gestorKml.gestorBarraLateral = new gestorBarraLateral(tipoMenu,gestorKml.docKmls);

	}
	
	//función que carga los datos del municipio mediante ajax, y una vez cargados
	//crea el mapa donde se muestra la situación del municipio
	function cargarKml(url,id)
	{
		jQuery.ajax({
			async:false,
			url: url,
			dataType: jQuery.browser.msie ? 'text' : 'xml',
			error: function(XMLHttpRequest, textStatus, errorThrown)
			{
				alert(XMLHttpRequest+textStatus+errorThrown)
			},
			success: function(data) 
			{
				var xml;
				if (jQuery.browser.msie) 
				{
					xml = new ActiveXObject("Microsoft.XMLDOM");
					xml.loadXML(data);
				} else 
				{
					xml = data;
				}
				
				procesaKml(xml,id);
			}
		});
	}
	

	function procesaKml(data,id)
	{
		var docKml = gestorKml.docKmls[id];
	
		//procesamos los estilos
		var idEstilo, nodoIcono, i;
		var nodosEstilo  = jQuery('Style',data);
		
		//para cada nodo <style>
		nodosEstilo.each(function()
		{
			var nodo = jQuery(this);
			
			//id del estilo
			idEstilo = nodo.attr('id');
			
			//ruta para la imagen del icono del estilo
			nodoIcono = jQuery('Icon',nodo);
			hrefIcono = jQuery('href',nodoIcono);
			hrefIcono = hrefIcono.text();
			
			//si hay iconos en el estilo (la doble negación de una cadena no vacía devuelve true)
			if (!!nodoIcono.length) 
			{
			  //almacenamos la ruta de la imagen en el array asociativo correspondiente para cada estilo
			  docKml.estilos['#' + idEstilo] = 
			  {
				href: hrefIcono
			  };
			}
			
		 })//nodosEstilo.each
		 
		 //metodo privado para procesar los estilos  
		 function procesarEstilos() 
		 {

			for (var idEstilo in docKml.estilos) 
			{
				
			  if (!!docKml.estilos[idEstilo].href) 
			  {
				//creamos los marcadores como atributos icono del array de estilos
				docKml.estilos[idEstilo].icon =  new google.maps.MarkerImage(
				  docKml.estilos[idEstilo].href,
				  new google.maps.Size(32, 37),
				  new google.maps.Point(0, 0),
				  new google.maps.Point(16, 12)
				);

			  }//if
			  
			}//for

	  	 }//procesarEstilos
		 
		 // Convertir estilos en instancias de marcadores de GMaps
		 procesarEstilos();

 
		 //metodo privado que procesa un nodo tipo Folder del XML; 
		 //importante tener en cuenta que es XML, no HTML, puesto que en XMl, jQuery no admite el metodo .html()
		 function procesarCarpeta(carpeta,tipo)
		 {
			 //recordemos que carpeta es el nodo 'Folder' del XML
			 var carpeta = carpeta;
			 var tipo = tipo;
			 
			 //importante usar el metodo first para seleccionar el nodo de la propia carpeta, puesto que
			 //las subcarpetas, tambien tienen los mismos nodos, y el metodo text() selecciona el texto de todos ellos
			 var id = carpeta.attr('id');
			 var nombre = jQuery('name',carpeta).first().text();
			 var visible = jQuery('visibility',carpeta).first().text();
			 var abierto = jQuery('open',carpeta).first().text();
			 var descripcion = jQuery('description',carpeta).first().text();
			 var categorias = [];
			 var marcadores = [];
			 
		     //creamos el objeto con los parametros de la carpeta
			 var objetoCarpeta = {
				 id:id,
				 nombre:nombre,
				 visible:visible,
				 abierto:abierto,
				 descripcion:descripcion,
				 tipo:tipo,
				 categorias:categorias,
				 marcadores:marcadores,
				 ocultarCarpeta:function ocultarCarpeta()
				 {
					 this.visible = 0;
					 return 0;
				 },
				 mostrarCarpeta:function mostrarCarpeta()
				 {
					 this.visible = 1;
					 return 1;
				 }
		
				 
			 }
			 
			 return objetoCarpeta;			 
			 
		 }//procesar carpeta
		 
		 
		 //metodo privado para procesar los marcadores que pertenezcan al nodo carpeta que se pasa como parámetro
		 function procesarMarcadores(nodoMarcador) 
		 {	 
			 var nodosPlacemark = jQuery('Placemark',nodoMarcador);
			 var conjuntoMarcadores = [];
			 
			 //para eliminar el marcador inicial que muestra el centro del mapa al inicializarlo
			 if (!!nodosPlacemark.length)
			 {
				gestorKml.gestorMapa.borrarMarcadores('centroMapa');
			 }
		 
		 	 //para cada marcador, ejecutamos el bucle que establece sus propiedades y lo crea en el mapa
			 nodosPlacemark.each(function()
			 {
				var nodoMarcador = jQuery(this);
				

				var id = gestorKml.contadorMarcadores;
								
				var nombre = jQuery('name',nodoMarcador).text();
				var descripcionXml = jQuery('description',nodoMarcador);
				var descripcion = nodoHtmlToTexto(descripcionXml.children());
				
				
				//estilo del marcador
				var estilo = jQuery('styleUrl',nodoMarcador).text();
				estilo = docKml.estilos[estilo] || {};
				
				var enlace = jQuery('link',nodoMarcador).text();
				
				var coordenadas = jQuery('coordinates',nodoMarcador).text();
				
				//posicion del marcador en formato objeto LatLng de google.maps
				coordenadas = coordenadas.split(',');
				
				coordenadas = 
				{
					lat: parseFloat(coordenadas[1]),
					lng: parseFloat(coordenadas[0]),
					alt: parseFloat(coordenadas[2])
				};
				
				coordenadas = new google.maps.LatLng(coordenadas.lat,coordenadas.lng);
				
			
				var datosMarcador = {
				  id:id,
				  nombre:nombre,
				  descripcion:descripcion,
				  estilo:estilo,
				  enlace:enlace,
				  coordenadas:coordenadas
				};
							
	
				//introducimos el marcador en el array de marcadores de esta categoria
				conjuntoMarcadores.push(datosMarcador);
				//renderizamos el marcador en el mapa
				gestorKml.gestorMapa.crearMarcadores(datosMarcador);
				//aumentamos el contador de marcadores
				gestorKml.contadorMarcadores++;
			
			});//nodosPlacemark.each
			 
			//devolvemos como valor de la función, el array de marcadores
			return conjuntoMarcadores;
				
			////////////////////////////////////////////funciones auxiliares////////////////////////////////////////////
				
			//metodo privado para convertir todo el contenido de un nodo XML que contiene HTML 
			//en una cadena de texto, etiquetas HTML incluidas
			function nodoHtmlToTexto(datos)
			{
				var cadena = "";
					
				datos.each(function()
				{			
				  var dato = jQuery(this).get(0);
					
				  //for IE 
				  if (window.ActiveXObject) 
				  {
					cadena += dato.xml;
				  }
				  // code for Mozilla, Firefox, Opera, etc.
				  else 
				  {
					cadena += (new XMLSerializer()).serializeToString(dato);
				  }
				});
				 
				return cadena;
				
			}//nodoHtmlToTexto
	
		 }//procesarMarcadores
		 
		 
		 //procesamos las carpetas de grupos de categorías, si existen
		 var nodoDocumento = jQuery('Document',data);
		 var nodosGruposCategorias = jQuery('Document > Folder',data);
		 var nodosCategorias = jQuery('Folder',nodosGruposCategorias);
		 
		 //si solo hay un nivel de categorias, tomaremos el nodo documento como grupo de categorias
		 if(nodosCategorias.length > 0)
		 {
			 //al array de carpetas de grupos le añadimos un atributo con el número total de carpetas
			 //puesto que al ser un array asociativo, no tiene propiedad length para saber su longitud
			 docKml.numCarpetasGrupo = nodosGruposCategorias.length;
		 }
		 else 
		 {
			 nodosGruposCategorias = nodoDocumento;
			 nodosCategorias = jQuery('Folder',nodoDocumento);
		 }
		 
		 //procesamos las carpetas, subcarpetas y marcadores
		 nodosGruposCategorias.each(function(numGrup)
		 {
			var nodoGrupo = jQuery(this);
			var grupoCategoria = procesarCarpeta(nodoGrupo,'grupocategoria');
			docKml.carpetasGrupo[grupoCategoria.id] =  grupoCategoria;
			
			docKml.marcadoresPorGrupo[grupoCategoria.id] = [];
			
			//procesamos las carpetas de categorías pertenecientes a este grupo de categorias, si existen
			var nodosCategorias = jQuery('Folder',nodoGrupo);
			
			nodosCategorias.each(function(numCat)
			{
				var nodoCategoria = jQuery(this);
				var categoria = procesarCarpeta(nodoCategoria,'categoria');
				docKml.carpetas[categoria.id] = categoria;
				docKml.carpetasGrupo[grupoCategoria.id].categorias.push(categoria.id);
						
				//procesamos los marcadores, pasando como parametro el nodo de la categoria
				//así como el id de la categoria
				var marcadores = procesarMarcadores(nodoCategoria,categoria.id);
				
				docKml.marcadoresPorCategoria[categoria.id] = [];
				
				for (idMarcador in marcadores)
				{
					docKml.marcadores.push(marcadores[idMarcador].id);
					docKml.marcadoresPorCategoria[categoria.id].push(marcadores[idMarcador].id);
					docKml.marcadoresPorGrupo[grupoCategoria.id].push(marcadores[idMarcador].id);
					docKml.carpetas[categoria.id].marcadores.push(marcadores[idMarcador].id);
					docKml.carpetasGrupo[grupoCategoria.id].marcadores.push(marcadores[idMarcador].id);
				}
						
				//si hay dos niveles de grupos y categorias		
				//cuando llegemos al último elemento de carpeta procesado añadimos el número de carpetas
				//de este grupo al total de carpetas
				if (numCat == (nodosCategorias.length - 1))
				{
					docKml.numCarpetas[grupoCategoria.id] = numCat + 1;
				}
						
		 	});//nodoscategorias.each	
				 
		 });//nodosGruposCategorias.each

				
  }//procesaKml
  
}
