/**
 *Funciones para cambio de coordenadas(Formulas de Coticchia-Surace)
 *@author Romanuel Ramon Antunez
**/

/**
 *Constantes... teniendo encuenta el elipsoide de Hayford
 **/
// Datos basicos del elipsoide de Hayford
var SemiEMayor = 6378388.0;
var SemiEMenor = 6356911.946130;

//Excentricidad
var Exc = Math.sqrt(Csq(SemiEMayor)-Csq(SemiEMenor))/SemiEMayor;
var Exc2 = Math.sqrt(Csq(SemiEMayor)-Csq(SemiEMenor))/SemiEMenor;
var Exc22 = Csq(Exc2);

//Radio polar de curvatura 
var Rpc = Csq(SemiEMayor)/SemiEMenor;

//Aplanamiento
var Ap = (SemiEMayor-SemiEMenor)/SemiEMayor;

//Grados a radianes
var deg2rad = Math.PI/180;

//factor de escala
var K0 = 0.9996;
/**
 *Fin de Constantes
**/

/**
* funcion principal encargada de convertir coordenas de grados decimales(lon lat) en UTM(m)
**/
function GD2UTM(lon,lat){
	//punto a devolver
	var utm = new Point();
	
	//convertir coord en GD a radianes para calculos
	var radLon = lon * deg2rad; //*-1;   para cuba la lon es negativa
	var radLat = lat * deg2rad;
	
	//calcular huso 
	var huso = Mod(parseInt((lon/6)+31));
	
	//meridiano central del huso
	var merid = huso * 6 - 183;
	var radmerid = merid * deg2rad;
	
	//distancia angular de la longitud al meridiano cenral
	var distang = radLon - radmerid;
	
	//Ecuaciones de Coticchia -Surace
	var a = Math.cos(radLat) * Math.sin(distang);
	var k = 1/2 * Math.log((1 + a)/(1 - a));
	var n = Math.atan(Math.tan(radLat)/Math.cos(distang)) - radLat;
	var v = (Rpc/Math.sqrt((1 + Exc22 * Csq(Math.cos(radLat))))) * K0;
	var c = Exc22/2 * Csq(k) * Csq(Math.cos(radLat));
	var a1 = Math.sin(2 * radLat);
	var a2 = a1 * Csq(Math.cos(radLat));
	var j2 = radLat + a1/2;
	var j4 = (3 * j2 + a2)/4;
	var j6 = (5 * j4 + a2 * Csq(Math.cos(radLat)))/3;
	var alfa = 3/4 * Exc22;
	var beta = 5/3 * Csq(alfa);
	var gamma = 35/27 * Math.pow(alfa,3);
	var beta1 = K0 * Rpc * (radLat - alfa*j2 + beta*j4 - gamma*j6);
	
	//calculo final
	utm.x = k * v * (1 + c/3) + 500000;
	utm.y = n * v * (1 + c) + beta1;  // para valores al sur del ecuador sumar 10000000
	
	return utm;
}

