#include "stdafx.h"
#ifdef OLIVIA_COMPILA
#include "olv_limp.h"
#include "olv.h"
#include "olv_limp_thr.h"
#include "olv_geom.h"
#include "math.h"
#include "ini_file.h"
#include "olv_tasks.h"
#include "sock_sv.h"

/**
*	@file olv_limp.cpp
*	Archivo de implementaciones de la utilidad de limpieza viaria del programa Olivia.
*/
//*******************************************************************************************************************************************
Colv_limp::Colv_limp(COlivia *olv)
{
	nod_plant=-1;
	this->olv = olv;
	res_circ=OLV_RES_NO;
	npts_ctrl = 3;
	uds_tto = OliviaDef::GeneralDef::OlvTipTtoNoDef;
	v_despl = 5;
	t_tto = 5*60;
	t_carg = 60*30;
	t_conv = 3600*8;
	t_desc = 60*40;
	t_despl = 60*25;
	t_sal=0;
	nsec=4;
	ancho_via = 2; //m	
	memset(coor_instal,0,3*sizeof(double));
	thr_limp = new Colv_limp_thr(this);
	//cost_amb=NULL;
	n_nw=n_amb=0;
	pp=-1;
	tipo_ambit=-1;
	inww_amb=NULL;
	memset(&conjs,0,sizeof(Info_conjs));
	cost_conj.clear();
	sec=NULL;
	amb_sec=NULL;
	rellena_campos();
	margen_sect=0.04;
	plan=NULL;
	calc_nsec=0;
	ang_conj=NULL;
	tip_conj.clear();
	ang_lim=OLV_LIMP_GIRO_VEHIC*OLV_PI/180; 
	ord_sec=NULL;
	nod_instal=-1;
	ord_sec_plan=NULL;
	t_ini=7*3600; //7 de la mañana
	igno_ais=FALSE;
	lateral=0;
	nsec_act=0;
	olv_tasks = new Colv_tasks(olv);
	soc=NULL;
	tipo_shp_viaj=OLV_SHPRUTINST;//OLV_SHPRUT_SHPINST
	nomb_tto[0]=0;
	barr_mix=FALSE;
}
//*******************************************************************************************************************************************
Colv_limp::~Colv_limp(void)
{
	int i;

	cancela();
	delete(thr_limp);

	if(inww_amb)
	{
		for(i=0;i<n_amb*tipo_ambit;i++)
		{
			if(inww_amb[i].inw_old)
				free(inww_amb[i].inw_old);
		}
		free(inww_amb);
	}
	inww_amb=NULL;

	if(conjs.coor)
		free(conjs.coor);
	conjs.coor=NULL;
	if(conjs.inc)
		free(conjs.inc);
	conjs.inc=NULL;
	
	cost_amb.clear();
	

	if(plan)
	{
		int j;
		for(i=0;i<nsec;i++)
		{
			if(plan[i].nelem)
			{
				if(plan[i].elem)
					free(plan[i].elem);				
				if(plan[i].pts_ctrl)
					free(plan[i].pts_ctrl);
			}
			for(j=0;j<plan[i].ninsta;j++)
			{
				if(plan[i].planif_insta[j].nelem)
				{
					if(plan[i].planif_insta[j].elem)
						free(plan[i].planif_insta[j].elem);				
					if(plan[i].planif_insta[j].pts_ctrl)
						free(plan[i].planif_insta[j].pts_ctrl);
				}
			}
			if(plan[i].planif_insta)
				free(plan[i].planif_insta);
		}
		free(plan);
	}


	if(ang_conj)
	{
		for(i=0;i<conjs.n;i++)
		{
			ang_conj[i].libera();			
		}		
		free(ang_conj);
		ang_conj=NULL;
	}
	if(ord_sec)
	{
		for(i=0;i<n_amb;i++)
		{
			if(ord_sec[i].ctnod[1] && (ord_sec[i].ctnod[1]!=ord_sec[i].ctnod[0]))
			{
				ord_sec[i].libera(1,conjs.n);
				free(ord_sec[i].ctnod[1]);
				ord_sec[i].ctnod[1]=NULL;
			}

			if(ord_sec[i].ctnod[0])
			{
				ord_sec[i].libera(0,conjs.n);
				free(ord_sec[i].ctnod[0]);
			}
			ord_sec[i].ctnod[0]=NULL;			
		}
		free(ord_sec);
		ord_sec=NULL;
	}

	if(ord_sec_plan)
	{
		for(int i=0;i<1;i++)//solo libera la primera parte
		{
			if(ord_sec_plan[i].ctnod[0])
			{
				ord_sec_plan[i].libera(0,conjs.n);
				free(ord_sec_plan[i].ctnod[0]);
			}
			ord_sec_plan[i].ctnod[0]=NULL;			
		}
		free(ord_sec_plan);
		ord_sec_plan=NULL;
	}
	if(olv_tasks)
		delete olv_tasks;
	if(soc)
	{
		soc->close();
		delete soc;
		soc=NULL;
	}

	for (std::map<int,Info_aso2>::iterator it=iaso.begin(); it!=iaso.end(); ++it)
	{
		it->second.del();
	}

	libera_memo_secto();
}
//*************************************************************************************
/**
 * Libera la memoria de las matrices de sectorización
 */
