﻿function setOriginalTileUrl(tilelayer) {
	var svc = grafcan.cfg.getService(grafcan.curService);
	var getTileUrl;
	for (var s in svc.layers) {
		if (svc.layers[s].layers==tilelayer.myLayers) {
			getTileUrl = svc.layers[s].tileFunction;
			break;
		}
	}
	svc=null;
	tilelayer.getTileUrl = eval(getTileUrl);
}
/*
 * Dimensiones de la aplicación
 */
function getHeight() {
	// ventana-toolbar-header-titulo
	//var height = windowHeight() - $id('toolbar').offsetHeight - ((grafcan.minSize>0)?0:$id('header').offsetHeight+4) - ((grafcan.minSize>0)?10:30);
	var height = windowHeight() - $id('header').offsetHeight - $id('titulo').offsetHeight - $id('toolbar').offsetHeight;
	height -= parseInt($ie()?$id('toolbar').currentStyle.marginTop:document.defaultView.getComputedStyle(document.getElementById('toolbar'),'').marginTop)
	height -= parseInt($ie()?$id('content').currentStyle.marginTop:document.defaultView.getComputedStyle(document.getElementById('content'),'').marginTop)
	return height;
}
function handleResize() {
	var isSidebar = $ie()?$id('sidebar').currentStyle.display!='none':document.defaultView.getComputedStyle(document.getElementById('sidebar'),'').display!='none';
	var height = getHeight();
	if (height<0) return;
	$id('map1').style.height = height + 'px';
	if (grafcan.syncMode) {
		$id('map2').style.height = height + 'px';
		$id('map2').style.width = ($id('map1').offsetLeft+$id('map1').offsetWidth)+'px';
		$id('map2').style.left = $id('map1').offsetWidth+'px';
		grafcan.synchronizeMap2(map.getCenter(), map.getZoom());
	}
	var diff = ($ie()?27:25);
	$id('sidebar').style.height = height + 'px';
	try{$id('resultados-div').style.height = (height-100) + 'px';}catch(e){};
	if (grafcan.tree) grafcan.tree.setHeight(height-diff);
	if (grafcan.sidebarCollapse) {
		if (!grafcan.sidebarCollapse.isVisible()) grafcan.sidebarCollapse.show();
		grafcan.sidebarCollapse.setPagePosition(windowWidth()-grafcan.sidebarCollapse.getSize().width+7,$id('toolbar').offsetTop+($ie()?13:12));
		if (!grafcan.sidebarCollapse.isVisible()) grafcan.sidebarCollapse.show();
	}	
	try{$id('busquedas-panel').style.height=(height-diff)+'px';/*$id('leyenda').style.height=(height-diff)+'px';*/}catch(e){};
	try{$id('divLeyendas').style.height=(height-diff)+'px';}catch(e){};
	try{
		var altoAyuda = parseInt($id('divAyuda').offsetHeight);
		altoAyuda += parseInt($ie()?$id('divAyuda').currentStyle.marginTop:document.defaultView.getComputedStyle(document.getElementById('divAyuda'),'').marginTop);
		if ($ie())
			$id('busquedas-resultados-panel').style.height = (parseInt($id('sidebar').style.height)-(120+altoAyuda)) + 'px';
		else
			$id('busquedas-resultados-panel').style.height = (parseInt($id('sidebar').style.height)-(125+altoAyuda)) + 'px';
	}catch(ex){};
	var offsetLeft = (grafcan.embedded==1&&!isSidebar)?1:grafcan.offsetLeft;
	// coordenadas
	$id('coords').style.left = $id('coords_').style.left = (offsetLeft+(grafcan.embedded==1?(!isSidebar?0:7):0))+'px';
	// escala
	$id('scale').style.top = $id('scale_').style.top = (height-21)+'px';
	$id('scale').style.left = $id('scale_').style.left = ((grafcan.embedded==1&&!isSidebar)?1:offsetLeft) + (parseInt($id('map1').offsetWidth)/2-parseInt($id('scale').offsetWidth)/2)+'px';
}
var oGInterval = "";
var cuentaBlink = 0;
function blinkKML() {
	if (!grafcan.queryOverlay) return;
	var maxCuentaBlink = 4;
	if (grafcan.queryOverlay.isHidden())
		grafcan.queryOverlay.show();
	else
		grafcan.queryOverlay.hide();
	if (++cuentaBlink >= maxCuentaBlink) stopBlinkKML();
}
function startBlinkKML() {
	if (oGInterval!="") {
		stopBlinkKML();
	}
	oGInterval = window.setInterval("blinkKML()", 200);
}
function stopBlinkKML() {
	cuentaBlink = 0;
	if(oGInterval!="") {
		window.clearInterval(oGInterval);
		oGInterval = "";
	}
}
function iniZoomLevel() {
	// nivel de zoom para que quepa en las dimensiones del control mapa
	/*var latlngbounds = new GLatLngBounds(map.getBounds().getSouthWest(), map.getBounds().getNorthEast());
	return map.getBoundsZoomLevel(latlngbounds);*/
	if (map.getSize().width>900) return grafcan.Ini_Zoom+1;
	else return grafcan.Ini_Zoom;
}
function layerVisible(mylayers, level) {
	var svc = map.cfg.getService(grafcan.curService);
	for (var s in svc.layers) {
		if (svc.layers[s].layers==mylayers) break;
	}
	var visible = (level>=svc.layers[s].visibility.minResolution && level<=svc.layers[s].visibility.maxResolution);
	return visible;
}
function layerVisibleToNextZoomLevel(service, layerName, nextZoomLevel) {
	if (!service.layers[layerName]) {
		//alert('No se encontró la capa correspondiente a "' + layerName + '"');
		return false;
	}
	var zoomLevel = map.getZoom();
	if (nextZoomLevel) zoomLevel = nextZoomLevel;
	return (zoomLevel>=service.layers[layerName].visibility.minResolution && zoomLevel<=service.layers[layerName].visibility.maxResolution);
}
/*
 * Utility function to calculate the appropriate zoom level for a
 * given bounding box and map image size. Uses the formula described
 * in the Google Mapki (http://mapki.com/).
 *
 * @param  bounds  bounding box (GBounds instance)
 * @param  mnode   DOM element containing the map.
 * @return         zoom level.
 */