/**
* funcion principal encargada de convertir coordenas UTM(m) en grados decimales(lon lat) 
**/
function UTM2GD(huso,utm){
	var lonlat = new Point();
	
	//eliminar retanqueo de la x utm
	utm.x = utm.x - 500000;
	
	//calculo del meridiano
	var meridiano = huso * 6 - 183;
	
	//Ecuaciones de Coticchia -Surace
	var Radlat = utm.y/(6366197.724 * K0);
	var v1 = (Rpc/Math.sqrt((1 + Exc22 * Csq(Math.cos(Radlat))))) * K0; 
	var aa = utm.x/v1;
	var aa1 = Math.sin(2 * Radlat);
	var aa2 = aa1 * Csq(Math.cos(Radlat));
	var jj2 = Radlat + aa1/2;
	var jj4 = (3 * jj2 + aa2)/4;
	var jj6 = (5 * jj4 + aa2 * Csq(Math.cos(Radlat)))/3;
	var alfa = 3/4 * Exc22;
	var beta = 5/3 * Csq(alfa);
	var gamma = 35/27 * Math.pow(alfa,3);
	var beta1 = K0 * Rpc * (Radlat - alfa*jj2 + beta*jj4 - gamma*jj6);
	var bb = (utm.y - beta1)/v1; 
	var c1 = (Exc22 * Csq(aa))/2 * Csq(Math.cos(Radlat));
	var k1 = aa * (1 - c1/3);
	var n1 = bb * (1 - c1) + Radlat;
	var senhk = (Math.pow(Math.E,k1) - Math.pow(Math.E,-k1))/2;
	var distang1 = Math.atan(senhk/Math.cos(n1));
	var t = Math.atan(Math.cos(distang1) * Math.tan(n1));
	
	//calculos finales
	lonlat.x = ((distang1/Math.PI) * 180)+ meridiano;
	lonlat.y = Radlat + (1 + Exc22 * Csq(Math.cos(Radlat)) - 3/2 * Exc22 * Math.sin(Radlat) * Math.cos(Radlat) * (t - Radlat)) * (t - Radlat);
	
	lonlat.y = (lonlat.y/Math.PI) * 180;
	
	return lonlat;
}


/**
 *Funciones utiles
 **/
 
 //funcion para elevar al cuadrado
function Csq(value) {
 return value*value;
}

function ConvUnidLonBase(medi){
	if(mapconfig.distAnt != "m"){
		switch(mapconfig.distAnt)
		{
		case "ch":
			medi /= 0.049709;
			break;
		case "cm":
			medi /= 100;
			break;
		case "ft":
		 	medi /= 3.2808399;
			break;
		case "in":
			medi /= 39.3700787;
			break;
		case "km":
			medi /= 0.001;
			break;
		case "li":
			medi /= 39.3700787;
			medi *= 7.92;
			break;
		case "mi":
			medi *= 1609.34;
			break;
		case "mm":
			medi /= 1000;
			break;
		case "nmi":
			medi /= 0.000539957;
			break;
		case "rd":
			medi /= 1.1961722488;
			break;
		case "survey ft":
			medi /= 3.280833329;
			break;
		case "yd":
			medi /= 1.0936133;
			break;
		}
	}
	
	return medi;
}

function ConvUnidLon(medi)
{  	
  switch(mapconfig.dist)
  {
    case "ch":
      medi *= 0.049709;
      break;
    case "cm":
      medi *= 100;
      break;
    case "ft":
      medi *= 3.2808399;
      break;
    case "in":
      medi *= 39.3700787;
      break;
    case "km":
      medi *= 0.001;
      break;
    case "li":
      medi *= 39.3700787;
      medi /= 7.92;
      break;
    case "m":
      medi = medi;
      break;
    case "mi":
      medi /= 1609.34;
      break;
    case "mm":
      medi *= 1000;
      break;
    case "nmi":
      medi *= 0.000539957;
      break;
    case "rd":
      medi *= 1.1961722488;
      break;
    case "survey ft":
      medi *= 3.280833329;
      break;
    case "yd":
      medi *= 1.0936133;
      break;
  }

  return medi;
}

function ConvUnidAreBase(med)
{
  if(mapconfig.supfAnt != "sq m"){
	switch(mapconfig.supfAnt)
  	{
    		case "acre":
      			med *= 4047;
      			break;
    		case "hectare":
      			med *= 10000;
      			break;
    		case "perch":
      			med /= 0.039536787;
      			break;
    		case "rood":
      			med /= 0.039536787;
      			med *= 40;
      			break;
    		case "sq ch":
      			med *= 404.70000;
      			break;
    		case "sq cm":
      			med /= 10000;
      			break;
    		case "sq ft":
      			med /=  10.76000;
      			break;
    		case "sq in":
      			med /= 1550;
      			break;
    		case "sq km":
      			med *= 1000000;
      			break;
    		case "sq li":
      			//TODO
      			med /= 1550;
      			med *= 62.7264;
      			break;
    		case "sq mi":
      			med *= 2589989;
      			break;
    		case "sq mm":
      			med /=  1000000;
      			break;
    		case "sq rd":
      			med /=  1,430828049;
      			break;
    		case "sq survey ft":
      			med /=  10.763867333;
      			break;
    		case "sq yd":
      			med /=  1.19600;
      			break;
  	}
  }
}