void Colv_limp::libera_memo_secto()
{
	if(sec)
	{
		for(int i=0;i<nsec_orig;i++)
		{
			if(sec[i].cost_amb_sec)
				free(sec[i].cost_amb_sec);
			if(sec[i].cost_amb_sec_aux)
				free(sec[i].cost_amb_sec_aux);
			if(sec[i].iamb)
				free(sec[i].iamb);
		}	
		free(sec);
		sec=NULL;
	}

	if(amb_sec)
		free(amb_sec);
	amb_sec=NULL;
}
//*************************************************************************************
/**
 * Inicia las tareas de la utilidad de limpieza viaria
 */
BOOL Colv_limp::inicia()
{
	//arranca el thread
	thr_limp->inicia_th();
	//empieza importando
	thr_limp->encola(thr_limp->OLV_LIMP_EV_ABRE_DAT,NULL,FALSE);

	return TRUE;
}
//*************************************************************************************
/**
 * Pone las opciones de configuración de lo que recibe por el socket
 */
int Colv_limp::pon_config(char *config_)
{
	int j;
	char *token;
	const int SZCONF = 8192;
	char config[SZCONF];

	if(!config)
		return 0;

	memset(config,0,SZCONF);
	strcpy_s(config,SZCONF,config_);

	//los parámetros son:
	token = strtok(config, OliviaDef::GeneralDef::EjecGeoParamSep);
	//avanza al siguiente token, el primero indica "\CONFIGURACION"
	token = strtok(NULL, OliviaDef::GeneralDef::EjecGeoParamSep); 

	//Lee parámetros
	j=0;
	while (token != NULL)
	{
		if(strstr(token,OliviaDef::GeneralDef::GL_tto))
		{
			if(!olv->dame_param(token, &t_tto))
				break;
			if(t_tto==0)
				break;
		}	
		else if(strstr(token,OliviaDef::GeneralDef::GL_res))
		{
			if(!olv->dame_param(token, &res_circ))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GL_uto))
		{
			if(!olv->dame_param(token, &uds_tto))
				break;
			if(uds_tto==OliviaDef::GeneralDef::OlvTipTtoMin)
			{
				tipo_ambit=OLV_AMB_PUN;
				t_tto=t_tto*60;//porque viene en minutos
			}
			else if(uds_tto>OliviaDef::GeneralDef::OlvTipTtoMin)
				tipo_ambit=OLV_AMB_LIN;
			else
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GL_vdp))
		{
			if(!olv->dame_param(token, &v_despl))
				break;
			if(v_despl<0)
				break;
			v_despl=v_despl*OLV_KMH2MS;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GL_tdp))
		{
			if(!olv->dame_param(token, &t_despl))
				break;
			t_despl=t_despl*60;//porque viene en minutos
		}
		else if(strstr(token,OliviaDef::GeneralDef::GL_tca))
		{
			if(!olv->dame_param(token, &t_carg))
				break;
			t_carg=t_carg*60;//porque viene en minutos
		}
		else if(strstr(token,OliviaDef::GeneralDef::GL_anc))
		{
			if(!olv->dame_param(token, &ancho_via))
				break;
			if(ancho_via<0)
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GG_tco))
		{
			if(!olv->dame_param(token, &t_conv))
				break;
			t_conv=t_conv*60;//porque viene en minutos
		}
		else if(strstr(token,OliviaDef::GeneralDef::GG_tdc))
		{
			if(!olv->dame_param(token, &t_desc))
				break;
			t_desc=t_desc*60;//porque viene en minutos
		}
		else if(strstr(token,OliviaDef::GeneralDef::GG_npt))
		{
			if(!olv->dame_param(token, &npts_ctrl))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GG_sec))
		{
			if(!olv->dame_param(token, &nsec))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GG_coox))
		{
			if(!olv->dame_param(token, &coor_instal[0]))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GG_cooy))
		{
			if(!olv->dame_param(token, &coor_instal[1]))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GG_hini))
		{
			if(!olv->dame_param(token, &t_ini))
				break;
			t_ini=t_ini*60;//porque viene en minutos
		}
		else if(strstr(token,OliviaDef::GeneralDef::GG_trafic))
		{
			if(!olv->dame_param(token, &f_trafic))
				break;
			f_trafic=f_trafic/100;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GG_ais))
		{
			if(!olv->dame_param(token, (int*)&igno_ais))
				break;
		}
		//el nombre del tto
		else if(strstr(token,OliviaDef::GeneralDef::GG_strtto))
		{
			if(!olv->dame_param(token, nomb_tto, sizeof(nomb_tto)))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GG_pd))
		{
			if(!olv->dame_param(token, olv->paths.path_data, sizeof(olv->paths.path_data)))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GG_pn))
		{
			if(!olv->dame_param(token, olv->paths.path_nw, sizeof(olv->paths.path_nw)))
				break;
		}
		//los campos a leer de la dbf
		else if(strstr(token,OliviaDef::GeneralDef::GAA_obser))
		{
			if(!olv->dame_param(token, camps.campo_obs, sizeof(camps.campo_obs))) 
				break;
			if(strlen(camps.campo_obs)>OLV_MAX_COL_SHP)//10 porque el shp solo pasa con 10 caracteres en los nombres de columna
				camps.campo_obs[OLV_MAX_COL_SHP]=0;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GAA_anch_tip))
		{
			if(!olv->dame_param(token, camps.campo_anch, sizeof(camps.campo_anch)))
				break;
			if(strlen(camps.campo_anch)>OLV_MAX_COL_SHP)//10 porque el shp solo pasa con 10 caracteres en los nombres de columna
				camps.campo_anch[OLV_MAX_COL_SHP]=0;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GAA_tipolo))
		{
			if(!olv->dame_param(token, camps.campo_tipo_ap, sizeof(camps.campo_tipo_ap)))
				break;
			if(strlen(camps.campo_tipo_ap)>OLV_MAX_COL_SHP)//10 porque el shp solo pasa con 10 caracteres en los nombres de columna
				camps.campo_tipo_ap[OLV_MAX_COL_SHP]=0;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GAA_entid))
		{
			if(!olv->dame_param(token, camps.campo_tipo_ent, sizeof(camps.campo_tipo_ent)))
				break;
			if(strlen(camps.campo_tipo_ent)>OLV_MAX_COL_SHP)//10 porque el shp solo pasa con 10 caracteres en los nombres de columna
				camps.campo_tipo_ent[OLV_MAX_COL_SHP]=0;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GAL_aparc))
		{
			if(!olv->dame_param(token, camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_AP], sizeof(camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_AP])))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GAL_bord))
		{
			if(!olv->dame_param(token, camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_BORD], sizeof(camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_BORD])))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GAL_acera))
		{
			if(!olv->dame_param(token, camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_ACERA], sizeof(camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_ACERA])))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GAL_peat))
		{
			if(!olv->dame_param(token, camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_PEAT], sizeof(camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_PEAT])))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GAL_ap_lin))
		{
			if(!olv->dame_param(token, camps.atr_tip_apa[OLV_ATR_TIP_AP_LIN], sizeof(camps.atr_tip_apa[OLV_ATR_TIP_AP_LIN])))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GAL_ap_bat))
		{
			if(!olv->dame_param(token, camps.atr_tip_apa[OLV_ATR_TIP_AP_BAT], sizeof(camps.atr_tip_apa[OLV_ATR_TIP_AP_BAT])))
				break;
		}
		//los campos a leer de la dbf de la red navegable
		else if(strstr(token,OliviaDef::GeneralDef::GTC_onew))
		{
			if(!olv->dame_param(token, camps.campo_circ, sizeof(camps.campo_circ)))
				break;
			if (strlen(camps.campo_circ) > OLV_MAX_COL_SHP)//10 porque el shp solo pasa con 10 caracteres en los nombres de columna
				camps.campo_circ[OLV_MAX_COL_SHP] = 0;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GTC_kph))
		{
			if(!olv->dame_param(token, camps.campo_velo, sizeof(camps.campo_velo)))
				break;
			if (strlen(camps.campo_velo) > OLV_MAX_COL_SHP)//10 porque el shp solo pasa con 10 caracteres en los nombres de columna
				camps.campo_velo[OLV_MAX_COL_SHP] = 0;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GTC_fow))
		{
			if(!olv->dame_param(token, camps.campo_fow, sizeof(camps.campo_fow)))
				break;
			if (strlen(camps.campo_fow) > OLV_MAX_COL_SHP)//10 porque el shp solo pasa con 10 caracteres en los nombres de columna
				camps.campo_fow[OLV_MAX_COL_SHP] = 0;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GTC_name))
		{
			if(!olv->dame_param(token, camps.campo_name, sizeof(camps.campo_name)))
				break;
			if (strlen(camps.campo_name) > OLV_MAX_COL_SHP)//10 porque el shp solo pasa con 10 caracteres en los nombres de columna
				camps.campo_name[OLV_MAX_COL_SHP] = 0;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GTA_TF))
		{
			if(!olv->dame_param(token, camps.atr_circ[OLV_ATR_CIRC_TF], sizeof(camps.atr_circ[OLV_ATR_CIRC_TF])))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GTA_FT))
		{
			if(!olv->dame_param(token, camps.atr_circ[OLV_ATR_CIRC_FT], sizeof(camps.atr_circ[OLV_ATR_CIRC_FT])))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GTA_N))
		{
			if(!olv->dame_param(token, camps.atr_circ[OLV_ATR_CIRC_NONE], sizeof(camps.atr_circ[OLV_ATR_CIRC_NONE])))
				break;
		}
		else if(strstr(token,OliviaDef::GeneralDef::GTA_pedes))
		{
			if(!olv->dame_param(token, camps.atr_circ[OLV_ATR_CIRC_PEDES], sizeof(camps.atr_circ[OLV_ATR_CIRC_PEDES])))
				break;
		}
		else
		{
			token = strtok(NULL, OliviaDef::GeneralDef::EjecGeoParamSep);
			continue;
		}
		token = strtok(NULL, OliviaDef::GeneralDef::EjecGeoParamSep);
		j++;
	}
	
	strcpy_s(olv->paths.path_res_rut,MAX_PATH,olv->paths.path_data);
	strcpy_s(olv->paths.path_res_pt,MAX_PATH,olv->paths.path_data);

	return j;
}
//*************************************************************************************
/**
 * Termina las tareas
 */