function best_zoom(bounds, mnode) {
    var width = mnode.offsetWidth;
    var height = mnode.offsetHeight;
	var dlat = Math.abs(bounds.maxY - bounds.minY);
    var dlon = Math.abs(bounds.maxX - bounds.minX);
    if(dlat == 0 && dlon == 0)
        return 4;

    // Center latitude in radians
    var clat = Math.PI*(bounds.minY + bounds.maxY)/360.;

    var C = 0.0000107288;
    var z0 = Math.ceil(Math.log(dlat/(C*height))/Math.LN2);
    var z1 = Math.ceil(Math.log(dlon/(C*width*Math.cos(clat)))/Math.LN2);

    return (z1 > z0) ? z1 : z0;
}
function centerKML(geoxml, oMap) {
	if (geoxml.getDefaultBounds()) {
		var zoomlevel = oMap.getBoundsZoomLevel(geoxml.getDefaultBounds());
		if (zoomlevel > grafcan.maxQueryZoomLevel) zoomlevel = grafcan.maxQueryZoomLevel;
		oMap.setCenter(geoxml.getDefaultCenter(), zoomlevel);		
	} else if (geoxml.getDefaultCenter()){
		oMap.setCenter(geoxml.getDefaultCenter(), 18);		
	}
	if (grafcan.syncMode) grafcan.synchronizeMap2(map1.getCenter(), map1.getZoom());
	
}
function blinkOverlay(overlay) {
	grafcan.queryOverlay = overlay;
	//startBlinkKML();
}
/*
 * Cursor del mapa
 */
function getMapCursor() {
	return $get_cursor($id(map.getContainer().id).firstChild.firstChild);
}
function setMapCursor(cursor) {
	$set_cursor($id(map1.getContainer().id).firstChild.firstChild, cursor);
	if (grafcan.syncMode) $set_cursor($id(map2.getContainer().id).firstChild.firstChild, cursor);
}
/*
 * Herramienta info
 */
function getInfo(pt, cfg) {
	var getURL = function(x, y, w, s, e, n, width, height, query, imageFormat) {
		var url = query.queryUrl;
		url+='&SERVICE=WMS';
		url+='&SRS=EPSG:4326';
		url+='&VERSION=1.1.1';
		url+='&REQUEST=GetFeatureInfo';
		url+='&X=' + parseInt(x);
		url+='&Y=' + parseInt(y);
		url+='&QUERY_LAYERS='+query.queryLayers;
		url+='&LAYERS='+query.queryLayers;
		url+='&STYLES=';
		url+='&INFO_FORMAT='+query.format;
		url+='&FORMAT='+imageFormat;
		url+='&BBOX='+w+','+s+','+e+','+n;
		url+='&WIDTH='+parseInt(width)+'&HEIGHT='+parseInt(height);
		return url;
	}	
	//var p = map.fromLatLngToContainerPixel(pt);
	// code from Lance on the Google Maps Group
	var b = grafcan.overMap.getBounds();
	var sw = b.getSouthWest();
	var ne = b.getNorthEast();
	var w = sw.lng();
	var e = ne.lng();
	var n = ne.lat();
	var s = sw.lat();
	var ts = s;
	var tw = w;
	if(n<s){s=n;n=ts;}
	if(e<w){w=e;e=tw;}
	if(s<-90)s=-90;
	if(n>90)n=90;
	if(e>180)e=180;
	if(w<-180)w=-180;

	var span_ew = Math.abs(e - w);
	var span_ns = Math.abs(n - s);
	//var width  = grafcan.overMap.getSize().width/2*(span_ew/span_ns);
	//var height = grafcan.overMap.getSize().height/2;
	var width  = grafcan.overMap.getSize().width;
	var height = grafcan.overMap.getSize().height;
	var x = (pt.x - w) * width/span_ew;
	var y = (n - pt.y) * height/span_ns;
	var utm = new geo2utm(pt);
	var label1 = 'Info';
	var label2 = _('Detalle');
	var html_2 = '<p style="margin:5px">Usted hizo clic en:<table border="0" style="margin-left:20px"><br/>'
			   + '<tr><td>'+_('Latitud')+'</td><td>'+_('Longitud')+'</td></tr>'
			   + '<tr><td><input type="text" readonly="true" size="14" value="' + (new DegreesFormat(pt.lat(), true).formatted) + '"/></td><td><input type="text" readonly="true" size="14" value="' + (new DegreesFormat(pt.lng(), false).formatted) + '"/></td></tr>'
			   + '<tr><td colspan=2>&nbsp;</td></tr>'
			   + '<tr><td>X</td><td>Y</td></tr>'
			   + '<tr><td><input type="text" readonly="true" size="14" value="' + formatNumber(utm.x, 2) + '"/></td><td><input type="text" readonly="true" size="14" value="' + formatNumber(utm.y, 2) + '"/></td></tr></table></p>';
	// recuperamos el formato de imagen de la capa consultable
	var imageFormat = (cfg.query.imageFormat?cfg.query.imageFormat:'image/png');
	for (var capa in cfg.layers) {
		if (cfg.layers[capa].layers.indexOf(cfg.query.queryLayers)>-1) {
			imageFormat = cfg.layers[capa].format;
			break;
		}
	}
	var URL = getURL(x, y, w, s, e, n, width, height, cfg.query, imageFormat);
	//var cursorMap = getMapCursor();
	setMapCursor('wait');
	GDownloadUrl('pages/genProxy.php?target='+encodeURIComponent(URL), function(data, responseCode) {
		if (responseCode==200) {
			if (data.length>0) {
				var p = new GPoint(pt);
				var html_1 = '<a href="javascript:grafcan.zoomIn('+p+');">'+_('Acercar')+'</a>&nbsp;|&nbsp;'
						   + '<a href="javascript:grafcan.zoomOut('+p+');">'+_('Alejar')+'</a>&nbsp;|&nbsp;'
						   + '<a href="'+URL+'" target="_blank">'+_('Abrir en nueva ventana')+'</a>'
						   + '<br><br><iframe id="iframeInfo" marginheight="2" marginwidth="2" style="width:500;height:250px" src="'+URL+'""></iframe>';
				grafcan.overMap.openInfoWindowTabsHtml(pt, [new GInfoWindowTab(label1,html_1), new GInfoWindowTab(label2,html_2)]);
				//setMapCursor(cursorMap);
			}
		}
	});
}
/*
 * Búsquedas
 */
