Olivia_v2017/Olivia/olv.cpp

577 lines
18 KiB
C++

#include "stdafx.h"
#ifdef OLIVIA_COMPILA
//olivia
#include "olv.h"
#include "olv_limp.h"
#include "olv_sock.h"
#include "olv_limp_thr.h"
#include "olv_reco.h"
#include "olv_tasks_def.h"
//utiles
#include "ini_file.h"
#include "_error.h"
#include "lock.h"
#include "Msmain.h"
#include "utl.h"
/**
* Una vez configurada la herramienta OLIVIA a través del Addin para ArcGIS desarrollado
* a tal efecto en c# vc2010, se llama al proceso OliviaTasks.exe que se encontrará en el directorio
* de instalación "\bin"
*/
/**
* @file olv.cpp
* Archivo de implementaciones generales de la herramienta Olivia de OliviaTasks.
*/
COlivia::COlivia(void)
{
isDebug = false;
tipo_oliv = OliviaDef::GeneralDef::OlivNoDef;
memset(&paths, 0, &paths.pfin-(char*)&paths);
olv_limp = NULL;
ya_config=FALSE;
fin=FALSE;
tarea=progreso=0;
rellena_tareas(); //Rellena los textos de las tareas
msg_proce[0]=0;
modo_ejec=OLV_EJEC_NDEBUG;
olv_reco=NULL;
olv_sock = new Colv_sock(this);
lock = new Clock();
strcpy_s(paths.path_cfg_geo,"");
modo_multitask=FALSE;
memset(&infotask,0,sizeof(InfoIniTask));
log.l_lisener = this;
}
COlivia::~COlivia(void)
{
if(olv_limp)
delete olv_limp;
if(olv_reco)
delete olv_reco;
delete (olv_sock);
delete (lock);
}
//*************************************************************************************
/**
* Rellena la matriz de textos de tareas
*/
void COlivia::rellena_tareas()
{
sprintf_s(tareas_str[OLV_TAREA_CALC],OLV_MAX_TAREA,"Conectado, comenzando cálculos\n");
sprintf_s(tareas_str[OLV_TAREA_IMP],OLV_MAX_TAREA,"Importando datos\n");
sprintf_s(tareas_str[OLV_TAREA_SENS],OLV_MAX_TAREA,"Leyendo información de carga de los sensores\n");
sprintf_s(tareas_str[OLV_TAREA_UNE_NW_AMB],OLV_MAX_TAREA,"Uniendo ámbitos a red navegable\n");
sprintf_s(tareas_str[OLV_TAREA_TOPO_NW],OLV_MAX_TAREA,"Generando topologías en la red\n");
sprintf_s(tareas_str[OLV_TAREA_COST_AMB],OLV_MAX_TAREA,"Calculando matriz de costes entre ámbitos\n");
sprintf_s(tareas_str[OLV_TAREA_GUARD_MAT],OLV_MAX_TAREA,"Guardando matrices\n");
sprintf_s(tareas_str[OLV_TAREA_MULTITASK],OLV_MAX_TAREA,"Calculando costes entre ámbitos en multitask...\n");
sprintf_s(tareas_str[OLV_TAREA_SECTORIZ],OLV_MAX_TAREA,"Sectorizando\n");
sprintf_s(tareas_str[OLV_TAREA_CALC_SEC],OLV_MAX_TAREA,"Calculando número de sectores\n");
sprintf_s(tareas_str[OLV_TAREA_PERMU],OLV_MAX_TAREA,"Calculando permutaciones para mejorar...Puede tardar unos minutos\n");
sprintf_s(tareas_str[OLV_TAREA_LEE_SECTO],OLV_MAX_TAREA,"Leyendo sectorización\n");
sprintf_s(tareas_str[OLV_TAREA_PLANIF],OLV_MAX_TAREA,"Planificando\n");
sprintf_s(tareas_str[OLV_TAREA_FIN_SEC],OLV_MAX_TAREA,OliviaDef::GeneralDef::SockSectFin);
sprintf_s(tareas_str[OLV_TAREA_FIN_PLANIF],OLV_MAX_TAREA,OliviaDef::GeneralDef::SockPlanFin);
sprintf_s(tareas_str[OLV_TAREA_FIN_OK],OLV_MAX_TAREA,OliviaDef::GeneralDef::SockFinOk);
sprintf_s(tareas_str[OLV_TAREA_FIN_NOK],OLV_MAX_TAREA,OliviaDef::GeneralDef::SockFinNOk);
}
//*************************************************************************************
/**
* Función llamada por el mainframe para delete el socket ppal
*/
void COlivia::destruye_socket(LPARAM lp)
{
delete ((Colv_sock*)lp);
}
//*************************************************************************************
/**
* Dada la línea de comandos, la divide en los parámetros necesarios
*/
BOOL COlivia::coge_param(char *param)
{
char *token;
int j;
//los parámetros son:
//\olivia \tipo_oliv \cfg.ini \ip \puerto \toutsock
token = strtok(param, OliviaDef::GeneralDef::EjecGeoParamSep);
//Lee parámetros
j=0;
while (token != NULL)
{
if(strstr(token,OliviaDef::GeneralDef::GG_tipo))
{
if(!dame_param(token,&tipo_oliv))
break;
}
else if(strstr(token,OliviaDef::GeneralDef::GG_ip))
{
if(!dame_param(token, olv_sock->ip,sizeof(olv_sock->ip)))
break;
}
else if(strstr(token,OliviaDef::GeneralDef::GG_port))
{
if(!dame_param(token, &olv_sock->puerto))
break;
}
else if(strstr(token,OliviaDef::GeneralDef::GG_tout))
{
int t_out;
if(!dame_param(token, &t_out))
break;
olv_sock->pon_tout(t_out);
}
else if(strstr(token,OliviaDef::GeneralDef::GG_pt))
{
if(!dame_param(token, paths.path_temp,sizeof(paths.path_temp)))
break;
}
else if(strstr(token,OliviaDef::GeneralDef::GG_pcfg))
{
if(!dame_param(token, paths.path_cfg_geo,sizeof(paths.path_cfg_geo)))
break;
}
else if(strstr(token, "debug"))
isDebug = true;
else
break;
token = strtok(NULL, OliviaDef::GeneralDef::EjecGeoParamSep);
j++;
}
if(j<OliviaDef::GeneralDef::ParamN)
return FALSE; //no ha leído los param suficientes
return TRUE;
}
//*************************************************************************************
/**
* Borra archivos de log antiguos para que no se acumulen
*/
void COlivia::borra_log_old()
{
char*f;
int n=0;
__int64 t = _time64(NULL);
int dia,mes,ano, i;
t-=60*60*24*15;
CTime tt(t);
dia=tt.GetDay();
mes=tt.GetMonth();
ano=tt.GetYear();
//pilla archivos-----------------
StrArray fils, filsa, buf;
Cdir_manager::lista_files(C_app::GetApp()->log.path,&fils);
fils.filtra(&filsa,".log");
n = filsa.size()-1;
//borra log antiguo-----------------------
while(n>=0)
{
buf.n_i = buf.n_str =0;
f =filsa.get(n--);
if(Cutl::stringSplit(f,"_", &buf)->n_i<5)
continue;
if(!strstr(buf.get(0),C_app::GetApp()->log.nombre))
continue;
i=atoi(buf.get(1));
if(i<ano)
goto borra;
else if(i>ano)
continue;
//busca mes-----------------
i=atoi(buf.get(2));
if(i<mes)
goto borra;
else if(i>mes)
continue;
//busca dia--------------------
if(atoi(buf.get(3))<dia)
goto borra;
continue;
borra:
DeleteFile(f);
}
}
//*************************************************************************************
/**
* Inicia la instancia de la herramienta Olivia, en modo limpieza o residuos
*/
BOOL COlivia::inicia(char *cmdline,char *err, int nerr)
{
BOOL ret = TRUE;
borra_log_old();//borra log antiguo-----
//olvlog(LOG_TODO, "olv", "Param %s", cmdline);
if(!coge_param(cmdline))
{
sprintf_s(err,nerr,"Error al iniciar OliviaTasks para OLIVIA:\nError al leer parámetros, menos de los esperados");
return FALSE;
}
switch(tipo_oliv)
{
case OliviaDef::GeneralDef::OlivLimp:
olv_limp = new Colv_limp(this);
break;
case OliviaDef::GeneralDef::OlivResi:
olv_reco = new Colv_reco(this);
break;
default:
sprintf_s(err,nerr,"Error al iniciar OliviaTasks para OLIVIA:\nTipo recibido no esperado");
ret=FALSE;
break;
}
if(ret)
{
//////////////////////////////
//si ha ido bien, inicia socket de comunicaciones
if(!olv_sock->pon_escucha(olv_sock->ip,olv_sock->puerto))
{
olv_sock->cierra();
sprintf_s(err,nerr,"Error al iniciar OliviaTasks para OLIVIA:\nError al iniciar socket");
ret=FALSE;
}
}
return ret;
}
//*************************************************************************************
/**
* Devuelve la tarea por la que se va ejecutando
*/
int COlivia::dame_tarea()
{
return tarea;
}
//*************************************************************************************
/**
* Devuelve el progreso de ejecución de la tarea, de 0 a 100
*/
int COlivia::dame_progre()
{
return progreso;
}
//*************************************************************************************
/**
* Pone las opciones de configuración de lo que recibe por el socket
*/
BOOL COlivia::pon_config(char *config)
{
BOOL ret=FALSE;
ya_config=TRUE;
////////////////////////////////////////////////
/*char config_log[1000];
sprintf_s(config_log, 1000, config);
olvlog(LOG_TODO, "olv", "Config %s", config_log);*/
////////////////////////////////////////////////
if(strstr(config,OliviaDef::GeneralDef::SockConfPlan))
modo_ejec=OLV_EJEC_PLAN;
else if(strstr(config,OliviaDef::GeneralDef::SockConfTodo))
modo_ejec=OLV_EJEC_TODO;
else if(strstr(config,OliviaDef::GeneralDef::SockConf))
modo_ejec=OLV_EJEC_SECT;
switch(tipo_oliv)
{
case OliviaDef::GeneralDef::OlivLimp:
if(olv_limp->pon_config(config)==OliviaDef::GeneralDef::ParamLimpN)
ret = olv_limp->inicia();
break;
case OliviaDef::GeneralDef::OlivResi:
if(olv_reco->pon_config(config)==OliviaDef::GeneralDef::ParamRecoN)
ret = olv_reco->inicia();
break;
default:
break;
}
return ret;
}
//*************************************************************************************
/**
* Cancela el proceso, borra archivos temporales y cierra
*/
void COlivia::cancela()
{
switch(tipo_oliv)
{
case OliviaDef::GeneralDef::OlivLimp:
olv_limp->cancela();
break;
default:
break;
}
/*if(olv_limp && olv_limp->thr_limp && !olv_limp->thr_limp->fin_permu)
{
//manda cerrar
//SendMessage(mfrm,WM_CLOSE,0,0);
mfrm->pirate = true;
}*/
mfrm->pirate = true;
}
//*************************************************************************************
/**
* Devuelve el parámetro, char*
*/
BOOL COlivia::dame_param(char *token, char *param, int sizeparam)
{
char *c;
int ss;
c=strstr(token,OliviaDef::GeneralDef::EjecGeoParamIgual);
if(!c)
return FALSE;
strcpy_s(param,sizeparam,(c+1));
ss=(int)strlen(param);
param[ss-1]=0;
return TRUE;
}
//*************************************************************************************
/**
* Devuelve el parámetro, int
*/
BOOL COlivia::dame_param(char *token, int *param)
{
char *c;
c=strstr(token,OliviaDef::GeneralDef::EjecGeoParamIgual);
if(!c)
return FALSE;
*param=atoi(c+1); //el valor está a continuación del separador
return TRUE;
}
//*************************************************************************************
/**
* Devuelve el parámetro, double
*/
BOOL COlivia::dame_param(char *token, double *param)
{
char *c;
c=strstr(token,OliviaDef::GeneralDef::EjecGeoParamIgual);
if(!c)
return FALSE;
*param=atof(c+1); //el valor está a continuación del separador
return TRUE;
}
//*************************************************************************************
/**
* Función de ejecución de prueba para Debug
*/
void COlivia::prueba()
{
int i;
const int max_char_cap=3048;
char config[max_char_cap];
///////////////////
//solo para debug elena olivia
i=2;
if(fin)
{
//cerrar_cartografia();
if(tipo_oliv==0)
{
delete olv_limp;
olv_limp = new Colv_limp(this);
}
else
{
delete olv_reco;
olv_reco = new Colv_reco(this);
}
}
switch(i)
{
case 1:
sprintf_s(config, max_char_cap,"/CONFIG_TODO /t_tto:2900 /restr_cir:0 /u_tto:3 /v_despl:5 /t_conv:480 /t_descan:30 /t_despl:25 /t_carg:40 "\
"/h_inicio:450 /trafico:80 /n_ptsctrl:3 /n_secdef:3 /anch_med:2 /coor_inst_x:0 /coor_inst_y:0 /aislados:1 /cons_obser:OBSERVACIONES "\
"/cons_anch_tip:ANCHO_TIPO /cons_tipolo:TIPOLOGIA /cons_tip_ent:NOM_TIPO_ENTIDAD /atr_aparc:Banda Aparcamiento /atr_bord:Bordillo Libre "\
"/atr_acera:Aceras /atr_peat:Peatonales /atr_ap_lin:Linea /atr_ap_bat:Bateria /cons_onew:ONEWAY /cons_kph:KPH /cons_fow:FOW /cons_name:NAME "\
"/atr_TF:TF /atr_FT:FT /atr_N:N /atr_pedes:14 /str_tto:Barrido_man "\
"/Camp_sector:SECTOR /Camp_secuencia:SECUENCIA /Camp_objectid:FID "\
"/Giro_max_vehiculo:175 /Desv_max_rel:0.15 /Desv_max_abs:1000 "\
"/Ancho_peat_def:6 /Ancho_acera_def:1.5 /Ancho_ap_lin_def:2 "\
"/Ancho_ap_bat_def:4 /Ancho_bord_lib_def:1.5 "\
"/path_data:D:\\Proyectos\\Olivia\\Instal3.0\\data_prueba_2\\data_T00_A0405_20230111_233224.shp "\
"/path_nw:D:\\Proyectos\\Olivia\\Instal3.0\\data_prueba_2\\nw_20230111_233224.shp ");
break;
case 2:
sprintf_s(config, max_char_cap, "/CONFIG_PLANIF /campo_capaci:CAPACIDAD /kg_max:7500 /campo_kgrecog:KGRECO /campo_uds:UNIDADES /recogida_kg:200 /carga_cont:0 "\
"/densidad:-1 /t_conv:480 /t_descan:30 /t_vacia:90 /t_descarg:40 /t_sallleg:25 /h_inicio:420 /trafico:80 "\
"/n_ptsctrl:3 /n_secdef:3 /anch_vehi:0 /giro_vehi:175 /coor_inst_x:544038,5064 /coor_inst_y:4624375,9191 "\
"/coor_desc_x:543887,2812 /coor_desc_y:4623093,8184 "\
"/sens_id:0 /sens_url:0 /sens_fechai:0 /sens_fechaf:0 /md_pet:0 /aislados:1 /lateralidad:0 "\
"/cons_onew:ONEWAY /cons_kph:KPH /cons_fow:FOW /cons_name:NAME "\
"/atr_TF:TF /atr_FT:FT /atr_N:N /atr_pedes:14 /str_tto:Resto "\
"/Camp_sector:SECTOR /Camp_secuencia:SECUENCIA /Camp_objectid:FID "\
"/Giro_max_vehiculo:175 /Desv_max_rel:0.15 /Desv_max_abs:1000 "\
"/path_data:D:\\Proyectos\\Olivia\\Instal3.0\\data_prueba_put_1\\data_F01_C01_20230207_112246.shp "\
"/path_nw:D:\\Proyectos\\Olivia\\Instal3.0\\data_prueba_put_1\\nw_20230207_112246.shp ");
break;
case 3://nw de arcmap
sprintf_s(config, max_char_cap, "/CONFIG /t_tto:2900 /restr_cir:0 /u_tto:3 /v_despl:5 /t_conv:480 /t_descan:30 /t_despl:25 /t_carg:40 "\
"/h_inicio:450 /trafico:80 /n_ptsctrl:3 /n_secdef:3 /anch_med:2 /coor_inst_x:0 /coor_inst_y:0 /aislados:1 /cons_obser:OBSERVACIONES "\
"/cons_anch_tip:ANCHO_TIPO /cons_tipolo:TIPOLOGIA /cons_tip_ent:NOM_TIPO_ENTIDAD /atr_aparc:Banda Aparcamiento /atr_bord:Bordillo Libre "\
"/atr_acera:Aceras /atr_peat:Peatonales /atr_ap_lin:Linea /atr_ap_bat:Bateria /cons_onew:ONEWAY /cons_kph:KPH /cons_fow:FOW /cons_name:NAME "\
"/atr_TF:TF /atr_FT:FT /atr_N:N /atr_pedes:14 /str_tto:Barrido_man "\
"/path_data:D:\\Proyectos\\Olivia\\Instal2.0\\data\\data_T00_A04050607_NNivel7_20220327_155737.shp /path_nw:D:\\Proyectos\\Olivia\\Instal2.0\\data\\nw_20220327_170516.shp ");
break;
case 5://orig arcmap
sprintf_s(config, max_char_cap, "/CONFIG /t_tto:2900 /restr_cir:0 /u_tto:3 /v_despl:5 /t_conv:480 /t_descan:30 /t_despl:25 /t_carg:40 "\
"/h_inicio:420 /trafico:80 /n_ptsctrl:3 /n_secdef:3 /anch_med:2 /coor_inst_x:0 /coor_inst_y:0 /aislados:0 /cons_obser:OBSERVACIONES "\
"/cons_anch_tip:ANCHO_TIPO /cons_tipolo:TIPOLOGIA /cons_tip_ent:NOM_TIPO_ENTIDAD /atr_aparc:Banda Aparcamiento /atr_bord:Bordillo Libre "\
"/atr_acera:Aceras /atr_peat:Peatonales /atr_ap_lin:Linea /atr_ap_bat:Bateria /cons_onew:ONEWAY /cons_kph:KPH /cons_fow:FOW /cons_name:NAME "\
"/atr_TF:TF /atr_FT:FT /atr_N:N /atr_pedes:14 /str_tto:Barrido_man "\
"/path_data:D:\\Proyectos\\Olivia\\Instal2.0\\data\\data_T00_A04050607_NNivel7_20220327_170516.shp /path_nw:D:\\Proyectos\\Olivia\\Instal2.0\\data\\nw_20220327_170516.shp ");
break;
case 4://datos arcgis
sprintf_s(config, max_char_cap, "/CONFIG /t_tto:2900 /restr_cir:0 /u_tto:3 /v_despl:5 /t_conv:480 /t_descan:30 /t_despl:25 /t_carg:40 "\
"/h_inicio:450 /trafico:80 /n_ptsctrl:3 /n_secdef:3 /anch_med:2 /coor_inst_x:0 /coor_inst_y:0 /aislados:0 /cons_obser:OBSERVACIONES "\
"/cons_anch_tip:ANCHO_TIPO /cons_tipolo:TIPOLOGIA /cons_tip_ent:NOM_TIPO_ENTIDAD /atr_aparc:Banda Aparcamiento /atr_bord:Bordillo Libre "\
"/atr_acera:Aceras /atr_peat:Peatonales /atr_ap_lin:Linea /atr_ap_bat:Bateria /cons_onew:ONEWAY /cons_kph:KPH /cons_fow:FOW /cons_name:NAME "\
"/atr_TF:TF /atr_FT:FT /atr_N:N /atr_pedes:14 /str_tto:Barrido_man "\
"/path_data:D:\\Proyectos\\Olivia\\Instal2.0\\data\\data_T00_A04050607_NNivel7_20220327_155737.shp /path_nw:D:\\Proyectos\\Olivia\\Instal2.0\\data\\nw_20220327_170516.shp ");
break;
}
///////////////////////////////////////////////
/*CoptiMemo oo;
int nvect = oo.calc_nvect_master(20000);
BOOL is = oo.is_multi(20000,8,12); */
///////////////////////////////////////////////
modo_ejec=OLV_EJEC_DEBUG_SIGUE;
pon_config(config);
if(!fin)
fin=TRUE;
}
//*************************************************************************************
BOOL COlivia::creaSocProces( Colv_limp *olv_limp )
{
//SendMessage(mfrm,WMS_CMD,WMS_CMD_OLV_CREA_SOCK_MULTI, (LPARAM)olv_limp);
return olv_limp->soc != NULL;
//crea socket
}
//*************************************************************************************
BOOL COlivia::destruyeSocProces( Colv_limp *olv_limp )
{
//SendMessage(mfrm,WMS_CMD,WMS_CMD_OLV_DEST_SOCK_MULTI, (LPARAM)olv_limp);
return olv_limp->soc != NULL;
//crea socket
}
//*************************************************************************************
/**
* Funcion llamada por el mainframe para crear el socket multitask
*/
void COlivia::crea_socket_multi( LPARAM lp )
{
/*
Colv_limp *limp = (Colv_limp*)lp;
limp->soc = new Csock_sv();
limp->soc->escucha=(Cescucha_sock_sv*)limp->olv_tasks;
if(!limp->soc->Create(TASKS_PORT,
SOCK_STREAM,FD_ACCEPT | FD_READ | FD_CLOSE,
limp->olv->olv_sock->ip))
{
goto mal;
}
if(!limp->soc->Listen())
goto mal;
return;
mal:
limp->soc->Close();
delete limp->soc;
limp->soc=NULL;*/
}
//*************************************************************************************
//*************************************************************************************
/**
* Funcion llamada por el mainframe para delete el socket multitask
*/
void COlivia::destruye_socket_multi( LPARAM lp )
{
/*
Colv_limp *olv_limp = (Colv_limp*)lp;
olv_limp->soc->Close();
delete olv_limp->soc;
olv_limp->soc=NULL;*/
}
//*************************************************************************************
void COlivia::log_ext( __time64_t tiemp, char *modulo, char *fmt )
{
if(mfrm)
mfrm->log_ext( tiemp, modulo, fmt );
/*
class CMsgdocOlv : public CObject
{
public:
// Construction....
CMsgdocOlv(){};
~CMsgdocOlv(){};
// Attributes....
CString m_modulo;
CString m_texto;
int m_nivel;
CTime m_time;
// access routines....
};
CMsgdocOlv* msg = new CMsgdocOlv();
msg->m_nivel = 1;
msg->m_modulo = modulo;
msg->m_texto = fmt;
//msg->smsg(nivel, modulo,buf);
//SendMessage(mfrm,(WM_USER+1), 0, (LPARAM) msg );*/
}
//*************************************************************************************
//*************************************************************************************
/**
* Función global para log
*/
void olvlog (int nivel, char * modulo, char *fmt, ...)
{
char buf[1024];
int k;
va_list arg_ptr;
va_start(arg_ptr, fmt);
k = _vsnprintf(buf,1000, fmt, arg_ptr);
va_end(arg_ptr);
if (k<0)
strcpy(&buf[200],"HAY MAS");
C_log::log(modulo,buf);
}
#endif