void Colv_limp::cancela()
{
	thr_limp->termina_th();
}
//*************************************************************************************
/**
 * Lee el ini y rellena los campos que lee, o bien por defecto
 */
BOOL Colv_limp::rellena_campos_ini(char *path)
{
	Cini_file ini;
	int ig;
	CString param;

	if(!ini.lee(path))
		return FALSE;

	param=OliviaDef::GeneralDef::GrupoCampoLimp;
	ig=ini.get_grupo(param.GetBuffer(param.GetLength()));
	if(ig>=0)
	{
		//leer campos del ini
		param=OliviaDef::GeneralDef::GAA_obser;
		strcpy_s(camps.campo_obs,OLV_LIMP_MAX_CAMP,ini.get(ig,param.GetBuffer(param.GetLength()),camps.campo_obs));
		camps.campo_obs[10]=0;

		param=OliviaDef::GeneralDef::GAA_anch_tip;
		strcpy_s(camps.campo_anch,OLV_LIMP_MAX_CAMP,ini.get(ig,param.GetBuffer(param.GetLength()),camps.campo_anch));
		camps.campo_anch[10]=0;

		param=OliviaDef::GeneralDef::GAA_tipolo;
		strcpy_s(camps.campo_tipo_ap,OLV_LIMP_MAX_CAMP,ini.get(ig,param.GetBuffer(param.GetLength()),camps.campo_tipo_ap));
		camps.campo_tipo_ap[10]=0;

		param=OliviaDef::GeneralDef::GAA_entid;
		strcpy_s(camps.campo_tipo_ent,OLV_LIMP_MAX_CAMP,ini.get(ig,param.GetBuffer(param.GetLength()),camps.campo_tipo_ent));
		camps.campo_tipo_ent[10]=0;
	}
	param=OliviaDef::GeneralDef::GrupoAtribLimp;
	ig=ini.get_grupo(param.GetBuffer(param.GetLength()));
	if(ig>=0)
	{

		param=OliviaDef::GeneralDef::GAL_aparc;
		strcpy_s(camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_AP],OLV_LIMP_MAX_CAMP,ini.get(ig,param.GetBuffer(param.GetLength()),camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_AP]));

		param=OliviaDef::GeneralDef::GAL_bord;
		strcpy_s(camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_BORD],OLV_LIMP_MAX_CAMP,ini.get(ig,param.GetBuffer(param.GetLength()),camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_BORD]));

		param=OliviaDef::GeneralDef::GAL_peat;
		strcpy_s(camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_PEAT],OLV_LIMP_MAX_CAMP,ini.get(ig,param.GetBuffer(param.GetLength()),camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_PEAT]));

		param=OliviaDef::GeneralDef::GAL_acera;
		strcpy_s(camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_ACERA],OLV_LIMP_MAX_CAMP,ini.get(ig,param.GetBuffer(param.GetLength()),camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_ACERA]));

		param=OliviaDef::GeneralDef::GAL_ap_lin;
		strcpy_s(camps.atr_tip_apa[OLV_ATR_TIP_AP_LIN],OLV_LIMP_MAX_CAMP,ini.get(ig,param.GetBuffer(param.GetLength()),camps.atr_tip_apa[OLV_ATR_TIP_AP_LIN]));

		param=OliviaDef::GeneralDef::GAL_ap_bat;
		strcpy_s(camps.atr_tip_apa[OLV_ATR_TIP_AP_BAT],OLV_LIMP_MAX_CAMP,ini.get(ig,param.GetBuffer(param.GetLength()),camps.atr_tip_apa[OLV_ATR_TIP_AP_BAT]));
	}
	//////////////////////////////////////////////////////
	param=OliviaDef::GeneralDef::GrupoCampoOtros;
	ig=ini.get_grupo(param.GetBuffer(param.GetLength()));
	if(ig>=0)
	{
		double ang;
		param=OliviaDef::GeneralDef::GTO_girmax;
		ang=ini.get(ig,param.GetBuffer(param.GetLength()),OLV_LIMP_GIRO_VEHIC);
		ang_lim = ang*OLV_PI/180;

		param=OliviaDef::GeneralDef::GTO_anch_peat;
		anchos_def[OLV_ANCH_DEF_PEAT]=ini.get(ig,param.GetBuffer(param.GetLength()),anchos_def[OLV_ANCH_DEF_PEAT]);

		param=OliviaDef::GeneralDef::GTO_anch_ace;
		anchos_def[OLV_ANCH_DEF_ACE]=ini.get(ig,param.GetBuffer(param.GetLength()),anchos_def[OLV_ANCH_DEF_ACE]);

		param=OliviaDef::GeneralDef::GTO_anch_aplin;
		anchos_def[OLV_ANCH_DEF_APLIN]=ini.get(ig,param.GetBuffer(param.GetLength()),anchos_def[OLV_ANCH_DEF_APLIN]);

		param=OliviaDef::GeneralDef::GTO_anch_apbat;
		anchos_def[OLV_ANCH_DEF_APBAT]=ini.get(ig,param.GetBuffer(param.GetLength()),anchos_def[OLV_ANCH_DEF_APBAT]);

		param=OliviaDef::GeneralDef::GTO_anch_bordlib;
		anchos_def[OLV_ANCH_DEF_BORD]=ini.get(ig,param.GetBuffer(param.GetLength()),anchos_def[OLV_ANCH_DEF_BORD]);

		param=OliviaDef::GeneralDef::GTO_desv_max;
		DESV_MAX=ini.get(ig,param.GetBuffer(param.GetLength()),OLV_DESV_MAX);

		param=OliviaDef::GeneralDef::GTO_desv_max_abs;
		DESV_MAX_ABS=ini.get(ig,param.GetBuffer(param.GetLength()),OLV_DESV_MAX_ABS);
	}
	return TRUE;
}
//*************************************************************************************
/**
 * Actualiza el ini
 */