function buscarToponimia(url, ipp, porZona) {
	function wait(flag) {
		$id('imgBusquedas').style.visibility = (flag)?'visible':'hidden';
	}
	function callback(xml) {
		if (!xml.documentElement || xml.documentElement.nodeName!='rows') {
			wait(false);
			alert(_('El sistema de búsquedas no está funcionando correctamente. Contacte con el administrador.'));
			return;
		} else if (xml.documentElement.attributes.getNamedItem("total") && xml.documentElement.attributes.getNamedItem("total").value==0) {
			wait(false);
			alert(_('No se encontró ninguna coincidencia'));
			return;
		}
		var xsl=$loadXML("scripts/toponimia.xsl");
		if (window.ActiveXObject) {
			var ex=xml.transformNode(xsl);
			activateBusquedas(true, ex);
		} else if (document.implementation && document.implementation.createDocument) {
			xsltProcessor=new XSLTProcessor();
			xsltProcessor.importStylesheet(xsl);
			var resultDocument = xsltProcessor.transformToDocument(xml);
			activateBusquedas(true, resultDocument.body.innerHTML);
		}
		wait(false);
		grafcan.currentTopoString = txt;
	}
	if (!ipp) ipp = 10;
	var txt = $id('toponimo').value;
	if (txt.length<3) {
		alert(_('Especifique un texto de búsqueda de al menos tres caracteres'));
		$id('toponimo').focus();		
		return false;
	}
	wait(true);
	var baseUrl = grafcan.urlBaseBusquedas;
	if (url) {
		// /toponimiaxml/2/10/<texto_busqueda>/"
		// /toponimiaxmlbbox/2/10/<texto_busqueda>/bbox/0/0/"
		var c = 0;
		var idx = 0;
		do{
		   idx = url.indexOf("/", idx);
		   ++idx;++c;
		   switch (c) {
			  case 4:
				 ini = idx;
				 break;
			  case 5:
				 fin = idx-1;
				 idx=url.length;
				 break;
		   }
		}while (idx<url.length);
		url = url.substring(0,ini) + encodeURIComponent(url.substring(ini,fin)) + url.substring(fin);
	}
	if (porZona) {
		var sw = new geo2utm(map.getBounds().getSouthWest());
		var ne = new geo2utm(map.getBounds().getNorthEast());
		var bbox = sw.x+","+sw.y+","+ne.x+","+ne.y;
		var xy = "0/0/";
		var topoURL = baseUrl + ((url)?url:"/toponimiaxmlbbox/1/"+ipp+"/"+encodeURIComponent(txt)+"/"+bbox+"/"+xy);
	} else
		var topoURL = baseUrl + ((url)?url:"/toponimiaxml/1/"+ipp+"/"+encodeURIComponent(txt)+"/");		
	//var url = grafcan.urlTopoProxy+'?proxy_url=' + encodeURIComponent(topoURL);
	var xml=$loadXML(topoURL, callback);
}
function situarToponimia(topoPos, topoID, topoPage, topoNumPage, toponimo) {
	if (!grafcan.overlayRepository) grafcan.clearQueryOverlay(true);	
	var kmlURL = grafcan.urlBaseBusquedas+"/toponimiakml/"+topoPage+"/"+topoNumPage+"/"+encodeURIComponent(grafcan.currentTopoString)+"/"+topoPos+"/"+topoID+"/";
	var geoxml = loadKML(kmlURL,function(){
									centerKML(geoxml, map);
									grafcan.queryOverlay = geoxml;
									grafcan.queryOverlayURL = kmlURL;
									window.focus();
								},
								function() {alert(_('Error al cargar el elemento asociado al topónimo'))});
	addCosa(toponimo,geoxml,kmlURL);
	map1.addOverlay(geoxml);
	if (grafcan.syncMode) {
		grafcan.queryOverlay2 = geoxml.copy();
		map2.addOverlay(grafcan.queryOverlay2);
	}
}
function situarUTM(_x, _y) {
	var x;
	var y;
	if (_x != null && _y != null) {
		x = parseInt(_x);
		y = parseInt(_y);
	} else {
		x = parseInt($id("utmX").value);
		y = parseInt($id("utmY").value);
	}
	if (isNaN(x)) {
		alert(Gettext.strargs(_('La coordenada %1 no es válida'),'X'));
		$id("utmX").focus();
		return false;
	}
	if (isNaN(y)) {
		alert(Gettext.strargs(_('La coordenada %1 no es válida'),'Y'));
		$id("utmY").focus();
		return false;
	}
	if (x<grafcan.LimitExtent.left || x>grafcan.LimitExtent.right || y<grafcan.LimitExtent.bottom || y>grafcan.LimitExtent.top) {
		var msg = _('Las coordenadas no son válidas. El rango válido es el siguiente')+":\n"
		        + "\n\tX "+_('de')+"  " + formatNumber(grafcan.LimitExtent.left, 0) + "  "+_('a')+"  " + formatNumber(grafcan.LimitExtent.right, 0)
				+ "\n\tY "+_('de')+"  " + formatNumber(grafcan.LimitExtent.bottom, 0) + "  "+_('a')+"  " + formatNumber(grafcan.LimitExtent.top, 0);
		alert(msg);
		return false;
	}
	
	var ll = UTMRefToLatLng(x, y, grafcan.Huso.Numero, grafcan.Huso.Letra);
	gotoGeoPoint(ll.lat, ll.lng);
}
function situarLatLon(lat_deg, lat_min, lat_sec, lat_ew, lon_deg, lon_min, lon_sec, lon_ns) {
	if (!lat_deg) {
		try {
			lat_deg = $id('searchLat_deg').value;
			lat_min = $id('searchLat_min').value;
			lat_sec = $id('searchLat_sec').value;
			lat_ns = $get_innerText('searchLat_ns')=='S'?-1:1;
		} catch(ex) {
			alert(_('Latitud inválida'));
			return false;
		}
	}
	if (!lon_deg) {
		try {
			lon_deg = $id('searchLon_deg').value;
			lon_min = $id('searchLon_min').value;
			lon_sec = $id('searchLon_sec').value;
			lon_ew = $get_innerText('searchLon_ew')=='O'?-1:1;
		} catch(ex) {
			alert(_('Longitud inválida'));
			return false;
		}
	}
	var lat = 0;
	var lon = 0;
	try {
		lat = parseFloat(lat_deg) + (parseFloat(lat_min)/60) + (parseFloat(lat_sec)/3600) * lat_ns;
	} catch (ex) {
		alert(_('Latitud inválida'));
		return false;
	}
	try {
		lon = (parseFloat(lon_deg) + (parseFloat(lon_min)/60) + (parseFloat(lon_sec)/3600)) * lon_ew;
	} catch (ex) {
		alert(_('Longitud inválida'));
		return false;
	}
	if (lat<grafcan.boundsLimit.getSouthWest().lat() || lat>grafcan.boundsLimit.getNorthEast().lat() || lon<grafcan.boundsLimit.getSouthWest().lng() || lon>grafcan.boundsLimit.getNorthEast().lng()) {
		var msg = _('Las coordenadas no son válidas. El rango válido es el siguiente')+":\n"
				+ "\n\t"+_('Latitud')+" "+_('de')+"  " + new DegreesFormat(grafcan.boundsLimit.getSouthWest().lat(), true, 0).formatted + "  "+_('a')+"  " + new DegreesFormat(grafcan.boundsLimit.getNorthEast().lat(), true, 0).formatted
		        + "\n\t"+_('Longitud')+" "+_('de')+"  " + new DegreesFormat(grafcan.boundsLimit.getNorthEast().lng(), false, 0).formatted + "  "+_('a')+"  " + new DegreesFormat(grafcan.boundsLimit.getSouthWest().lng(), false, 0).formatted;
		alert(msg);
		return false;
	}
	gotoGeoPoint(lat, lon);
}
function gotoGeoPoint(lat, lon) {
	var center = new GLatLng(lat, lon);
	map.setCenter(center, 18);
	if (grafcan.queryOverlay) {
		try {
			map.removeOverlay(grafcan.queryOverlay);
		} catch (ex) {}
	}
	grafcan.queryOverlayURL = center;
	var utm = new geo2utm(center);
	var title = _('Latitud')+': ' + new DegreesFormat(lat,true).formatted + '  '+_('Longitud')+': ' + new DegreesFormat(lon,false).formatted
	          + '\nX: ' + formatNumber(utm.x, 2) + '  Y: ' + formatNumber(utm.y, 2);
	grafcan.queryOverlay = new GMarker(center, {title:title});
	map.addOverlay(grafcan.queryOverlay);
	blinkOverlay(grafcan.queryOverlay);
	center=null;
}
function situarCoordenadas() {
	if (document.getElementsByName('optCoord')[0].checked)
		situarUTM();
	else
		situarLatLon();
}
/* Fin rutinas búsquedas */
function lockedPopups(oWin, alertar) {
	if (oWin==null || typeof(oWin)=="undefined") {
		if (alertar) alert(_('Para el correcto funcionamiento de la aplicación, desactive el bloqueo de popups.'));
		return true;
	}
	return false;
}

