//--------------------------------------------------------------------------
// utilsGMaps.js
//--------------------------------------------------------------------------
// Javascript amb funcions utils per GMaps
//--------------------------------------------------------------------------

//<![CDATA[

	// Creem un objecte UTILS_GMAPS i ho definim tot a dins per no omplir
	// el namespace global amb moltes definicions i funcions. Així mantenim
	// el function closure i només posem UTILS_GMAPS al namespace global.
	UTILS_GMAPS = {};
	
	// Definim les icones que utilitzarem
	// ICONA XXX01 --> Verd (fluid)
	// ICONA XXX02 --> Taronja (dens)
	// ICONA XXX03 --> Vermell (congestió)
	// ICONA XXX04 --> Negre (tallat/interromput)
	// ICONA XXX05 --> Blau (estat genéric/sense dades/sense info)
	UTILS_GMAPS.ICONA_OBRES = "./img/obres05.gif";
	UTILS_GMAPS.ICONA_TRANSIT = "./img/trafic05.gif";
	UTILS_GMAPS.ICONA_ACCIDENT = "./img/accident05.gif";
	UTILS_GMAPS.ICONA_CAMARA = "./img/camara05.gif";
	UTILS_GMAPS.ICONA_PANELL = "./img/panell05.gif";
	UTILS_GMAPS.ICONA_METEO = "./img/temps05.gif";
	UTILS_GMAPS.ICONA_INCIDENCIES = "./img/incident05.gif";
	UTILS_GMAPS.ICONA_SORTIDA = "./img/enlace01.gif";
	UTILS_GMAPS.ICONA_ESTACIO_METEO = "./img/estmet05.gif";
	// Icones en un array per que són de diferent color segons el nivell de servei de la incidéncia
	UTILS_GMAPS.ICONES_OBRES = ["./img/obres01.gif","./img/obres02.gif","./img/obres03.gif","./img/obres04.gif","./img/obres05.gif"];
	UTILS_GMAPS.ICONES_TRANSIT = ["./img/trafic01.gif","./img/trafic02.gif","./img/trafic03.gif","./img/trafic04.gif","./img/trafic05.gif"];
	UTILS_GMAPS.ICONES_ACCIDENT = ["./img/accident01.gif","./img/accident02.gif","./img/accident03.gif","./img/accident04.gif","./img/accident05.gif"];
	UTILS_GMAPS.ICONES_CAMARA = ["./img/camara01.gif","./img/camara02.gif","./img/camara03.gif","./img/camara04.gif","./img/camara05.gif"];
	UTILS_GMAPS.ICONES_PANELL = ["./img/panell01.gif","./img/panell02.gif","./img/panell03.gif","./img/panell04.gif","./img/panell05.gif"];
	UTILS_GMAPS.ICONES_METEO = ["./img/temps01.gif","./img/temps02.gif","./img/temps03.gif","./img/temps04.gif","./img/temps05.gif"];
	UTILS_GMAPS.ICONES_INCIDENCIES = ["./img/incident01.gif","./img/incident02.gif","./img/incident03.gif","./img/incident04.gif","./img/incident05.gif"];
	UTILS_GMAPS.ICONES_EST_MET = ["./img/estmet05.gif","./img/estmet05.gif","./img/estmet05.gif","./img/estmet05.gif","./img/estmet05.gif"];
	
	// Definim i inicialitzem les constants comunes per totes les concessions en una "classe" UTILS_GMAPS.CONSTANTS_CLASS
	UTILS_GMAPS.CONSTANTS_CLASS = {};
	UTILS_GMAPS.CONSTANTS_CLASS.MINUTS_REFRESC = 5;
	UTILS_GMAPS.CONSTANTS_CLASS.ARRAY_IMATGE_FLUID = 0;
	UTILS_GMAPS.CONSTANTS_CLASS.ARRAY_IMATGE_DENS = 1;
	UTILS_GMAPS.CONSTANTS_CLASS.ARRAY_IMATGE_RETENCIO = 2;
	UTILS_GMAPS.CONSTANTS_CLASS.ARRAY_IMATGE_TALLAT = 3;
	UTILS_GMAPS.CONSTANTS_CLASS.ARRAY_IMATGE_SENSE_DADES = 4;
	UTILS_GMAPS.CONSTANTS_CLASS.MAX_ZOOM = 12;
	UTILS_GMAPS.CONSTANTS_CLASS.MIN_ZOOM = 8;
	UTILS_GMAPS.CONSTANTS_CLASS.COLOR_TRANSIT_RETENCIO = "#cc0000";
	UTILS_GMAPS.CONSTANTS_CLASS.COLOR_TRANSIT_DENS = "#FFCC33";
	UTILS_GMAPS.CONSTANTS_CLASS.COLOR_TRANSIT_FLUID = "#33cc33";
	UTILS_GMAPS.CONSTANTS_CLASS.COLOR_TRANSIT_SENSE_DADES = "#cccccc";
	UTILS_GMAPS.CONSTANTS_CLASS.COLOR_TRANSIT_TALLAT = "#000000";
	UTILS_GMAPS.CONSTANTS_CLASS.COLOR_TRANSIT_BORDE_POLIGON = "#ffffff";
	UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_RETENCIO = 0;
	UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_DENS = 1;
	UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_FLUID = 2;
	UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_TALLAT = 3;
	UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_SENSE_DADES = -1;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_TRANSIT = 0;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ACCIDENT = 1;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_OBRES = 3;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_INCIDENCIES = 2;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_METEO = 4;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_CAMARES = 6;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_PANELLS = 5;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ESTACIO_METEO = 7;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ZONA_GIRONA = 8;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ZONA_BARCELONA = 9;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ZONA_TARRAGONA = 10;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ZONA_LLEIDA = 11;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ZONA_HUESCA = 12;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ZONA_ZARAGOZA = 13;
	UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_LENGTH = 14;	// Anar actualitzant aquest var per tal que l'array d'opcions sempre sigui correcte!!!!

	// Definim els atributs comuns per totes les concessions en una "classe" UTILS_GMAPS.AtributsClass
  UTILS_GMAPS.AtributsClass = {};
	UTILS_GMAPS.AtributsClass.map = null;											// El Mapa (GMap2).
	UTILS_GMAPS.AtributsClass.latIni;													// Latitud inicial del mapa.
	UTILS_GMAPS.AtributsClass.lngIni;													// Longitud inicial del mapa.
	UTILS_GMAPS.AtributsClass.zoomIni;												// Nivell de zoom inicial del mapa (int entre UTILS_GMAPS.CONSTANTS_CLASS.MAX_ZOOM i UTILS_GMAPS.CONSTANTS_CLASS.MIN_ZOOM).
	UTILS_GMAPS.AtributsClass.m_arrayTransit = new Array();		// Array per guardar les incidéncies de Transit.
	UTILS_GMAPS.AtributsClass.m_arrayAccidents = new Array();	// Array per guardar les incidéncies d'accidents
	UTILS_GMAPS.AtributsClass.m_arrayObres = new Array();			// Array per guardar les incidéncies d'Obres.
	UTILS_GMAPS.AtributsClass.m_arrayMeteo = new Array();			// Array per guardar les incidéncies Meteorològiques
	UTILS_GMAPS.AtributsClass.m_arrayCamares = new Array();		// Array per guardar les incidéncies de Càmares.
	UTILS_GMAPS.AtributsClass.m_arrayPanells = new Array();		// Array per guardar les incidéncies de Panells.
	UTILS_GMAPS.AtributsClass.m_arrayPanellsMaxZoom = new Array();// Array per guardar les incidéncies de Panells q s'han de mostrar només al nivell més alt de zoom.
	UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces = null;			// Array per guardar els panells d'accés (panells que s'agrupen i es mostern només al màxim nivell de zoom).
	UTILS_GMAPS.AtributsClass.m_arrayEstMeteo = new Array();	// Array per guardar les Estacions Meteorològiques
	UTILS_GMAPS.AtributsClass.m_arrayIncidencies = new Array();// Array per guardar les incidéncies d'altres típus.
	UTILS_GMAPS.AtributsClass.m_arrayLiniaIcones = new Array();// Array per guardar les línies de les icones
	UTILS_GMAPS.AtributsClass.coordenadesPermeses = null;			// Les coordenades permeses del mapa (GLatLngBounds).
	UTILS_GMAPS.AtributsClass.m_tooltip;											// El valor del tooltip per a una incidéncia (l'inicialitzem en el load i el posem en un listener, per això està aquí)
	UTILS_GMAPS.AtributsClass.markerManager = null;						// Punter a un marker manager per controlar els trams i les sortides
	UTILS_GMAPS.AtributsClass.m_bLogicsCarregatsAcesa = false;// Per controlar si ja hem llegit el XML dels Subjectes Lògics
	UTILS_GMAPS.AtributsClass.m_bEquipsCarregatsAcesa = false;// Per controlar si ja hem llegit el XML dels Equipaments
	UTILS_GMAPS.AtributsClass.m_bLogicsCarregatsAucat = false;// Per controlar si ja hem llegit el XML dels Subjectes Lògics
	UTILS_GMAPS.AtributsClass.m_bEquipsCarregatsAucat = false;// Per controlar si ja hem llegit el XML dels Equipaments
	UTILS_GMAPS.AtributsClass.m_arrayChecks = new Array(UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_LENGTH);
	UTILS_GMAPS.AtributsClass.m_bDataOk = false;							// Bool per mirar si la data del fitxer XML és OK (menys de 15 minuts de la data acatual del servidor)
	UTILS_GMAPS.AtributsClass.m_strDataFitxer = "";						// Data llegida del fitxer XML en el format "dd/mm/yyyy hh:mi"
	UTILS_GMAPS.AtributsClass.m_arrayInicidencies2Ubicacions = new Array();
	UTILS_GMAPS.AtributsClass.m_msgAlert = "";
	
	// Definim una "classe" (UTILS_GMAPS.LogicalClass) per encapsular les dades del XML del típus <Logical>. Això de fet encapsula tres subclasses més que s'encarreguens dels atributs de logial, del Location i del LaneAffectation.
	UTILS_GMAPS.LogicalClass = {};
	UTILS_GMAPS.LogicalClass.AtributsClass = UTILS_GMAPS.LogicalAtributsClass;
	UTILS_GMAPS.LogicalClass.LaneAfClass = UTILS_GMAPS.LaneAfClass;
	//UTILS_GMAPS.LogicalClass.InitialLocationClass = UTILS_GMAPS.LocationClass;
	//UTILS_GMAPS.LogicalClass.FinalLocationClass = UTILS_GMAPS.LocationClass;
	UTILS_GMAPS.LogicalClass.InitialLocationClass = {};
	UTILS_GMAPS.LogicalClass.InitialLocationClass.description = "";
	UTILS_GMAPS.LogicalClass.InitialLocationClass.highWayCode = "";
	UTILS_GMAPS.LogicalClass.InitialLocationClass.highWayName = "";
	UTILS_GMAPS.LogicalClass.InitialLocationClass.accessName = "";
	UTILS_GMAPS.LogicalClass.InitialLocationClass.kmPoint = "";
	UTILS_GMAPS.LogicalClass.InitialLocationClass.direction = "";
	UTILS_GMAPS.LogicalClass.InitialLocationClass.descDirection = "";
	UTILS_GMAPS.LogicalClass.InitialLocationClass.networkKind = "";
	UTILS_GMAPS.LogicalClass.InitialLocationClass.platformTollKind = "";
	UTILS_GMAPS.LogicalClass.InitialLocationClass.roadLinkKind = "";
	UTILS_GMAPS.LogicalClass.InitialLocationClass.longitude = "";
	UTILS_GMAPS.LogicalClass.InitialLocationClass.latitude = "";
	UTILS_GMAPS.LogicalClass.InitialLocationClass.latlng = null;	// GLatLng
	UTILS_GMAPS.LogicalClass.InitialLocationClass.levelNumber = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass = {};
	UTILS_GMAPS.LogicalClass.FinalLocationClass.description = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass.highWayCode = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass.highWayName = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass.accessName = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass.kmPoint = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass.direction = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass.descDirection = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass.networkKind = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass.platformTollKind = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass.roadLinkKind = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass.longitude = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass.latitude = "";
	UTILS_GMAPS.LogicalClass.FinalLocationClass.latlng = null;	// GLatLng
	UTILS_GMAPS.LogicalClass.FinalLocationClass.levelNumber = "";
	
	// Definim una "classe" (UTILS_GMAPS.LogicalAtributsClass) per encapsular les dades dels ATRIBUTS del XML del típus <Logical>. Només els atributs, no encapsula el q conté "a dins" (típus SL, Location, LaneAffectation).
	UTILS_GMAPS.LogicalAtributsClass = {};
	UTILS_GMAPS.LogicalAtributsClass.code = "";
	UTILS_GMAPS.LogicalAtributsClass.creationDate = "";
	UTILS_GMAPS.LogicalAtributsClass.updateDate = "";
	UTILS_GMAPS.LogicalAtributsClass.comment = "";
	UTILS_GMAPS.LogicalAtributsClass.locationComment = "";
	UTILS_GMAPS.LogicalAtributsClass.place = "";

	// Definim una "classe" (UTILS_GMAPS.LocationClass) per encapsular les dades del XML del típus <Location>
	UTILS_GMAPS.LocationClass = {};
	UTILS_GMAPS.LocationClass.description = "";
	UTILS_GMAPS.LocationClass.highWayCode = "";
	UTILS_GMAPS.LocationClass.highWayName = "";
	UTILS_GMAPS.LocationClass.accessName = "";
	UTILS_GMAPS.LocationClass.kmPoint = "";
	UTILS_GMAPS.LocationClass.direction = "";
	UTILS_GMAPS.LocationClass.descDirection = "";
	UTILS_GMAPS.LocationClass.networkKind = "";
	UTILS_GMAPS.LocationClass.platformTollKind = "";
	UTILS_GMAPS.LocationClass.roadLinkKind = "";
	UTILS_GMAPS.LocationClass.longitude = "";
	UTILS_GMAPS.LocationClass.latitude = "";
	UTILS_GMAPS.LocationClass.latlng = null;	// GLatLng
	
	// Definim una "classe" (UTILS_GMAPS.LaneAfClass) per encapsular les dades del XML del típus <LaneAffectation>
	UTILS_GMAPS.LaneAfClass = {};
	UTILS_GMAPS.LaneAfClass.hardShoulder = "";
	UTILS_GMAPS.LaneAfClass.total = "";
	UTILS_GMAPS.LaneAfClass.partial = "";
	UTILS_GMAPS.LaneAfClass.carrilesAfectados = "";
	UTILS_GMAPS.LaneAfClass.desc = "";
	
	// Definim una "classe" (UTILS_GMAPS.EquipmentClass) per encapsular les dades del XML del típus <Equipment>. Això de fet encapsula quatre subclasses més que s'encarreguens dels atributs de equipment, del Location i del Camera o el Board (panell).
	UTILS_GMAPS.EquipmentClass = {};
	UTILS_GMAPS.EquipmentClass.AtributsClass = UTILS_GMAPS.EquipmentAtributsClass;
	UTILS_GMAPS.EquipmentClass.CameraClass = UTILS_GMAPS.CameraClass;
	UTILS_GMAPS.EquipmentClass.BoardClass = UTILS_GMAPS.BoardClass;
	UTILS_GMAPS.EquipmentClass.EstMetClass = UTILS_GMAPS.EstMetClass;
	UTILS_GMAPS.EquipmentClass.LocationClass = UTILS_GMAPS.LocationClass;
	
	// Definim una "classe" (UTILS_GMAPS.EquipmentAtributsClass) per encapsular les dades dels ATRIBUTS del XML del típus <Equipment>. Només els atributs, no encapsula el q conté "a dins" (típus equipment, Location).
	UTILS_GMAPS.EquipmentAtributsClass = {};
	UTILS_GMAPS.EquipmentAtributsClass.code = "";
	UTILS_GMAPS.EquipmentAtributsClass.active = "";
	UTILS_GMAPS.EquipmentAtributsClass.updateDate = "";
	
	// Definim una "classe" (UTILS_GMAPS.BoardClass) per encapsular les dades del XML del típus <Board>. Aquesta 'classe' encpasula 2 'subclasses': Una per guardar els atributs (BoardClass.Atributs) i una altre per guardar el missatge (BoardClass.Message).
	UTILS_GMAPS.BoardClass = {};
	UTILS_GMAPS.BoardClass.Atributs = {};
	UTILS_GMAPS.BoardClass.Atributs.name = "";
	UTILS_GMAPS.BoardClass.Atributs.number = "";
	UTILS_GMAPS.BoardClass.Atributs.type = "";
	UTILS_GMAPS.BoardClass.Atributs.fileNumber = "";
	UTILS_GMAPS.BoardClass.Atributs.columnNumber = "";
	UTILS_GMAPS.BoardClass.Atributs.iconPosition = "";
	UTILS_GMAPS.BoardClass.Atributs.isActive = "";
	UTILS_GMAPS.BoardClass.Atributs.warningState = "";
	UTILS_GMAPS.BoardClass.Atributs.publish = "";
	UTILS_GMAPS.BoardClass.Message1 = {};
	UTILS_GMAPS.BoardClass.Message1.number = "";
	UTILS_GMAPS.BoardClass.Message1.leftIcon = "";
  UTILS_GMAPS.BoardClass.Message1.rightIcon = "";
  UTILS_GMAPS.BoardClass.Message1.difference = "";
  UTILS_GMAPS.BoardClass.Message1.message = "";
	UTILS_GMAPS.BoardClass.Message2 = {};
	UTILS_GMAPS.BoardClass.Message2.number = "";
	UTILS_GMAPS.BoardClass.Message2.leftIcon = "";
  UTILS_GMAPS.BoardClass.Message2.rightIcon = "";
  UTILS_GMAPS.BoardClass.Message2.difference = "";
  UTILS_GMAPS.BoardClass.Message2.message = "";
	
	// Definim una "classe" (UTILS_GMAPS.CameraClass) per encapsular les dades del XML del típus <Camera>. Aquesta 'classe' encpasula 2 'subclasses': Una per guardar els atributs (CameraClass.Atributs) i una altre per guardar les zones de cobertura (CameraClass.CoverZones), que de moment només conté un array (CameraClass.CoverZones.zones) de subclasses del típus 'CameraClass.CoverZones.Zone'.
	UTILS_GMAPS.CameraClass = {};
	UTILS_GMAPS.CameraClass.Atributs = {};
	UTILS_GMAPS.CameraClass.Atributs.name = "";
	UTILS_GMAPS.CameraClass.Atributs.kind = "";
	UTILS_GMAPS.CameraClass.Atributs.number = "";
	UTILS_GMAPS.CameraClass.Atributs.legend = "";
	UTILS_GMAPS.CameraClass.Atributs.url = "";
	UTILS_GMAPS.CameraClass.Atributs.file = "";
	UTILS_GMAPS.CameraClass.CoverZones = {};
	UTILS_GMAPS.CameraClass.CoverZones.zones = new Array();	// Array de UTILS_GMAPS.CameraClass.CoverZones.Zone = {};
	UTILS_GMAPS.CameraClass.CoverZones.Zone = {};
	UTILS_GMAPS.CameraClass.CoverZones.Zone.preposition = "";
	UTILS_GMAPS.CameraClass.CoverZones.Zone.description = "";
	UTILS_GMAPS.CameraClass.CoverZones.Zone.highWayCode = "";
	UTILS_GMAPS.CameraClass.CoverZones.Zone.initialKm = "";
	UTILS_GMAPS.CameraClass.CoverZones.Zone.finalKm = "";
	
	// Definim una "classe" (UTILS_GMAPS.EstMetClass) per encapsular les dades del XML del típus <EstacioMeteo>.
	UTILS_GMAPS.EstMetClass = {};
	UTILS_GMAPS.EstMetClass.Atributs = {};
	UTILS_GMAPS.EstMetClass.Atributs.nom = "";
	UTILS_GMAPS.EstMetClass.Atributs.temp = "";
	UTILS_GMAPS.EstMetClass.Atributs.vent = "";
	UTILS_GMAPS.EstMetClass.Atributs.plujaHora = "";	// Pluja acumulada durant la última hora
	UTILS_GMAPS.EstMetClass.Atributs.plujaDia = "";		// Pluja acumulada durant les últimes 24 hores
	
	// Definim una "classe" UTILS_GMAPS.SegmentClass per encapsular les propietats d'un segment. Definim un Array UTILS_GMAPS.Segments per tal de guardar-los tots. Les polylines d'un segment s'encapsulen dins una classe UTILS_GMAPS.SegmentClass.LiniaClass, on guardarem els punts, els punts codificats i els nivells codificats. Per cada segemtn, tindrem 3 da'questes línies: La de la direcció, i les 2 paraleles.
	UTILS_GMAPS.Segments = new Array();		// Array de UTILS_GMAPS.SegmentClass
	UTILS_GMAPS.SegmentClass = {};
	UTILS_GMAPS.SegmentClass.Id = "";
	UTILS_GMAPS.SegmentClass.Origen = "";	// La coordenada del punt Orígen. Ex: "41.5785558, 2.523548"
	UTILS_GMAPS.SegmentClass.Desti = "";	// La coordenada del punt Orígen. Ex: "41.5785558, 2.523548"
	UTILS_GMAPS.SegmentClass.LiniaClass = {};
	UTILS_GMAPS.SegmentClass.LiniaClass.Punts = new Array();	// Serà un array de punts. Ex: "41.5785558, 2.523548"
	UTILS_GMAPS.SegmentClass.LiniaClass.EncodedPoints = "";
	UTILS_GMAPS.SegmentClass.LiniaClass.EncodedLevels = "";
	UTILS_GMAPS.SegmentClass.Direccio = UTILS_GMAPS.SegmentClass.LiniaClass; 
	UTILS_GMAPS.SegmentClass.Paralela1 = UTILS_GMAPS.SegmentClass.LiniaClass;
	UTILS_GMAPS.SegmentClass.Paralela2 = UTILS_GMAPS.SegmentClass.LiniaClass; 
	
	// Definim els nivells de servei	
	UTILS_GMAPS.NivellsServei = new Array();		// Array de UTILS_GMAPS.NSClass
	/*
	UTILS_GMAPS.NSClass = {};
	UTILS_GMAPS.NSClass.identifier = "";
	UTILS_GMAPS.NSClass.highWayCode = "";
	UTILS_GMAPS.NSClass.pkIni = "";
	UTILS_GMAPS.NSClass.pkEnd = "";
	UTILS_GMAPS.NSClass.direction = "";
	UTILS_GMAPS.NSClass.levelNumber = "";
	UTILS_GMAPS.NSClass.level = "";
	UTILS_GMAPS.NSClass.description = "";
	*/
	
	// Funció que retorna el HTML amb la info general a mostrar en un marker
	// @param icon La icona ah posar al HTML
	// @param titol El titol de la finestra d'info
	// @param hora La hora de la incidéncia (en que s'ha creat)
	// @param update La hora en que s'han actualitzat les dades de la incidéncia
	// @param desc Descripció de la incidéncia
	// @param iniFi Els PKs d'inici i final de la incidéncia
	// @param loc Localitat on es troba la incidéncia (referéncia per situació, la incidéncia estarà a la autopista!)
	// @return Un string amb el HTML generat
	UTILS_GMAPS.htmlMarkerInfoGeneral = function(icon, titol, hora, update, desc, iniFi, loc, laneAfClass) {
		var html = UTILS_GMAPS.htmlTitol( titol, icon );	// Agafem el títol
		html += "<table class='markerInfoTableHeader' cellpadding='3' cellspacing='2' border='0'>";
		html += "<tr><td width='120'>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.DIA ) + "</td><td width='280'> " + hora + "</td></tr>";
		if ( desc == null )
			html += "<tr><td >" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.DESC ) + "</td><td> </td></tr>";
		else
			html += "<tr><td >" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.DESC ) + "</td><td> " + UTILS_GMAPS.espaisEntersHtml(desc) + "</td></tr>";
			//html += "<tr><td >" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.DESC ) + "</td><td> " + UTILS_GMAPS.entersHtml(desc) + "</td></tr>";
		if ( laneAfClass.desc == null )
			html += "<tr><td >" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.AFECTACIO ) + "</td><td> </td></tr>";
		else
			html += "<tr><td >" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.AFECTACIO ) + "</td><td> " + laneAfClass.desc + "</td></tr>";
		if ( iniFi == null )
			html += "<tr><td >" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INICI ) + "</td><td> </td></tr>";
		else
			html += "<tr><td >" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INICI ) + "</td><td> " + iniFi + "</td></tr>";
		if ( loc == null )
			html += "<tr><td >" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.LOCALITZACIO ) + "</td><td> </td></tr>";
		else
			html += "<tr><td >" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.LOCALITZACIO ) + "</td><td> " + loc + "</td></tr>";
		html += "</table>";
		return html;
	}

	// Funció que retorna el HTML amb la info addicional a mostrar en un marker
	// @param icon La icona ah posar al HTML
	// @param titol El titol de la finestra d'info
	// @param labels Array amb les etiquetes de la info addicional
	// @param contents Array amb el contingut de la info addicional
	// @return Un string amb el HTML generat
	UTILS_GMAPS.htmlMarkerInfoAdicional = function(icon, titol, labels, contents) {
		var html = UTILS_GMAPS.htmlTitol( titol, icon );	// Agafem el titol
		html += "<table class='markerInfoTableHeader' cellpadding='3' cellspacing='2' border='0'>";
		for ( var i = 0; i < labels.length; i++ )
			html += "<tr><td width='120'>" + labels[i] + ":</td><td>" + contents[i] + "</td></tr>";
		html += "</table>";
		return html;
	}
	
	// Funció que retorna el HTML amb la info a mostrar (el nivell de servei) en un tram
	// @param titol El titol de la finestra d'info
	// @param update La hora en que s'han actualitzat les dades del tram
	// @param levelNumber Nivell de servei del tram
	// @param iniFi Els PKs d'inici i final del tram
	// @param sentit Sentit del tram
	// @param loc Localitat on es troba el tram (referéncia per situació del tram a  la autopista)
	// @return Un string amb el HTML generat
	UTILS_GMAPS.htmlNivellServei = function(titol, update, levelNumber, iniFi, sentit, loc, notes ) {
		var html = UTILS_GMAPS.htmlTitol( titol, UTILS_GMAPS.getIcona("TR",levelNumber) );	// Agafem el titol
		html += "<table class='markerInfoTableHeader' cellpadding='3' cellspacing='2' border='0'>";
		var servei = UTILS_GMAPS.getDescLevelNumber( levelNumber );
		html += "<tr><td>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.ESTAT ) + "</td><td width='280'>" + servei + "</td></tr>";
		html += "<tr><td>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.DESC ) + "</td><td>" + notes + "</td></tr>";
		html += "<tr><td>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INICI ) + "</td><td>" + iniFi + "</td></tr>";
		html += "<tr><td>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.SENTIT ) + "</td><td>" + sentit + "</td></tr>";
		html += "<tr><td>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.LOCALITZACIO ) + "</td><td>" + loc + "</td></tr>";
		html += "</table>";
		return html;
	}

	// Funció que retorna el HTML d'ún títol (format, icona i títol en si)
	// @param Titol El text a posar com a titol
	// @param icona La icona amostrar al costat del titol
	// @return Un string amb el html del títol (format, icona i títol en si)
	UTILS_GMAPS.htmlTitol = function( titol, icona ) {
		var html = "<br><table class='markerInfoTableHeader' cellpadding='5' cellspacing='0' border='0'>";
		html += "<tr>";
		html += "<th><img src='" + icona + "'></th>";
		html += "<th>" + titol + "</th>";
		html += "</tr></table>";
		return html;
	}

	// Funció que retorna la descripció d'un nivell de servei donat
	// @param levelNumber Nivell de servei del que volem saber la descripció
	// @return Un string amb la descripció del nivell de servei passat
	UTILS_GMAPS.getDescLevelNumber = function( levelNumber ) {
		var desc = "";
		if ( levelNumber == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_RETENCIO )
			desc = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CONGESTIO );
		else if ( levelNumber == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_DENS )
			desc = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.DENS );
		else if ( levelNumber == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_FLUID )
			desc = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.FLUID );
		else if ( levelNumber == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_TALLAT )
			desc = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.TALLAT );
		else //if ( levelNumber == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_SENSE_DADES )
			desc = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.NO_DADES );
		return desc;
	}
	
	// Funció que retorna el HTML amb la info a mostrar en un marker de panell
	// @param titol El titol de la finestra d'info
	// @param msg El missatge a mostrar en el panell
	// @param iconaEsq La icona a posar a l'esquerra del panell
	// @param iconaDreta La icona a posar a la dreta del panell
	// @param levelNumber Nivell de servei del panell
	// @return Un string amb el HTML generat
	UTILS_GMAPS.htmlPanell = function(titol, msg, iconaEsq, iconaDreta, levelNumber, msg2, iconaEsq2, iconaDreta2 ) {
		var html = UTILS_GMAPS.htmlTitol( titol, UTILS_GMAPS.getIcona("PMV", levelNumber) );	// Agafem el titol

		// Agafem el típus de panell
		var classeTaula, classeText;
		var aTipusPanell = UTILS_GMAPS.getTipusPanell( msg, iconaEsq, iconaDreta );
		classeTaula = aTipusPanell[0];
		classeText = aTipusPanell[1];
		
		// Canviem els salts d línia del msg a salts HTML i mirem quin msg és + llarg per posar els salts de línia del panell
		var msgPanell1 = UTILS_GMAPS.entersHtml(msg);
		var msgPanell2 = UTILS_GMAPS.entersHtml(msg2);
		var iNumEnters = UTILS_GMAPS.numeroEntersHtml(msgPanell1);
		var iNumEnters2 = UTILS_GMAPS.numeroEntersHtml(msgPanell2);
		if ( iNumEnters2 > iNumEnters )
			iNumEnters = iNumEnters2;
		if ( iNumEnters == 0 )	// Els panells tenen mínim 2 línies. Si no hi ha cap enter, contem q tenim 1 enter (2 línies)
			iNumEnters = 1;

		// Construim la taula	amb la info del panell
		html += "<br><center>";
		html += "<TABLE class='" + classeTaula + "'><TR>";
		// Posem la icona d l'esquerra
		if ( iconaEsq.length > 0 ) {
			html += "<TD style='width: 19%;' ALIGN=CENTER><img src='" + iconaEsq + "' width=40 height=40></TD>";
		}
		// Posem una mini casella amb els salts de línia dels panells
		html += "<TD style='width: 1%;' ALIGN=CENTER>";
		for ( i = 0; i <= iNumEnters+1; i++ )
			html += "<BR>";
		html += "</TD>";
		// Posem el msg		
		html += "<TD style='width: 60%;'><SPAN class='" + classeText + "'>" + msgPanell1 + "</CENTER></SPAN></TD>";
		// Posem la icona d la dreta
		if ( iconaDreta.length > 0 ) {
			html += "<TD style='width: 20%;' ALIGN=CENTER><img src='" + iconaDreta + "' width=40 height=40></TD>";
		}
		html += "</TR></TABLE><BR>";
		html += "</center>";
		
		if ( msg2 != "" ) {
			html += "<br><center>";
			html += "<TABLE class='" + classeTaula + "'><TR>";
			// Posem la icona d l'esquerra
			if ( iconaEsq2.length > 0 ) {
				html += "<TD style='width: 20%;' ALIGN=CENTER><img src='" + iconaEsq2 + "' width=40 height=40></TD>";
			}
			// Posem una mini casella amb els salts de línia dels panells
			html += "<TD style='width: 1%;' ALIGN=CENTER>";
			for ( i = 0; i <= iNumEnters+1; i++ )
				html += "<BR>";
			html += "</TD>";
			// Posem el msg		
			html += "<TD style='width: 60%;'><SPAN class='" + classeText + "'>" + msgPanell2 + "</CENTER></SPAN></TD>";
			// Posem la icona d la dreta
			if ( iconaDreta2.length > 0 ) {
				html += "<TD style='width: 20%;' ALIGN=CENTER><img src='" + iconaDreta2 + "' width=40 height=40></TD>";
			}
			html += "</TR></TABLE><BR>";
			html += "</center>";
		}
	
		return html;
	}

	// Funció que retorna el número d'enters d'un msg
	// @param msg Un string amb el text al que vole contar els enters
	// @return EL número d'enters que conté el msg passat
	UTILS_GMAPS.numeroEntersHtml = function( msg ) {
		var iNumEnters = 0;
		var i = msg.indexOf("<BR>");
		while ( i >= 0 ) {
			iNumEnters++;
			if ( i < msg.length-1 )
				i = msg.indexOf("<BR>", i+1);
			else
				break;
		}
		return iNumEnters;
	}
	
	// Funció que retorna el número d'enters d'un msg
	// @param msg Un string amb el text al que vole contar els enters
	// @return EL número d'enters que conté el msg passat
	UTILS_GMAPS.numeroEnters = function( msg ) {
		var iNumEnters = 0;
		var i = msg.indexOf("\n");
		while ( i >= 0 ) {
			iNumEnters++;
			if ( i < msg.length-1 )
				i = msg.indexOf("\n", i+1);
			else
				break;
		}
		return iNumEnters;
	}

	// Funció recursiva que canvia els salts de línia d'un text a salts de línia de html ("<BR>").
	// @param msg Un string amb el text al que es volen canviar els salts de línia
	// @return Un string amb els salts de línia en format html
	UTILS_GMAPS.entersHtml = function( msg ) {
		/*
		var msgReturn = msg.replace("\n","<BR>");
		if ( msgReturn.indexOf("\n") >= 0 )
			return UTILS_GMAPS.entersHtml( msgReturn );
		else {
				return msgReturn;
		}
		*/
		var msgReturn = msg.replace("\r\n","<BR>");
		if ( msgReturn.indexOf("\r\n") >= 0 )
			return UTILS_GMAPS.entersHtml( msgReturn );
		else {
			msgReturn = msgReturn.replace("\n","<BR>");
			if ( msgReturn.indexOf("\n") >= 0 )
				return UTILS_GMAPS.entersHtml( msgReturn );
			else
				return msgReturn;
		}
	}

	// Funció recursiva que canvia els espais d'un text a espais de html ("&nbsp"). Només fel el canvi quan hi han 2 o més blancs seguits (els espais simples els deixem igual x poder fer els salts de línia automàtics) o quan és el primer espai.
	// @param msg Un string amb el text al que es volen canviar els espais
	// @return Un string amb els espais en format html
	UTILS_GMAPS.espaisHtml = function( msg ) {
		/*
		// Canviant tots els " " per "&nbsp;", a sac:
		var msgReturn = msg.replace(" ","&nbsp;");
		if ( msgReturn.indexOf(" ") >= 0 )
			return UTILS_GMAPS.espaisHtml( msgReturn );
		else
			return msgReturn;
		*/
		
		// Canviant quan hi ha més d'un " " seguit o és el primer espai:
		var msgReturn = msg.replace("  ","&nbsp;&nbsp;");
		if ( msgReturn.indexOf("  ") >= 0 )
			return UTILS_GMAPS.espaisHtml( msgReturn );
		else {
			msgReturn = msgReturn.replace("&nbsp;&nbsp; ","&nbsp;&nbsp;&nbsp;");
			if ( msgReturn.indexOf("&nbsp;&nbsp; ") >= 0 )
				return UTILS_GMAPS.espaisHtml( msgReturn );
			else {
				if ( msgReturn.indexOf(" ") == 0 )
					msgReturn = msgReturn.replace(" ","&nbsp;");
				return msgReturn;
			}
		}
	}

	// Funció que canvia els espais i els salts de lína d'un text a espais i salts de línia de html.
	// @param msg Un string amb el text al que es volen canviar els salts de línia i els espais
	// @return Un string amb els espais i els salts de línia en format html
	UTILS_GMAPS.espaisEntersHtml = function( msg ) {
		var msgReturn = UTILS_GMAPS.espaisHtml( msg );
		msgReturn = UTILS_GMAPS.entersHtml( msgReturn );
		return msgReturn;
	}
		
	// Funció que retorna el típus de panell a partir del missatge i les icones passades
	// @param msg El misstage del panell
	// @param iconaEsq La icona de l'esquerra del panell (o "" si no n'hi ha)
	// @param iconaDreta La icona de la dreta del panell (o "" si no n'hi ha)
	// @return Un array amb dos strings. el primer indica la classe (el valor al CSS) de la taula, i el 2on la classe (el valor al CSS) del text
	UTILS_GMAPS.getTipusPanell = function( msg, iconaEsq, iconaDreta ) {
		// Sempre retornem el mateix típus. De mometn ignroem aquí si té una o dos ciones o el número de línies.
		var classeTaula, classeText;
		if ( ( iconaEsq.length > 0 ) && ( iconaDreta.length > 0 ) ) {
			// Icona a cada costat
			classeTaula = "classePanell";
			classeText = "classeTextPanell";
		}
		else if ( iconaEsq.length > 0 ) {
			// Icona només a la esquerra
			classeTaula = "classePanell";
			classeText = "classeTextPanell";
		}
		else if ( iconaDreta.length > 0 ) {
			// Icona només a la dreta
			classeTaula = "classePanell";
			classeText = "classeTextPanell";
		}
		else {
			// Sense icones
			classeTaula = "classePanell";
			classeText = "classeTextPanell";
		}
		return [classeTaula, classeText];
	}
	
	// Funció que retorna el HTML amb la info a mostrar en un marker de càmera
	// @param titol El titol de la finestra d'info
	// @param levelNumber Nivell de servei de la càmera
	// @return Un string amb el HTML generat
	UTILS_GMAPS.htmlCamera = function(titol,levelNumber, fitxer, active) {
		
		// TREURE!!!!! COMENTAR PER PROVES LOCALS!!!!!! DESP TREURE!!!!!!!!!!!
		fitxer += "?dummy="+Math.random()+".flv";

		// Contruim el HTML que posa el títol i mostra el video
		var html = UTILS_GMAPS.htmlTitol( titol, UTILS_GMAPS.getIcona("CAM", levelNumber) );	// Agafem el titol
		html += "<br><center><div style='width:320px;height:240px'>";
		// Si la càmera està fora de servei, posem un fons informant del mateix. Si no, mostrem el seu video.
		if ( active == 'False' ) {
			//html += "<img src='./cam/foraServei.jpg' width=320 height=240>";
			fitxer = "default2.flv";	// PENDENT!!! Quan el desactivat sigui un video, treure aquest comentari, treure la línia de dalt i treure tb el "else".
		}
		//else {
			html += "<!--[if IE]>";
			html += "<style type='text/css'> .containerdiv { float: left; position: relative; } .cornerimage { position: absolute; top: 0; right: 0; } </style>"
			html += "<br><center><div class='containerdiv'style='width:320px;height:240px'>";
			html += "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' width='320' height='240' id='CamarasAcesa'>";
			html += "<param name='movie' value='./js/player.swf' />";
			html += "<param name='allowscriptaccess' value='always' />";
			//html += "<param name='flashvars' value='file=../cam/" + fitxer + "&autostart=true&displayclick=none&resizing=false&controlbar=none' />";
			html += "<param name='flashvars' value='file=../cam/" + fitxer + "&autostart=true&displayclick=none&resizing=false&controlbar=none&repeat=single' />";
			//html += "<param name='flashvars' value='file=../cam/" + fitxer + "&autostart=true&resizing=false&controlbar=none' />";
			html += "<a href='http://www.adobe.com/go/getflashplayer'>";
			html += "<img src='http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif' alt='Get Adobe Flash player' />";
			html += "</a>";
			html += "</object>";
			html += "<img class='cornerimage' border='0' src='./img/blanc.bmp'>";
			html += "</div></center>";
			html += "</body></html>";
			html += "<![endif]-->";
			html += "<!--[if !IE]>-->";
			html += "<br><center><div style='width:320px;height:240px'>";
			html += "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' width='320' height='240' id='CamarasAcesa'>";
			html += "<param name='movie' value='./js/player.swf' />";
			html += "<param name='flashvars' value='file=../cam/" + fitxer + "&controlbar=none&autostart=true&displayclick=none' />";
			html += "<object type='application/x-shockwave-flash' data='./js/player.swf' width='320' height='240'>";
			//html += "<param name='flashvars' value='file=../cam/" + fitxer + "&controlbar=none&autostart=true&displayclick=none' />";
			html += "<param name='flashvars' value='file=../cam/" + fitxer + "&controlbar=none&autostart=true&displayclick=none&repeat=single' />";
			html += "<a href='http://www.adobe.com/go/getflashplayer'>";
			html += "<img src='http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif' alt='Get Adobe Flash player' />";
			html += "</a>";
			html += "</object>";
			html += "</object>";
			html += "</div></center>";
			html += "<!--<![endif]-->";
			html += "<span id='flashcontent'></span>";
			html += "</div></center>";
			// TESTS. TREURE!!!!!!!!
			/*
			html += "<script type='text/javascript'>";
			html += "var player = null;";
			html += "function playerReady(thePlayer) {";
			html += "alert('PLAYER READY!!!');";
			html += "player = window.document[thePlayer.id];";
			html += "player.addControllerListener('STOP','stopMovie');";
			html += "}";
			html += "function stopMovie(obj) { alert('VIDEO ACABAT!!!'); }";
			html += "</script>";
			*/
		//}
		return html;
	}

	// Funció que crea una icona base per a un marker amb una imatge donada
	// @param icona El fitxer que conté la icona (amb path si cal) que volem posar al marker
	// @return Un string amb el HTML generat
	UTILS_GMAPS.crearIconaMarker = function( icona, autopista, sentit, pk ) {
		// Contruim la base de la icona
		var baseIcon = new GIcon();
		baseIcon.shadow = "";
		// La icona de la sortida, la fem de 20x20, i la resta, d 28x28
		if ( icona == UTILS_GMAPS.ICONA_SORTIDA ) {
			baseIcon.iconSize = new GSize(20, 20);
			baseIcon.shadowSize = new GSize(20, 20);
		}
		else {
			baseIcon.iconSize = new GSize(28, 28);
			baseIcon.shadowSize = new GSize(28, 28);
		}
		baseIcon.image = icona;

		// Si no és la icona de la sortida, busquem una posició (segons autopista, sentit i pk) per que quedi ben situada)
		var pointIcona = new GPoint( 0, 0 );
		var pointInfo = new GPoint( 0, 0 );
		if ( icona != UTILS_GMAPS.ICONA_SORTIDA ) {
			pointIcona = UTILS_GMAPS.getIconAnchorPos(autopista, sentit, pk );
			pointInfo = pointIcona;	// Al fer això la info apareix just a la coordenada orígen del desplaçament de la icona
		}
		// Posem les coordenades on es posarà la icona i la info		
		baseIcon.iconAnchor = pointIcona;
		baseIcon.infoWindowAnchor = pointInfo;
		baseIcon.infoShadowAnchor = pointInfo;

		return baseIcon;
	}

	// Desplaça la icona segons autopista, sentit i PK per tal que es representi al costat de l'autopista (a la banda que toqui).
	// @param autopista
	// @param sentit
	// @param pk
	// @return Un GPoint amb el desplaçament a fer sobre la icona o amb 0 desplaçament si no es coneix l'autopista
	UTILS_GMAPS.getIconAnchorPos = function( autopista, sentit, pk ) {
		// Valors X /Y pel desplaçament:
		// 	- X positiu desplaça icona cap a l'esquerra
		// 	- X negatiu desplaça icona cap a la dreta
		// 	- Y positiu desplaça icona cap a dalt
		// 	- Y negatiu desplaça icona cap a baix
		// Tamany icona: 28x28
		// Posició ancoratge icona: A dalt a l'esquerra. (això vol dir q la cantonada de dalt a l'esquerra correspón a la coordenada si deixem el iconAnchor a (0,0)
		// Ample nivell de servei: 6pixels x sentit
		// Suposant q la coordenada està al mig:
		//	- Per posar-la a la dreta: (-10,0);		// 10 pels 6 del nivell de servei + un petit marge
		//	- Per posar-la a la esquerra: (38,0);	// 38 = 10 + 28. 28 per l'ample de la icona. 10 pels 6 del nivell de servei + un petit marge
		//	- Per posar-la a dalt: (0,38);				// 38 = 10 + 28. 28 per l'ample de la icona. 10 pels 6 del nivell de servei + un petit marge
		//	- Per posar-la a baix: (0,-10);				// 10 pels 6 del nivell de servei + un petit marge
		var moureN = new GPoint(4,38);		// N = North = Amunt
		var moureE = new GPoint(-10,14);		// E = East = Dreta
		var moureS = new GPoint(4,-10);		// S = South = Avall
		var moureW = new GPoint(38,14);		// W = West = Esquerra
		var moureNE = new GPoint(-10,38);
		var moureSE = new GPoint(-4,4);
		var moureSW = new GPoint(-5,0);
		var moureNW = new GPoint(24,38);

		if ( autopista == "AP7" ) {
			// AP7. Fins a PK 70 movem dreta (sentit Nord) o esquerra (sentit Sud). A partir d'aquí movem dreta avall (sentit Nord) i esquerra amunt (sentit Sud).
			if ( pk <= 70000 ) {
				if ( sentit == "N" ) {
					return moureE;
				}
				else { //if ( sentit == "S" ) {	// Per defecte agafem sentit sud (és a dir, icones a dalt)
					return moureW;
				}
			}
			else {
				if ( sentit == "N" ) {
					return moureSE;
				}
				else { //if ( sentit == "S" ) { // Per defecte agafem sentit sud (és a dir, icones a dalt)
					return moureNW;
				}
			}
		}
		else if ( autopista == "AP2" ) {
			// AP2. Desplacem icona cap avall si va en sentit Mediterrani i cap a dalt si va en sentit Zaragoza
			if ( sentit == "M" ) {
				return moureS;
			}
			else { // if ( sentit == "Z" ) { // Per defecte agafem sentit Zaragoza (és a dir, icones a dalt)
				return moureN;
			}
		}
		else if ( autopista == "AP2A" ) {
			// AP2A. Papiol - Molins es considera direcció NORD i Molins - Papiol direcció SUD. Desplacem icona cap la dreta si va en sentit SUD i cap a l'esquerra si va en sentit NORD.
			if ( sentit == "N" ) {
				return moureW;
			}
			else { // if ( sentit == "S" ) { // Per defecte agafem sentit sud (és a dir, icones a l'esquerra)
				return moureE;
			}
		}
		else if ( autopista == "C31" ) {
			// C31. Desplacem icona cap a baix dreta si va en sentit Nord i cap a dalt esquerra si va en sentit Sud.
			if ( sentit == "S" ) {
				return moureNW;
			}
			else { // if ( sentit == "N" ) { // Per defecte agafem sentit nord (és a dir, icones a baix)
				return moureSE;
			}
		}
		else if ( autopista == "C32" ) {
			// C32. Desplacem icona cap a baix dreta si va en sentit Nord i cap a dalt esquerra si va en sentit Sud.
			if ( sentit == "S" ) {
				return moureNW;
			}
			else { // if ( sentit == "N" ) { // Per defecte agafem sentit nord (és a dir, icones a baix)
				return moureSE;
			}
		}
		else if ( autopista == "C33" ) {
			// C33. Desplacem icona cap la dreta si va en sentit Nord i cap a l'esquerra si va en sentit Sud.
			if ( sentit == "N" ) {
				return moureE;
			}
			else { // if ( sentit == "S" ) { // Per defecte agafem sentit sud (és a dir, icones a l'esquerra)
				return moureW;
			}
		}
		
		return new GPoint( 0, 0 );
	}


	// Funció que crea un marker sense click (però mostra info via tooltip
	// @param latlng Cooredenades (latitud, longitud) on s'ha de posar el marker
	// @param markerOptions les opcions del marker (icona, clickable, movible,...)
	// @param strTooltip El string a mostrar com a tooltip del marker
	// @param AtributsConcessio Els atributs de la concessió (per poder agafar el mapa i el necessari en algun submétode)
	// @return El marker
	UTILS_GMAPS.crearMarkerSenseClick = function( latlng, markerOptions, strTooltip, AtributsConcessio ) {
		var marker = new GMarker(latlng, markerOptions);
		// Si passem tooltip, el posem, i creem els seus events
		if ( strTooltip.length > 0 ) {
			marker.tooltip = "<div style='width:150px; background-color:#eeeeee; color:#888888; padding: 10px 5px; border: solid 1px #888888;'>" + strTooltip + "</div>";
	  	GEvent.addListener(marker,"mouseover", function() {
				UTILS_GMAPS.showTooltip(marker, AtributsConcessio);
	    });        
	    GEvent.addListener(marker,"mouseout", function() {
				AtributsConcessio.m_tooltip.style.visibility="hidden";
	    });        
		}
		return marker;
	}
	
	UTILS_GMAPS.crearMarkerSortida = function( latlng, markerOptions, strTooltip, AtributsConcessio, idAutopista, idSortida ) {
		var marker = new GMarker(latlng, markerOptions);
		// Si passem tooltip, el posem, i creem els seus events
		if ( strTooltip.length > 0 ) {
			marker.tooltip = "<div style='width:150px; background-color:#eeeeee; color:#888888; padding: 10px 5px; border: solid 1px #888888;'>" + strTooltip + "</div>";
	  	GEvent.addListener(marker,"mouseover", function() {
				UTILS_GMAPS.showTooltip(marker, AtributsConcessio);
	    });        
	    GEvent.addListener(marker,"mouseout", function() {
				AtributsConcessio.m_tooltip.style.visibility="hidden";
	    });        

	    var linia;
			// Posem l'event de click: obrir una info
			GEvent.addListener(marker,"click", function() {
				linia = UTILS_GMAPS.getLiniaIcona( marker, AtributsConcessio.map );
				AtributsConcessio.map.addOverlay( linia );
				AtributsConcessio.m_tooltip.style.visibility="hidden";	// Si apretem la icona, amaguem el tooltip
				var strImgSortida = "sortida_" + idAutopista + "_" + idSortida + ".png";
				// Proves. HARDCODEJAT NOM. TREURE!!!!!!!!!!!!
				if ( idSortida > 7 )
					//strImgSortida = "sortida_ap7_7b.png";
					strImgSortida = "sortida_ap7_7b.gif";
				else
					//strImgSortida = "sortida_ap7_7b_blau.png";
					strImgSortida = "sortida_ap7_7b_blau.gif";
				//var htmlSortida = "<center><img src='img/" + strImgSortida + "' width=150 height=200/></center>";
				var htmlSortida = "<center><img src='img/" + strImgSortida + "'/></center>";
				/*
				// Prova per tansparencia PNGs
				// Posem codi per arreglar la transparencia de PNG per les icones d les sortides
				var htmlSortida = "<!--[if lt IE 7]>";
				htmlSortida += "var arVersion = navigator.appVersion.split('MSIE');";
				htmlSortida += "var version = parseFloat(arVersion[1]);";
				htmlSortida += "if ((version >= 5.5) && (document.body.filters)) {";
				htmlSortida += "for(var i=0; i<document.images.length; i++) {";
				htmlSortida += "var img = document.images[i];";
				htmlSortida += "var imgName = img.src.toUpperCase();";
				htmlSortida += "if (imgName.substring(imgName.length-3, imgName.length) == 'PNG') {";
				htmlSortida += "var imgID = (img.id) ? 'id='' + img.id + '' ' : '';";
				htmlSortida += "var imgClass = (img.className) ? 'class='' + img.className + '' ' : '';";
				htmlSortida += "var imgTitle = (img.title) ? 'title='' + img.title + '' ' : 'title='' + img.alt + '' ';";
				htmlSortida += "var imgStyle = 'display:inline-block;' + img.style.cssText;";
				htmlSortida += "if (img.align == 'left') imgStyle = 'float:left;' + imgStyle;";
				htmlSortida += "if (img.align == 'right') imgStyle = 'float:right;' + imgStyle;";
				htmlSortida += "if (img.parentElement.href) imgStyle = 'cursor:hand;' + imgStyle;"
				htmlSortida += "var strNewHTML = '<span ' + imgID + imgClass + imgTitle";
				htmlSortida += "+ ' style=\'' + 'width:' + img.width + 'px; height:' + img.height + 'px;' + imgStyle + ';'";
				htmlSortida += "+ 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader'";
				htmlSortida += "+ '(src=\'' + img.src + '\', sizingMethod='scale');\'></span>';";
				htmlSortida += "img.outerHTML = strNewHTML";
				htmlSortida += "i = i-1;";
				htmlSortida += "}";
				htmlSortida += "}";
				htmlSortida += "}";
				htmlSortida += "<![endif]-->";
				htmlSortida += "<center><img src='img/" + strImgSortida + "'/></center>";
				// Fi prova per tansparencia PNGs
				*/
				marker.openInfoWindowHtml(htmlSortida);
			});

	    GEvent.addListener(marker,"infowindowclose", function() {
				AtributsConcessio.map.removeOverlay( linia );
	    });        
		}
		return marker;
	}

	// Funció que crea un marker i respon al event de click (si passem algun valor a htmlInfoGeneral)
	// @param latlng Cooredenades (latitud, longitud) on s'ha de posar el marker
	// @param markerOptions les opcions del marker (icona, clickable, movible,...)
	// @param strTooltip El string a mostrar com a tooltip del marker
	// @param htmlInfoGeneral Un string amb el html a mostrar a la pestanya general
	// @param htmlInfoExtra  Un string amb el html a mostrar a la pestanya addicional. Si es passa en blanc, no es mostra aquesta pestanya.
	// @param AtributsConcessio Els atributs de la concessió (per poder agafar el mapa i el necessari en algun submétode)
	// @return El marker
	UTILS_GMAPS.crearMarker = function( latlng, markerOptions, strTooltip, htmlInfoGeneral, htmlInfoExtra, AtributsConcessio ) {
		var marker = new GMarker(latlng, markerOptions);
		// Si passem tooltip, el posem, i creem els seus events
		if ( strTooltip.length > 0 ) {
			marker.tooltip = "<div style='width:150px; background-color:#eeeeee; color:#888888; padding: 10px 5px; border: solid 1px #888888;'>" + strTooltip + "</div>";
	  	GEvent.addListener(marker,"mouseover", function() {
				UTILS_GMAPS.showTooltip(marker, AtributsConcessio);
	    });        
	    GEvent.addListener(marker,"mouseout", function() {
				AtributsConcessio.m_tooltip.style.visibility="hidden";
	    });
	    // Dibuixem una línia de la icona a la seva coordenada real quan fem click a la icona.
	    // Si la icona té 2 ubicacions, les unim amb una linia
	    // Quan tanquem la finestra de info esborrem la línia (i tb la que uneix les 2 ubicacions, si l'hem dibuixat).
	    var linia;
	    var liniaUbicacions = null;
	    var liniaUbicacionsIcona = null;
	    GEvent.addListener(marker,"click", function() {
				linia = UTILS_GMAPS.getLiniaIcona( marker, AtributsConcessio.map );
				AtributsConcessio.map.addOverlay( linia );
				// Si la icona apretada té 2 ubicacions, fem una linia entre les 2
				for ( var iUbicacions = 0; iUbicacions < UTILS_GMAPS.AtributsClass.m_arrayInicidencies2Ubicacions.length; iUbicacions++ ) {
					var ubiDoble = UTILS_GMAPS.AtributsClass.m_arrayInicidencies2Ubicacions[iUbicacions];
					if ( ( ubiDoble.ubicacioInicial == latlng ) || ( ubiDoble.ubicacioFinal == latlng ) ) {
						liniaUbicacions = new GPolyline( [ubiDoble.ubicacioInicial, ubiDoble.ubicacioFinal], "#000000", 4 );
						AtributsConcessio.map.addOverlay( liniaUbicacions );
						// Dibuixem la línia que uneix la coordena de la incidéncia amb el punt on posem la icona de la incidencia
						var marker2 = null;
						if ( latlng == ubiDoble.ubicacioInicial )
							marker2 = UTILS_GMAPS.getMarkerCoordenada( ubiDoble.ubicacioFinal );
						else
							marker2 = UTILS_GMAPS.getMarkerCoordenada( ubiDoble.ubicacioInicial );
						if ( marker2 != null ) {
							liniaUbicacionsIcona = UTILS_GMAPS.getLiniaIcona( marker2, AtributsConcessio.map );
							AtributsConcessio.map.addOverlay( liniaUbicacionsIcona );
						}
					}
				}
	    });        
	    GEvent.addListener(marker,"infowindowclose", function() {
				AtributsConcessio.map.removeOverlay( linia );
				if ( liniaUbicacions != null )
					AtributsConcessio.map.removeOverlay( liniaUbicacions );
				if ( liniaUbicacionsIcona != null )
					AtributsConcessio.map.removeOverlay( liniaUbicacionsIcona );
	    });        
		}
	
		// Si passem alguna info en html, és que volem mostrar info al fer click, per tant afegim la funció de click.
		// Segons si volem mostrar info addicional o no, obrirem 2 tabs o només un.
		if ( htmlInfoGeneral.length > 0 ) {
			// Posem l'event de click: obrir una info
			GEvent.addListener(marker,"click", function() {
				AtributsConcessio.m_tooltip.style.visibility="hidden";	// Si apretem la icona, amaguem el tooltip
				if ( htmlInfoExtra.length > 0 ) {	// Si hem de posar info extra, necessitem 2 tabs
					var tabs = [];
					tabs.push(new GInfoWindowTab("General",htmlInfoGeneral));
					tabs.push(new GInfoWindowTab("Adicional",htmlInfoExtra));
					marker.openInfoWindowTabsHtml(tabs);
				}
				else {
					//alert( htmlInfoGeneral );
					marker.openInfoWindowHtml(htmlInfoGeneral);
				}
			});
		}
		
		return marker;
	}
	
	// Funció que busca un marker que estigui en les cooordenades passades. Només mira en els
	// markers de Meteorologia i d'Inicidencies.
	// @param latlng La coordenada en la que busquem el marker
	// @return El marker (un GMarker) que es troba en la coordenada passada o null si no s'ha trobat.
	UTILS_GMAPS.getMarkerCoordenada = function ( latlng ) {
		var marker = null;
		// Busquem la coordenada al array de casos de meteorologia
		marker = UTILS_GMAPS.getMarkerCoordenadaArray( latlng, UTILS_GMAPS.AtributsClass.m_arrayMeteo );
		if ( marker != null )
			return marker;
		// Busquem la coordenada al array de casos de incidencies
		marker = UTILS_GMAPS.getMarkerCoordenadaArray( latlng, UTILS_GMAPS.AtributsClass.m_arrayIncidencies );
		if ( marker != null )
			return marker;
		// Si arribem aquí, no hem trobat el marker. Retornem un null.
		return null;
	}
	
	// Funció que busca un marker an l'array passat que estigui en les cooordenades passades.
	// @param latlng La coordenada en la que busquem el marker
	// @param arrayMarkers L'array on busca el marker
	// @return El marker (un GMarker) que es troba en la coordenada passada o null si no s'ha trobat.
	UTILS_GMAPS.getMarkerCoordenadaArray = function ( latlng, arrayMarkers ) {
		for ( var iMarker = 0; iMarker < arrayMarkers.length; iMarker++ ) {
			if ( arrayMarkers[iMarker].getLatLng() == latlng )
				return arrayMarkers[iMarker];
		}
	}

	// Funció que mostra el tooltip
	// @param marker el marker (GMarker) sobre el que volem mostrar el tooltip
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	UTILS_GMAPS.showTooltip = function(marker, atributs) {
		/*
		// Aquesta codi mostra el tooltip sempre a dalt a la dreta, per tant a vegades queda tallat
		atributs.m_tooltip.innerHTML = marker.tooltip;
		var point=atributs.map.getCurrentMapType().getProjection().fromLatLngToPixel(atributs.map.fromDivPixelToLatLng(new GPoint(0,0),true),atributs.map.getZoom());
		var offset=atributs.map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),atributs.map.getZoom());
		var anchor=marker.getIcon().iconAnchor;
		var width=marker.getIcon().iconSize.width;
		var height=atributs.m_tooltip.clientHeight;
		var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x + width, offset.y - point.y -anchor.y -height)); 
		pos.apply(atributs.m_tooltip);
		atributs.m_tooltip.style.visibility="visible";
		*/
		// Aquest codi mostra el tooltip a dalt o avall, a la dreta o a la esquerra, segons on està la icona respecte el mapa
		atributs.m_tooltip.innerHTML = marker.tooltip; 
		// get point (x,y) 
		var point=atributs.map.getCurrentMapType().getProjection().fromLatLngToPixel(atributs.map.fromDivPixelToLatLng(new GPoint(0,0),true),atributs.map.getZoom()); 
		// pixel position of marker 
		var offset=atributs.map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),atributs.map.getZoom()); 
		var anchor=marker.getIcon().iconAnchor; 
		var width=marker.getIcon().iconSize.width; 
		var height=atributs.m_tooltip.clientHeight; 
		var x = offset.x - point.x - anchor.x + width; 
		var y = offset.y - point.y - anchor.y - height; 
		var center = atributs.map.getCenter();  // lat,lng 
		var centerPoint = atributs.map.getCurrentMapType().getProjection().fromLatLngToPixel(center,atributs.map.getZoom()); 
		// the following 3 variables need to be set for your personal settings 
    var mapWidth= 600; //  map width your map 
    var mapHeight=450; //  map height your map 
    var tooltipWidth=200; // for some reason need this with Firefox can't use tooltip.clientWidth; 
		if (offset.y - height - anchor.y < centerPoint.y - mapHeight/2 ) 
			y = y + height + anchor.y + 40; 
    if (offset.x + tooltipWidth - anchor.x + width > centerPoint.x + mapWidth/2) 
			x = x - tooltipWidth - width + 40; 
		var pos = new GControlPosition(G_ANCHOR_TOP_LEFT,  new GSize(x,y)); 
		pos.apply(atributs.m_tooltip); 
		atributs.m_tooltip.style.visibility="visible"; 
	}

	// Funció que parseja una estructura XML del típus <Logical> i retorna un objecte de tipus LogicalClass;
	// @param xml Un XML del típus <Logical>
	// @return Un objecte de tipus LogicalClass
	UTILS_GMAPS.parseLogical = function ( xml ) {
		var logicalObj = UTILS_GMAPS.LogicalClass;
		logicalObj.AtributsClass = UTILS_GMAPS.parseLogicalAtributs( xml );
		// Posem el comment en l'idioma q toca
		var xmlLogicalComments = xml.getElementsByTagName("Comments");
		if ( xmlLogicalComments != null ) {
			if ( xmlLogicalComments.length > 0 ) {
				logicalObj.AtributsClass.comment = UTILS_GMAPS.parseLogicalComments( xmlLogicalComments[0] );
			}
		}
		var xmlInitialLocation = xml.getElementsByTagName("InitialLocation");
		//logicalObj.InitialLocationClass = UTILS_GMAPS.parseLocation( xmlInitialLocation[0] );
			var initialLocation = UTILS_GMAPS.parseLocation( xmlInitialLocation[0] );
			logicalObj.InitialLocationClass.description = initialLocation.description;
			logicalObj.InitialLocationClass.highWayCode = initialLocation.highWayCode;
			logicalObj.InitialLocationClass.highWayName = initialLocation.highWayName;
			logicalObj.InitialLocationClass.accessName = initialLocation.accessName;
			logicalObj.InitialLocationClass.kmPoint = initialLocation.kmPoint;
			logicalObj.InitialLocationClass.direction = initialLocation.direction;
			logicalObj.InitialLocationClass.descDirection = initialLocation.descDirection;
			logicalObj.InitialLocationClass.networkKind = initialLocation.networkKind;
			logicalObj.InitialLocationClass.platformTollKind = initialLocation.platformTollKind;
			logicalObj.InitialLocationClass.roadLinkKind = initialLocation.roadLinkKind;
			logicalObj.InitialLocationClass.longitude = initialLocation.longitude;
			logicalObj.InitialLocationClass.latitude = initialLocation.latitude;
			logicalObj.InitialLocationClass.latlng = initialLocation.latlng;
			logicalObj.InitialLocationClass.levelNumber = initialLocation.levelNumber;
		// Si tenim final location, l'agafem.
		var xmlFinalLocation = xml.getElementsByTagName("FinalLocation");
		if ( xmlFinalLocation != null ) {
			if ( xmlFinalLocation.length > 0 ) {
				//logicalObj.FinalLocationClass = UTILS_GMAPS.parseLocation( xmlFinalLocation[0] );
					var finalLocation = UTILS_GMAPS.parseLocation( xmlFinalLocation[0] );
					logicalObj.FinalLocationClass.description = finalLocation.description;
					logicalObj.FinalLocationClass.highWayCode = finalLocation.highWayCode;
					logicalObj.FinalLocationClass.highWayName = finalLocation.highWayName;
					logicalObj.FinalLocationClass.accessName = finalLocation.accessName;
					logicalObj.FinalLocationClass.kmPoint = finalLocation.kmPoint;
					logicalObj.FinalLocationClass.direction = finalLocation.direction;
					logicalObj.FinalLocationClass.descDirection = finalLocation.descDirection;
					logicalObj.FinalLocationClass.networkKind = finalLocation.networkKind;
					logicalObj.FinalLocationClass.platformTollKind = finalLocation.platformTollKind;
					logicalObj.FinalLocationClass.roadLinkKind = finalLocation.roadLinkKind;
					logicalObj.FinalLocationClass.longitude = finalLocation.longitude;
					logicalObj.FinalLocationClass.latitude = finalLocation.latitude;
					logicalObj.FinalLocationClass.latlng = finalLocation.latlng;
					logicalObj.FinalLocationClass.levelNumber = initialLocation.levelNumber;
			}
			else {
				logicalObj.FinalLocationClass.latlng = null;
			}
		}
		else {
			logicalObj.FinalLocationClass.latlng = null;
		}
		var laneAf = xml.getElementsByTagName("LaneAffectation");
		logicalObj.LaneAfClass = UTILS_GMAPS.parseLaneAffectation( laneAf[0] );
		return logicalObj;
	}

	// Funció que parseja els atributs d'una estructura XML del típus <Logical> i retorna un objecte de tipus LogicalAtributsClass;
	// @param xml Un XML del típus <Logical>
	// @return Un objecte de tipus LogicalAtributsClass
	UTILS_GMAPS.parseLogicalAtributs = function ( xml ) {
		var logicalAtributs = UTILS_GMAPS.LogicalAtributsClass;
		logicalAtributs.code = xml.getAttribute("code");
		logicalAtributs.creationDate = UTILS_ABERTIS.parseData( xml.getAttribute("CreationDate") );
		logicalAtributs.updateDate = UTILS_ABERTIS.parseData( xml.getAttribute("UpdateDate") );
		logicalAtributs.comment = xml.getAttribute("Comment");
		logicalAtributs.locationComment = xml.getAttribute("LocationComment");
		logicalAtributs.place = xml.getAttribute("Place");
		
		return logicalAtributs;
	}
	
	// Funció que parseja els comentaris d'una estructura XML del típus <Comment> i retorna un string amb el comentari en l'idioma de la pàgina
	// @param xml Un XML del típus <Comments>
	// @return Un string amb el comentari en l'idioma de la pàgina o "" si no hi ha l'idioma (no ha de passar).
	UTILS_GMAPS.parseLogicalComments = function ( xml ) {
		// Agafem l'idioma q tenim configurat
		var idioma = UTILS_GMAPS.getIdiomaActual();
		if ( idioma == UTILS_GMAPS.IDIOMA.CAT )
			idioma = "CAT";
		else if ( idioma == UTILS_GMAPS.IDIOMA.CAS )
			idioma = "ESP";
		else if ( idioma == UTILS_GMAPS.IDIOMA.ENG )
			idioma = "ENG";
		else if ( idioma == UTILS_GMAPS.IDIOMA.FR )
			idioma = "FR";
		else	// Per defecte posem castellà. Però no hauria d'agafar mai el valor per defecte.
			idioma = "ESP";
		// Parsegem els comments per agafar el q toca (el que té configurat a la pàgina).
		var xmlComments = xml.getElementsByTagName("Comment");
		for ( idxComment = 0; idxComment < xmlComments.length; idxComment++ ) {
			var lang = xmlComments[idxComment].getAttribute("lang");
			if ( lang == idioma ) {
				return xmlComments[idxComment].getAttribute("desc");
			}
		}
		return "";	// No hem trobat l'idioma. Retornem blanc. No ha de passar!!!!
	}
	
	// Funció que parseja una estructura XML del típus <Location> i retorna un objecte de tipus LocationClass;
	// @param xml Un XML del típus <Location>
	// @return Un objecte de tipus LocationClass
	UTILS_GMAPS.parseLocation = function ( xml ) {
		var locationObj = UTILS_GMAPS.LocationClass;
		locationObj.description = xml.getAttribute("Description");
		locationObj.highWayCode = xml.getAttribute("HighWayCode");
		locationObj.highWayName = xml.getAttribute("HighWayName");
		locationObj.accessName = xml.getAttribute("AccessName");
		locationObj.kmPoint = xml.getAttribute("KmPoint");
		locationObj.direction = xml.getAttribute("Direction");
		locationObj.descDirection = xml.getAttribute("DescDirection");
		locationObj.networkKind = xml.getAttribute("NetworkKind");
		locationObj.platformTollKind = xml.getAttribute("PlatformTollKind");
		locationObj.roadLinkKind = xml.getAttribute("RoadLinkKind");
		locationObj.longitude = xml.getAttribute("Longitude");
		locationObj.latitude = xml.getAttribute("Latitude");
		locationObj.latlng = new GLatLng(parseFloat(locationObj.latitude), parseFloat(locationObj.longitude));
		locationObj.levelNumber = xml.getAttribute("LevelNumber");
		
		// Si no hem recuperat el sentit, l'agafem a partir de la direcció
		if ( locationObj.descDirection == null )
			locationObj.descDirection = UTILS_GMAPS.getSentitFromDirection( locationObj.highWayName, locationObj.direction );

		return locationObj ;
	}
	
	// Funció que posa el sentit a partir de la direcció (inc o dec) i la autopista.
	// Si es passa el camp descDirection ja no fa falta.
	// @param highwayName El nom de l'autopista.
	// @param direction La direcció dels kilometres (INCrement o DECrement).
	// @return El sentit (S/N/M/Z) corresponent a l'autopista i direcció passades o "" si no s'haa trobat algun dels 2 paràmetres
	UTILS_GMAPS.getSentitFromDirection = function( highwayName, direction ) {
		if ( highwayName == "AP7" ) {
			if ( direction == "Inc" )
				return "S";
			else if ( direction == "Desc" )
				return "N";
			else {
				//alert ( "AP7. DIRECTION: " + direction );
				return "";
			}
		}
		else if ( highwayName == "AP2" ) {
			if ( direction == "Inc" )
				return "M";
			else if ( direction == "Desc" )
				return "Z";
			else {
				//alert ( "AP2. DIRECTION: " + direction );
				return "";
			}
		}
		else if ( ( highwayName == "AP2A" ) || ( highwayName == "C31" ) || ( highwayName == "C32" ) || ( highwayName == "C33" ) ) {
			if ( direction == "Inc" )
				return "N";
			else if ( direction == "Desc" )
				return "S";
			else {
				//alert ( "AP2A o C31 o C32 o C33. DIRECTION: " + direction );
				return "";
			}
		}
		else {
			//alert ( "AUTOPSITA: " + highwayName + ". DIRECTION: " + direction );
			return "";
		}
	}

	// Funció que parseja una estructura XML del típus <LaneAffectation> i retorna un objecte de tipus LaneAfClass;
	// @param xml Un XML del típus <LaneAffectation>
	// @return Un objecte de tipus LaneAfClass
	UTILS_GMAPS.parseLaneAffectation = function( xml ) {
		var laneAfObject = UTILS_GMAPS.LaneAfClass;
		// Si no tenim dades d'afectació, posem la descripció i retornem
		if ( xml == null ) {
			laneAfObject.desc = "";//UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.SIN_AFEC );
			return laneAfObject;
		}

		// Comprovem les dades bàsiques (voral, total, parcial
		if ( xml.getAttribute("HardShoulder") == 'True' ) {
			laneAfObject.hardShoulder = "Sí";
		}
		else {
			laneAfObject.hardShoulder = "No";
		}
		if ( xml.getAttribute("Total") == 'True' ) {
			laneAfObject.total = "Sí";
		}
		else {
			laneAfObject.total = "No";
		}
		if ( xml.getAttribute("Partial") == 'True' ) {
			laneAfObject.partial = "Sí";
		}
		else {
			laneAfObject.partial = "No";
		}

		// Mirem si tenim alguna afectació de carrils
		var bAfectacio = false;
		laneAfObject.carrilesAfectados = "";
		var lanes = xml.getElementsByTagName("Lane");
		var iLane = 0;
		var numLanes = xml.getAttribute("NumLanes");
		// DMR. Posem aquest IF per assegurar que llegim bé el NumLanes. Si no és així, posem els carrils que rebem (com estava abans).
		if ( (numLanes == null) || (numLanes >6) )
			numLanes = lanes.length;
		for ( iLane = 0; iLane < numLanes; iLane++ ) {
			if ( lanes[iLane].getAttribute("Affected") == 'True') {
				bAfectacio = true;
				if ( laneAfObject.carrilesAfectados.length == "" ) {
					laneAfObject.carrilesAfectados = "Carril " + lanes[iLane].getAttribute("Number");
				}
				else {
					laneAfObject.carrilesAfectados += ", carril " + lanes[iLane].getAttribute("Number");
				}
			}
		}
		if ( laneAfObject.carrilesAfectados == "" ) {
			laneAfObject.carrilesAfectados = "Ninguno";
		}

		// Posem un text descriptiu de l'afectació en una sola línia
		laneAfObject.desc = "";
		if ( xml.getAttribute("Total") == 'True' )	// Si tenim afectació total, és autopista tallada
			laneAfObject.desc = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.AUTO_CORTADA );
		else {
			if ( bAfectacio == true ) {	// Si tenim algun(s) carril(s) afectat(s), posem la info
				// Tenim afectació, la posem en format text descriptiu
				/*
				for ( iLane = 0; iLane < numLanes; iLane++ ) {
					if ( lanes[iLane].getAttribute("Affected") == 'True') {
						if ( iLane == 0 )
							laneAfObject.desc = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_DERECHO );
						else if ( numLanes == iLane+1 ) {
								if ( laneAfObject.desc.length == "" )
									laneAfObject.desc = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_IZQUIERDO );
								else
									laneAfObject.desc += ", " + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_IZQUIERDO ).toLowerCase();
						}
						else {
								if ( laneAfObject.desc.length == "" )
									laneAfObject.desc = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CENTRAL );
								else
									laneAfObject.desc += ", " + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CENTRAL ).toLowerCase();
						}
					}
				}
				*/
				laneAfObject.desc = UTILS_GMAPS.getDescTextualAfectacio(numLanes, lanes);
			}
			else {	// Si no tenim cap carril afectat, és sense afectació (encara q afecti al voral).
				//laneAfObject.desc = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.SIN_AFEC );
				laneAfObject.desc = "";
			}
		}
		return laneAfObject;
	}

	UTILS_GMAPS.getDescTextualAfectacio = function(numLanes, lanes) {
		// EL FRANCÉS ESTÀ PENDENT DE FER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
		var strReturn = "";
		// El tram no té cap carril --------------------------------------------------------------------
		if ( numLanes == 0 )	{ // No ha d passar
			strReturn = "";
		}
		// El tram té 1 carril -------------------------------------------------------------------------
		else if ( numLanes == 1 )	{	// No ha d pasasr (x q no hi ha ca tram amb un sol carril)
			if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.ENG ) {
				strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_DERECHO ) + " " +
					UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRIL );
			}
			else {
				strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRIL ) + " " +
					UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_DERECHO );
			}
		}
		// El tram té 2 carrils ------------------------------------------------------------------------
		else if ( numLanes == 2 )	{
			if ( ( lanes[0].getAttribute("Affected") == 'True') && ( lanes[1].getAttribute("Affected") == 'True') ) {
				if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.ENG ) {
					strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_DERECHO ) + " " +
						UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_AND ) + " " +
						UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_IZQUIERDO ) + " " +
						UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRILS );
				}
				else {
					if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.CAS ) {
						// En castellà, és "derecho E izquierdo", no "derecho Y izquierdo"
						strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRILS ) + " " +
							UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_DERECHO ) + " " +
							"e " +
							UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_IZQUIERDO );
					}
					else {
						strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRILS ) + " " +
							UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_DERECHO ) + " " +
							UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_AND ) + " " +
							UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_IZQUIERDO );
					}
				}
			}
			else if ( lanes[0].getAttribute("Affected") == 'True') {
				if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.ENG ) {
					strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_DERECHO ) + " " +
						UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRIL );
				}
				else {
					strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRIL ) + " " +
						UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_DERECHO );
				}
			}
			else { //if ( lanes[1].getAttribute("Affected") == 'True') {
				if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.ENG ) {
					strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_IZQUIERDO ) + " " +
						UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRIL );
				}
				else {
					strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRIL ) + " " +
						UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_IZQUIERDO );
				}
			}
		}
		// El tram té >= 3 carrils ----------------------------------------------------------------------
		else { // if ( numLanes >= 3 )	{
			// Mirem quans carrils tenim afectats
			var iNumAfectats = 0;
			for ( iLane = 0; iLane < numLanes; iLane++ ) {
				if ( lanes[iLane].getAttribute("Affected") == 'True')
					iNumAfectats++;
			}
			if ( iNumAfectats > 1 ) {
				// Tenim + d 1 carril afectat! Mirem quins són.
				var textCarrilDret = "";
				var textCarrilCentral = "";
				var textCarrilEsquerra = "";
				// Mirem el carril dret (el primer)
				if ( lanes[0].getAttribute("Affected") == 'True') {
					textCarrilDret = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_DERECHO );
				}
				// Mirem el carril esquerra (l'últim)
				if ( lanes[numLanes-1].getAttribute("Affected") == 'True') {
					textCarrilEsquerra = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_IZQUIERDO );
				}
				// Mirem els centrals
				if ( numLanes == 3 ) {
					if ( lanes[1].getAttribute("Affected") == 'True') {
						textCarrilCentral = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CENTRAL );
					}
				}
				else {
					var numCentralsAfectats = 0;
					for ( iLane = 1; iLane < numLanes-1; iLane++ ) {
						if ( lanes[iLane].getAttribute("Affected") == 'True') {
							numCentralsAfectats++;
						}
					}
					if ( numCentralsAfectats == 0 ) {
						textCarrilCentral = "";
					}
					else if ( numCentralsAfectats == 1 ) {
						textCarrilCentral = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CENTRAL );
					}
					else	{ //if ( numCentralsAfectats > 1 ) {
						textCarrilCentral = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CENTRALES );
					}
				}
				// Construim el text dels carrils. Hem d concatenar dret + central + esquerra, posant "," o "i" entre ells (segons toqui).
				var descPosar = "";
				// Posem el carril dret
				descPosar += textCarrilDret;
				// Posem el carril central (el seu text, pot ser 1 o 3 centrals, ja estarà en singular o plural, segons toqui)
				if ( descPosar.length > 0 ) {	// si ja teniem text, hem de poasr una ", " o " i " abans del central
					if ( textCarrilEsquerra.length > 0 ) {	// Si tenim esquerra, posem un ", "
						descPosar += ", ";
					}
					else {	// Si no, posem un " i "
						descPosar += " " + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_AND ) + " ";
					}
				}
				descPosar += textCarrilCentral;
				// Posem el carril esquerra
				if ( ( descPosar.length > 0 ) && ( textCarrilEsquerra.length > 0 ) ) {
					// En castellà, és "derecho E izquierdo", no "derecho Y izquierdo"
					if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.CAS ) {
						descPosar += " e ";
				}
					else {
						descPosar += " " + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_AND ) + " ";
					}
				}
				descPosar += textCarrilEsquerra;
				// Posem el text de carrils + la descripció dels carrils en l'ordre q toqui (segons l'idioma).
				if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.ENG ) {
					strReturn = descPosar + " " +
						UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRILS );
				}
				else {
					strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRILS ) + " " +
						descPosar;
				}
			}
			else {	// Tenim >= 3 carrils. Però només 1 afecat. Mirem quin.
				// Mirem si tenim afectat el 1er (dret)
				if ( lanes[0].getAttribute("Affected") == 'True'  ) {
					if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.ENG ) {
						strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_DERECHO ) + " " +
							UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRIL );
					}
					else {
						strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRIL ) + " " +
							UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_DERECHO );
					}
				}
				// Mirem si tenim afectat l'últim (esquerra)
				else if ( lanes[numLanes-1].getAttribute("Affected") == 'True' ) {
					if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.ENG ) {
						strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_IZQUIERDO ) + " " +
							UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRIL );
					}
					else {
						strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRIL ) + " " +
							UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_IZQUIERDO );
					}
				}
				// Tenim afectat algun dels centrals
				else { 
					if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.ENG ) {
						strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CENTRAL ) + " " +
							UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CARRIL );
					}
					else {
						strReturn = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_CENTRAL ) + " " +
							UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAR_IZQUIERDO );
					}
				}
			}
		}
		// Posem la primera lletra en majúscula!
		if ( strReturn.length > 0 ) {
			var primera = strReturn.charAt(0);
			var rest = strReturn.substring(1);
			strReturn = primera.toUpperCase() + rest;
		}
		return strReturn;
	}
	
	// Funció que parseja una estructura XML del típus <Equipment> i retorna un objecte de tipus EquipmentClass;
	// @param xml Un XML del típus <Equipment>
	// @return Un objecte de tipus EquipmentClass
	UTILS_GMAPS.parseEquipment = function( xml ) {
		var equipmentObj = UTILS_GMAPS.EquipmentClass;
		equipmentObj.AtributsClass = null;
		equipmentObj.CameraClass = null;
		equipmentObj.BoardClass = null;
		equipmentObj.LocationClass = null;
		
		// Parsegem els atributs
		equipmentObj.AtributsClass = UTILS_GMAPS.parseEquipmentAtributs( xml );
		
		// Parsegem les dades de panell
		var xmlBoard = xml.getElementsByTagName("Board");
		if ( xmlBoard.length > 0 ) {
			equipmentObj.BoardClass = UTILS_GMAPS.parseBoard( xmlBoard[0] );
		}
		else {
			equipmentObj.BoardClass = null;
		}
		
		// Parsegem les dades de càmera
		var xmlCamera = xml.getElementsByTagName("Camera");
		if ( xmlCamera.length > 0 ) {
			equipmentObj.CameraClass = UTILS_GMAPS.parseCamera( xmlCamera[0] );
		}
		else {
			equipmentObj.CameraClass = null;
		}
		
		// Parsegem les dades de les Estacions Meteorològiques
		var xmlEstMet = xml.getElementsByTagName("WeatherStation");
		if ( xmlEstMet.length > 0 ) {
			equipmentObj.EstMetClass = UTILS_GMAPS.parseEstMet( xmlEstMet[0] );
		}
		else {
			equipmentObj.EstMetClass = null;
		}
		
		// Parsegem les dades de location
		var xmlLocation = xml.getElementsByTagName("Location");
		equipmentObj.LocationClass = UTILS_GMAPS.parseLocation( xmlLocation[0] );
		
		return equipmentObj;
	}

	// Funció que parseja els atributs d'una estructura XML del típus <Equipment> i retorna un objecte de tipus EquipmentAtributsClass;
	// @param xml Un XML del típus <Equipment>
	// @return Un objecte de tipus EquipmentAtributsClass
	UTILS_GMAPS.parseEquipmentAtributs = function( xml ) {
		var equipmentAtributs = UTILS_GMAPS.EquipmentAtributsClass;
		equipmentAtributs.code = xml.getAttribute("code");
		equipmentAtributs.active = xml.getAttribute("Active");
		equipmentAtributs.updateDate = UTILS_ABERTIS.parseData( xml.getAttribute("UpdateDate") );
		return equipmentAtributs;
	}

	// Funció que parseja una estructura XML del típus <Board> i retorna un objecte de tipus BoardClass;
	// @param xml Un XML del típus <Board>
	// @return Un objecte de tipus BoardClass
	UTILS_GMAPS.parseBoard = function( xml ) {
		var boardObj = UTILS_GMAPS.BoardClass;
		// Agafem els atributs de panell
		boardObj.Atributs.name = xml.getAttribute("Name");
		boardObj.Atributs.number = xml.getAttribute("Number");
		boardObj.Atributs.type = xml.getAttribute("Type");
		boardObj.Atributs.fileNumber = xml.getAttribute("FileNumber");
		boardObj.Atributs.columnNumber = xml.getAttribute("ColumnNumber");
		boardObj.Atributs.iconPosition = xml.getAttribute("IconPosition");
		boardObj.Atributs.isActive = xml.getAttribute("IsActive");
		boardObj.Atributs.warningState = xml.getAttribute("WarningState");
		boardObj.Atributs.publish = xml.getAttribute("Publish");
		// Agafem el missatge
		var xmlMsg = xml.getElementsByTagName("Message");
		if ( xmlMsg.length > 0 ) {
			// Agafem els atributs del missatge 1
			boardObj.Message1.number = xmlMsg[0].getAttribute("Number");
			boardObj.Message1.leftIcon = xmlMsg[0].getAttribute("LeftIcon");
			boardObj.Message1.rightIcon = xmlMsg[0].getAttribute("RightIcon");
			boardObj.Message1.difference = xmlMsg[0].getAttribute("Difference");
			// Agafem el missatge 1 en sí. Per IE fem servir TEXT. Per altres, TEXTCONTENT
			if ( ieTest )
				boardObj.Message1.message = xmlMsg[0].text;
			else
				boardObj.Message1.message = xmlMsg[0].textContent;
			// Si tenim 2 missatges (alternats), agafem el 2on.
			if ( xmlMsg.length > 1 ) {
				// Agafem els atributs del missatge 2
				boardObj.Message2.number = xmlMsg[1].getAttribute("Number");
				boardObj.Message2.leftIcon = xmlMsg[1].getAttribute("LeftIcon");
				boardObj.Message2.rightIcon = xmlMsg[1].getAttribute("RightIcon");
				boardObj.Message2.difference = xmlMsg[1].getAttribute("Difference");
				// Agafem el missatge 2 en sí. Per IE fem servir TEXT. Per altres, TEXTCONTENT
				if ( ieTest )
					boardObj.Message2.message = xmlMsg[1].text;
				else
					boardObj.Message2.message = xmlMsg[1].textContent;
			}
			else {
				boardObj.Message2.number = -1;
			}
		}
		else {
			boardObj.Message1.number = -1;
			boardObj.Message2.number = -1;
		}
		return boardObj;
	}

	// Funció que parseja una estructura XML del típus <Camera> i retorna un objecte de tipus CameraClass
	// @param xml Un XML del típus <Camera>
	// @return Un objecte de tipus CameraClass
	UTILS_GMAPS.parseCamera = function( xml ) {
		var cameraObj = UTILS_GMAPS.CameraClass;
		// Agafem els atributs de càmara
		cameraObj.Atributs.name = xml.getAttribute("Name");
		cameraObj.Atributs.kind = xml.getAttribute("Kind");
		cameraObj.Atributs.number = xml.getAttribute("Number");
		cameraObj.Atributs.legend = xml.getAttribute("Legend");
		cameraObj.Atributs.url = xml.getAttribute("url");
		cameraObj.Atributs.file  = xml.getAttribute("File");
		if ( !cameraObj.Atributs.file )	// Si no hem trobat el nom del fitxer, podem posar un per defecte. PENDENT ARREGLAR!!!
			cameraObj.Atributs.file = "test.flv";
		var xmlCoverZones = xml.getElementsByTagName("CameraCoverZones");
		if (xmlCoverZones.length > 0 ) {
			var xmlZone = xmlCoverZones[0].getElementsByTagName("Zone");
			for ( var i = 0; i < xmlZone.length; i++ ) {
				var zone = UTILS_GMAPS.CameraClass.CoverZones.Zone;
				zone.preposition = xmlZone[i].getAttribute("Preposition");
				zone.description = xmlZone[i].getAttribute("Description");
				zone.highWayCode = xmlZone[i].getAttribute("HighWayCode");
				zone.initialKm = xmlZone[i].getAttribute("InitialKm");
				zone.finalKm = xmlZone[i].getAttribute("FinalKm");
				cameraObj.CoverZones.zones.push( zone );
			}
		}
		return cameraObj;
	}

	// Funció que parseja una estructura XML del típus <EstMet> i retorna un objecte de tipus EstMetClass
	// @param xml Un XML del típus <EstMet>
	// @return Un objecte de tipus EstMetClass
	UTILS_GMAPS.parseEstMet = function( xml ) {
		//alert( "UTILS_GMAPS.parseEstMet" );
		var estMetObj = UTILS_GMAPS.EstMetClass;
		estMetObj.Atributs.nom = xml.getAttribute("Name");
		estMetObj.Atributs.temp = xml.getAttribute("AirTemperature");
		estMetObj.Atributs.vent = xml.getAttribute("WindVelocity");
		estMetObj.Atributs.plujaHora = xml.getAttribute("RainLastHour");
		estMetObj.Atributs.plujaDia = xml.getAttribute("RainLast24Hours");
		return estMetObj;
	}

	// Funció que controla els límits del mapa. Si la posició està fora del marge, torna enrera
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estrem treballant.
	UTILS_GMAPS.checkBounds = function( atributs ) {
		// Comprovem les coordendes i retornem si són OK
		if (atributs.coordenadesPermeses.contains(atributs.map.getCenter())) {
			return;
		}
		// Cordenada no permesa. Busquem el punt més proper i ens hi movem.
		var C = atributs.map.getCenter();
		var X = C.lng();
		var Y = C.lat();

		var AmaxX = atributs.coordenadesPermeses.getNorthEast().lng();
		var AmaxY = atributs.coordenadesPermeses.getNorthEast().lat();
		var AminX = atributs.coordenadesPermeses.getSouthWest().lng();
		var AminY = atributs.coordenadesPermeses.getSouthWest().lat();
		
		if (X < AminX) {X = AminX;}
		if (X > AmaxX) {X = AmaxX;}
		if (Y < AminY) {Y = AminY;}
		if (Y > AmaxY) {Y = AmaxY;}
		atributs.map.setCenter(new GLatLng(Y,X));
	}

	// Funció que crea un Pop Up amb la llegenda
	UTILS_GMAPS.llegenda = function()	{
		var pagina = self.location.href.match( /\/([^/]+)$/ )[1];
		var llegendaFile = UTILS_GMAPS.getLlegendaFile();
		var llegendaButton = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.LLEGENDA );
		var popupLlegenda=window.open(llegendaFile,llegendaButton,'height=350,width=570,resizable=no');
		// Forcem el focus (per si la teniem oberta però no a primer plà i la volem tornar a mostrar.
		popupLlegenda.focus();
	}

	UTILS_GMAPS.getLlegendaFile = function() {
		var idioma = UTILS_GMAPS.getIdiomaActual();
		if ( idioma == UTILS_GMAPS.IDIOMA.CAT ) {
			return "llegenda_cat.htm";
		}
		else if ( idioma == UTILS_GMAPS.IDIOMA.CAS ) {
			return "llegenda_cas.htm";
		}
		else if ( idioma == UTILS_GMAPS.IDIOMA.ENG ) {
			return "llegenda_eng.htm";
		}
		else if ( idioma == UTILS_GMAPS.IDIOMA.FR ) {
			return "llegenda_fr.htm";
		}
		else {
			return "llegenda_cas.htm";	// Per defecte retornem el fitxer de la llegenda en castellà
		}
	}

	//---------- Funcions per afegir el botó de la llegenda ----------
	LlegendaControl.prototype = new GControl();
	function LlegendaControl() {
	}
	LlegendaControl.prototype.initialize = function(map) {
		var container = document.createElement("div");
		var zoomInDiv = document.createElement("div");
		this.setButtonStyle_(zoomInDiv);
		container.appendChild(zoomInDiv);
		var llegendaButton = UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.LLEGENDA );
		zoomInDiv.appendChild(document.createTextNode(llegendaButton));
		GEvent.addDomListener(zoomInDiv, "click", function() {
			UTILS_GMAPS.llegenda();
		});
		LlegendaControl.prototype.getDefaultPosition = function() {
			return new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(5, 2));
		}
		map.getContainer().appendChild(container);
		return container;
	}
	LlegendaControl.prototype.getDefaultPosition = function() {
		return new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(5, 2));
	}
	LlegendaControl.prototype.setButtonStyle_ = function(button) {
		//button.style.textDecoration = "underline";
		button.style.color = "#888888";
		button.style.backgroundColor = "white";
		button.style.font = "small Arial";
		button.style.border = "1px solid black";
		button.style.padding = "2px";
		button.style.marginBottom = "3px";
		button.style.textAlign = "center";
		button.style.width = "6em";
		button.style.cursor = "pointer";
	}
	
	// Funció que inicialitza el mapa
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió a inicialitzar.
	UTILS_GMAPS.inicialitzarMapa = function( atributs ) {
			//---------- Configuració del Mapa ----------
			// Creem el mapa
			atributs.map = new GMap2(document.getElementById("map"));
			
			// Sobreescribim els métodes getMinimumResolution() i getMaximumResolution() per tots els típus de mapes
			var mapTypes = atributs.map.getMapTypes();	// Llista de mapes
			for (var i=0; i<mapTypes.length; i++) {
				mapTypes[i].getMinimumResolution = function() {return UTILS_GMAPS.CONSTANTS_CLASS.MIN_ZOOM;}
				mapTypes[i].getMaximumResolution = function() {return UTILS_GMAPS.CONSTANTS_CLASS.MAX_ZOOM;}
			}
			
			// Posem el control de zoom/pan que volem
			atributs.map.addControl(new GLargeMapControl());	// Posa el control de Mapa gran (zoom, pan, slide) a dalt a l'esquerra.

			// Activem q la roda del mouse faci zoom
			atributs.map.enableScrollWheelZoom();
			
			// Posició inicial del mapa
			atributs.map.setCenter(new GLatLng(atributs.latIni, atributs.lngIni), atributs.zoomIni);	
			
			// Posem el transit de Google (per França)
			// NOTA: A 25-3-09 encara no es veu (integrat aquí, des de Google Maps sí). En canvi, si trec els
			// límits del mapa, al arribar a UK si que es veu. Se suposa que estarà disponible molt aviat.
      var trafficOptions = {incidents:true};
			var trafficInfo = new GTrafficOverlay(trafficOptions);
		  atributs.map.addOverlay(trafficInfo);

			// Inicialitzem el Tooltip
			atributs.m_tooltip = document.createElement("div");
			atributs.map.getPane(G_MAP_FLOAT_PANE).appendChild(atributs.m_tooltip);
			atributs.m_tooltip.style.visibility="hidden";

			// Posem el botó de la llegenda
			atributs.map.addControl(new LlegendaControl());
			
			// Dibuixem un quadrat mig transparent sobre el mapa per esmorteïr-lo
			var coordenades = new GLatLngBounds(new GLatLng(35.59722324495565,-6.0819091796875), new GLatLng(47.27720532212024, 8.39453125));
			var polygon = new GPolygon([
				new GLatLng(coordenades.getNorthEast().lat(), coordenades.getNorthEast().lng()),
				new GLatLng(coordenades.getSouthWest().lat(), coordenades.getNorthEast().lng()),
				new GLatLng(coordenades.getSouthWest().lat(), coordenades.getSouthWest().lng()),
				new GLatLng(coordenades.getNorthEast().lat(), coordenades.getSouthWest().lng())],
				"#ffffff",	// Color de la línia
				1,					// Gruix de la línia al voltant del polígon
				1,					// Pintar el polígon per dins
				//"#ffffff",	// Color de dins del polígon
				//0.4);				// Factor de transparéncia
				//"#dddddd",	// Color de dins del polígon
				//0.4);				// Factor de transparéncia
				"#cccccc",	// Color de dins del polígon
				0.3);				// Factor de transparéncia
				//"#33ccff",	// Color de dins del polígon
				//0.2);				// Factor de transparéncia
				//"#ccffff",	// Color de dins del polígon
				//0.4);				// Factor de transparéncia
			// Posem un listener al polígon per tal que es tanquin les finestres d'info al apretar-lo (com passa al apretar sobre el mapa)
			GEvent.addListener(polygon,"click", function() {
				atributs.map.closeInfoWindow();
			});
			atributs.map.addOverlay(polygon);
			
			// Inicialitzem les variables que indiquen que encara no hem descarega les dades del XML
			atributs.m_bLogicsCarregatsAcesa = false;
			atributs.m_bEquipsCarregatsAcesa = false;
			atributs.m_bLogicsCarregatsAucat = false;
			atributs.m_bEquipsCarregatsAucat = false;
	}

	// Funcions que parsegen subjectes lògics (tag <Logical>) del fitxer xml passat i posa markers per cada un d'ells
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	// @param urlFile La URL o el fitxer (amb el path si cal) que conté els SL a parsejar
	// Aquesta funció utilitza les crides HTTP per agafar el XML. Només funciona amb una URL.
	UTILS_GMAPS.parsejarSL_http = function( atributs, urlFile ) {
		var httpRequest;
		if (window.XMLHttpRequest) { // Mozilla, Safari, ...
			httpRequest = new XMLHttpRequest();
			if (httpRequest.overrideMimeType) {
				httpRequest.overrideMimeType('text/xml');
			}
		} 
		else if (window.ActiveXObject) { // IE
			try {
				httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
			} 
			catch (e) {
				try {
					httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
				} 
				catch (e) {}
			}
		}
			
		if (!httpRequest) {
			alert('Giving up :( Cannot create an XMLHTTP instance');
			return false;
		}
		httpRequest.onreadystatechange = function() { UTILS_GMAPS.parseSL(atributs, httpRequest); };
		httpRequest.open('GET', urlFile, true);
		httpRequest.setRequestHeader("Accept-Charset", "ISO-8859-1;UTF-8");
		httpRequest.setRequestHeader("Accept-Encoding", "gzip, deflate");
		httpRequest.setRequestHeader("Accept-Language", "es");
		httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		httpRequest.send('');
	}

	// Funció auxiliar de les crides HTTP.
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	// @param httpRequest La resposta de HTTP
	UTILS_GMAPS.parseSL = function (atributs, httpRequest) {
		if (httpRequest.readyState == 4) {
			if (httpRequest.status == 200) {
				alert("httpRequest.responseText:\n" + httpRequest.responseText);
				alert("httpRequest.responseXML:\n" + httpRequest.responseXML);
				//alert( "httpRequest.getAllResponseHeaders:\n" + httpRequest.getAllResponseHeaders() );
				//alert( "httpRequest.getResponseHeader Content-Type:\n" + httpRequest.getResponseHeader("Content-Type") );
				//alert( "httpRequest.getResponseHeader charset:\n" + httpRequest.getResponseHeader("Charset") );

				// Parsegem el fitxer XML
				//UTILS_GMAPS.parsejarSL_XML( atributs, httpRequest.responseText );
				var encoded = UTILS_ABERTIS.utf8_encode( httpRequest.responseText );
				UTILS_GMAPS.parsejarSL_XML( atributs, encoded );
			} else {
				alert('There was a problem with the request.');
			}
		}
	}

	// Aquesta funció utilitza la crida de Google Maps per agafar el XML. Funciona amb URL i amb fitxer.
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	// @param urlFile La URL o el fitxer (amb el path si cal) que conté els SL a parsejar
	UTILS_GMAPS.parsejarSL_gmaps = function( atributs, urlFile, concessio ) {
		urlFile += "?dummy="+Math.random();
		GDownloadUrl(urlFile, function(data) {
			UTILS_GMAPS.parsejarSL_XML( atributs, data, concessio );
		});
	}

	// Aquesta és la funció que fa el parseig del XML en sí.
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	// @param xmlRebut El XML que hem agafat i que hem de parsejar
	UTILS_GMAPS.parsejarSL_XML = function( atributs, xmlRebut, concessio ) {
		var xml = GXml.parse(xmlRebut);
		
		// Agafem la data en la que s'ha generat el fitxer i el missateg de Warning
		if ( concessio == "ACESA" ) {
			var elementsXML = xml.getElementsByTagName("Elements");
			if( elementsXML.length > 0 ) {	// Ho ha de ser!!!!!
				// Llegim i compovem la data
				var dataFitxer = elementsXML[0].getAttribute("Date");
				UTILS_GMAPS.checkData( dataFitxer );
				
				// Llegim el missatge i cridem el métode que el mostra o l'amaga
				//var msg = elementsXML[0].getAttribute("Warning");
				var aReturn = UTILS_GMAPS.getWarningMessage( elementsXML[0] );
				var msg = aReturn[0];
				var level = aReturn[1];
				//alert( "msg="+msg+". level="+level);
				UTILS_GMAPS.mostrarMsgAlert( msg, level );
			}
			else {
				UTILS_GMAPS.AtributsClass.m_bDataOk = false;	// No podem llegir la data. La donem per errònia.
				UTILS_GMAPS.mostrarMsgAlert( "", -1 );						// No podem llegir el warning. Suposem q no n'hi ha.
			}
		}

		var subjectsXML = xml.documentElement.getElementsByTagName("Subjects");
		if( subjectsXML.length > 0 ) {
			var logicalXML = subjectsXML[0].getElementsByTagName("Logical");
			for (var i = 0; i < logicalXML.length; i++) {
				// Parsegem el XML d'un SL (<Logical>)
				var logicalObj = UTILS_GMAPS.parseLogical( logicalXML[i] );
				// Mirem quin típus de Subjecte estem tractant
				// Obres
				var obres = logicalXML[i].getElementsByTagName("RoadWork");
				if ( obres.length > 0 ) {		// Parsegem les obres
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.OBRA ), "TP" );
				}
				// Transit
				var trafic = logicalXML[i].getElementsByTagName("Traffic");
				if ( trafic.length > 0 ) {		// Parsegem les obres
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.TRANSIT ), "TR" );
				}
				// Meteo
				var meteo = logicalXML[i].getElementsByTagName("Meteorology");
				if ( meteo.length > 0 ) {		// Parsegem les obres
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.METEO ), "ME" );
				}
				// Accidents
				var accidents = logicalXML[i].getElementsByTagName("Accident");
				if ( accidents.length > 0) {	// Parsegem els accidents
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.ACCIDENT ), "AC" );
				}
				// Incidéncies (resta d'incidéncies en general)
				var incidencias = logicalXML[i].getElementsByTagName("WinterBaseActivation");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
				incidencias = logicalXML[i].getElementsByTagName("MechanicalAssistance");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
				incidencias = logicalXML[i].getElementsByTagName("MedicalAssistance");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
				incidencias = logicalXML[i].getElementsByTagName("PoliceControl");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
				incidencias = logicalXML[i].getElementsByTagName("RoadDamage");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
				incidencias = logicalXML[i].getElementsByTagName("Fire");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
				incidencias = logicalXML[i].getElementsByTagName("Incidence");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
				incidencias = logicalXML[i].getElementsByTagName("RoadObstacle");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
				incidencias = logicalXML[i].getElementsByTagName("SpecialOperation");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
				incidencias = logicalXML[i].getElementsByTagName("Complaint");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
				incidencias = logicalXML[i].getElementsByTagName("Steal");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
				incidencias = logicalXML[i].getElementsByTagName("SpecialTransport");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
				incidencias = logicalXML[i].getElementsByTagName("ForlornVehicle");
				if ( incidencias.length > 0 ) {
					UTILS_GMAPS.parseSlIncidencias(logicalObj, atributs, UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.INCIDENCIA ), "IN");
				}
	
			}	//for (var i = 0; i < logicalXML.length; i++) {
		}	//if( subjectsXML.length > 0 ) {
		
		// Marquem el bool de la càrrega dels SL
		if ( concessio == "ACESA" )
			atributs.m_bLogicsCarregatsAcesa = true;
		else if ( concessio == "AUCAT" )
			atributs.m_bLogicsCarregatsAucat = true;
		else {	// Si no sabem la concessió, marquem tot carregat. (No ha d passar!)
			atributs.m_bLogicsCarregatsAcesa = true;
			atributs.m_bLogicsCarregatsAucat = true;
		}
		
	}


	// Parseig de tots els SLs per fer-los de la mateixa manera. El métode crida a un submétode que és qui fa el parseig.
	// Al submétode se'l crida sempre passant-li la ubicació inicial i el level number de la inicidencia.
	// Si hi ha una ubicació final, es torna a cridar al submétode passant la ubicació final i el level number que equival a sense dades
	// @param logicalObj És un UTILS_GMAPS.LogicalAtributsClass. És la incidéncia a mostrar
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	// @param descIncidencia La descripció de la incidéncia
	// @param tipusIncidencia El típus de la incidéncia
	UTILS_GMAPS.parseSlIncidencias = function(logicalObj, atributs, descIncidencia, tipusIncidencia ) {
		// Posem la icona corresponent a la ubicació inicial
		UTILS_GMAPS.parseSlIncidenciasLocation(logicalObj, atributs, descIncidencia, tipusIncidencia, logicalObj.InitialLocationClass, logicalObj.InitialLocationClass.levelNumber);
		// Si tenim 2 ubicacions (només ha de passar x casos de Meteorologia i de Operacions Especials),
		// posem una 2a icona al final i afegim les seves coordenades a l'array m_arrayInicidencies2Ubicacions
		if ( logicalObj.FinalLocationClass.latlng != null ) {
			UTILS_GMAPS.parseSlIncidenciasLocation(logicalObj, atributs, descIncidencia, tipusIncidencia, logicalObj.FinalLocationClass, logicalObj.FinalLocationClass.levelNumber);
			var dosUbicacions = new UTILS_GMAPS.Incidencies2UbicacionsClass( logicalObj.InitialLocationClass.latlng, logicalObj.FinalLocationClass.latlng );
			UTILS_GMAPS.AtributsClass.m_arrayInicidencies2Ubicacions.push( dosUbicacions );
		}
	}

	// Funció que crea un objecte del típus Incidencies2UbicacionsClass (on tenim la ubicació inicial i final
	// d'incidencies que tenen 2 ubicacions, i per tant 2 icones)
	// @param ubicacioInicial Un GLatLng amb la ubicacio inicial d'un cas
	// @param ubicacioFinal Un GLatLng amb la ubicacio final d'un cas
	UTILS_GMAPS.Incidencies2UbicacionsClass = function( ubicacioInicial, ubicacioFinal ) {
		this.ubicacioInicial = ubicacioInicial;
		this.ubicacioFinal = ubicacioFinal;
	}

	// Parseig de tots els SLs per fer-los de la mateixa manera. És un submétode de UTILS_GMAPS.parseSlIncidencias
	// @param logicalObj És un UTILS_GMAPS.LogicalAtributsClass. És la incidéncia a mostrar
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	// @param descIncidencia La descripció de la incidéncia
	// @param tipusIncidencia El típus de la incidéncia
	// @param locationClass La classe Location que farem servir (pot ser la inicial o la final)
	// @param levelNumber El levelNumber que farem servir (per la ubicació inicail, és la del cas, i per la final, la de sense dades)
	UTILS_GMAPS.parseSlIncidenciasLocation = function(logicalObj, atributs, descIncidencia, tipusIncidencia, locationClass, levelNumber ) {
		// Formem el títol agafant les dades pertinent
		var titol = descIncidencia + " " + locationClass.highWayName + " PK " + locationClass.kmPoint/1000 + " " + locationClass.descDirection;
		// Posem la info del tooltip
		var strTooltip = titol;
		// Agafem la icona partir del nivell de servei de la incidéncia
		var icona = UTILS_GMAPS.getIcona(tipusIncidencia, levelNumber);
		// Construim el HTML de la pestanya General
		var htmlInfoGeneral = UTILS_GMAPS.htmlMarkerInfoGeneral(icona, titol, logicalObj.AtributsClass.creationDate, logicalObj.AtributsClass.updateDate, logicalObj.AtributsClass.comment, logicalObj.AtributsClass.locationComment, logicalObj.AtributsClass.place, logicalObj.LaneAfClass);
		// Creem el marker amb la icona i la info general
		var baseIcon = UTILS_GMAPS.crearIconaMarker( icona, locationClass.highWayName, locationClass.descDirection, locationClass.kmPoint );
		var markerOptions = { icon:baseIcon };
		var marker = UTILS_GMAPS.crearMarker( locationClass.latlng, markerOptions, strTooltip, htmlInfoGeneral, "", atributs );
		atributs.map.addOverlay( marker );
		marker.hide();
		if ( tipusIncidencia == "TP" )
			atributs.m_arrayObres.push(marker);
		else if ( tipusIncidencia == "TR" )
			atributs.m_arrayTransit.push(marker);
		else if ( tipusIncidencia == "AC" )
			atributs.m_arrayAccidents.push(marker);
		else if ( tipusIncidencia == "IN" )
			atributs.m_arrayIncidencies.push(marker);
		else if ( tipusIncidencia == "ME" )
			atributs.m_arrayMeteo.push(marker);
		else	// Si no es cap d'aquests, ho posem com una incidéncia
			atributs.m_arrayIncidencies.push(marker);
	}

	
	// Dibuixa una línia entre les icones de SLs i la seva coordenada real
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	UTILS_GMAPS.dibuixarLiniaIcones = function ( atributs ) {
		// Esborrem les línies prévies
		UTILS_GMAPS.eliminarIcones( atributs.m_arrayLiniaIcones, atributs.map );
		// Calculem les noves línies (només pels SLs, no per càmares ni panells)
		var linia;
		for ( i = 0; i < atributs.m_arrayTransit.length; i++ ) {
			linia = UTILS_GMAPS.getLiniaIcona( atributs.m_arrayTransit[i], atributs.map );
			atributs.m_arrayLiniaIcones.push( linia );
		}
		for ( i = 0; i < atributs.m_arrayAccidents.length; i++ ) {
			linia = UTILS_GMAPS.getLiniaIcona( atributs.m_arrayAccidents[i], atributs.map );
			atributs.m_arrayLiniaIcones.push( linia );
		}
		for ( i = 0; i < atributs.m_arrayObres.length; i++ ) {
			linia = UTILS_GMAPS.getLiniaIcona( atributs.m_arrayObres[i], atributs.map );
			atributs.m_arrayLiniaIcones.push( linia );
		}
		for ( i = 0; i < atributs.m_arrayMeteo.length; i++ ) {
			linia = UTILS_GMAPS.getLiniaIcona( atributs.m_arrayMeteo[i], atributs.map );
			atributs.m_arrayLiniaIcones.push( linia );
		}
		for ( i = 0; i < atributs.m_arrayIncidencies.length; i++ ) {
			linia = UTILS_GMAPS.getLiniaIcona( atributs.m_arrayIncidencies[i], atributs.map );
			atributs.m_arrayLiniaIcones.push( linia );
		}
		
		// Dibuixem les noves línies
		for ( i = 0; i < atributs.m_arrayLiniaIcones.length; i++ ) {
			atributs.map.addOverlay( atributs.m_arrayLiniaIcones[i] );
		}
	}
	
	// Dibuixa una línia entre una icones donada i la seva coordenada real.
	// @param marker La icona sobre la que volem dibuixar la línia.
	// @param map El mapa.
	UTILS_GMAPS.getLiniaIcona = function ( marker, map ) {
		// Valors X /Y pel desplaçament:
		// 	- X positiu desplaça icona cap a l'esquerra
		// 	- X negatiu desplaça icona cap a la dreta
		// 	- Y positiu desplaça icona cap a dalt
		// 	- Y negatiu desplaça icona cap a baix
		// Tamany icona: 28x28
		var moureN = new GPoint(4,38);		// N = North = Amunt
		var moureE = new GPoint(-10,14);		// E = East = Dreta
		var moureS = new GPoint(4,-10);		// S = South = Avall
		var moureW = new GPoint(38,14);		// W = West = Esquerra
		var moureNE = new GPoint(-10,38);
		var moureSE = new GPoint(-4,4);
		var moureSW = new GPoint(-5,0);
		var moureNW = new GPoint(24,38);

		var baseIcon = marker.getIcon();
		var punt = map.fromLatLngToDivPixel(marker.getLatLng());
		if ( baseIcon.iconAnchor.equals(moureN) ) {
			punt.x -= baseIcon.iconAnchor.x-14;
			punt.y -= baseIcon.iconAnchor.y-14;
		}
		else if ( baseIcon.iconAnchor.equals(moureE) ) {
			punt.x -= baseIcon.iconAnchor.x-14;
			punt.y -= baseIcon.iconAnchor.y-14;
		}
		else if ( baseIcon.iconAnchor.equals(moureS) ) {
			punt.x -= baseIcon.iconAnchor.x-14;
			punt.y -= baseIcon.iconAnchor.y;
		}
		else if ( baseIcon.iconAnchor.equals(moureW) ) {
			punt.x -= baseIcon.iconAnchor.x-14;
			punt.y -= baseIcon.iconAnchor.y-14;
		}
		else if ( baseIcon.iconAnchor.equals(moureNE) ) {
			punt.x -= baseIcon.iconAnchor.x-14;
			punt.y -= baseIcon.iconAnchor.y-14;
		}
		else if ( baseIcon.iconAnchor.equals(moureSE) ) {
			punt.x -= baseIcon.iconAnchor.x-14;
			punt.y -= baseIcon.iconAnchor.y;
		}
		else if ( baseIcon.iconAnchor.equals(moureSW) ) {
			punt.x -= baseIcon.iconAnchor.x-14;
			punt.y -= baseIcon.iconAnchor.y;
		}
		else if ( baseIcon.iconAnchor.equals(moureNW) ) {
			punt.x -= baseIcon.iconAnchor.x-14;
			punt.y -= baseIcon.iconAnchor.y-14;
		}
		var coord = map.fromDivPixelToLatLng(punt);
		var linia = new GPolyline( [marker.getLatLng(), coord], "#000000", 3 );
		return linia;
	}
	
	// Funció que parseja equipaments (tag <Equipments>) del fitxer xml passat i posa markers per cada un d'ells
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	// @param fitxer El fitxer (amb el path si cal) que conté els equips a parsejar
	UTILS_GMAPS.parsejarEquips = function ( atributs, fitxer, concessio ) {
		fitxer += "?dummy="+Math.random();
		GDownloadUrl(fitxer, function(data, responseCode) {
			var xml = GXml.parse(data);
			var subjectsXML = xml.documentElement.getElementsByTagName("Subjects");
			if( subjectsXML.length > 0 ) {
				var equipmentXML = subjectsXML[0].getElementsByTagName("Equipment");
				for (var i = 0; i < equipmentXML.length; i++) {
					// Parsegem el XML d'un equip (<Equipment>)
					var equipmentObj = UTILS_GMAPS.parseEquipment( equipmentXML[i] );
					// Mostrem el que toca segons el típus d'equipament que estem tractant
					if ( equipmentObj.BoardClass != null ) {	// Panells
						// Si hem de pubicar el panell, fem tot el necessari per posar la seva info. Si no, no fem res.
						if ( equipmentObj.BoardClass.Atributs.publish == "True" ) {
							if ( equipmentObj.BoardClass.Atributs.type == 2 ) {
								//UTILS_GMAPS.agruparPanells( equipmentObj ); // És un panell d'accés. Els hem d'agrupar.
							}
							else {
								// Formem el títol agafant les dades pertinent
								var titol = UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.PANELL ) + " "  + equipmentObj.LocationClass.highWayName + " PK " + equipmentObj.LocationClass.kmPoint/1000 + " " + equipmentObj.LocationClass.descDirection;
								// Posem la info del tooltip
								var strTooltip = titol;
								// Agafem la icona partir del nivell de servei de la incidéncia
								var levelNumber = UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_SENSE_DADES;
								var icona = UTILS_GMAPS.getIcona("PMV", levelNumber);
								// Agafem les dades pel panell i fem l'html a mostrar
								var msg = "";
								var iconaEsq = "";
								var iconaDreta = "";
								if ( equipmentObj.BoardClass.Message1.number != -1 ) { // Ho ha de ser!
									msg = equipmentObj.BoardClass.Message1.message;
									if ( equipmentObj.BoardClass.Message1.leftIcon != null )
										iconaEsq = "./img/Pictograms/" + equipmentObj.BoardClass.Message1.leftIcon + "_2.bmp";
									if ( equipmentObj.BoardClass.Message1.rightIcon != null )
										iconaDreta = "./img/Pictograms/" + equipmentObj.BoardClass.Message1.rightIcon + "_2.bmp";
								}
								var msg2 = "";
								var iconaEsq2 = "";
								var iconaDreta2 = "";
								if ( equipmentObj.BoardClass.Message2.number != -1) {
									msg2 = equipmentObj.BoardClass.Message2.message;
									if ( equipmentObj.BoardClass.Message2.leftIcon != null )
										iconaEsq2 = "./img/Pictograms/" + equipmentObj.BoardClass.Message2.leftIcon + "_2.bmp";
									if ( equipmentObj.BoardClass.Message2.rightIcon != null )
										iconaDreta2 = "./img/Pictograms/" + equipmentObj.BoardClass.Message2.rightIcon + "_2.bmp";
								}
								var htmlInfoGeneral = UTILS_GMAPS.htmlPanell(titol, msg, iconaEsq, iconaDreta, levelNumber, msg2, iconaEsq2, iconaDreta2);
								// Creem el marker amb la icona i la info general
								var baseIcon = UTILS_GMAPS.crearIconaMarker( icona, equipmentObj.LocationClass.highWayName, equipmentObj.LocationClass.descDirection, equipmentObj.LocationClass.kmPoint );
								var markerOptions = { icon:baseIcon };
								var marker = UTILS_GMAPS.crearMarker( equipmentObj.LocationClass.latlng, markerOptions, strTooltip, htmlInfoGeneral, "", atributs );
								atributs.map.addOverlay( marker );
								marker.hide();
								// Hem de posar els panells d'avís a l'array de panells q sempre és visible, i al resta al del macim nivell de zoom
								if ( equipmentObj.BoardClass.Atributs.warningState == "True" ) {
									atributs.m_arrayPanells.push(marker);
								}
								else {
									atributs.m_arrayPanellsMaxZoom.push(marker);
								}
							}
						}
					}
					else if ( equipmentObj.CameraClass != null ) {	// Camera
						// Mostrem TOTES les càmeres. Però si no estan actives, mostrem el video de fora de servei.
						//if ( equipmentObj.AtributsClass.active == "True" ) {	// Si posessim això, no mostrariem les q no estan actives
						// Formem el títol agafant les dades pertinent
						var titol = UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.CAMERA ) + " " + equipmentObj.LocationClass.highWayName + " PK " + equipmentObj.LocationClass.kmPoint/1000 + " " + equipmentObj.LocationClass.descDirection;
						// Posem la info del tooltip
						var strTooltip = titol;
						// Agafem la icona partir del nivell de servei de la incidéncia
						var levelNumber = UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_SENSE_DADES;
						var icona = UTILS_GMAPS.getIcona("CAM", levelNumber);
						// Fem el HTML que mostra la càmera
						var fitxer = equipmentObj.CameraClass.Atributs.file;
						var htmlInfoGeneral = UTILS_GMAPS.htmlCamera(titol, levelNumber, fitxer, equipmentObj.AtributsClass.active );
						// Creem el marker amb la icona i la info general
						var baseIcon = UTILS_GMAPS.crearIconaMarker( icona, equipmentObj.LocationClass.highWayName, equipmentObj.LocationClass.descDirection, equipmentObj.LocationClass.kmPoint );
						var markerOptions = { icon:baseIcon };
						var marker = UTILS_GMAPS.crearMarker( equipmentObj.LocationClass.latlng, markerOptions, strTooltip, htmlInfoGeneral, "", atributs );
						atributs.map.addOverlay( marker );
						marker.hide(); 
						atributs.m_arrayCamares.push(marker);
						// }	// Si posessim això, no mostrariem les q no estan actives
					}
					else if ( equipmentObj.EstMetClass != null ) {	// Estacio Meteorològica
						// Només mostrem les meteos q estan actives
						if ( equipmentObj.AtributsClass.active == "True" ) {
							// Formem el títol agafant les dades pertinent
							var titol = UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.ESTACIO_METEO ) + " " + equipmentObj.LocationClass.highWayName + " PK " + equipmentObj.LocationClass.kmPoint/1000 + " " + equipmentObj.LocationClass.descDirection;
							// Posem la info del tooltip
							var strTooltip = titol;
							// Agafem la icona partir del nivell de servei de la incidéncia
							var levelNumber = UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_SENSE_DADES;
							var icona = UTILS_GMAPS.getIcona("EST", levelNumber);
							// Fem el HTML que mostra la est. meteo
							htmlInfoGeneral = UTILS_GMAPS.htmlMeteo(titol, equipmentObj.EstMetClass.Atributs.temp, equipmentObj.EstMetClass.Atributs.vent, equipmentObj.EstMetClass.Atributs.plujaHora, equipmentObj.EstMetClass.Atributs.plujaDia);
							// Creem el marker amb la icona i la info general
							var baseIcon = UTILS_GMAPS.crearIconaMarker( icona, equipmentObj.LocationClass.highWayName, equipmentObj.LocationClass.descDirection, equipmentObj.LocationClass.kmPoint );
							var markerOptions = { icon:baseIcon };
							var marker = UTILS_GMAPS.crearMarker( equipmentObj.LocationClass.latlng, markerOptions, strTooltip, htmlInfoGeneral, "", atributs );
							atributs.map.addOverlay( marker );
							marker.hide(); 
							atributs.m_arrayEstMeteo.push(marker);
						}
					}
					
				}	// for (var i = 0; i < equipmentXML.length; i++) {
			}
			// Marquem el bool de la càrrega dels equipaments
			if ( concessio == "ACESA" )
				atributs.m_bEquipsCarregatsAcesa = true;
			else if ( concessio == "AUCAT" )
				atributs.m_bEquipsCarregatsAucat = true;
			else {	// Si no sabem la concessió, marquem tot carregat. (No ha d passar!)
				atributs.m_bEquipsCarregatsAcesa = true;
				atributs.m_bEquipsCarregatsAucat = true;
			}
		});
	}
	
	// Funció que parseja equipaments (tag <Equipments>) del fitxer xml passat i posa markers per cada un d'ells
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	// @param fitxer El fitxer (amb el path si cal) que conté els nivells de servei a parsejar
	// @param tramsSortidesManager La funció que posarà els trams (on està el marker manager)
	// @param concessio La cocnessió q estem parsejant ("ACESA" o "AUCAT"). NOTA: Paràmetre afegit 30-11-09 per
	// poder fer un offset en els ids d'Aucat
	UTILS_GMAPS.parsejarNivellsServei = function( atributs, fitxer, tramsSortidesManager, concessio  ) {
		fitxer += "?dummy="+Math.random();
		GDownloadUrl(fitxer, function(data, responseCode) {
			var xml = GXml.parse(data);
			var zonesXML = xml.documentElement.getElementsByTagName("Zone");
			for ( var i = 0; i < zonesXML.length; i ++ ) {
				//UTILS_GMAPS.NSClass = function( i, h, pkIni, pkend, d, lN, l, d ) {
				//var nivell = new UTILS_GMAPS.NSClass(null,null,null,null,null,null,null,null);
				var nivell = new Object();
				nivell.identifier = zonesXML[i].getAttribute("Identifier");
				
				// CANVI DMR 30-11-09. Afegim un offset de 90 as iodentificador d'Aucat
				if ( concessio == "AUCAT" ) {
					nivell.identifier = parseInt(nivell.identifier, 10) + 90;
					//alert( "nivell.identifier="+nivell.identifier );
				}
				// END CANVI DMR 30-11-09. Afegim un offset de 90 as iodentificador d'Aucat
				
				//nivell.highWayCode = zonesXML[i].getAttribute("HighWayCode");
				//nivell.pkIni = zonesXML[i].getAttribute("PkIni");
				//nivell.pkEnd = zonesXML[i].getAttribute("PkEnd");
				//nivell.direction = zonesXML[i].getAttribute("Direction");
				nivell.levelNumber = zonesXML[i].getAttribute("LevelNumber");
				//nivell.level = zonesXML[i].getAttribute("Level");
				//nivell.description = zonesXML[i].getAttribute("Description");
				UTILS_GMAPS.NivellsServei.push( nivell );
			}
			
			// Un cop hem parsejat els nivells de servei, dibuixem els trams (amb el seu color) i les sortides
			// Posem els trams i les sortides fent servir el MarkerManager
			window.setTimeout(tramsSortidesManager, 0);
		});
	}

	// Funció que retorna el color d'un tram donat en funció del seu nivell de servei
	// @param idTram ID del tram del que volem saber el seu color
	// @return Un string amb eL color del tram (o en blanc si no s'ha trobat).
	UTILS_GMAPS.getColorTram = function( idTram ) {
		var color;
		var iNivellServei = UTILS_GMAPS.getNivellServei( idTram );
		if ( iNivellServei == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_RETENCIO )
			color = UTILS_GMAPS.CONSTANTS_CLASS.COLOR_TRANSIT_RETENCIO;
		else if ( iNivellServei == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_DENS )
			color = UTILS_GMAPS.CONSTANTS_CLASS.COLOR_TRANSIT_DENS;
		else if ( iNivellServei == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_FLUID )
			color = UTILS_GMAPS.CONSTANTS_CLASS.COLOR_TRANSIT_FLUID;
		else if ( iNivellServei == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_TALLAT )
			color = UTILS_GMAPS.CONSTANTS_CLASS.COLOR_TRANSIT_TALLAT;
		else //if ( iNivellServei == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_SENSE_DADES )
			color = UTILS_GMAPS.CONSTANTS_CLASS.COLOR_TRANSIT_SENSE_DADES;
		return color;
	}

	// Funció que retorna el nivell de servei d'un tram passat
	// @param idTram ID del tram del que es vol saber el nivell de servei
	// @return El nivell de servei del tram o bé -1 (Sense Dades) si no s'ha trobat la ID del tram.
	UTILS_GMAPS.getNivellServei = function ( idTram ) {
		for ( i = 0; i < UTILS_GMAPS.NivellsServei.length; i++ ) {
			if ( UTILS_GMAPS.NivellsServei[i].identifier == idTram ){
				return UTILS_GMAPS.NivellsServei[i].levelNumber;
			}
		}
		return -1;
	}
	
	// Crear un div per mostrar un msg a l'estil de "Cargando...".
	// NOTA: la posició està hardcodejada per estar "centrat" en un mapa  de 600x450
	UTILS_GMAPS.crearCarregant = function() {
		var tip = document.createElement("div"); 
		tip.setAttribute("id","div_loading"); 
		document.getElementById("map").appendChild(tip); 
		var pos = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(225,180)); 
		pos.apply(document.getElementById("div_loading")); 
		tip.style.visibility="hidden";
	}

	// Mostrar el msg passat en el div d'informació.
	// @param msg El missatge a mostrar. Si es passa un msg en blanc, s'amaga el div.
	UTILS_GMAPS.mostrarCarregant = function( msg ){ 
		if ( msg.length > 0 ) {
			document.getElementById("div_loading").innerHTML = "<div style='background-color:#ffffff;font-size:16px;font-family:arial;font-weight:bold;border:1px #000000 solid'><table width = 150px><tr><td width=1px></td><td>" + msg + "</td><td width=1px></td></tr></table></div>";
			document.getElementById("div_loading").style.visibility="visible";
	  }
		else {
	  	document.getElementById("div_loading").style.visibility="hidden";
	  }
	}

	// Funció que utilitza el MarkerManager de google per mostrar les sortides en un nivell determinat de zoom
	// @param Atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	// @param Sortides Array que conté les sortides a mostrar
	// @return Un array amb els markers de les sortides per tal que el marker manager les posi
	UTILS_GMAPS.getSortides	= function( Atributs, Sortides ) {
		var batch = [];
		for ( iSortida = 0; iSortida < Sortides.length; iSortida++ ) {
			if ( (Sortides[iSortida].lat != null) && (Sortides[iSortida].lng != null) ) {
				var baseIcon = UTILS_GMAPS.crearIconaMarker( UTILS_GMAPS.ICONA_SORTIDA, "", "", "" );	// No desplacem la icona, per tant no passem ni autopista, ni pk, ni sentit.
				//var markerOptions = { icon:baseIcon };
				var markerOptions = { icon:baseIcon, zIndexProcess:UTILS_GMAPS.ordreIcones };
				var latlng = new GLatLng(parseFloat(Sortides[iSortida].lat), parseFloat(Sortides[iSortida].lng));
				var strTooltip;
				if ( Sortides[iSortida].idSortida != 1000 )
					strTooltip = Sortides[iSortida].idSortida + ": " + Sortides[iSortida].nom;
				else
					strTooltip = Sortides[iSortida].nom;
				batch.push( UTILS_GMAPS.crearMarkerSenseClick( latlng, markerOptions, strTooltip, Atributs ) );
				//batch.push( UTILS_GMAPS.crearMarkerSortida( latlng, markerOptions, strTooltip, Atributs, Sortides[iSortida].idAutopista, Sortides[iSortida].idSortida ) );
			}
		}
		return batch;
	}

	// Funció que utilitza el MarkerManager de google per mostrar els panell de detall en un nivell determinat de zoom
	// @param Atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	// @return Un array amb els markers dels panells per tal que el marker manager els posi
	UTILS_GMAPS.getPanells	= function( Atributs ) {
		var batch = [];
		for ( iPanell = 0; iPanell < Atributs.m_arrayPanellsMaxZoom.length; iPanell++ ) {
			batch.push( Atributs.m_arrayPanellsMaxZoom[iPanell] );
		}
		return batch;
	}

	// Funció que utilitza el MarkerManager de google per mostrar els trams en un nivell determinat de zoom
	// @param Atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	// @param Trams Array que conté els trams a mostrar
	// @param nivellZoom El nivell de zoom en que es volen mostrar aquests trams
	// @return Un array amb els polígons dels trams per tal que el marker manager els posi
	UTILS_GMAPS.getTrams = function(Concessio, nivellZoom ) {
		var batch = [];
		var iZoom = nivellZoom - UTILS_GMAPS.CONSTANTS_CLASS.MIN_ZOOM;
		if ( document.opcions.opcio[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ZONA_GIRONA].checked == true ) {
			UTILS_GMAPS.getTramsZona( Concessio.zonaGirona, Concessio.Trams, iZoom, Concessio.Atributs.map, batch );
		}
		if ( document.opcions.opcio[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ZONA_BARCELONA].checked == true ) {
			UTILS_GMAPS.getTramsZona( Concessio.zonaBarcelona, Concessio.Trams, iZoom, Concessio.Atributs.map, batch );
		}
		if ( document.opcions.opcio[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ZONA_TARRAGONA].checked == true ) {
			UTILS_GMAPS.getTramsZona( Concessio.zonaTarragona, Concessio.Trams, iZoom, Concessio.Atributs.map, batch );
		}
		if ( document.opcions.opcio[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ZONA_LLEIDA].checked == true ) {
			UTILS_GMAPS.getTramsZona( Concessio.zonaLleida, Concessio.Trams, iZoom, Concessio.Atributs.map, batch );
		}
		if ( document.opcions.opcio[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ZONA_ZARAGOZA].checked == true ) {
			UTILS_GMAPS.getTramsZona( Concessio.zonaZaragoza, Concessio.Trams, iZoom, Concessio.Atributs.map, batch );
		}
		if ( document.opcions.opcio[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ZONA_HUESCA].checked == true ) {
			UTILS_GMAPS.getTramsZona( Concessio.zonaHuesca, Concessio.Trams, iZoom, Concessio.Atributs.map, batch );
		}
		UTILS_GMAPS.mostrarCarregant("");
		return batch;
	}
	
	UTILS_GMAPS.getTramsZona = function ( zona, Trams, iZoom, map, batch ) {
		var idxTramZona = 0;
		for ( idxTramZona = 0; idxTramZona < zona.tramsZona.length; idxTramZona++ ) {
			var iPosTram = UTILS_GMAPS.getPosTram( Trams, zona.tramsZona[idxTramZona] );
			if ( iPosTram > -1  ) {
				// Ens assegurem que tenim punts per poder dibuixar el polígon del tram en qüestió
				if ( Trams[iPosTram].zoom[iZoom].encodedPoints.length > 0 ) {
					batch.push( UTILS_GMAPS.crearPoligonTram(Trams[iPosTram], iZoom, map) );
				}
			}
		}
	}
	
	// Funció que busca un tram passat dins del vector de trams passat i retorna la seva posició
	// @param Trams El vector de trams on volem buscar el tram
	// @param idTram La ID del tram a buscar
	// @ return L'índex on es troba el tram si aquest s'ha trobat o -1 si no s'ha trobat.
	UTILS_GMAPS.getPosTram = function( Trams, idTram ) {
		for ( iTram = 0; iTram < Trams.length; iTram++ ) {
			if ( Trams[iTram].idTram == idTram )
				return iTram;
		}
		return -1;
	}

	// Funció que crea el polígon per representar un tram
	// @param tram El tram amb la info a representar en el polígon
	// @param iZoom El nivell de zoom en el que volem crear el polígon
	// @param map El mapa on afegir el polígon
	// @return El polígon que representa el tram
	UTILS_GMAPS.crearPoligonTram = function(tram, iZoom, map ) {
		// Agafem el color el nivell de servei pel tram actual
		var fillColor = UTILS_GMAPS.getColorTram( tram.idTram );
		// Creem el polígon (a partir del polígon codificat)
		var oPoligon = new GPolygon.fromEncoded({
			polylines: [{
				color: UTILS_GMAPS.CONSTANTS_CLASS.COLOR_TRANSIT_BORDE_POLIGON,
				weight: 1,
				points: tram.zoom[iZoom].encodedPoints,
				levels: tram.zoom[iZoom].encodedLevels,
				opacity: 1,
				zoomFactor: 2,
				numLevels: 18}],
			fill: true,
			color: fillColor,
			opacity: 1,
			outline: true});
		/*
		// Posem l'event de click: obrir una info
		var titol = "ESTADO TRÁFICO " + tram.autopista;
		var update = "";	//"18-12-08 17:00";
		var levelNumber = UTILS_GMAPS.getNivellServei( tram.idTram );
		var iniFi = tram.pkIni + " - " + tram.pkFi
		var sentit = tram.sentit;
		var loc = "";	//"Maçanet"
		var notes = ""; //"Retención del pk 80.5 al 82.5"
		var strHtmlInfo = UTILS_GMAPS.htmlNivellServei(titol, update, levelNumber, iniFi, sentit, loc, notes );
		GEvent.addListener(oPoligon,"click", function(point) {
			map.openInfoWindowHtml(point,strHtmlInfo);
		});
		*/
		return oPoligon;
	}

	// Funció que ens dóna la icona a posar en funció del nivell de servei i el típus d'incidéncia o equipament
	// @param sl Típus d'incidéncia (SL) o equipament:
	//		"TP" = "OBRES(TRABAJOS PISTA)"
	//		"TR" = "TRANSIT"
	//		"AC" = "ACCIDENT"
	//		"IN" = "INCIDENCIA"
	//		"ME" = "METEOROLOGIA"
	//		"PMV" = "PANEL"
	//		"CAM" = "CAMARA"
	//		"EST" = "ESTACIÓ METEOROLÓGICA"
	// @param levelNumber El nivell de sevei de la incidéncia
	// @return La icona que correspón al nivell de servei donat per al sl o equipament donat.
	UTILS_GMAPS.getIcona = function (sl, levelNumber) {
		var icona = "";
		if ( sl == "TP" )
			icona = UTILS_GMAPS.getIconaArray( UTILS_GMAPS.ICONES_OBRES, levelNumber);
		else if ( sl == "TR" )
			icona = UTILS_GMAPS.getIconaArray( UTILS_GMAPS.ICONES_TRANSIT, levelNumber);
		else if ( sl == "AC" )
			icona = UTILS_GMAPS.getIconaArray( UTILS_GMAPS.ICONES_ACCIDENT, levelNumber);
		else if ( sl == "IN" )
			icona = UTILS_GMAPS.getIconaArray( UTILS_GMAPS.ICONES_INCIDENCIES, levelNumber);
		else if ( sl == "ME" )
			icona = UTILS_GMAPS.getIconaArray( UTILS_GMAPS.ICONES_METEO, levelNumber);
		else if ( sl == "PMV" )
			icona = UTILS_GMAPS.getIconaArray( UTILS_GMAPS.ICONES_PANELL, levelNumber);
		else if ( sl == "CAM" )
			icona = UTILS_GMAPS.getIconaArray( UTILS_GMAPS.ICONES_CAMARA, levelNumber);
		else if ( sl == "EST" )
			icona = UTILS_GMAPS.getIconaArray( UTILS_GMAPS.ICONES_EST_MET, levelNumber);
		return icona;
	}

	// Funció que ens dóna la icona a posar per una incidéncia o equipament donat en funció del nivell de servei
	// @param arrayIcones Un array amb les icones corresponents al típus d'incidéncia o equipament
	// @param levelNumber El nivell de servei de la incidéncia
	// @return La icona que correspón al nivell de servei donat
	UTILS_GMAPS.getIconaArray = function (arrayIcones, levelNumber) {
		var icona = "";
		if ( levelNumber == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_FLUID )
			icona = arrayIcones[UTILS_GMAPS.CONSTANTS_CLASS.ARRAY_IMATGE_FLUID];
		else if ( levelNumber == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_DENS )
			icona = arrayIcones[UTILS_GMAPS.CONSTANTS_CLASS.ARRAY_IMATGE_DENS];
		else if ( levelNumber == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_RETENCIO )
			icona = arrayIcones[UTILS_GMAPS.CONSTANTS_CLASS.ARRAY_IMATGE_RETENCIO];
		else if ( levelNumber == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_TALLAT )
			icona = arrayIcones[UTILS_GMAPS.CONSTANTS_CLASS.ARRAY_IMATGE_TALLAT];
		else //if ( levelNumber == UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_SENSE_DADES )
			icona = arrayIcones[UTILS_GMAPS.CONSTANTS_CLASS.ARRAY_IMATGE_SENSE_DADES];
		return icona;
	}

	// Funció que elimina del mapa totes les icones que passem en un array
	// @param arrayIcones Array amb les icones a eliminar del mapa
	// @param map EL mapa del que hem d'eliminar les icones
	UTILS_GMAPS.eliminarIcones = function ( arrayIcones, map ) {
		for ( i = 0; i < arrayIcones.length; i++ ) {
			map.removeOverlay( arrayIcones[i] );
		}
		arrayIcones.length = 0;
	}
	
	// Afegim el métode getPoint al polígon (retorna el centre del polígon) per tal de poder
	// fer servir el marker manager amb els polígons
	GPolygon.prototype.getPoint = function() {
  	if (!this.Centre) {
    	this.Centre = this.getBounds().getCenter();
	  }
  	return this.Centre;
	}

	// Funció que elimina les dades prévies del SLs i els esborra del mapa
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	UTILS_GMAPS.netejarSL = function( atributs ) {
		// Resetegem les variables de control per comprovar si la càrrega del XML ha acabat
		UTILS_GMAPS.AtributsClass.m_bLogicsCarregatsAcesa = false;
		UTILS_GMAPS.AtributsClass.m_bLogicsCarregatsAucat = false;

		// Eliminem les dades dels SLs
		UTILS_GMAPS.eliminarIcones( atributs.m_arrayTransit, atributs.map );
		UTILS_GMAPS.eliminarIcones( atributs.m_arrayObres, atributs.map );
		UTILS_GMAPS.eliminarIcones( atributs.m_arrayIncidencies, atributs.map );
		UTILS_GMAPS.eliminarIcones( atributs.m_arrayMeteo, atributs.map );
		UTILS_GMAPS.eliminarIcones( atributs.m_arrayAccidents, atributs.map );
	}
	
	// Funció que elimina les dades prévies del equipaments i els esborra del mapa
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	UTILS_GMAPS.netejarEquips = function ( atributs ) {
		// Resetegem les variables de control per comprovar si la càrrega del XML ha acabat
		UTILS_GMAPS.AtributsClass.m_bEquipsCarregatsAcesa = false;
		UTILS_GMAPS.AtributsClass.m_bEquipsCarregatsAucat = false;

		// Eliminem les dades dels equipaments
		UTILS_GMAPS.eliminarIcones( atributs.m_arrayPanells, atributs.map );
		UTILS_GMAPS.eliminarIcones( atributs.m_arrayPanellsMaxZoom, atributs.map );
		UTILS_GMAPS.eliminarIcones( atributs.m_arrayCamares, atributs.map );
		UTILS_GMAPS.eliminarIcones( atributs.m_arrayEstMeteo, atributs.map );
		if ( UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces != null ) {
			UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces.length = 0;
			UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces = null;
		}
	}
		
	// Funció que elimina les dades prévies del nivells de servei i els esborrar del mapa
	UTILS_GMAPS.netejarNivellsServei = function() {
		// Eliminem les dades dels trams
		UTILS_GMAPS.NivellsServei.length = 0;
	}
	
	// Funció que retorna l'idioma actual (a partir de la pàgina html sobre la que s'executa el script)
	// @return L'idioma actual, que pot ser UTILS_GMAPS.IDIOMA.CAT, UTILS_GMAPS.IDIOMA.CAS o UTILS_GMAPS.IDIOMA.ENG. Per defecte retorna UTILS_GMAPS.IDIOMA.CAS
	UTILS_GMAPS.getIdiomaActual = function() {
		var pagina = self.location.href.match( /\/([^/]+)$/ )[1];
		if ( pagina == "map_acesa_cat.html" )
			return UTILS_GMAPS.IDIOMA.CAT;
		else if ( pagina == "map_acesa_cas.html" )
			return UTILS_GMAPS.IDIOMA.CAS;
		else if ( pagina == "map_acesa_eng.html" )
			return UTILS_GMAPS.IDIOMA.ENG;
		else if ( pagina == "map_acesa_fr.html" )
			return UTILS_GMAPS.IDIOMA.FR;
		else
			return UTILS_GMAPS.IDIOMA.CAS;
	}

	// Funció que retorna el text que volem en l'idioma que volem
	// @param idioma L'idioma que volem. Pot ser UTILS_GMAPS.IDIOMA.CAT, UTILS_GMAPS.IDIOMA.CAS o UTILS_GMAPS.IDIOMA.ENG.
	// @param textConst Una constant (veure el fitxer lang.js) que identifica el text que volem recuperar
	// @return El text que volem recuperar en l'idioma seleccionat
	UTILS_GMAPS.getTextIdioma = function( idioma, textConst ) {
		// Si no volem que els texts estiguin traduits i els volem tots en castellà,
		//només cal canviar la línia actual per aquesta:
		//return UTILS_GMAPS.IDIOMA.TEXTS.Literals[textConst][UTILS_GMAPS.IDIOMA.CAS];
		return UTILS_GMAPS.IDIOMA.TEXTS.Literals[textConst][idioma];
	}

	// Funció que retorna el text que volem en l'idioma que volem en MAJÚSCULES
	// @param idioma L'idioma que volem. Pot ser UTILS_GMAPS.IDIOMA.CAT, UTILS_GMAPS.IDIOMA.CAS o UTILS_GMAPS.IDIOMA.ENG.
	// @param textConst Una constant (veure el fitxer lang.js) que identifica el text que volem recuperar
	// @return El text que volem recuperar en l'idioma seleccionat
	UTILS_GMAPS.getTextIdiomaCaps = function( idioma, textConst ) {
		return UTILS_GMAPS.getTextIdioma( idioma, textConst ).toUpperCase();
	}

	// Funció que inicialitza l'array amb el valor dels checkboxes per defecte en funció del navegador utilitzat
	UTILS_GMAPS.inicialitzarOpcions = function() {
		if ( ieTest ) {	// Si utilitzem un Internet Explorer, només marquem els SL (no marquem equipaments ni nivell de servei)
			// DESmarquem tot
			for ( i = 0; i < UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_LENGTH; i++ ) {
				UTILS_GMAPS.AtributsClass.m_arrayChecks[i] = false;
			}
			// Marquem els SL
			UTILS_GMAPS.AtributsClass.m_arrayChecks[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_TRANSIT] = true;
			UTILS_GMAPS.AtributsClass.m_arrayChecks[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ACCIDENT] = true;
			//UTILS_GMAPS.AtributsClass.m_arrayChecks[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_OBRES] = true;
			UTILS_GMAPS.AtributsClass.m_arrayChecks[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_INCIDENCIES] = true;
			UTILS_GMAPS.AtributsClass.m_arrayChecks[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_METEO] = true;
			UTILS_GMAPS.AtributsClass.m_arrayChecks[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_CAMARES] = true;
		}
		else {	// Si no utilitzem IE, marquem tot els SL i els nivells de servei, i no marquem els equipaments
			// Marquem tot
			for ( i = 0; i < UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_LENGTH; i++ ) {
				UTILS_GMAPS.AtributsClass.m_arrayChecks[i] = true;
			}
			// DESmarquem els equipaments
			//UTILS_GMAPS.AtributsClass.m_arrayChecks[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_CAMARES] = false;
			UTILS_GMAPS.AtributsClass.m_arrayChecks[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_OBRES] = false;
			UTILS_GMAPS.AtributsClass.m_arrayChecks[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_PANELLS] = false;
			UTILS_GMAPS.AtributsClass.m_arrayChecks[UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_ESTACIO_METEO] = false;
		}
	}

	// Funció que posa els checkboxes del navegador als últims valors (els que hi havien abans de refrescar)
	UTILS_GMAPS.setOpcions = function() {
		for ( i = 0; i < UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_LENGTH; i++ ) {
			document.opcions.opcio[i].checked = UTILS_GMAPS.AtributsClass.m_arrayChecks[i];
		}
	}

	// Funció que agafa els valors dels checkboxes
	UTILS_GMAPS.getOpcions = function() {
		for ( i = 0; i < UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_LENGTH; i++ ) {
			UTILS_GMAPS.AtributsClass.m_arrayChecks[i] = document.opcions.opcio[i].checked;
		}
		// Guardem els valors a les cookies de sessió
		document.cookie = "infotrafic.m_arrayChecks=" + UTILS_GMAPS.AtributsClass.m_arrayChecks;
	}
	
	// Funció que posa al html els valors guardats o els per defecte
	UTILS_GMAPS.posarValorOpcions = function() {
		// Agafem els valor guardats a les cookies de sessió
		var aValors = UTILS_ABERTIS.getCookie("infotrafic.m_arrayChecks");
		if ( aValors != "" ) {
			// Hem de posar els valors en un array. Hem d'agafar substrings fins a la coma
			var valor = "";
			var idxIni = 0;
			var idxComa = 0;
			for ( i = 0; i < UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_LENGTH; i++ ) {
				if ( i < UTILS_GMAPS.CONSTANTS_CLASS.OPCIONS_LENGTH - 1 ) {
					idxComa = aValors.indexOf(",",idxIni);
					valor = aValors.substring( idxIni, idxComa );
					idxIni = idxComa+1;
				}
				else {	// Si estem a l'últim valor, anem de la coma (idxIni) fins al final.
					valor = aValors.substring( idxIni );	
				}
				if ( valor == "true" )
					UTILS_GMAPS.AtributsClass.m_arrayChecks[i] = true;
				else //if ( valor == "false" )
					UTILS_GMAPS.AtributsClass.m_arrayChecks[i] = false;
			}
			UTILS_GMAPS.setOpcions();
			
		}
		else {
			UTILS_GMAPS.inicialitzarOpcions();
			UTILS_GMAPS.setOpcions();
		}
	}

	// Funció que posa el panell d'accés passat al grup que toca a l'array de panells d'accés.
	// Si no es troba la ubicació del panell, es crea un nou grup.
	// Utilitza "UTILS_GMAPS.afegirGrupPanells" per crear un nou grup
	// @param equipmentObj És un panell d'accés encapsulat dins un UTILS_GMAPS.BoardClass
	UTILS_GMAPS.agruparPanells = function( equipmentObj ) {
		var panellAgrupar = new UTILS_GMAPS.PanellAgrupar( equipmentObj );
		if ( UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces == null ) {
			UTILS_GMAPS.afegirGrupPanells( panellAgrupar );
		}
		else if ( UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces.length == 0 ) {
			UTILS_GMAPS.afegirGrupPanells( panellAgrupar );
		}
		else {
			var bAdded = false;
			for ( i = 0; i < UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces.length; i++ ) {
				if ( UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces[i].ubicacio == panellAgrupar.LocationClass.description ) {
					UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces[i].afegirPanell( panellAgrupar );
					bAdded = true;
				}
			}
			if ( !bAdded ) {
				UTILS_GMAPS.afegirGrupPanells( panellAgrupar );
			}
		}
	}
	
	UTILS_GMAPS.PanellAgrupar = function( equipmentObj ) {
		// Agafem la info dels atributs
		this.AtributsClass = {};
		this.AtributsClass.code = equipmentObj.AtributsClass.code;
		this.AtributsClass.active = equipmentObj.AtributsClass.active;
		this.AtributsClass.updateDate = equipmentObj.AtributsClass.updateDate;

		// Agafem la info dels panells
		this.BoardClass = {};
		this.BoardClass.Atributs = {};
		this.BoardClass.Atributs.name = equipmentObj.BoardClass.Atributs.name;
		this.BoardClass.Atributs.number = equipmentObj.BoardClass.Atributs.number;
		this.BoardClass.Atributs.type = equipmentObj.BoardClass.Atributs.type;
		this.BoardClass.Atributs.fileNumber = equipmentObj.BoardClass.Atributs.fileNumber;
		this.BoardClass.Atributs.columnNumber = equipmentObj.BoardClass.Atributs.columnNumber;
		this.BoardClass.Atributs.iconPosition = equipmentObj.BoardClass.Atributs.iconPosition;
		this.BoardClass.Atributs.isActive = equipmentObj.BoardClass.Atributs.isActive;
		this.BoardClass.Atributs.warningState = equipmentObj.BoardClass.Atributs.warningState;
		this.BoardClass.Atributs.publish = equipmentObj.BoardClass.Atributs.publish;
		this.BoardClass.Message1 = {};
		this.BoardClass.Message1.number = equipmentObj.BoardClass.Message1.number;
		this.BoardClass.Message1.leftIcon = equipmentObj.BoardClass.Message1.leftIcon;
	  this.BoardClass.Message1.rightIcon = equipmentObj.BoardClass.Message1.rightIcon;
	  this.BoardClass.Message1.difference = equipmentObj.BoardClass.Message1.difference;
	  this.BoardClass.Message1.message = equipmentObj.BoardClass.Message1.message;
		this.BoardClass.Message2 = {};
		this.BoardClass.Message2.number = equipmentObj.BoardClass.Message2.number;
		this.BoardClass.Message2.leftIcon = equipmentObj.BoardClass.Message2.leftIcon;
	  this.BoardClass.Message2.rightIcon = equipmentObj.BoardClass.Message2.rightIcon;
	  this.BoardClass.Message2.difference = equipmentObj.BoardClass.Message2.difference;
	  this.BoardClass.Message2.message = equipmentObj.BoardClass.Message2.message;
	
		// Agafem la info del Location
		this.LocationClass = {};
		this.LocationClass.description = equipmentObj.LocationClass.description
		this.LocationClass.highWayCode = equipmentObj.LocationClass.highWayCode
		this.LocationClass.highWayName = equipmentObj.LocationClass.highWayName
		this.LocationClass.accessName = equipmentObj.LocationClass.accessName
		this.LocationClass.kmPoint = equipmentObj.LocationClass.kmPoint
		this.LocationClass.direction = equipmentObj.LocationClass.direction
		this.LocationClass.descDirection = equipmentObj.LocationClass.descDirection
		this.LocationClass.networkKind = equipmentObj.LocationClass.networkKind
		this.LocationClass.platformTollKind = equipmentObj.LocationClass.platformTollKind
		this.LocationClass.roadLinkKind = equipmentObj.LocationClass.roadLinkKind
		this.LocationClass.longitude = equipmentObj.LocationClass.longitude;
		this.LocationClass.latitude = equipmentObj.LocationClass.latitude;
		this.LocationClass.latlng = equipmentObj.LocationClass.latlng;
	}
	
	// Funció que crea un objecte del típus GrupPanellClass (on tenim la ubicació del grup de panells i un
	// array amb tots els panells que hi han)
	// @param ubicació Un string amb la ubicació on estan aquests panells que agrupem en un.
	UTILS_GMAPS.GrupPanellClass = function( ubicacio ) {
		this.ubicacio = ubicacio;
		this.arrayPanells = new Array();
	}
	// Afegim un métode a GrupPanellClass que ens permet afegir el panell passat a l'array de panells de l'objecte
	// @param equipmentObj El panell que volem afegir (és un panell d'accés encapsulat dins un UTILS_GMAPS.BoardClass)
	UTILS_GMAPS.GrupPanellClass.prototype.afegirPanell = function( equipmentObj ) {
		this.arrayPanells.push( equipmentObj );
	}

	// Funció que crea un nou grup de panells per al panell passat i posa el grup creat a l'array de panells d'accés.
	// @param equipmentObj És un panell d'accés encapsulat dins un UTILS_GMAPS.BoardClass
	UTILS_GMAPS.afegirGrupPanells = function( equipmentObj ) {
		// Si l'array de panells agrupats no està creada, la creem.
		if ( UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces == null )
			UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces = new Array();
			
		// Creem un objecte del típus GrupPanellClass, hi afegim el panell passat, i posem l'objecte a l'array de panells d'accés (q són els agrupats)
		var grupPanell = new UTILS_GMAPS.GrupPanellClass( equipmentObj.LocationClass.description );
		grupPanell.afegirPanell( equipmentObj );
		UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces.push( grupPanell );
	}

	// Funció que afegeix els panells q hem agrupat (d'accés) a l'array de panells visibles al màxim nivell de zoom.
	// @param atributs UTILS_GMAPS.AtributsClass propi de la concessió sobre la que estem treballant.
	UTILS_GMAPS.afegirPanellsAgrupats = function( atributs ) {
		if ( UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces != null ) {
			for ( iPanellsAgrupats = 0; iPanellsAgrupats < UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces.length; iPanellsAgrupats++ ) {
				// Agafem el primer panell per generar la info general (títol, tooltip i icona)
				var equipmentObj = UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces[iPanellsAgrupats].arrayPanells[0];
				// Formem el títol agafant les dades pertinent
				var titol = UTILS_GMAPS.getTextIdiomaCaps( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.PANELL ) + " "  + equipmentObj.LocationClass.highWayName + " PK " + equipmentObj.LocationClass.kmPoint/1000 + " " + equipmentObj.LocationClass.descDirection;
				// Posem la info del tooltip
				var strTooltip = titol;
				// Agafem la icona partir del nivell de servei de la incidéncia
				var levelNumber = UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_SENSE_DADES;
				//var levelNumber = UTILS_GMAPS.CONSTANTS_CLASS.SERVEI_TRANSIT_FLUID;	// TREURE!!! Posa't d'altre color x veure'l clar!!!
				var icona = UTILS_GMAPS.getIcona("PMV", levelNumber);
				
				// Creem el html de cada panell
				var htmlTabs = new Array();
				for ( jPanellsAgrupats = 0; jPanellsAgrupats < UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces[iPanellsAgrupats].arrayPanells.length; jPanellsAgrupats++ ) {
					var panell =  UTILS_GMAPS.AtributsClass.m_arrayPanellsAcces[iPanellsAgrupats].arrayPanells[jPanellsAgrupats];
					var msg = "";
					var iconaEsq = "";
					var iconaDreta = "";
					if ( panell.BoardClass.Message1.number != -1 ) { // Ho ha de ser!
						msg = panell.BoardClass.Message1.message;
						if ( panell.BoardClass.Message1.leftIcon != null )
							iconaEsq = "./img/Pictograms/" + panell.BoardClass.Message1.leftIcon + "_2.bmp";
						if ( panell.BoardClass.Message1.rightIcon != null )
							iconaDreta = "./img/Pictograms/" + panell.BoardClass.Message1.rightIcon + "_2.bmp";
					}
					var msg2 = "";
					var iconaEsq2 = "";
					var iconaDreta2 = "";
					if ( panell.BoardClass.Message2.number != -1) {
						msg2 = panell.BoardClass.Message2.message;
						if ( panell.BoardClass.Message2.leftIcon != null )
							iconaEsq2 = "./img/Pictograms/" + panell.BoardClass.Message2.leftIcon + "_2.bmp";
						if ( panell.BoardClass.Message2.rightIcon != null )
							iconaDreta2 = "./img/Pictograms/" + panell.BoardClass.Message2.rightIcon + "_2.bmp";
					}
					var htmlInfoGeneral = UTILS_GMAPS.htmlPanell(titol, msg, iconaEsq, iconaDreta, levelNumber, msg2, iconaEsq2, iconaDreta2);
					htmlTabs.push( htmlInfoGeneral );
				}
				// Creem el marker amb la icona i la info general
				var baseIcon = UTILS_GMAPS.crearIconaMarker( icona, equipmentObj.LocationClass.highWayName, equipmentObj.LocationClass.descDirection, equipmentObj.LocationClass.kmPoint );
				var markerOptions = { icon:baseIcon };
				var marker = UTILS_GMAPS.crearMarkerPanellsAgrupats( equipmentObj.LocationClass.latlng, markerOptions, strTooltip, htmlTabs, atributs );
				atributs.map.addOverlay( marker );
				marker.hide();
				atributs.m_arrayPanellsMaxZoom.push(marker);
			}
		}
	}

	// Funció que comprova la data passada amb la data del sevidor.
	// Si la data passada és + antiga q la data del servidor + un marge de 15 minuts, marca l'error
	// a l'atribut UTILS_GMAPS.AtributsClass.m_bDataOk i posa com a data la data actual.
	// Si no, marca l'atribut com OK i posa com a data la del fitxer
	UTILS_GMAPS.checkData = function( strDataFitxer ) {
		// TREURE!!!!!! POSAT PER PROVES EN LOCAL (SENSE PHP)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
		//UTILS_GMAPS.AtributsClass.m_bDataOk = true;
		//UTILS_GMAPS.AtributsClass.m_strDataFitxer = UTILS_ABERTIS.dataActual();
		//return;
		// END TREURE!!!!!! POSAT PER PROVES EN LOCAL (SENSE PHP)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

		// Passem un '1' a UTILS_ABERTIS.strData2Date per indicar que ha de descontar un mes.
		var dateFitxer = UTILS_ABERTIS.strData2Date( strDataFitxer, 1 );
		if ( dateFitxer != null ) {
			UTILS_GMAPS.AtributsClass.m_strDataFitxer = UTILS_ABERTIS.parseData( strDataFitxer );
			var dateServer = UTILS_ABERTIS.getServerDate();
			var dif = dateServer.getTime() - dateFitxer.getTime();
			if ( dif <= 15*60*1000 ) {	// Donem 15 minuts de marge. Tenim la dif en mili segons, per tant 15min = 1000*60*15
				UTILS_GMAPS.AtributsClass.m_bDataOk = true;
			}
			else {
				// La data del fitxer és antiga. Posem el bool d'error i agafem com a data la data actual
				UTILS_GMAPS.AtributsClass.m_bDataOk = false;
				UTILS_GMAPS.AtributsClass.m_strDataFitxer = UTILS_ABERTIS.dataActual();
			}
		}
		else {
			// No hem pogut llegir la data del fitxer. Posem el bool d'error i agafem com a data la data actual
			UTILS_GMAPS.AtributsClass.m_strDataFitxer = UTILS_ABERTIS.dataActual();
			UTILS_GMAPS.AtributsClass.m_bDataOk = false;
		}
	}

	// Funció que crea un div per informar que el sistema es troba fora de servei
	UTILS_GMAPS.crearMsgErrorDates = function() {
		// Ens assegurem que no el tenim ja creat
		if ( document.getElementById("div_errorData") == null ) {
			var tip = document.createElement("div"); 
			tip.setAttribute("id","div_errorData"); 
			document.getElementById("map").appendChild(tip); 
			var pos = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(150,250)); 
			pos.apply(document.getElementById("div_errorData")); 
			tip.style.visibility="hidden";
		}
	}

	// Mostrar el msg passat en el div de fora de servei
	// @param msg El missatge a mostrar. Si es passa un msg en blanc, s'amaga el div.
	UTILS_GMAPS.mostrarMsgErrorDates = function( msg ){ 
		if ( msg.length > 0 ) {
			document.getElementById("div_errorData").innerHTML = "<div style='background-color:#ffffff;font-size:16px;font-family:arial;font-weight:bold;border:1px #000000 solid'><table width = 345px><tr><td width=1px></td><td>" + msg + "</td><td width=1px></td></tr></table></div>";
			document.getElementById("div_errorData").style.visibility="visible";
	  }
		else {
			// Abans d'amagar-lo, ens assegurem que el tenim creat
			if ( document.getElementById("div_errorData") != null )
	  		document.getElementById("div_errorData").style.visibility="hidden";
	  }
	}

	// Funció que posa la data d'actualització al tag html passat.
	// Com a data d'actualització, s'agafa la data del fitxer
	// @param idData Id del tag HTML on es vol psoar al data d'actualització
	UTILS_GMAPS.actualizarData = function ( idData ) {
		document.getElementById(idData).innerHTML = UTILS_GMAPS.AtributsClass.m_strDataFitxer;
	}


	UTILS_GMAPS.crearMarkerPanellsAgrupats = function( latlng, markerOptions, strTooltip, htmlTabs, AtributsConcessio ) {
		var marker = new GMarker(latlng, markerOptions);
		// Si passem tooltip, el posem, i creem els seus events
		if ( strTooltip.length > 0 ) {
			marker.tooltip = "<div style='width:150px; background-color:#eeeeee; color:#888888; padding: 10px 5px; border: solid 1px #888888;'>" + strTooltip + "</div>";
	  	GEvent.addListener(marker,"mouseover", function() {
				UTILS_GMAPS.showTooltip(marker, AtributsConcessio);
	    });        
	    GEvent.addListener(marker,"mouseout", function() {
				AtributsConcessio.m_tooltip.style.visibility="hidden";
	    });
	    // Dibuixem una línia de la icona a la seva coordenada real quan fem click a la icona.
	    // Quan tanquem la finestra de info esborrem la línia
	    var linia;
	    GEvent.addListener(marker,"click", function() {
				linia = UTILS_GMAPS.getLiniaIcona( marker, AtributsConcessio.map );	    	
				AtributsConcessio.map.addOverlay( linia );
	    });        
	    GEvent.addListener(marker,"infowindowclose", function() {
				AtributsConcessio.map.removeOverlay( linia );
	    });        
		}
	
		// Posem l'event de click: obrir una info
		GEvent.addListener(marker,"click", function() {
			AtributsConcessio.m_tooltip.style.visibility="hidden";	// Si apretem la icona, amaguem el tooltip
			var tabs = [];
			for ( iTab = 0; iTab < htmlTabs.length; iTab++ ) {
				tabs.push(new GInfoWindowTab(UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.PANELL )+" "+(iTab+1),htmlTabs[iTab]));
			}
			marker.openInfoWindowTabsHtml(tabs);
				
		});
		return marker;
	}


	UTILS_GMAPS.htmlMeteo = function(titol, temp, vent, pluja, pluja24h) {
		var html = UTILS_GMAPS.htmlTitol( titol, UTILS_GMAPS.ICONA_ESTACIO_METEO );	// Agafem el títol
		html += "<table class='markerInfoTableHeader' cellpadding='3' cellspacing='2' border='0'>";

		if ( temp == null )
			html += "<tr><td width=30%>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.TEMPERATURA ) + "</td><td> </td></tr>";
		else
			html += "<tr><td width=30%>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.TEMPERATURA ) + "</td><td> " + temp + "</td></tr>";
		if ( vent == null )
			html += "<tr><td width=30%>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.VENT ) + "</td><td> </td></tr>";
		else
			html += "<tr><td width=30%>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.VENT ) + "</td><td> " + vent + "</td></tr>";
		if ( pluja == null )
			html += "<tr><td> width=30%" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.PLUJA ) + "</td><td> </td></tr>";
		else
			html += "<tr><td width=30%>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.PLUJA ) + "</td><td> " + pluja + "</td></tr>";
		if ( pluja24h == null )
			html += "<tr><td width=30%>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.PLUJA24H ) + "</td><td> </td></tr>";
		else
			html += "<tr><td width=30%>" + UTILS_GMAPS.getTextIdioma( UTILS_GMAPS.getIdiomaActual(), UTILS_GMAPS.IDIOMA.TEXTS.PLUJA24H ) + "</td><td> " + pluja24h + "</td></tr>";
		return html;
	}

	// Funció que retorna l'ordre de la icona en funció del típus de la icona i el seu nivell de servei.
	// Aquests 2 valors es guarden com a característiques de la icona
	// @param marker El GMarker de la icona
	// @param b DESCONEGUT. Google passa aquests 2 paràmetres, però de moment no fem servir el 2on.
	// @return L'índex de l'ordre de la icona
	UTILS_GMAPS.ordreIcones = function(marker,b) {
		return GOverlay.getZIndex(marker.getPoint().lat()) - 1000000;
		/*
		// Ordre (de - a +): Sortides, Equipaments, Incidencies
		//return GOverlay.getZIndex(marker.getPoint().lat()) + marker.importance*1000000;
		if ( marker.tipus == "SORTIDA" ) {
			return GOverlay.getZIndex(marker.getPoint().lat()) - 1000000;
		}
		else if ( ( marker.tipus == "CAM" ) || ( tipus == "PMV" ) || ( tipus == "EST_MET" ) ) {	// Els equipaments
			return GOverlay.getZIndex(marker.getPoint().lat()) - 100000;
		}
		else {	// Les incidencies. Podriem definir algun ordre concret entre elles i fer servir el nivell per definir un altre ordre.
			return GOverlay.getZIndex(marker.getPoint().lat());
		}
		*/
	}
	
	// Funció que reb una cadena amb el msg de Warning. Si el missatge està en blanc, no es mostra el camp d'alarma.
	// Si hi ha un msg, es crida a un métode que el mostra amb un scroll
	// @param msg El msg d'alarma
	UTILS_GMAPS.mostrarMsgAlert = function(msg, level) {
		/*
		if ( msg != null ) {
			if ( msg.length > 0 ) {
				// Posem blancs al davant del text (pe que es vagi desplaçant des del final
				//while ( msg.length < 235 )
				//	msg = " " + msg;
				// Assignem el missatge i el mostrem amb el scroll
				//document.formMsgAlert.msgAlert.style.display = "block";
				//UTILS_GMAPS.AtributsClass.m_msgAlert = msg;
				//UTILS_GMAPS.scrollMsgAlert();

				// Si deixem el texte fixe, fem això ennloc del while i la crida:
				document.formMsgAlert.msgAlert.style.display = "block";
				document.formMsgAlert.msgAlert.value = msg;
		  }
			else {
				document.formMsgAlert.msgAlert.value = "";
				document.formMsgAlert.msgAlert.style.display = "none";
			}
		}
		else {
			document.formMsgAlert.msgAlert.value = "";
			document.formMsgAlert.msgAlert.style.display = "none";
		}
		*/
		
		var tDivMsgAlert = document.getElementById("divMsgAlert");
		if ( msg != null ) {
			if ( msg.length > 0 ) {
				tDivMsgAlert.style.visibility = 'visible'; 
				tDivMsgAlert.innerHTML = msg; 
				if ( level == 0 ) 
					tDivMsgAlert.className = "classDivMsgAlert0";
				else if ( level == 1 ) 
					tDivMsgAlert.className = "classDivMsgAlert1";
				else if ( level == 2 ) 
					tDivMsgAlert.className = "classDivMsgAlert2";
				else 
					tDivMsgAlert.className = "classDivMsgAlert0";
		  }
			else {
				tDivMsgAlert.style.visibility = 'hidden'; 
				tDivMsgAlert.innerHTML = ""; 
			}
		}
		else {
			tDivMsgAlert.style.visibility = 'hidden'; 
			tDivMsgAlert.innerHTML = ""; 
		}
		
	}
	
	// Funció que mostra el msg d'alarma (movent-se horitzontalment en scroll)en un camp de text.
	UTILS_GMAPS.scrollMsgAlert = function() {
		document.formMsgAlert.msgAlert.value = UTILS_GMAPS.AtributsClass.m_msgAlert;
		UTILS_GMAPS.AtributsClass.m_msgAlert = UTILS_GMAPS.AtributsClass.m_msgAlert.substring(1, UTILS_GMAPS.AtributsClass.m_msgAlert.length) + UTILS_GMAPS.AtributsClass.m_msgAlert.charAt(0);
		window.setTimeout("UTILS_GMAPS.scrollMsgAlert()",100);
	}

	UTILS_GMAPS.getWarningMessage = function( elementsXML ) {
		//return elementsXML.getAttribute("Warning");
		var msg = ""
		var warningLevel = -1;
		var eWarnings = elementsXML.getElementsByTagName("Warning");
		if ( eWarnings != null ) {
			if ( eWarnings.length > 0 ) {
				var eMessages = eWarnings[0].getElementsByTagName("WarningParameters");
				if ( eMessages != null ) {
					if ( eMessages.length > 0 ) {
						// Agafem el missatge de warning en els 4 idiomes i el nivell de criticitat
						var msgCas = eMessages[0].getAttribute("WarningTextCas");	// Sempre hi serà si tenim un warning!!!!
						var msgCat = eMessages[0].getAttribute("WarningTextCat");
						var msgEng = eMessages[0].getAttribute("WarningTextEng");
						var msgFr = eMessages[0].getAttribute("WarningTextFr");
						warningLevel = eMessages[0].getAttribute("level");

						// Si no tenim msg en cat o eng o fr, el posem en cas
						if ( msgCat != null ) {
							if ( msgCat.length == 0 ) {
								msgCat = msgCas;
							}
						}
						else {
							msgCat = msgCas;
						}
						if ( msgEng != null ) {
							if ( msgEng.length == 0 ) {
								msgCat = msgCas;
							}msgEng
						}
						else {
							msgEng = msgCas;
						}
						if ( msgFr != null ) {
							if ( msgFr.length == 0 ) {
								msgFr = msgCas;
							}
						}
						else {
							msgFr = msgCas;
						}
						
	
						// Agafem el msg q ens toca (segons l'idioma q tenim selecionat)
						if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.CAT ) {
							msg = msgCat;
						}
						else if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.CAS ) {
							msg = msgCas;
						}
						else if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.ENG ) {
							msg = msgEng;
						}
						else if ( UTILS_GMAPS.getIdiomaActual() == UTILS_GMAPS.IDIOMA.FR ) {
							msg = msgFr;
						}
						else {
							msg = msgCas;
						}
					}
				}
			}
		}
		var aReturn = [msg, warningLevel];
		return aReturn;
	}