BOOL Colv_limp::guarda_campos_ini(char *path)
{
	Cini_file ini;
	int ig;

	ig =ini.add_grupo(OLV_LIMP_GRUPO_DBF);
	if(ig<0)
		return FALSE;

	ini.add(ig,OLV_LIMP_PARAM_OBS,camps.campo_obs);
	ini.add(ig,OLV_LIMP_PARAM_ANCHO,camps.campo_anch);
	ini.add(ig,OLV_LIMP_PARAM_TIPO_AP,camps.campo_tipo_ap);
	ini.add(ig,OLV_LIMP_PARAM_TIPO_ENT,camps.campo_tipo_ent);

	ini.add(ig,OLV_LIMP_PARAM_TIPO_ENT_APARCA,camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_AP]);
	ini.add(ig,OLV_LIMP_PARAM_TIPO_ENT_BORD,camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_BORD]);
	ini.add(ig,OLV_LIMP_PARAM_TIPO_ENT_PEATO,camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_PEAT]);
	ini.add(ig,OLV_LIMP_PARAM_TIPO_ENT_ACERA,camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_ACERA]);

	ini.add(ig,OLV_LIMP_PARAM_TIPO_AP_LIN,camps.atr_tip_apa[OLV_ATR_TIP_AP_LIN]);
	ini.add(ig,OLV_LIMP_PARAM_TIPO_AP_BAT,camps.atr_tip_apa[OLV_ATR_TIP_AP_BAT]);
	
	ig =ini.add_grupo(OLV_LIMP_GRUPO_OTROS);
	if(ig<0)
		return FALSE;
	ini.add(ig,OLV_LIMP_PARAM_GIRO_VEHIC,OLV_LIMP_GIRO_VEHIC);
	ini.add(ig,OLV_LIMP_PARAM_ANCH_DEF_PEAT,anchos_def[OLV_ANCH_DEF_PEAT]);
	ini.add(ig,OLV_LIMP_PARAM_ANCH_DEF_ACE,anchos_def[OLV_ANCH_DEF_ACE]);
	ini.add(ig,OLV_LIMP_PARAM_ANCH_DEF_APLIN,anchos_def[OLV_ANCH_DEF_APLIN]);
	ini.add(ig,OLV_LIMP_PARAM_ANCH_DEF_APBAT,anchos_def[OLV_ANCH_DEF_APBAT]);
	ini.add(ig,OLV_LIMP_PARAM_ANCH_DEF_BORD,anchos_def[OLV_ANCH_DEF_BORD]);

	ini.add(ig,OLV_LIMP_PARAM_DESV_MAX,DESV_MAX);
	ini.add(ig,OLV_LIMP_PARAM_DESV_MAX_ABS,DESV_MAX_ABS);

	if(!ini.guarda(path))
		return FALSE;
	return TRUE;
	
}
//*************************************************************************************
/**
 * Rellena los nombres de los campos de la dbf
 */