function numeros(event, negativo)
{
	var keyCode = $keyCode(event);
	if((keyCode>=48 && keyCode<=57) || keyCode==46 || (keyCode>=8 && keyCode<=9) || (keyCode>=35 && keyCode<=39) || (negativo && keyCode==45)) return true;
	return false;
}
/*
 * Rutinas de mediciones
 */
var removeShape = function() {};
var removePolyline = function() {};
var removePolygon = function() {};
var earthRadius = 6378137; // in metres
var latlngs = [];
// anticipates two 3-element arrays representing 3d vectors, returns a 3-element array representing their cross-product
function crossProduct(a, b) {
	return [(a[1] * b[2]) - (a[2] * b[1]), 
			(a[2] * b[0]) - (a[0] * b[2]), 
			(a[0] * b[1]) - (a[1] * b[0])];
}
// anticipates two 3-element arrays, returns scalar value
function dotProduct(a, b) {
	return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]);
}
function spherePointAngle(A, B, C) { // returns angle at B
    return Math.atan2(dotProduct(crossProduct(C, B), A), dotProduct(crossProduct(B, A), crossProduct(B, C)));
}
// returns 3-element array representing cartesian location of a point given by a GLatLng object
function cartesianCoordinates(latlng) {
    var x = Math.cos(latlng.latRadians()) * Math.sin(latlng.lngRadians());
    var y = Math.cos(latlng.latRadians()) * Math.cos(latlng.lngRadians());
    var z = Math.sin(latlng.latRadians());
	return [x, y, z];
}
// Calculate area inside of polygon, in square metres
function polylineArea(latlngs) {
	var id, sum = 0, pointCount = latlngs.length, cartesians = [];
	if (pointCount < 3) return 0;
	
	for (id in latlngs) {
	    cartesians[id] = cartesianCoordinates(latlngs[id]);
	}
	
	// pad out with the first two elements
	cartesians.push(cartesians[0]);
	cartesians.push(cartesians[1]);
		
	for(id = 0; id < pointCount; id++) {
		var A = cartesians[id];
		var B = cartesians[id + 1];
		var C = cartesians[id + 2];
		sum += spherePointAngle(A, B, C);
	}

	var alpha = Math.abs(sum - (pointCount - 2) * Math.PI);
    alpha -= 2 * Math.PI * Math.floor(alpha / (2 * Math.PI));
    alpha = Math.min(alpha, 4 * Math.PI - alpha);    	
	
	return Math.round(alpha * Math.pow(earthRadius, 2));
}
function marker_dragend(latlng) {
	latlngs[this.latlngsId] = latlng;
	redrawShape();
	if (grafcan.makePerfil && grafcan.perfil && grafcan.perfil.isVisible()) {
		grafcan.endMeasure(1, true); //refrescamos perfil
	}
}
function initializePoint(id) {
	var marker = new GMarker(latlngs[id], {draggable:true,title:'Vértice '+id});
	marker.latlngsId = id; // necesario cuando se modifica el título del marker
	map.addOverlay(marker);
	grafcan.measureOverlay.push(marker);
	GEvent.addListener(marker, 'dragend', marker_dragend);
	GEvent.addListener(marker, 'click', measureMarker_click);
}
function marker_click(latlng) {
	var marker=this;
	var markerWindow = Ext.getCmp('marker-window');
	if (!markerWindow) {
		fp = new Ext.FormPanel({
			closable:true,
			border:false,
			bodyStyle:'padding:10px;',
			defaultType:'textfield',
			defaults: {
				anchor: '100%',
				allowBlank: false,
				labelSeparator: ''
			},
			items:[{id:'marker-categoria',
					xtype: 'combo',
					fieldLabel: _('Categoría'),
					displayField: 'catDesc',
					valueField: 'catId',
					typeAhead: true,
					lazyRender: true,
					triggerAction: 'all',
					store: new Ext.data.Store({
						proxy: new Ext.data.HttpProxy({
							url: 'pages/CallejeroTypes.php'
						}),
						reader: new Ext.data.XmlReader({record: 'object'}, [{name:'catDesc',mapping:'field'},{name:'catId',mapping:'@pk'}])
					}),
					width:150},
					{id:'marker-texto',
					xtype:'textarea',
					fieldLabel: _('Comentario'),
					readOnly:false,
					value:marker.getTitle(),
					width:150}
			],
			bbar: new Ext.Toolbar({
				defaultText: '',
				statusAlign: 'right',
				items: [{id:'marker-enviar',text:_('Enviar'),
						 listeners:{
							 'click':function(b,e){
								var categoria = b.ownerCt.ownerCt.findById('marker-categoria').getValue();
								var comment = b.ownerCt.ownerCt.findById('marker-texto').getValue();
								if (categoria=='') return false;
								if (comment=='') return false;
								if (grafcan.overlayRepository) {
									for (var id in grafcan.cosas) {
										if (grafcan.cosas[id]==marker) {
											var latlng = marker.getLatLng();
											break;
										}
									}
								} else {
									var latlng = grafcan.markerOverlay.getLatLng();
								}
								var wfst = new WFST();
								wfst.addVia(comment,categoria,3,latlng.lat(),latlng.lng());
								b.ownerCt.ownerCt.ownerCt.close();
								setToolMode(grafcan.defaultToolMode);
							 }
						 }
						},
						{id:'marker-borrar',text:_('Cancelar'),
						 listeners:{
							 'click':function(b,e){
								if (grafcan.overlayRepository) {
									var store = Ext.getCmp('gridCosas').getStore();
									for (var id in grafcan.cosas) {
										if (grafcan.cosas[id]==marker) {
											var record = store.getById(id);
											store.remove(record);
										}
									}
								} else {
									map.removeOverlay(grafcan.markerOverlay);
									grafcan.markerOverlay = null;
								}
								b.ownerCt.ownerCt.ownerCt.close();
							 }
						 }
						}
					]
			})
		});
		markerWindow = new Ext.Window({
			id:'marker-window',
			title:_('Información de errores - IDECanarias'),
			resizable:false,
			constrain:true,
			width:300,autoHeight:true,
			items:[fp],
			listeners:{'close':function(){setToolMode(grafcan.defaultToolMode)}}
		})
	}
	markerWindow.show();
}
function measureMarker_click(latlng) {
	var marker=this;
	var markerWindow = Ext.getCmp('marker-window');
	if (!markerWindow) {
		fp = new Ext.FormPanel({
			closable:true,
			border:false,
			bodyStyle:'padding:10px;',
			defaultType:'textfield',
			defaults: {
				anchor: '100%',
				allowBlank: false
			},
			items:[{id:'marker-texto',
					hideLabel:true,
					readOnly:false,
					value:marker.getTitle(),
					width:120}
			],
			bbar: new Ext.Toolbar({
				defaultText: '',
				statusAlign: 'right',
				items: [{id:'marker-aceptar',text:_('Modificar'),
						 listeners:{
							 'click':function(b,e){
								var id = marker.latlngsId;
								latlngs[id] = marker.getLatLng();
								map.removeOverlay(marker);
								marker = new GMarker(latlngs[id], {title:b.ownerCt.ownerCt.findById('marker-texto').getValue(),draggable:true});
								GEvent.addListener(marker,'click',measureMarker_click);
								marker.latlngsId = id;
								GEvent.addListener(marker, 'dragend', marker_dragend);
								map.addOverlay(marker);
								grafcan.measureOverlay[marker.latlngsId] = marker;
								b.ownerCt.ownerCt.ownerCt.close();
							 }
						}
				}]
			})
		});
		markerWindow = new Ext.Window({
			id:'marker-window',
			title:_('Información del marcador'),
			resizable:false,
			constrain:true,
			width:250,autoHeight:true,
			items:[fp]
		})
	}
	markerWindow.show();
}
function getMarkerIcon(id) {
	var myIcon = new GIcon();
	myIcon.image = 'img/markers/image.png';
	myIcon.shadow = 'img/markers/shadow.png';
	myIcon.iconSize = new GSize(32,32);
	myIcon.shadowSize = new GSize(48,32);
	myIcon.iconAnchor = new GPoint(16,32);
	myIcon.infoWindowAnchor = new GPoint(16,0);
	myIcon.printImage = 'img/markers/printImage.gif';
	myIcon.mozPrintImage = 'img/markers/mozPrintImage.gif';
	myIcon.printShadow = 'img/markers/printShadow.gif';
	myIcon.transparent = 'img/markers/transparent.png';
	myIcon.imageMap = [20,0,21,1,22,2,23,3,24,4,24,5,24,6,24,7,24,8,24,9,24,10,24,11,24,12,24,13,23,14,22,15,21,16,21,17,20,18,20,19,19,20,19,21,18,22,18,23,18,24,17,25,17,26,17,27,17,28,17,29,17,30,17,31,14,31,14,30,14,29,14,28,14,27,14,26,14,25,14,24,13,23,13,22,13,21,12,20,12,19,11,18,10,17,10,16,9,15,8,14,7,13,7,12,7,11,7,10,7,9,7,8,7,7,7,6,7,5,7,4,8,3,9,2,10,1,11,0];			if (!grafcan.overlayRepository) try{map.removeOverlay(grafcan.markerOverlay)}catch(e){};
	return myIcon;
}
function handleMapClick(marker, latlng) {
	if (!marker) {
		if (map.toolMode==grafcan.toolMode.setMarker) {
			//
			var myIcon = getMarkerIcon('callejero');
			//
			grafcan.markerOverlay = new GMarker(latlng,{icon:myIcon,draggable:false,title:(grafcan.markerOverlay && grafcan.markerOverlay.getTitle()?grafcan.markerOverlay.getTitle():'')});
			GEvent.addListener(grafcan.markerOverlay,'click',marker_click);
			map.addOverlay(grafcan.markerOverlay);
			addCosa(_('Marcador')+' '+latlng.toString(), grafcan.markerOverlay);
			GEvent.trigger(grafcan.markerOverlay, 'click');
		} else {
			latlngs.push(latlng);			
			initializePoint(latlngs.length - 1);
			redrawShape();
			if (grafcan.makePerfil && grafcan.perfil && grafcan.perfil.isVisible()) {
				grafcan.endMeasure(1, true); //refrescamos perfil
			}
		}
	}
}
function redrawShape() {
    var pointCount = latlngs.length;
    var id;
	
	if (map.toolMode==grafcan.toolMode.measureArea) {
		// Plot polyline, adding the first element to the end, to close the loop
		latlngs.push(latlngs[0]);
	}
	var polyline = new GPolyline(latlngs, "#ff0000", 2, 1);
	var polygon = new GPolygon(latlngs, "#ff0000", 2, 1, "#ffffff", 0.3);	
	try {
		if (map.toolMode==grafcan.toolMode.measureLength || map.toolMode==grafcan.toolMode.perfil) {
			map.addOverlay(polyline);
			grafcan.measureOverlay['polyline'] = polyline;
		} else {
			map.addOverlay(polygon);
			grafcan.measureOverlay['polygon'] = polygon;
		}
	} catch (e) {}
	
	// Calculate total length of polyline (length for 2, perimeter for > 2)
	if (pointCount >= 2) {		
		var length = polyline.getLength();
		var longitud = length;
		var unidad = "m";
		var denominador = 1;
		if (length>=1000.0) {
			// para pasar a kilómetros
			denominador = 1000;
			unidad = "km";			
		}
		if (map.toolMode==grafcan.toolMode.measureArea) {
			if (pointCount > 2) {
				longitud = Math.round(length)/denominador;
				etiqueta = _('Perímetro');
			} else {
				longitud = Math.round(length)/(2*denominador);
				etiqueta = _('Distancia');
			}
		} else {
			longitud = Math.round(length)/denominador;
			etiqueta = _('Distancia');
		}
		grafcan.measurePanel.findById('length-data').setFieldLabel(etiqueta);
		grafcan.measurePanel.findById('length-data').setRawValue(formatNumber(longitud, 2)+' '+unidad);
	}
	if (map.toolMode==grafcan.toolMode.measureArea)
		latlngs.pop(); // restaura el array a su estado anterior (elimina el último punto)
	
	// Área en kms cuadrados
	if (pointCount >= 3 && map.toolMode==grafcan.toolMode.measureArea) {
		var area = polygon.getArea();
		if (area>=1000000.0) {
			area /= 1000000;
			unidad = "km²";
		} else {
			//area /= 1000;
			unidad = "m²";
		}
		grafcan.measurePanel.findById('area-data').setRawValue(formatNumber(area, 2)+' '+unidad);
	}
	if (pointCount > 0) grafcan.measureWin.show();
    	
	// eliminamos anterior polyline/polygon
	if (map.toolMode==grafcan.toolMode.measureLength || map.toolMode==grafcan.toolMode.perfil)
		removePolyline();
	else
		removePolygon();
	
	// set us up to zap the current polyline when we draw the next one.
	removePolyline = function() {
		map.removeOverlay(polyline);
	}	
	removePolygon = function() {
		map.removeOverlay(polygon);
	}	
}
/*
 * Como ir a...
 */