function ConvUnidAre(med)
{
  if(mapconfig.supfAnt != "sq m"){
	switch(mapconfig.supfAnt)
  	{
    		case "acre":
      			med *= 4047;
      			break;
    		case "hectare":
      			med *= 10000;
      			break;
    		case "perch":
      			med /= 0.039536787;
      			break;
    		case "rood":
      			med /= 0.039536787;
      			med *= 40;
      			break;
    		case "sq ch":
      			med *= 404.70000;
      			break;
    		case "sq cm":
      			med /= 10000;
      			break;
    		case "sq ft":
      			med /=  10.76000;
      			break;
    		case "sq in":
      			med /= 1550;
      			break;
    		case "sq km":
      			med *= 1000000;
      			break;
    		case "sq li":
      			//TODO
      			med /= 1550;
      			med *= 62.7264;
      			break;
    		case "sq mi":
      			med *= 2589989;
      			break;
    		case "sq mm":
      			med /=  1000000;
      			break;
    		case "sq rd":
      			med /=  1,430828049;
      			break;
    		case "sq survey ft":
      			med /=  10.763867333;
      			break;
    		case "sq yd":
      			med /=  1.19600;
      			break;
  	}
  }	

  switch(mapconfig.supf)
  {
    case "acre":
      med /= 4047;
      break;
    case "hectare":
      med /= 10000;
      break;
    case "perch":
      med *= 0.039536787;
      break;
    case "rood":
      med *= 0.039536787;
      med /= 40;
      break;
    case "sq ch":
      med /= 404.70000;
      break;
    case "sq cm":
      med *= 10000;
      break;
    case "sq ft":
      med *=  10.76000;
      break;
    case "sq in":
      med *= 1550;
      break;
    case "sq km":
      med /= 1000000;
      break;
    case "sq li":
      //TODO
      med *= 1550;
      med /= 62.7264;
      break;
    case "sq m":
      med = med;
      break;
    case "sq mi":
      med /= 2589989;
      break;
    case "sq mm":
      med *=  1000000;
      break;
    case "sq rd":
      med *=  1,430828049;
      break;
    case "sq survey ft":
      med *=  10.763867333;
      break;
    case "sq yd":
      med *=  1.19600;
      break;
  }

  return med;
}

function IsNumeric(strString){
	//  cheque de caracteres validos para numero	
	var strValidChars = "0123456789.-";
	var strChar;
	var blnResult = true;

	if (strString.length == 0) return false;

	//  test strString consiste en validar los caracteres
	for (i = 0; i < strString.length && blnResult == true; i++){
		strChar = strString.charAt(i);
		if (strValidChars.indexOf(strChar) == -1){
			blnResult = false;
		}
	}

	return blnResult;
}


function Redondear(numero, cantdec) {
	cantdec = (!cantdec ? 2 : cantdec);
	return Math.round(parseFloat(numero)*Math.pow(10,cantdec))/Math.pow(10,cantdec);
}

/**
** Funcion para determinar distancia acumulada en una porcion de feature
**/

function DistAcumPor(feature, pos){
	var d = 0;	
			
	for(i = 0; i < pos; i++){
		d += mapconfig.CalculoDist(feature.vertices[i], feature.vertices[i+1]);
	}
	
	return d;
}

function GMaGD(val){
	temp = val[1]/60;
	dg1 = val[0]/1;
	dg = Mod(dg1) + temp;

	if(dg1 < 0)
		return dg * -1;
	else
		return dg;
}

function GMSaGD(val){
	temp1 = val[2]/60/60;
	temp = val[1]/60;
	dg1 = val[0]/1;
	dg = Mod(dg1) + temp + temp1;
	
	if(dg1 < 0)
		return dg * -1;
	else
		return dg;
}

/**
 *Fin funciones utiles
**/