void Colv_limp::rellena_campos()
{
	//TOM TOM
	sprintf_s(camps.campo_circ,OLV_LIMP_MAX_CAMP,"ONEWAY");
	sprintf_s(camps.campo_velo,OLV_LIMP_MAX_CAMP,"KPH");
	sprintf_s(camps.campo_fow,OLV_LIMP_MAX_CAMP,"FOW");
	sprintf_s(camps.campo_name,OLV_LIMP_MAX_CAMP,"NAME");

	//VSM
	sprintf_s(camps.campo_obs,OLV_LIMP_MAX_CAMP,"OBSERVACIO");
	sprintf_s(camps.campo_anch,OLV_LIMP_MAX_CAMP,"ANCHO_TIPO");
	sprintf_s(camps.campo_tipo_ap,OLV_LIMP_MAX_CAMP,"TIPOLOGIA");
	sprintf_s(camps.campo_tipo_ent,OLV_LIMP_MAX_CAMP,"NOM_TIPO_E");

	//IGT
	sprintf_s(camps.campo_secto,OLV_LIMP_MAX_CAMP,OliviaDef::GeneralDef::NombColSector);

	///////rellena los atributos
	//TOMTOM
	sprintf_s(camps.atr_circ[OLV_ATR_CIRC_TF],OLV_LIMP_MAX_CAMP,"TF");
	sprintf_s(camps.atr_circ[OLV_ATR_CIRC_FT],OLV_LIMP_MAX_CAMP,"FT");
	sprintf_s(camps.atr_circ[OLV_ATR_CIRC_NONE],OLV_LIMP_MAX_CAMP,"N");
	sprintf_s(camps.atr_circ[OLV_ATR_CIRC_PEDES],OLV_LIMP_MAX_CAMP,"14");
	//VSM
	sprintf_s(camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_AP],OLV_LIMP_MAX_CAMP,"Banda_Aparcamiento");
	sprintf_s(camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_BORD],"Bordillo_Libre");
	sprintf_s(camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_PEAT],OLV_LIMP_MAX_CAMP,"Peatonales");
	sprintf_s(camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_ACERA],OLV_LIMP_MAX_CAMP,"Acera");
	//
	sprintf_s(camps.atr_tip_apa[OLV_ATR_TIP_AP_LIN],OLV_LIMP_MAX_CAMP,"Linea");
	sprintf_s(camps.atr_tip_apa[OLV_ATR_TIP_AP_BAT],OLV_LIMP_MAX_CAMP,"Bateria");

	///////rellena los valores de anchos por defecto
	anchos_def[OLV_ANCH_DEF_PEAT]=6;
	anchos_def[OLV_ANCH_DEF_ACE]=1.5;
	anchos_def[OLV_ANCH_DEF_APLIN]=2;
	anchos_def[OLV_ANCH_DEF_APBAT]=4;
	anchos_def[OLV_ANCH_DEF_BORD]=1.5;
	//rellena datos de desviación
	DESV_MAX=OLV_DESV_MAX;
	DESV_MAX_ABS=OLV_DESV_MAX_ABS;

	if(olv->paths.path_cfg_geo[0])
	{
		rellena_campos_ini(olv->paths.path_cfg_geo);			
	}	
}
//*************************************************************************************
/**
 * Prueba debug
 */