function checkDirection(direction, callback) {
	var geo = new GClientGeocoder();
	geo.setBaseCountryCode(grafcan.routeData['baseCountryCode']);
	geo.setViewport(grafcan.boundsLimit);
	geo.getLocations(direction, callback);
}
function validateDirection(targetControl, dir, callback) {
	//$id(targetControl).value = $get_innerText(dir);
	$id(targetControl).value = dir;
	if (callback) {
		grafcan.direction.source = $id(targetControl).value;
		checkDirection(grafcan.direction.target, callback);
	} else {
		grafcan.direction.target = $id(targetControl).value;
		calculateRoute();
	}
}
function calculateRoute() {
	if (grafcan.lang=='en') {
		var reason=[];
		reason[G_GEO_SUCCESS]            = "Success";
		reason[G_GEO_MISSING_ADDRESS]    = "Missing Address: The address was either missing or had no value.";
		reason[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address: No corresponding geographic location could be found for the specified address.";
		reason[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address: The geocode for the given address cannot be returned due to legal or contractual reasons.";
		reason[G_GEO_BAD_KEY]            = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
		reason[G_GEO_TOO_MANY_QUERIES]   = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
		reason[G_GEO_SERVER_ERROR]       = "Server error: The geocoding request could not be successfully processed.";
		reason[G_GEO_BAD_REQUEST]        = "A directions request could not be successfully parsed.";
		reason[G_GEO_MISSING_QUERY]      = "No query was specified in the input.";
		reason[G_GEO_UNKNOWN_DIRECTIONS] = "The GDirections object could not compute directions between the points.";
	} else {
		var razon=[];
		razon[G_GEO_SUCCESS]            = "Correcto";
		razon[G_GEO_MISSING_ADDRESS]    = "Especifique la dirección que falta.";
		razon[G_GEO_UNKNOWN_ADDRESS]    = "No se ha encontrado correspondencia geográfica para la dirección especificada.";
		razon[G_GEO_UNAVAILABLE_ADDRESS]= "Dirección no disponible.";
		razon[G_GEO_BAD_KEY]            = "La clave de la API de Google Maps no es correcta.";
		razon[G_GEO_TOO_MANY_QUERIES]   = "Se ha excedido la cuota diaria de consultas para este sitio.";
		razon[G_GEO_SERVER_ERROR]       = "Error de servidor: la petición no ha podido ser procesada.";
		razon[G_GEO_BAD_REQUEST]        = "Error en el tratamiento de una dirección.";
		razon[G_GEO_MISSING_QUERY]      = "Especifique las direcciones de origen y destino.";
		razon[G_GEO_UNKNOWN_DIRECTIONS] = "El objeto GDirections no ha podido calcular la ruta entre ambas direcciones.";
	}
	var ruta = new GDirections(map, $id('resultados-div'));
	grafcan.gdir = ruta;
	GEvent.addListener(ruta, "load", function() {setMapCursor(grafcan.cursor);$id('cmdPrintRoute').style.display = 'block'});
	GEvent.addListener(ruta, "addoverlay", function() {
		with(ruta.getPolyline()) {
			color = grafcan.direction.color;
			weight = grafcan.direction.weight;
			opacity = grafcan.direction.opacity;
		}
	});
	GEvent.addListener(ruta, "error", function() {
		var code = ruta.getStatus().code;
		var msg = _('Código') + " " + code;
		if (razon[code]) {
			msg = razon[code];
		}
		alert(msg);
		setMapCursor(grafcan.cursor);
	});
	var fromto = 'from: ' + grafcan.direction.source + ' to: ' + grafcan.direction.target;
	$set_innerHTML('resultados-div', '');
	ruta.load(fromto);
	//ruta.loadFromWaypoints(['28.435,-16.374','28.419,-16.412']);
}
function showLocations(targetControl, msg, placemark, isFinale) {	
	var reCN = new RegExp(grafcan.routeData['administrativeAreaNameRE'], 'gi');
	try {
		// si el resultado es una única dirección española y canaria, salimos
		if (placemark.length==1 &&
			placemark[0].AddressDetails.Country.CountryNameCode.toUpperCase()==grafcan.routeData['baseCountryCode'].toUpperCase() &&
			placemark[0].AddressDetails.Country.AdministrativeArea.AdministrativeAreaName.match(reCN))
			return placemark[0].address+', '+placemark[0].AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
	} catch(ex) {}
	if (!isFinale)
		var dir = '<li><a href="#" onclick="validateDirection(\'' + targetControl + '\', $get_innerText(this), getDestinoLocations)">#direccion#</a></li>';
	else
		var dir = '<li><a href="#" onclick="validateDirection(\'' + targetControl + '\', $get_innerText(this))">#direccion#</a></li>';
	var html = msg + '<p/><ul>';
	var exito = false;
	for (var i=0; i<placemark.length; i++) {
		if ((placemark[i].AddressDetails.Country.CountryNameCode.toUpperCase()==grafcan.routeData['baseCountryCode'].toUpperCase() &&
			 !placemark[i].AddressDetails.Country.AdministrativeArea) ||
			(placemark[i].AddressDetails.Country.CountryNameCode.toUpperCase()==grafcan.routeData['baseCountryCode'].toUpperCase() &&
			 placemark[i].AddressDetails.Country.AdministrativeArea.AdministrativeAreaName.match(reCN))) {
			exito = true;
			html += dir.replace(/#direccion#/g, placemark[i].address);
		}
	}
	if (!exito) return false;
	html += '</ul>';
	$set_innerHTML('resultados-div', html);
	return true;
}
function getOrigenLocations(response) {
	if (typeof(response)=='string')
		validateDirection('txtOrigen', response);
	else if (!response || response.Status.code != 200) {
		alert(Gettext.strargs(_("No se ha encontrado una correspondencia geográfica para la dirección de %1 '%2' o está fuera del ámbito geográfico."),_('origen'),response.name));
	} else {
		var ret = showLocations('txtOrigen', Gettext.strargs(_('Seleccione una dirección como dirección de %1'),_('origen'))+':', response.Placemark, false);
		if (typeof(ret)=='string') {
			// el resultado fue único y válido en el ámbito
			grafcan.direction.source = ret;
			checkDirection(grafcan.direction.target, getDestinoLocations);
		} else if (!ret)
			alert(Gettext.strargs(_("No se ha encontrado una correspondencia geográfica para la dirección de %1 '%2' o está fuera del ámbito geográfico."),_('origen'),response.name));
	}
}
function getDestinoLocations(response) {
	if (typeof(response)=='string')
		validateDirection('txtDestino', response);
	else if (!response || response.Status.code != 200) {
		alert(Gettext.strargs(_("No se ha encontrado una correspondencia geográfica para la dirección de %1 '%2' o está fuera del ámbito geográfico."),_('destino'),response.name));
	} else {
		var ret = showLocations('txtDestino', Gettext.strargs(_('Seleccione una dirección como dirección de %1'),_('destino'))+':', response.Placemark, true);
		if (typeof(ret)=='string')
			// el resultado fue único y válido en el ámbito
			validateDirection('txtDestino', ret);
		else if (!ret)
			alert(Gettext.strargs(_("No se ha encontrado una correspondencia geográfica para la dirección de %1 '%2' o está fuera del ámbito geográfico."),_('destino'),response.name));
	}
}
function queryRoute(origen, destino) {
	$id('cmdPrintRoute').style.display = 'none';
	grafcan.direction = {source: origen, target: destino, color: grafcan.direction.color, weight: grafcan.direction.weight, opacity: grafcan.direction.opacity};
	grafcan.cursor = getMapCursor();
	if (grafcan.gdir) grafcan.gdir.clear();
	grafcan.direction.source = $id('txtOrigen').value;
	grafcan.direction.target = $id('txtDestino').value;
	if (!grafcan.direction.source.match(new RegExp(grafcan.routeData['zoneNameRE'], 'gi'))) grafcan.direction.source += ', ' + grafcan.routeData['zoneName'];
	if (!grafcan.direction.target.match(new RegExp(grafcan.routeData['zoneNameRE'], 'gi'))) grafcan.direction.target += ', ' + grafcan.routeData['zoneName'];
	if (!grafcan.direction.source.match(new RegExp(grafcan.routeData['countryNameRE'], 'gi'))) grafcan.direction.source += ', ' + grafcan.routeData['countryName'];
	if (!grafcan.direction.target.match(new RegExp(grafcan.routeData['countryNameRE'], 'gi'))) grafcan.direction.target += ', ' + grafcan.routeData['countryName'];	
	// Comprueba origen y destino
	setMapCursor('wait');
	checkDirection(grafcan.direction.source, getOrigenLocations);
}
function printRoute() {
	var win = window.open("pages/printRoute.htm","_blank","location=no,scrollbars=yes,resizable=yes,menubar=no,status=no,toolbar=no,titlebar=no,width=500,height=600");	
}
//
function getSingleTileUrl(params) {
	var svc = grafcan.currentMapCfg();
	var lBbox = "";
	var width = height = 0;
	var latlngbounds = params["latlngbounds"];
	if (!params["bbox"]) {
		var bounds=map.getBounds();
		var sw=bounds.getSouthWest();
		var ne=bounds.getNorthEast();
		latlngbounds = new GLatLngBounds(sw, ne);
		lBbox=sw.lng()+","+sw.lat()+","+ne.lng()+","+ne.lat();
		width = map.getSize().width;
		height = map.getSize().height;
	} else {
		lBbox = params["bbox"];
		width = params["width"];
		height = params["height"];
	}
	var url = addAmp(svc.layers[params["layerName"]].singleTile);
	if (params["srs"])
		url = url.replace(/EPSG:4326/i,params["srs"]);
	return url + "BBOX="+lBbox+"&WIDTH="+width+"&HEIGHT="+height;
}
function correccionLat(m, bbox) {
	// bbox: lng1,lat1,lng2,lat2
	var zl = m.getZoom();
	var v = bbox.split(',');
	if (zl>6 && zl<9) {					
		var diffh = parseFloat(v[3])-parseFloat(v[1])-(zl==7?4:2);
		if (diffh>0) {				
			var lat_center = m.getCenter().lat();
			if (zl==7)
				var diff_lat = 0.017*diffh - Math.abs(lat_center-28) * 0.004*diffh;
			else
				var diff_lat = 0.008*diffh - Math.abs(lat_center-28) * 0.0025*diffh;
			v[1] = parseFloat(v[1]) + diff_lat;
			v[3] = parseFloat(v[3]) + diff_lat;						
		}
	}
	return v.join(',');
}
function showSingleTile(params) {
	var gmap = params['gmap'];
	grafcan.removeMapOverlay(gmap,params['layerName']);
	if (params['visible']) {
		var svc = gmap.cfg.getService(gmap.getCurrentMapType().getName());
		var lBbox = "";
		var width = height = 0;
		var latlngbounds = params['latlngbounds'];
		if (!params['bbox']) {
			var bounds=gmap.getBounds();
			var sw=bounds.getSouthWest();
			var ne=bounds.getNorthEast();
			latlngbounds = new GLatLngBounds(sw, ne);
			lBbox=sw.lng()+','+sw.lat()+','+ne.lng()+','+ne.lat();
			width = gmap.getSize().width;
			height = gmap.getSize().height;
		} else {
			lBbox = params['bbox'];
			width = params['width'];
			height = params['height'];
		}
		// corrección latitudinal en los niveles 7 y 8 (discrepancia entre coordenadas geográficas y Web Mercator)
		lBbox = correccionLat(map,lBbox);
		//
		var url = svc.layers[params['layerName']].singleTile + '&BBOX='+lBbox+'&WIDTH='+width+'&HEIGHT='+height;
		url+="&ID="+grafcan.uid;
		gmap.mapOverlay[params['layerName']] = new ProjectedOverlay({imageUrl:url,bounds:latlngbounds,id:params['layerName']});
		gmap.addOverlay(gmap.mapOverlay[params['layerName']]);
		gmap.mapOverlay[params['layerName']].setOpacity(svc.layers[params['layerName']].opacity*100);
	}
}
function getSingleTiles(gmap) {
	var svc = gmap.cfg.getService(gmap.getCurrentMapType().getName());
	for (var s in svc.layers) {	
		var bounds = gmap.getBounds();
		var sw = bounds.getSouthWest();
		var ne = bounds.getNorthEast();
		var bbox = sw.lng()+','+sw.lat()+','+ne.lng()+','+ne.lat();
		var width = height = 0;
		var oMap = gmap.getContainer();
		if (navigator.appName=="Netscape") {
			width = parseInt(getComputedStyle(oMap,null).getPropertyValue('width'));
			height = parseInt(getComputedStyle(oMap,null).getPropertyValue('height'));
		} else {
			width = oMap.style.pixelWidth;
			height = oMap.style.pixelHeight;
		}
		width = gmap.getSize().width;
		height = gmap.getSize().height;
		if (svc.layers[s].singleTile && svc.layers[s].visible) {
			var visible = svc.layers[s].visibility.minResolution <= gmap.getZoom() && svc.layers[s].visibility.maxResolution >= gmap.getZoom();
			showSingleTile({gmap:gmap,layerName:s,bbox:bbox,width:width,height:height,latlngbounds:new GLatLngBounds(sw, ne),visible:visible});
		}
	}
}
function showCurrentViewURL() {
	var url = document.location.href.replace('#','');
	var p = url.indexOf('default.php');
	if (p>-1)
		url = url.substring(0, p);
	url += 'default.php';
	grafcan.hyplnk = url+'?svc='+grafcan.curService+'&lat='+map.getCenter().lat()+'&lng='+map.getCenter().lng()+'&zoom='+map.getZoom();
	if (grafcan.lang) grafcan.hyplnk+='&lang='+grafcan.lang;
	if (grafcan.markerOverlay) {
		grafcan.hyplnk += '&mklat='+grafcan.markerOverlay.getLatLng().lat()+'&mklng='+grafcan.markerOverlay.getLatLng().lng()
		if (grafcan.markerOverlay.getTitle()) grafcan.hyplnk += '&mktip='+encodeURIComponent(grafcan.markerOverlay.getTitle());
		
	} else if (grafcan.queryOverlay) {
		if (grafcan.queryOverlay instanceof GMarker)
			grafcan.hyplnk += '&mklat='+grafcan.queryOverlay.getPoint().lat()+'&mklng='+grafcan.queryOverlay.getPoint().lng();
		else {
			grafcan.hyplnk += '&mklat='+grafcan.queryOverlay.getDefaultCenter().lat()+'&mklng='+grafcan.queryOverlay.getDefaultCenter().lng();
			if (grafcan.queryOverlayURL)
				grafcan.hyplnk += '&mkurl='+encodeURIComponent(grafcan.queryOverlayURL);
		}
	}
	var win = window.open("pages/VistaActual_"+grafcan.lang+".htm", "vistaActual", "location=no,menubar=no,resizable=no,scrollbars=no,status=no,toolbar=no,titlebar=no,width=450,height=60");
	win.focus();
}
function export2KML() {
	if (latlngs.length==0) return false;
	var esLinea = (latlngs.length>1);
	var esPoligono = (map.toolMode==grafcan.toolMode.measureArea&&latlngs.length>2);
	var kml = '<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.1"><Document>';
	kml += '<Style id="myStyle">'
	     + '<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/red-circle_maps.png</href></Icon><hotSpot x="15" y="0" xunits="pixels" yunits="pixels"/></IconStyle>'
		 + (esPoligono||esLinea?'<LineStyle><color>ff0000ff</color><width>4</width></LineStyle>':'')
		 + (esPoligono?'<PolyStyle><color>7fffffff</color></PolyStyle>':'')
		 + '</Style>'
	//
	var coords = '';
	var sep = '';
	for (var j=0;j<latlngs.length;j++) {
		// vértices
		coords += sep + latlngs[j].lng()+','+latlngs[j].lat()+',0';
		sep = ' ';
		// marcadores de vértices
		if (latlngs.length>1) {
			kml += '<Placemark><name></name><description><![CDATA[<h2>'+grafcan.measureOverlay[j].getTitle()+'</h2>]]></description>'
				 + '<styleUrl>#myStyle</styleUrl>'
				 + '<Point><coordinates>'+latlngs[j].lng()+','+latlngs[j].lat()+',0</coordinates></Point></Placemark>';
		}
	}
	if (esPoligono) {
		coords += sep + latlngs[0].lng()+','+latlngs[0].lat()+',0';
		kml += '<Placemark><styleUrl>#myStyle</styleUrl><Polygon><outerBoundaryIs><LinearRing><coordinates>'+coords+'</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark>';
	} else if (esLinea)
		kml += '<Placemark><styleUrl>#myStyle</styleUrl><LineString><coordinates>'+coords+'</coordinates></LineString></Placemark>';			
	else
		kml += '<Placemark><name></name><description><![CDATA[<h2>'+grafcan.measureOverlay[0].getTitle()+'</h2>]]></description>'
		     + '<styleUrl>#myStyle</styleUrl><Point><coordinates>'+coords+'</coordinates></Point></Placemark>';
	kml += '</Document></kml>';
	with($id('frmConfig')) {
		thing.value = kml;
		filename.value = (esPoligono?'area':(esLinea?'longitud':'punto'))+'.kml';
		action = 'pages/saveKML.php';
		submit();
	}
	return kml;
}
function cosa2KML(id) {
	var cosa = grafcan.cosas[id];
	if (cosa instanceof GMarker) {
		var kml = '<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.1"><Document>';
		kml += '<Style id="myStyle">'
			 + '<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/red-circle_maps.png</href></Icon><hotSpot x="15" y="0" xunits="pixels" yunits="pixels"/></IconStyle>'
			 + '</Style>'
		var coords = cosa.getLatLng().lng()+','+cosa.getLatLng().lat()+',0';
		kml += '<Placemark><name></name><description><![CDATA[<h2>'+cosa.getTitle()+'</h2>]]></description>'
			 + '<styleUrl>#myStyle</styleUrl><Point><coordinates>'+coords+'</coordinates></Point></Placemark>';
		kml += '</Document></kml>';
		with($id('frmConfig')) {
			thing.value = kml;
			filename.value = 'punto.kml';
			action = 'pages/saveKML.php';
			submit();
		}
		return kml;
	} else {
		var store = Ext.getCmp('gridCosas').getStore();
		window.open(store.getById(id).data.url);
	}	
}