void Colv_limp::prueba()
{
	Param_olv_limp_thr par;
	pp++;
	par.id_e=-1;

	int i =thr_limp->OLV_LIMP_EV_UNE_AMB_NW;
	thr_limp->encola(i,&par,FALSE);
	i ++;
	thr_limp->encola(i,&par,FALSE);
	i ++;
	thr_limp->encola(i,&par,FALSE);
}
//*************************************************************************************
/**
 * Devuelve el coste de recorrer un segmento en función de si es ámbito, segmento o carretera
 */
double Colv_limp::dame_ancho(char *observ, char *tipo)
{
	double aux, ancho,aux2;
	char *token;
	int i,ii,ff;

	ancho=0;
	aux=aux2=0;
	//El formato de observaciones tiene la forma "n metros", y el ancho es 'n'. 
	//Si no lo encontrara, tiene que ver el "ancho tipo"
	if(strlen(observ)>0)
	{
		//busca los números
		ii=-1;
		for(i=0;i<(int)strlen(observ);i++)
		{
			if((observ[i]>='1') && (observ[i]<='9'))
			{
				if(ii<0)
					ii=i;
				ff=i;
			}
		}
		if(ii>=0)
		{
			if(ff<((int)strlen(observ)-1))//delimita el número, donde acaba pone un null			
				observ[ff+1]=0;
			aux = atof(&observ[ii]);
		}
		if(aux>0)
			ancho=aux;
	}
	if(aux==0 && (strlen(tipo)>0))//bien porque no había campo observ o porque no se ha conseguido calcular
	{		
		//se coge el campo de tipo, con el formato de "2-4" o "<2" o ">4"
		if(token=strstr(tipo,"-"))//El ancho es tipo "2-4"
		{
			if((token-1)>0)
				aux=atof(token-1);
			if((token+1)>0)
				aux2=atof(token+1);
			aux=(aux+aux2)/2;
			if(aux)
				ancho=aux;
		}
		else if(token=strstr(tipo,"<"))//El ancho es tipo "<2"
		{
			if((token+1)>0)
				aux=atof(token+1);
			if(aux>1)
				ancho=aux-1;
		}
		else if(token=strstr(tipo,">"))//El ancho es tipo ">4"
		{
			if((token+1)>0)
				aux=atof(token+1);
			if(aux)
				ancho=aux+1;
		}
	}

	return ancho;
}
//*************************************************************************************
/**
 * Devuelve el coste de recorrer un segmento en función de si es ámbito, segmento o carretera
 */
void Colv_limp::dame_cost(double ltot, int ia, float *cost, float *cost2)
{
	double velo;
	double ancho;

	////////////////////////////////////////////////////////////////////////
	//Calcula el coste en función de si es carretera, segmento o ámbito
	//Posibilidades:
	//Se le da el coste al propio ámbito.	
	//Si es ámbito lineal, y t_tto es en km/h, cost=ltot/t_tto, pasando t_tto a m/s
	//Si es ámbito lineal, y t_tto es km2/h, si ancho_via==0 entonces el ancho es el leído de la dbf
	//y el coste de ida y de vuelta es cost=ltot*anch/t_tto, donde anch puede ser ancho_via o el de la info asociada
	//Si es ámbito puntual, el coste es directamente t_tto, pasando t_tto de min a seg
	//Si es segmento, ambos costes son 0
	//Si es carretera, la velocidad puede ser definida por la vía o v_despl si no es 0
	//y el cost=ltot/velo
	//también hay que mirar si se puede en los dos sentidos o no
	////////////////////////////////////////////////////////////////////////	
	if(iaso[ia].flgs & OLV_LIMP_FLG_AMB)
	{
		//calculamos el coste del ámbito
		if(tipo_ambit==OLV_AMB_LIN)
		{		
			if((uds_tto==OliviaDef::GeneralDef::OlvTipTtoMh) || (uds_tto==OliviaDef::GeneralDef::OlvTipTtoMh_eje))
				ancho=1;
			else if(uds_tto==OliviaDef::GeneralDef::OlvTipTtoM2h)
				ancho=iaso[ia].inf_l.ancho;
			else if(uds_tto==OliviaDef::GeneralDef::OlvTipTtoM2h_eje)
				ancho=ancho_via;

			*cost2=*cost=(float)(ltot*ancho*3600/t_tto);			//en segundos
		}
		else if(tipo_ambit==OLV_AMB_PUN)
		{
			*cost=*cost2=(float)t_tto; //en segundos
		}
	}
	else if(iaso[ia].flgs & OLV_LIMP_FLG_SEG_AMB)
	{
		//coste fijo para los segmentos que unen ambitos, proporcional a su longitud
		*cost2=*cost=0;//(float)(ltot/(3*OLV_KMH2MS));//OLV_LIMP_COST_SEGM
	}	
	else if(iaso[ia].flgs & (OLV_LIMP_FLG_SEG_LIN | OLV_LIMP_FLG_SEG_PUN))
	{
		//coste fijo para los segmentos
		*cost2 = *cost = 0;// (float)(ltot / (3 * OLV_KMH2MS));//OLV_LIMP_COST_SEGM
	}	
	else if(iaso[ia].flgs & OLV_LIMP_FLG_PEAT_REP)
	{
		//coste de desplazarse andando por las peatonales, no trabajando
		if(v_despl==0)
			velo=OLV_LIMP_VELO_DESP_PEAT*OLV_KMH2MS;
		else
			velo=v_despl; //velocidad que se haya configurado
		*cost2=*cost=float(ltot/velo);	
	}
	else if(iaso[ia].flgs & OLV_LIMP_FLG_NW)//es carretera
	{
		//calculamos el coste de la carretera
		if(v_despl==0)
			velo=iaso[ia].inf_n.velo; //velocidad definida por las vías, la que se ha leído del dbf
		else
		{
			velo=v_despl*f_trafic; //velocidad que se haya configurado
		}
		//////////////////////////////////////////////////////////
		/*if(iaso[ia].flgs & OLV_LIMP_FLG_CIRC_NONE)//es pedestrian o prohibido, no se puede circular
			*cost=*cost2=(float)MAYUSCULO;		
		else*/
		{			
			*cost=*cost2=(float)(ltot/velo); //en ambos sentidos
			if(iaso[ia].flgs & OLV_LIMP_FLG_CIRC_FT)
				*cost2=(float)MAYUSCULO;
			else if(iaso[ia].flgs & OLV_LIMP_FLG_CIRC_TF)
				*cost=(float)MAYUSCULO;
		}		
	}
}
//*************************************************************************************
void Secu_amb::libera(int i, int n)
{
	for(int j=0;j<n;j++)
	{
		ctnod[i][j].libera();
	}
}
//*************************************************************************************
#endif