10369 lines
281 KiB
C++
10369 lines
281 KiB
C++
#include "stdafx.h"
|
||
|
||
#ifdef OLIVIA_COMPILA
|
||
//olivia
|
||
#include "olv_limp_thr.h"
|
||
#include "olv_thr.h"
|
||
#include "olv_limp.h"
|
||
#include "olv_shp.h"
|
||
#include "olv_geofoto.h"
|
||
#include "olv.h"
|
||
#include "olv_geom.h"
|
||
#include "olv_csv.h"
|
||
//geofoto
|
||
#include "varios.h"
|
||
#include "wvarios.h"
|
||
#include "gdiplus.h"
|
||
#include "obgeo.h"
|
||
#include "dbf.h"
|
||
#include "vector.h"
|
||
#include "nivelint.h"
|
||
#include "Geomet.h"
|
||
//igt_base
|
||
#include "igt_lock.h"
|
||
#include "vector.h"
|
||
#include "value.h"
|
||
#include <stack>
|
||
#include "olv_tasks.h"
|
||
#include "olv_tasks_def.h"
|
||
#include "olv_sock.h"
|
||
#include "dir_manager.h"
|
||
|
||
UINT th_planificacion(LPVOID pp);
|
||
/**
|
||
* @file olv_limp_thr.cpp
|
||
* Archivo de implementaciones del thread de control de la utilidad de limpieza viaria del programa Olivia.
|
||
*/
|
||
|
||
Colv_limp_thr::Colv_limp_thr(Colv_limp *olv_limp) : Colv_thr(olv_limp->olv)
|
||
{
|
||
this->olv_limp = olv_limp;
|
||
thr_padre=NULL;
|
||
n_subthr_fin=0;
|
||
pirate=FALSE;
|
||
fin_permu=FALSE;
|
||
//los subthreads
|
||
n_subthr=Colv_geom::dame_n_nucleos(); //lanza un thread por procesador
|
||
subthrs = (Colv_limp_thr **)malloc(n_subthr*sizeof(Colv_limp_thr *));
|
||
for(int i=0;i<n_subthr;i++)
|
||
{
|
||
subthrs[i] = NULL;
|
||
}
|
||
prog_subthr=0;
|
||
ob_rut = NULL;
|
||
ob_ctrl = NULL;
|
||
ob_flech=NULL;
|
||
ob_inst=NULL;
|
||
ob_inst_fl=NULL;
|
||
n_subthr_mal=0;
|
||
visto_ang=NULL;
|
||
tramos=NULL;
|
||
}
|
||
|
||
Colv_limp_thr::~Colv_limp_thr(void)
|
||
{
|
||
int i;
|
||
|
||
//destruye los subthreads
|
||
if(subthrs)
|
||
{
|
||
for(i=0;i<n_subthr;i++)
|
||
{
|
||
if(subthrs[i])
|
||
delete subthrs[i];
|
||
}
|
||
free(subthrs);
|
||
}
|
||
if(ob_rut)
|
||
delete ob_rut;
|
||
if(ob_ctrl)
|
||
delete ob_ctrl;
|
||
if(ob_flech)
|
||
delete ob_flech;
|
||
if(ob_inst)
|
||
delete ob_inst;
|
||
if(ob_inst_fl)
|
||
delete ob_inst_fl;
|
||
if(visto_ang)
|
||
free(visto_ang);
|
||
borra_temp_files();
|
||
if(tramos)
|
||
delete [] tramos;
|
||
}
|
||
|
||
//*************************************************************************************
|
||
void Colv_limp_thr::inicia_th()
|
||
{
|
||
inicia(OLV_MILIS_COLA,&cola_proc,-1,"limp_thr");
|
||
wgeolog(LOG_TODO,"olv_limp_t","Thread de limpieza limp_thr arrancado");
|
||
borra_temp_files();
|
||
pirate=FALSE;
|
||
fin_permu=FALSE;
|
||
}
|
||
|
||
//*************************************************************************************
|
||
void Colv_limp_thr::cola_proc(int evento, Casync_cola<Param_olv_limp_thr> *clase,Param_olv_limp_thr *e)
|
||
|
||
{
|
||
BOOL bien=TRUE;
|
||
|
||
Colv_limp_thr *this_i=static_cast<Colv_limp_thr *>(clase);
|
||
switch (evento)
|
||
{
|
||
case OLV_LIMP_EV_ABRE_DAT:
|
||
{
|
||
bien=this_i->abre_datos();
|
||
if(bien && (this_i->olv->modo_ejec<OLV_EJEC_DEBUG_NOSIGUE) && !this_i->pirate)//sigue
|
||
this_i->encola(OLV_LIMP_EV_RELL_DAT,NULL,FALSE);
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_RELL_DAT:
|
||
{
|
||
bien=this_i->rellena_datos();
|
||
if(bien && (this_i->olv->modo_ejec<OLV_EJEC_DEBUG_NOSIGUE) && !this_i->pirate)//sigue
|
||
{
|
||
if(!this_i->olv->olv_limp->barr_mix)
|
||
this_i->encola(OLV_LIMP_EV_UNE_AMB_NW,NULL,FALSE);
|
||
else
|
||
this_i->encola(OLV_LIMP_EV_BARRMIX,NULL,FALSE);
|
||
}
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_BARRMIX:
|
||
{
|
||
//esta tarea lanza varios subthreads para realizar las comprobaciones del barrido mixto
|
||
//y estos cuando acaban le encolan al padre (el que los ha lanzado)
|
||
//la tarea de comprueba_barr_mixto_fin
|
||
this_i->mejora_barr_mix();
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_BARRMIX_SUB:
|
||
{
|
||
//aqu<71> entran los subthreads para hacer las comprobaciones del barrido mixto
|
||
//encolan al padre la tarea de fin
|
||
int ithr;
|
||
if(e!=NULL)
|
||
ithr=e->id_e;
|
||
this_i->mejora_barr_mix_sub(ithr);
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_BARRMIX_FIN:
|
||
{
|
||
//aqu<71> entra el padre cuando van acabando los subthreads
|
||
//si han terminado todos encola la siguiente tarea
|
||
|
||
this_i->n_subthr_fin++;
|
||
if(this_i->n_subthr_fin==this_i->n_subthr)
|
||
{
|
||
this_i->n_subthr_fin=0;
|
||
bien=this_i->mejora_barr_mix_fin();
|
||
if(bien && (this_i->olv->modo_ejec<OLV_EJEC_DEBUG_NOSIGUE) && !this_i->pirate)//sigue
|
||
{
|
||
this_i->encola(OLV_LIMP_EV_UNE_AMB_NW,NULL,FALSE);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_UNE_AMB_NW:
|
||
{
|
||
int soloi=-1;
|
||
bien=this_i->une_amb_nw(soloi);
|
||
if(bien && (this_i->olv->modo_ejec<OLV_EJEC_DEBUG_NOSIGUE) && !this_i->pirate)//sigue
|
||
this_i->encola(OLV_LIMP_EV_TOPO_NW,NULL,FALSE);
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_TOPO_NW:
|
||
{
|
||
bien=this_i->topo_nw();
|
||
if(bien && (this_i->olv->modo_ejec<OLV_EJEC_DEBUG_NOSIGUE) && !this_i->pirate)//sigue
|
||
this_i->encola(OLV_LIMP_EV_COST_CONJ,NULL,FALSE);
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_COST_CONJ:
|
||
{
|
||
//esta tarea lanza varios subthreads para realizar los c<>lculos
|
||
//de costes entre conjunciones (les encola la tarea dist_conj_sub),
|
||
//y estos cuando acaban le encolan al padre (el que los ha lanzado)
|
||
//la tarea de dist_conj_fin
|
||
bien=this_i->calcula_cost_conj();
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_COST_CONJ_SUB:
|
||
{
|
||
//aqu<71> entran los subthreads para hacer los c<>lculos de distancia, cuando acaban
|
||
//encolan al padre la tarea de fin
|
||
int ithr;
|
||
if(e!=NULL)
|
||
ithr=e->id_e;
|
||
this_i->calcula_cost_conj_sub(ithr);
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_COST_CONJ_FIN:
|
||
{
|
||
//aqu<71> entra el padre cuando van acabando los subthreads
|
||
//si han terminado todos encola la siguiente tarea
|
||
|
||
this_i->n_subthr_fin++;
|
||
if(this_i->n_subthr_fin==this_i->n_subthr)
|
||
{
|
||
this_i->n_subthr_fin=0;
|
||
bien=this_i->calcula_cost_conj_fin();
|
||
if(bien && (this_i->olv->modo_ejec<OLV_EJEC_DEBUG_NOSIGUE) && !this_i->pirate)//sigue
|
||
{
|
||
if(this_i->olv_limp->res_circ!=OLV_RES_NO)
|
||
this_i->encola(OLV_LIMP_EV_ANG_CONJ,NULL,FALSE);
|
||
else if(this_i->olv_limp->olv->modo_multitask)
|
||
this_i->encola(OLV_LIMP_EV_GUARD_MATS,NULL,FALSE);
|
||
else
|
||
this_i->encola(OLV_LIMP_EV_COST_AMB,NULL,FALSE);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_ANG_CONJ:
|
||
{
|
||
//esta tarea lanza varios subthreads para realizar los c<>lculos
|
||
//de <20>ngulos entre conjunciones (les encola la tarea ang_conj_sub),
|
||
//y estos cuando acaban le encolan al padre (el que los ha lanzado)
|
||
//la tarea de ang_conj_fin
|
||
bien=this_i->calcula_ang_conj();
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_ANG_CONJ_SUB:
|
||
{
|
||
//aqu<71> entran los subthreads para hacer los c<>lculos de <20>ngulos, cuando acaban
|
||
//encolan al padre la tarea de fin
|
||
int ithr;
|
||
if(e!=NULL)
|
||
ithr=e->id_e;
|
||
this_i->calcula_ang_conj_sub(ithr);
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_ANG_CONJ_FIN:
|
||
{
|
||
//aqu<71> entra el padre cuando van acabando los subthreads
|
||
//si han terminado todos encola la siguiente tarea
|
||
this_i->n_subthr_fin++;
|
||
if(this_i->n_subthr_fin==this_i->n_subthr)
|
||
{
|
||
this_i->n_subthr_fin=0;
|
||
bien=this_i->calcula_ang_conj_fin();
|
||
if(bien && this_i->olv_limp->olv->modo_multitask && !this_i->pirate)
|
||
this_i->encola(OLV_LIMP_EV_GUARD_MATS,NULL,FALSE);
|
||
else if(bien && (this_i->olv->modo_ejec<OLV_EJEC_DEBUG_NOSIGUE) && !this_i->pirate)//sigue
|
||
this_i->encola(OLV_LIMP_EV_COST_AMB,NULL,FALSE);
|
||
}
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_GUARD_MATS:
|
||
{
|
||
bien=this_i->guarda_mats();
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_GUARD_MATS_SUB:
|
||
{
|
||
int ithr;
|
||
if(e!=NULL)
|
||
ithr=e->id_e;
|
||
this_i->guarda_mats_sub(ithr);
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_GUARD_MATS_FIN:
|
||
{
|
||
//aqu<71> entra el padre cuando van acabando los subthreads
|
||
//si han terminado todos encola la siguiente tarea
|
||
this_i->n_subthr_fin++;
|
||
int i;
|
||
if(this_i->n_subthr_fin==this_i->n_subthr)
|
||
{
|
||
this_i->n_subthr_fin=0;
|
||
for(i=0;i<this_i->n_subthr;i++)
|
||
if(this_i->subthrs[i]->prog_subthr<0)
|
||
break;
|
||
if(i<this_i->n_subthr)
|
||
{
|
||
bien=FALSE;
|
||
this_i->pon_mi_msg("Errores al guardar matrices de costes");
|
||
break;
|
||
}
|
||
bien=this_i->guarda_mats_fin();
|
||
if(bien && (this_i->olv->modo_ejec<OLV_EJEC_DEBUG_NOSIGUE) && !this_i->pirate)//sigue
|
||
this_i->encola(OLV_LIMP_EV_TASK_ESCUCHA,NULL,FALSE);
|
||
}
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_TASK_ESCUCHA:
|
||
{
|
||
bien=this_i->task_dj_escucha();
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_TASK_FIN:
|
||
{
|
||
this_i->n_subthr_fin++;
|
||
if((e!=NULL) && e->id_e<0)//ha ido mal
|
||
{
|
||
if(e->id_e==-1)
|
||
this_i->subthrs[this_i->n_subthr_fin-1]->prog_subthr=-1;
|
||
else if(e->id_e==-2)
|
||
{
|
||
bien=FALSE;
|
||
this_i->pon_mi_msg("Errores en c<>lculo multitask, no ha habido conexi<78>n");
|
||
break;
|
||
}
|
||
}
|
||
int i;
|
||
if(this_i->n_subthr_fin==this_i->n_subthr)
|
||
{
|
||
this_i->n_subthr_fin=0;
|
||
for(i=0;i<this_i->n_subthr;i++)
|
||
if(this_i->subthrs[i]->prog_subthr<0)
|
||
break;
|
||
if(i<this_i->n_subthr)
|
||
{
|
||
bien=FALSE;
|
||
this_i->pon_mi_msg("Errores en c<>lculo multitask");
|
||
break;
|
||
}
|
||
this_i->task_dj_fin();
|
||
if(bien && (this_i->olv->modo_ejec<OLV_EJEC_DEBUG_NOSIGUE) && !this_i->pirate)//sigue
|
||
this_i->encola(OLV_LIMP_EV_COST_AMB,NULL,FALSE);
|
||
}
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_COST_AMB:
|
||
{
|
||
//esta tarea lanza varios subthreads para realizar los c<>lculos
|
||
//de costes(les encola la tarea dist_amb_sub),
|
||
//y estos cuando acaban le encolan al padre (el que los ha lanzado)
|
||
//la tarea de dist_amb_fin
|
||
bien=this_i->calcula_cost_amb();
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_COST_AMB_SUB:
|
||
{
|
||
//aqu<71> entran los subthreads para hacer los c<>lculos de costes entre <20>mbitos, cuando acaban
|
||
//encolan al padre la tarea de fin
|
||
int ithr;
|
||
if(e!=NULL)
|
||
ithr=e->id_e;
|
||
this_i->calcula_cost_amb_sub(ithr);
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_COST_AMB_FIN:
|
||
{
|
||
//aqu<71> entra el padre cuando van acabando los subthreads
|
||
//si han terminado todos encola la siguiente tarea
|
||
int i;
|
||
this_i->n_subthr_fin++;
|
||
if(this_i->n_subthr_fin==this_i->n_subthr)
|
||
{
|
||
this_i->n_subthr_fin=0;
|
||
for(i=0;i<this_i->n_subthr;i++)
|
||
if(this_i->subthrs[i]->prog_subthr<0)
|
||
break;
|
||
if(i<this_i->n_subthr)
|
||
{
|
||
bien=FALSE;
|
||
this_i->pon_mi_msg("Errores al calcular coste entre <20>mbitos");
|
||
break;
|
||
}
|
||
bien=this_i->calcula_cost_amb_fin();
|
||
if(bien && (this_i->olv->modo_ejec<OLV_EJEC_DEBUG_NOSIGUE) && !this_i->pirate)//sigue
|
||
{
|
||
if(this_i->olv->modo_ejec==OLV_EJEC_PLAN) //lee info de sectorizaci<63>n y va a planif
|
||
this_i->encola(OLV_LIMP_EV_LEE_SECTO,NULL,FALSE);
|
||
else //sectoriza
|
||
{
|
||
if(this_i->olv_limp->nsec==0)//hay que calcular el n<>mero de sectores
|
||
this_i->encola(OLV_LIMP_EV_CALC_NSEC,NULL,FALSE);
|
||
else
|
||
{
|
||
if(this_i->olv_limp->nsec<0)
|
||
{
|
||
this_i->olv_limp->calc_nsec=this_i->dame_cost_jornada();//indica que se tiene que ajustar a la jornada
|
||
this_i->olv_limp->nsec=this_i->olv_limp->nsec_act=this_i->olv_limp->nsec*(-1);
|
||
}
|
||
this_i->encola(OLV_LIMP_EV_SECTORIZA,NULL,FALSE);
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_CALC_NSEC:
|
||
{
|
||
bien=this_i->calcula_n_sec();
|
||
if(bien && (this_i->olv->modo_ejec<OLV_EJEC_DEBUG_SIGUE_NOPLAN) && !this_i->pirate)//sigue
|
||
{
|
||
this_i->encola(OLV_LIMP_EV_SECTORIZA,NULL,FALSE);
|
||
}
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_SECTORIZA:
|
||
{
|
||
bien=this_i->sectoriza();
|
||
if(bien && (this_i->olv->modo_ejec<OLV_EJEC_DEBUG_SIGUE_NOPLAN) && !this_i->pirate)//sigue
|
||
{
|
||
this_i->pon_info_resul();
|
||
if(this_i->olv->modo_ejec>=OLV_EJEC_DEBUG_SIGUE)
|
||
this_i->encola(OLV_LIMP_EV_PLANIFICA,NULL,FALSE);
|
||
else
|
||
{
|
||
this_i->borra_temp_files();
|
||
this_i->pon_mi_progre(OLV_TAREA_FIN_SEC,0);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_LEE_SECTO:
|
||
{
|
||
bien=this_i->lee_secto();
|
||
if(bien && !this_i->pirate)//sigue
|
||
{
|
||
this_i->encola(OLV_LIMP_EV_PLANIFICA,NULL,FALSE);
|
||
}
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_PLANIFICA:
|
||
{
|
||
bien=this_i->planifica();
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_PLANIFICA_SUB:
|
||
{
|
||
//aqu<71> entran los subthreads para hacer los c<>lculos de planificaci<63>n, cuando acaban
|
||
//encolan al padre la tarea de fin
|
||
int ithr;
|
||
if(e!=NULL)
|
||
ithr=e->id_e;
|
||
this_i->planifica_sub_1(ithr, this_i->olv_limp->cost_amb);
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_PLANIFICA_FIN:
|
||
{
|
||
//aqu<71> entra el padre cuando van acabando los subthreads
|
||
//si han terminado todos encola la siguiente tarea
|
||
int i;
|
||
this_i->n_subthr_fin++;
|
||
if(this_i->n_subthr_fin==this_i->n_subthr)
|
||
{
|
||
this_i->n_subthr_fin=0;
|
||
for(i=0;i<this_i->n_subthr;i++)
|
||
{
|
||
if(this_i->subthrs[i]->prog_subthr<0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
if(i<this_i->n_subthr)
|
||
{
|
||
bien=FALSE;
|
||
this_i->pon_mi_msg("Errores al planificar th %ld",i);
|
||
break;
|
||
}
|
||
bien = this_i->planifica_fin();
|
||
//pone progreso como que ha terminado
|
||
if(bien)
|
||
{
|
||
this_i->pon_info_resul();
|
||
this_i->borra_temp_files();
|
||
this_i->pon_mi_progre(OLV_TAREA_FIN_PLANIF,0);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case OLV_LIMP_EV_SUBTHR_PROG:
|
||
{
|
||
//aqu<71> entra el padre porque le encolan los subthreads para avisarle del progreso
|
||
double pro=0;
|
||
for(int i=0;i<this_i->n_subthr;i++)
|
||
pro+=this_i->subthrs[i]->prog_subthr;
|
||
pro=OliviaDef::GeneralDef::ProgrMax*pro/this_i->n_subthr;
|
||
if(e!=NULL)
|
||
{
|
||
this_i->pon_mi_progre(e->id_e,(int)pro);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
if(!bien)
|
||
{
|
||
this_i->pon_mi_progre(OLV_TAREA_FIN_NOK,0);
|
||
#ifndef _DEBUG
|
||
this_i->borra_temp_files();
|
||
#endif
|
||
}
|
||
}
|
||
//*************************************************************************************
|
||
void Colv_limp_thr::termina_th()
|
||
{
|
||
if(tarea==OLV_TAREA_PERMU && !fin_permu)
|
||
{
|
||
fin_permu=TRUE;
|
||
return;
|
||
}
|
||
if(fin_permu)
|
||
fin_permu=FALSE;
|
||
pirate=TRUE;
|
||
para_subthrs();
|
||
termina();
|
||
wgeolog(LOG_TODO,"olv_limp_t","Thread de limpieza limp_thr finalizado");
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Abre los datos de cartograf<61>a
|
||
*/
|
||
BOOL Colv_limp_thr::abre_datos()
|
||
{
|
||
int icla,ii,KK,flx,flx_s;
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Abriendo datos");
|
||
pon_mi_progre(OLV_TAREA_IMP, 0);
|
||
pon_mi_msg("");
|
||
err_str[0]=0;
|
||
|
||
//OJO siempre primero van los <20>mbitos y luego la red navegable a continuaci<63>n,
|
||
//si se cambia, tener en cuenta en los c<>lculos del thread
|
||
|
||
//abre la cartograf<61>a con los datos
|
||
KK=olv_limp->tipo_ambit;
|
||
if(KK==OLV_AMB_LIN)
|
||
icla=OLV_ICLA_LIN_AMB;
|
||
else if(KK==OLV_AMB_PUN)
|
||
icla=OLV_ICLA_PUN_AMB;
|
||
if(!olv_limp->olv->olv_sh->abre_shp(olv_limp->olv->paths.path_data,icla,MODO_SHP_MEMO))
|
||
{
|
||
pon_mi_msg("Error en la importaci<63>n del archivo\n%s",olv_limp->olv->paths.path_data);
|
||
return FALSE;
|
||
}
|
||
olv_limp->n_amb=olv_limp->olv->olv_ob->vect.nobj;
|
||
olv_limp->n_ini_nw=olv_limp->n_amb;
|
||
|
||
if(olv_limp->n_amb>=USHRT_MAX)
|
||
{
|
||
pon_mi_msg("N<EFBFBD>mero de <20>mbitos (%ld) mayor que el permitido (%ld)\n",olv_limp->n_amb,USHRT_MAX);
|
||
return FALSE;
|
||
}
|
||
|
||
//abre la red navegable a continuaci<63>n
|
||
if(!olv_limp->olv->olv_sh->abre_shp(olv_limp->olv->paths.path_nw, OLV_ICLA_LIN_NW,MODO_SHP_MEMO))
|
||
{
|
||
pon_mi_msg("Error en la importaci<63>n del archivo\n%s",olv_limp->olv->paths.path_nw);
|
||
return FALSE;
|
||
}
|
||
olv_limp->n_nw=olv_limp->olv->olv_ob->vect.nobj-olv_limp->n_amb;
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
//inicializa el array de informaci<63>n asociada
|
||
//si es tipo puntual, se almacenan 2 infos asociadas, la del propio puntual
|
||
//y para cuando se a<>ada el segmento
|
||
//si es tipo lineal, se almacenan 3 infos asociadas, porque se necesita conservar la del
|
||
//lineal como tal, y aparte se dan dos, una para cada segmento de uni<6E>n.
|
||
olv_limp->ias = (Info_aso *)malloc((olv_limp->n_nw+olv_limp->n_amb*(KK+1))*sizeof(Info_aso));
|
||
if(!olv_limp->ias)
|
||
{
|
||
pon_mi_msg("Error, sin memoria para la informaci<63>n asociada");
|
||
return FALSE;
|
||
}
|
||
memset(olv_limp->ias,0,(olv_limp->n_nw+olv_limp->n_amb*(KK+1))*sizeof(Info_aso));
|
||
olv_limp->n_ini_amb_iai=olv_limp->n_ini_nw+olv_limp->n_nw;//los segmentos del inicio empiezan donde acaba el nw
|
||
if(KK==OLV_AMB_LIN)
|
||
olv_limp->n_ini_amb_iaf=olv_limp->n_ini_amb_iai+olv_limp->n_amb;//los segmentos del final empiezan donde acaba el anterior
|
||
//si es tipo eje de calle lo pone en el flag
|
||
if((olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoMh_eje) ||
|
||
(olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoM2h_eje))
|
||
{
|
||
flx=OLV_LIMP_FLG_EJE;
|
||
flx_s=OLV_LIMP_FLG_EJE_SEG;
|
||
}
|
||
else
|
||
{
|
||
flx=0;
|
||
flx_s=0;
|
||
}
|
||
//inicializa los <20>ndices a los shapes originales en la informaci<63>n asociada
|
||
//OJO toma por seguro que en el ob se ha abierto primero los <20>mbitos y luego la red nw
|
||
for(ii=0; ii<olv_limp->n_amb;ii++)
|
||
{
|
||
olv_limp->ias[ii].flgs = OLV_LIMP_FLG_AMB|flx;
|
||
olv_limp->ias[ii].ishp=ii;
|
||
(*olv_limp->olv->olv_ob->objt)[ii].ia=ii;
|
||
if(KK==OLV_AMB_LIN)
|
||
{
|
||
//ahora la ia de sus segmentos, pero no lo apunta porque no est<73>n en el ob todav<61>a
|
||
olv_limp->ias[ii+olv_limp->n_ini_amb_iai].flgs = OLV_LIMP_FLG_SEG_LIN | flx_s;
|
||
olv_limp->ias[ii+olv_limp->n_ini_amb_iai].ishp=ii;
|
||
olv_limp->ias[ii+olv_limp->n_ini_amb_iaf].flgs = OLV_LIMP_FLG_SEG_LIN | OLV_LIMP_FLG_FIN | flx_s;
|
||
olv_limp->ias[ii+olv_limp->n_ini_amb_iaf].ishp=ii;
|
||
}
|
||
else if(KK==OLV_AMB_PUN)
|
||
{
|
||
olv_limp->ias[ii+olv_limp->n_ini_amb_iai].flgs = OLV_LIMP_FLG_SEG_PUN;
|
||
olv_limp->ias[ii+olv_limp->n_ini_amb_iai].ishp=ii;
|
||
}
|
||
}
|
||
for(ii=olv_limp->n_ini_nw; ii<olv_limp->n_ini_nw+olv_limp->n_nw;ii++)
|
||
{
|
||
olv_limp->ias[ii].ishp=ii-KK*olv_limp->n_ini_nw;
|
||
(*olv_limp->olv->olv_ob->objt)[ii].ia=ii;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
//rellena la informaci<63>n asociada: sentidos de circulaci<63>n, velocidad de la v<>a, ancho de acera...
|
||
if(!rellena_info_nw())
|
||
{
|
||
pon_mi_msg("Error al leer info asociada a red navegable: %s", err_str);
|
||
return FALSE;
|
||
}
|
||
|
||
////////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Finaliza Abrir datos con <20>xito");
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la informaci<63>n asociada de la red navegable y los datos de limpieza
|
||
*/
|
||
BOOL Colv_limp_thr::rellena_datos()
|
||
{
|
||
if(!rellena_info_amb())
|
||
{
|
||
pon_mi_msg("Error al leer info asociada a <20>mbitos: %s", err_str);
|
||
return FALSE;
|
||
}
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Finaliza Rellena datos con <20>xito");
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Comrpueba las entidades para adecuarlas al barrido mixto
|
||
*/
|
||
void Colv_limp_thr::mejora_barr_mix()
|
||
{
|
||
int nthr=n_subthr;
|
||
wgeolog(LOG_TODO,"olv_limp_t","Comienza las comprobaciones para el barrido mixto");
|
||
lanza_subthrs(OLV_LIMP_EV_BARRMIX_SUB,nthr);
|
||
|
||
//fuerza fin para que avance olivia
|
||
for(int i=nthr;i<n_subthr;i++)
|
||
{
|
||
if(!subthrs[i])
|
||
subthrs[i]=new Colv_limp_thr(olv_limp);
|
||
subthrs[i]->prog_subthr = 0;
|
||
}
|
||
for(int i=0;i<n_subthr-nthr;i++)
|
||
encola(OLV_LIMP_EV_BARRMIX_FIN,NULL,FALSE);
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Comrpueba las entidades para adecuarlas al barrido mixto
|
||
*/
|
||
BOOL Colv_limp_thr::mejora_barr_mix_fin()
|
||
{
|
||
////////////////
|
||
//para los threads
|
||
para_subthrs();
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Comrpueba las entidades para adecuarlas al barrido mixto
|
||
*/
|
||
void Colv_limp_thr::mejora_barr_mix_sub(int ithr)
|
||
{
|
||
//recorre los <20>mbitos
|
||
int i,j;
|
||
int na_desp,na_ini, na_fin, seg;
|
||
Cobgeo *ob;
|
||
//variables para apuntar al <20>mbito y nw en cuesti<74>n
|
||
int npt_ace, il_ace,i_ace;
|
||
int npt_otro, il_otro,i_otro;
|
||
double (*pt_ace)[3],(*pt_otro)[3];
|
||
double lon_ace, lon_otro, pond;
|
||
BOOL mal=FALSE;
|
||
BOOL paralelas;
|
||
|
||
na_desp = (int)ceil(1.0*(olv_limp->n_amb)/n_subthr);
|
||
na_ini=ithr*na_desp;
|
||
na_fin = min((ithr+1)*na_desp,olv_limp->n_amb);
|
||
ob=thr_padre->olv_limp->olv->olv_ob;
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Comprueba Barr Mix Ambs %04d a %04d", ithr, na_ini, na_fin);
|
||
seg = GetTickCount();
|
||
|
||
//Bucle en los <20>mbitos
|
||
for(i=na_ini;i<na_fin && !pirate; i++)
|
||
{
|
||
if((*olv_limp->olv->olv_ob->objt)[i].tipo != OBJ_LINEAL)
|
||
continue;//comprueba clases
|
||
|
||
if(olv_limp->ias[i].info3!=OLV_AMBLIN_ACE)
|
||
continue;
|
||
|
||
//apunta el array de puntos de la acera
|
||
il_ace=(*olv_limp->olv->olv_ob->objt)[i].indx;
|
||
npt_ace = (*olv_limp->olv->olv_ob->lial)[il_ace].n;
|
||
i_ace=(*olv_limp->olv->olv_ob->lial)[il_ace].indx;
|
||
pt_ace = &(*olv_limp->olv->olv_ob->ptos)[i_ace];
|
||
|
||
//Se recorre las aceras
|
||
//Por cada acera, se recorre el resto de entidades, y las que sean
|
||
//bordillo o banda de aparcamiento, comprueba si es paralela
|
||
for(j=0;j<olv_limp->n_amb && !pirate; j++)
|
||
{
|
||
if(((*olv_limp->olv->olv_ob->objt)[j].tipo != OBJ_LINEAL) || (j==i) || (olv_limp->ias[j].info3>=OLV_AMBLIN_ACE))
|
||
continue;//comprueba clases
|
||
|
||
//apunta al array de puntos de esta otra entidad, que puede ser bordillo libre o aparcamiento
|
||
il_otro=(*olv_limp->olv->olv_ob->objt)[j].indx;
|
||
npt_otro = (*olv_limp->olv->olv_ob->lial)[il_otro].n;
|
||
i_otro=(*olv_limp->olv->olv_ob->lial)[il_otro].indx;
|
||
pt_otro = &(*olv_limp->olv->olv_ob->ptos)[i_otro];
|
||
|
||
//recorre ambas rectas a la par
|
||
//para ello, primero mira cu<63>l es la m<>s larga
|
||
lon_ace=long_linea((double (*)[][3]) pt_ace,npt_ace,NULL,NULL,NULL,NULL);
|
||
lon_otro=long_linea((double (*)[][3]) pt_otro,npt_otro,NULL,NULL,NULL,NULL);
|
||
|
||
//wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Comprueba %04d a %04d-----------------", ithr, i,j);
|
||
|
||
//parte de la m<>s corta, y avanza en pasos del PORC_AVANCE% de su longitud
|
||
if(lon_ace<lon_otro)
|
||
{
|
||
paralelas=barr_mix_paralelas(npt_ace, pt_ace, lon_ace, npt_otro, pt_otro);
|
||
}
|
||
else
|
||
{
|
||
//wgeolog(LOG_TODO,"olv_limp_t","Otro corto");
|
||
paralelas=barr_mix_paralelas(npt_otro, pt_otro, lon_otro, npt_ace, pt_ace);
|
||
}
|
||
if(!paralelas)
|
||
continue;
|
||
|
||
//marca la acera como nula
|
||
//No pasa nada multithread porque toca cada thread unas aceras
|
||
//indica que no se use ese <20>mbito para sectorizar, y lo apunta al bordillo con el que se hace
|
||
if(!(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO))
|
||
{
|
||
olv_limp->ias[i].flgs=olv_limp->ias[i].flgs | OLV_LIMP_FLG_AMB_NO;
|
||
}
|
||
olv_limp->ias[i].info0=j;
|
||
|
||
//suma los anchos de forma ponderada
|
||
pond=lon_ace/lon_otro;
|
||
if(pond>1)
|
||
pond=1; //cuando la acera es m<>s grande, se suma el ancho de la acera, no se amplia
|
||
|
||
//cuando la acera es m<>s peque<75>a, puede que en ese bordillo o banda de aparcamiento
|
||
//haya otra acera en paralelo, as<61> que se le sumar<61> despu<70>s su ancho tambi<62>n,
|
||
//de forma que la suma total sea la ponderaci<63>n de los anchos
|
||
olv_limp->ias[j].info1 += olv_limp->ias[i].info1*pond;
|
||
}
|
||
|
||
//avisa de progreso
|
||
if(((i-na_ini)%100==0) || ((i-na_ini)==(na_desp-1)))
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Comprobando Barrido Mixto ambs %ld de %ld", ithr,
|
||
(i-na_ini+1),na_desp);
|
||
}
|
||
|
||
}
|
||
|
||
if(mal)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Error en mejoras Barrido mixto", ithr);
|
||
prog_subthr=-1;//para avisar al padre de que ha habido un error
|
||
}
|
||
else
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Fin mejoras Barrido mixto, %.3f seg", ithr, 1.0*(GetTickCount()-seg)/1000);
|
||
}
|
||
thr_padre->encola(OLV_LIMP_EV_BARRMIX_FIN,NULL,FALSE);
|
||
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Devuelve true si hay que descartar que sean paralelas porque est<73>n muy lejos
|
||
* Para ello, hace la recta que une el punto inicial de cada una de las dos rectas y
|
||
* calcula el <20>ngulo que forma esa recta con la primera.
|
||
* La distancia entre las dos rectas ser<65> la longitud de ese segmento por el seno del <20>ngulo
|
||
* Si esa distancia es mayor que dminmax se descarta
|
||
*/
|
||
BOOL Colv_limp_thr::barr_mix_desc(int npt1, double (*pt1)[3], int npt2, double (*pt2)[3])
|
||
{
|
||
short ip;
|
||
float lamb;
|
||
double dist;
|
||
|
||
dist=Colv_geom::dist_pto_poli((double (*)[3])pt1,(double (*)[][3])pt2,npt2,&ip, &lamb);
|
||
if(dist<=OLV_BARRMIX_DMAX_DESC)//est<73> cerca, no se descarta
|
||
return FALSE;
|
||
|
||
return TRUE;
|
||
|
||
double pt_aux[2][3], laux,ang;
|
||
|
||
//hace la recta que une el punto inicial de cada una de las dos rectas
|
||
memcpy(pt_aux[0],pt1,3*sizeof(double));
|
||
memcpy(pt_aux[1],pt2,3*sizeof(double));
|
||
laux=long_linea((double (*)[][3]) pt_aux,2,NULL,NULL,NULL,NULL);
|
||
|
||
//calcula el <20>ngulo que forma esa recta con la primera
|
||
ang=Colv_geom::ang_vect_ptos((double (*)[][3])pt1, (double (*)[][3])pt_aux);
|
||
laux=laux*sin(ang);
|
||
|
||
//wgeolog(LOG_TODO,"olv_limp_t","laux=%.2f, ang=%.2f", laux,ang*180/OLV_PI);
|
||
|
||
if(laux<=OLV_BARRMIX_DMAX_DESC)//est<73> cerca, no se descarta
|
||
return FALSE;
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Avanza desde el primer punto de pt1 y el m<>s pr<70>ximo en pt2,
|
||
* en pasos de l_avan, midiendo la distancia entre las dos rectas
|
||
* devuelve si son paralelas o no en funci<63>n de la dmedia y la desv
|
||
*/
|
||
BOOL Colv_limp_thr::barr_mix_paralelas(int npt1, double (*pt1)[3], double long1, int npt2, double (*pt2)[3])
|
||
{
|
||
const double PORC_AVANCE = 0.2; //avanza en pasos del porc % de la longitud de la l<>nea peque<75>a
|
||
////////////////////////////////////
|
||
double l_avan, pt[3], l_parc, dmed, desv;
|
||
int i;
|
||
short ip;
|
||
float lamb;
|
||
std::vector<double> dmin;
|
||
|
||
//comprueba si las puede descartar porque est<73>n muy lejos
|
||
if(barr_mix_desc(npt1, pt1, npt2, pt2))
|
||
return FALSE;
|
||
|
||
l_avan=PORC_AVANCE*long1;
|
||
|
||
i=0;
|
||
l_parc=0;
|
||
while(l_parc<long1)
|
||
{
|
||
Colv_geom::dame_pto_poli((double (*)[][3]) pt1, npt1, l_parc, long1, (double (*)[3])pt);
|
||
dmin.push_back(Colv_geom::dist_pto_poli((double (*)[3])pt,(double (*)[][3])pt2,npt2,&ip, &lamb));
|
||
i++;
|
||
l_parc+=l_avan;
|
||
}
|
||
if(i==0 || dmin.size()==0)
|
||
return FALSE;
|
||
|
||
//calcula la dmed y la desv
|
||
dmed=0;
|
||
for(i=0;i<(int)dmin.size();i++)
|
||
{
|
||
dmed+=dmin[i];
|
||
}
|
||
dmed=dmed/dmin.size();
|
||
|
||
desv=0;
|
||
for(i=0;i<(int)dmin.size();i++)
|
||
{
|
||
desv+=pow(dmin[i]-dmed,2);
|
||
}
|
||
desv=desv/dmin.size();
|
||
desv=sqrt(desv);
|
||
|
||
//wgeolog(LOG_TODO,"olv_limp_t","dmed=%.3f desv=%.3f", dmed, desv);
|
||
|
||
if(dmed>OLV_BARRMIX_DMED_MAX || desv>OLV_BARRMIX_DESV_MAX)
|
||
return FALSE;
|
||
|
||
//wgeolog(LOG_TODO,"olv_limp_t","PARALELAS");
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Copia en las aceras que no se han usado para sectorizar porque se han asignado a bordillos o
|
||
* bandas de aparcamiento, el mismo sector que el bordillo que tienen asignado
|
||
* modo 0 secto, modo 1 planif
|
||
*/
|
||
void Colv_limp_thr::copia_info_barr_mix()
|
||
{
|
||
for(int i=0;i<olv_limp->n_amb;i++)
|
||
{
|
||
if(!(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO) || olv_limp->ias[i].info0<0)
|
||
continue;
|
||
|
||
olv_limp->amb_sec[i].sec=olv_limp->amb_sec[olv_limp->ias[i].info0].sec;
|
||
olv_limp->amb_sec[i].iseq=olv_limp->amb_sec[olv_limp->ias[i].info0].iseq;
|
||
}
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la informaci<63>n de sentidos de circulaci<63>n y velocidad de las v<>as
|
||
* en la tabla de informaci<63>n asociada
|
||
*/
|
||
BOOL Colv_limp_thr::rellena_info_nw()
|
||
{
|
||
int n, ntf, nft, nboth, nno,s,ia,icamps,icampv,icampn,icampf,f;
|
||
char nfile[MAX_PATH];
|
||
Cdbf dbf;
|
||
char *sent, *velo, *name,*fow;
|
||
BOOL ret=TRUE,ispedestrian;
|
||
|
||
if(!olv_limp->ias)
|
||
return FALSE;
|
||
|
||
sent=velo=name=fow=NULL;
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Rellenando matriz de info asociada a carreteras");
|
||
pon_mi_progre(OLV_TAREA_IMP, (int) (OliviaDef::GeneralDef::ProgrMax*1/3)); //1/32 porque ya ha hecho 1/3, que es la importaci<63>n
|
||
|
||
n=0;
|
||
ntf=nft=nboth=nno=0;
|
||
|
||
//si no aplican los sentidos de circulaci<63>n no se calculan, se ponen todos a todos sentidos
|
||
if(olv_limp->res_circ==OLV_RES_NO)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","No aplican sentidos de circulaci<63>n, puestos todos a 'ambos'");
|
||
nboth=olv_limp->n_nw;
|
||
}
|
||
|
||
//lee dbf del shp
|
||
strcpy_s(nfile,MAX_PATH,olv->paths.path_nw);
|
||
cambiaext(nfile,".shp",".dbf");
|
||
dbf.noespa = TRUE;
|
||
if (!dbf.abre(nfile,0))
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al abrir %s",nfile);
|
||
wgeolog(LOG_TODO,"olv_limp_t","Error al abrir %s",nfile);
|
||
return FALSE;
|
||
}
|
||
|
||
//busca el campo del sentido "ONEWAY" y el de "KPH"
|
||
icamps=icampv=icampn=icampf=-1;
|
||
for(n=0; n<dbf.ncamp && (icamps==-1 || icampv==-1 || icampn==-1 || icampf==-1); n++)
|
||
{
|
||
if(!strcmp((*dbf.camp)[n].nombre,olv_limp->camps.campo_circ))
|
||
icamps=n;
|
||
if(!strcmp((*dbf.camp)[n].nombre,olv_limp->camps.campo_velo))
|
||
icampv=n;
|
||
if(!strcmp((*dbf.camp)[n].nombre,olv_limp->camps.campo_name))
|
||
icampn=n;
|
||
if(!strcmp((*dbf.camp)[n].nombre,olv_limp->camps.campo_fow))
|
||
icampf=n;
|
||
}
|
||
if(icamps==-1 || icampv==-1 || icampn==-1 || icampf==-1)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"No encontrado campo %s y/o %s y/o %s en\n%s",olv_limp->camps.campo_circ,
|
||
olv_limp->camps.campo_velo,olv_limp->camps.campo_name,nfile);
|
||
wgeolog(LOG_TODO,"No encontrado campo %s y/o %s y/o %s en\n%s",olv_limp->camps.campo_circ,
|
||
olv_limp->camps.campo_velo,olv_limp->camps.campo_name,nfile);
|
||
return FALSE;
|
||
}
|
||
|
||
////////////////////////////////////////
|
||
//prepara para leer la info de sentidos de circulaci<63>n y la guarda en los flags
|
||
sent=(char*)malloc((*dbf.camp)[icamps].nb*2);//*2 para dejar un margen
|
||
if(!sent)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al pedir memoria para campo %s en\n%s",olv_limp->camps.campo_circ,nfile);
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
sent[0]=0;
|
||
|
||
////////////////////////////////////////
|
||
//prepara para leer la info de sentidos de circulaci<63>n y la guarda en los flags
|
||
velo=(char*)malloc((*dbf.camp)[icampv].nb*2);//*2 para dejar un margen
|
||
if(!velo)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al pedir memoria para campo %s en\n%s",olv_limp->camps.campo_velo,nfile);
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
velo[0]=0;
|
||
|
||
////////////////////////////////////////
|
||
//prepara para leer la info de sentidos de nombre la guarda en los flags
|
||
name=(char*)malloc((*dbf.camp)[icampn].nb*2);//*2 para dejar un margen
|
||
if(!name)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al pedir memoria para campo %s en\n%s",olv_limp->camps.campo_name,nfile);
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
name[0]=0;
|
||
|
||
////////////////////////////////////////
|
||
//prepara para leer la info de sentidos de FOW
|
||
fow=(char*)malloc((*dbf.camp)[icampf].nb*2);//*2 para dejar un margen
|
||
if(!fow)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al pedir memoria para campo %s en\n%s",olv_limp->camps.campo_fow,nfile);
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
fow[0]=0;
|
||
|
||
for(n=0;n<olv_limp->n_nw; n++)
|
||
{
|
||
ia=(*olv_limp->olv->olv_ob->objt)[n+olv_limp->n_ini_nw].ia;
|
||
if (!dbf.lee_rec(n,0))
|
||
{
|
||
break;
|
||
}
|
||
///////////////////////////////
|
||
ispedestrian=FALSE;
|
||
if(olv_limp->res_circ!=OLV_RES_NO)
|
||
{
|
||
//("FOW" =3 OR "FOW">=7) AND ("ONEWAY" = 'N' OR "ONEWAY" = ' ' )
|
||
//si se cumple lo anterior, son como doble sentido pero no se replican
|
||
//////////////////////////
|
||
//sentido de circulaci<63>n
|
||
dbf.dame_campo_c(icamps,sent);
|
||
s=0;
|
||
if(strlen(sent)==0)
|
||
{
|
||
nboth++;
|
||
}
|
||
else if(strcmp(sent,olv_limp->camps.atr_circ[OLV_ATR_CIRC_TF])==0)
|
||
{
|
||
s=OLV_LIMP_FLG_CIRC_TF;
|
||
ntf++;
|
||
}
|
||
else if(strcmp(sent,olv_limp->camps.atr_circ[OLV_ATR_CIRC_FT])==0)
|
||
{
|
||
s=OLV_LIMP_FLG_CIRC_FT;
|
||
nft++;
|
||
}
|
||
else if(strcmp(sent,olv_limp->camps.atr_circ[OLV_ATR_CIRC_NONE])==0)
|
||
{
|
||
//no aplica la restricci<63>n por ser servicio p<>blico, c<>mo se sabe si es de un <20>nico sentido?
|
||
//s=OLV_LIMP_FLG_CIRC_NONE;
|
||
nno++;
|
||
}
|
||
|
||
///////////////////////////////
|
||
//fow
|
||
f=0;
|
||
dbf.dame_campo_c(icampf,fow);
|
||
//solo mira si es pedestrian, f==14
|
||
if(atoi(fow)==atoi(olv_limp->camps.atr_circ[OLV_ATR_CIRC_PEDES]))
|
||
{
|
||
s=OLV_LIMP_FLG_CIRC_NONE;
|
||
ispedestrian=TRUE;
|
||
}
|
||
///////////////////////////////
|
||
|
||
olv_limp->ias[ia].flgs=s;
|
||
}
|
||
|
||
///////////////////////////////
|
||
//velocidad
|
||
if((olv_limp->ias[ia].flgs & OLV_LIMP_FLG_CIRC_NONE) || ispedestrian)
|
||
{
|
||
s= OLV_LIMP_VELO_PEAT; //se le pone velo muy bajita para que intente no ir por ah<61>, porque son calles prohibidas
|
||
//a no ser que haya un contenedor
|
||
//o si es peatonal igual, que no haga las rutas por ah<61>, pero s<> pase a hacer tratamientos
|
||
}
|
||
else
|
||
{
|
||
dbf.dame_campo_c(icampv,velo);
|
||
s=atoi(velo);
|
||
}
|
||
if(s<=0)
|
||
{
|
||
s=OLV_LIMP_VELO_DEF;//pone por def
|
||
//wgeolog(LOG_TODO,"olv_limp_t","Cuidado, info asociada a nw, %ld, puesta velo por defecto 10 km/h",n+1);
|
||
}
|
||
|
||
olv_limp->ias[ia].info1=1.0*s;
|
||
|
||
///////////////////////////////
|
||
//nombre
|
||
dbf.dame_campo_c(icampn,name);
|
||
|
||
olv_limp->ias[ia].info2 = (char*)malloc((*dbf.camp)[icampn].nb);
|
||
if(!olv_limp->ias[ia].info2)
|
||
break;
|
||
strcpy_s(olv_limp->ias[ia].info2,(*dbf.camp)[icampn].nb,name);
|
||
|
||
olv_limp->ias[ia].info0=olv_limp->ias[ia].info3=-1;
|
||
|
||
///////////////////////////////
|
||
//avisa de progreso
|
||
if((n%200==0) || (n==(olv_limp->n_nw-1)))
|
||
{
|
||
pon_mi_progre(OLV_TAREA_IMP, (int) (OliviaDef::GeneralDef::ProgrMax*
|
||
(1.0*(n+1)/olv_limp->n_nw/3)+1/3));//por 2/3 porque esta tarea es la 2/3
|
||
wgeolog(LOG_TODO,"olv_limp_t","Rellenando info asociada a nw, %ld de %ld",
|
||
n+1,olv_limp->n_nw);
|
||
}
|
||
|
||
|
||
}
|
||
if(n<olv_limp->n_nw)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al leer record %ld en\n%s",n,nfile);
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Finaliza matriz de info asociada a carreteras: %ld doble sentido, %ld TF, %ld FT, %ld ninguno, %ld de %ld",
|
||
nboth,ntf,nft, nno, nboth+ntf+nft+nno, olv_limp->n_nw);
|
||
|
||
fin:
|
||
if(sent)
|
||
free(sent);
|
||
if(velo)
|
||
free(velo);
|
||
if(name)
|
||
free(name);
|
||
if(fow)
|
||
free(fow);
|
||
return ret;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la informaci<63>n de ancho de los <20>mbitos
|
||
* en la tabla de informaci<63>n asociada
|
||
*/
|
||
BOOL Colv_limp_thr::rellena_info_amb()
|
||
{
|
||
int n, icampa,icampo,icampta,icampte,ia;
|
||
char nfile[MAX_PATH];
|
||
Cdbf dbf;
|
||
char *tipent, *tipap, *obs,*anc;
|
||
double ancho;
|
||
BOOL log_debug=FALSE;
|
||
BOOL ret=TRUE;
|
||
int barr_mix=0; //si entra en banda ap a<>ade 1, en bordillo libre a<>ade 2 y en acera a<>ade 4, de forma que si es mayor que 4 es barrido mixto
|
||
|
||
if(!olv_limp->ias)
|
||
return FALSE;
|
||
|
||
//en principio, tipos puntuales no tienen info asociada
|
||
if(olv_limp->tipo_ambit==OLV_AMB_PUN)
|
||
return TRUE;
|
||
|
||
//cuando se ha enviado eje de calle, no se lee info asociada porque la tabla es de tomotom, no tiene info
|
||
//tipo entidad ni nada..
|
||
if((olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoMh_eje) ||
|
||
(olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoM2h_eje))
|
||
return TRUE;
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Rellenando matriz de info asociada a <20>mbitos");
|
||
pon_mi_progre(OLV_TAREA_IMP, (int) (OliviaDef::GeneralDef::ProgrMax*2/3));
|
||
|
||
obs=anc=tipent=tipap=NULL;
|
||
|
||
//lee dbf del shp
|
||
strcpy_s(nfile,MAX_PATH,olv->paths.path_data);
|
||
cambiaext(nfile,".shp",".dbf");
|
||
dbf.noespa = TRUE;
|
||
if (!dbf.abre(nfile,0))
|
||
{
|
||
pon_mi_msg("Error al abrir %s",nfile);
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
|
||
//busca el campo de observaciones, de ancho_tipo, de tipo_entidad y tipolog<6F>a_aparc
|
||
icampa=icampo=icampta=icampte=-1;
|
||
for(n=0; n<dbf.ncamp && (icampa==-1 || icampo==-1 || icampta==-1 || icampte==-1); n++)
|
||
{
|
||
if(!strcmp((*dbf.camp)[n].nombre,olv_limp->camps.campo_obs))
|
||
icampo=n;
|
||
if(!strcmp((*dbf.camp)[n].nombre,olv_limp->camps.campo_anch))
|
||
icampa=n;
|
||
if(!strcmp((*dbf.camp)[n].nombre,olv_limp->camps.campo_tipo_ap))
|
||
icampta=n;
|
||
if(!strcmp((*dbf.camp)[n].nombre,olv_limp->camps.campo_tipo_ent))
|
||
icampte=n;
|
||
}
|
||
if(icampa==-1 || icampo==-1 || icampta==-1 || icampte==-1)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"No encontrado campo %s y/o %s y/o %s\ny/o %s en\n%s",olv_limp->camps.campo_obs,olv_limp->camps.campo_anch,
|
||
olv_limp->camps.campo_tipo_ap,olv_limp->camps.campo_tipo_ent,nfile);
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
|
||
////////////////////////////////////////
|
||
//prepara para leer la info de tipo de entidad
|
||
tipent=(char*)malloc((*dbf.camp)[icampte].nb*2); //*2 para dejar un margen
|
||
if(!tipent)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al pedir memoria para campo %s en\n%s",olv_limp->camps.campo_tipo_ent,nfile);
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
tipent[0]=0;
|
||
|
||
////////////////////////////////////////
|
||
//prepara para leer la info de tipo de aparcamiento
|
||
tipap=(char*)malloc((*dbf.camp)[icampta].nb*2); //*2 para dejar un margen
|
||
if(!tipap)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al pedir memoria para campo %s en\n%s",olv_limp->camps.campo_tipo_ap,nfile);
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
tipap[0]=0;
|
||
|
||
////////////////////////////////////////
|
||
//prepara para leer la info observaciones
|
||
obs=(char*)malloc((*dbf.camp)[icampo].nb*2); //*2 para dejar un margen
|
||
if(!obs)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al pedir memoria para campo %s en\n%s",olv_limp->camps.campo_obs,nfile);
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
obs[0]=0;
|
||
|
||
////////////////////////////////////////
|
||
//prepara para leer la info de anchos de acera
|
||
anc=(char*)malloc((*dbf.camp)[icampa].nb*2); //*2 para dejar un margen
|
||
if(!anc)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al pedir memoria para campo %s en\n%s",olv_limp->camps.campo_anch,nfile);
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
anc[0]=0;
|
||
|
||
for(n=0;n<olv_limp->n_amb; n++)
|
||
{
|
||
ia=(*olv_limp->olv->olv_ob->objt)[n].ia;//ojo, se toma por seguro que la primera capa abierta es la de <20>mbitos
|
||
if (!dbf.lee_rec(n,0))
|
||
{
|
||
break;
|
||
}
|
||
|
||
//si el campo tipo de entidad es banda_aparcamiento, el ancho es fijo,
|
||
//en funci<63>n de la tipolog<6F>a del aparcamiento
|
||
//si no, hay que leer el ancho
|
||
ancho=OLV_LIMP_ANCH_DEF;
|
||
olv_limp->ias[ia].info3=0;
|
||
///////////////////////////////
|
||
dbf.dame_campo_c(icampte,tipent);
|
||
if(strlen(tipent)>0 && strcmp(tipent,olv_limp->camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_AP])==0)
|
||
{
|
||
//es banda de aparcamiento
|
||
dbf.dame_campo_c(icampta,tipap);
|
||
if(strlen(tipap)>0 && strcmp(tipap,olv_limp->camps.atr_tip_apa[OLV_ATR_TIP_AP_LIN])==0)
|
||
{
|
||
//es aparcamiento lineal, ancho fijo 2
|
||
ancho=olv_limp->anchos_def[OLV_ANCH_DEF_APLIN];
|
||
}
|
||
else if(strlen(tipap)>0 && strcmp(tipap,olv_limp->camps.atr_tip_apa[OLV_ATR_TIP_AP_BAT])==0)
|
||
{
|
||
//es aparcamiento en bater<65>a, ancho fijo 4
|
||
ancho=olv_limp->anchos_def[OLV_ANCH_DEF_APBAT];
|
||
}
|
||
|
||
if(log_debug)
|
||
wgeolog(LOG_TODO,"olv_limp_t","info aso a <20>mb %ld: tipent %s, tipap %s",n+1,tipent,tipap);
|
||
|
||
//lo marca para saber si es barrido mixto
|
||
olv_limp->ias[ia].info3=OLV_AMBLIN_APA;
|
||
if(!olv_limp->barr_mix && !(barr_mix & (1<<(OLV_AMBLIN_APA-1))))
|
||
barr_mix |= (1<<(OLV_AMBLIN_APA-1));
|
||
}
|
||
else if(strlen(tipent)>0 && strcmp(tipent,olv_limp->camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_BORD])==0)
|
||
{
|
||
//es bordillo libre
|
||
ancho=olv_limp->anchos_def[OLV_ANCH_DEF_BORD];
|
||
|
||
//lo marca para saber si es barrido mixto
|
||
olv_limp->ias[ia].info3=OLV_AMBLIN_BORD;
|
||
if(!olv_limp->barr_mix && !(barr_mix & (1<<(OLV_AMBLIN_BORD-1))))
|
||
barr_mix |= (1<<(OLV_AMBLIN_BORD-1));
|
||
}
|
||
else if(strlen(tipent)>0)
|
||
{
|
||
//es acera o peatonal
|
||
//hay que leer el ancho
|
||
dbf.dame_campo_c(icampo,obs);
|
||
dbf.dame_campo_c(icampa,anc);
|
||
|
||
if(log_debug)
|
||
wgeolog(LOG_TODO,"olv_limp_t","info aso a <20>mb %ld: obs %s, anch %s",n+1,obs,anc);
|
||
|
||
if(strcmp(tipent,olv_limp->camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_ACERA])==0)
|
||
{
|
||
ancho=olv_limp->anchos_def[OLV_ANCH_DEF_ACE];//acera
|
||
|
||
//lo marca para saber si es barrido mixto
|
||
olv_limp->ias[ia].info3=OLV_AMBLIN_ACE;
|
||
if(!olv_limp->barr_mix && !(barr_mix & (1<<(OLV_AMBLIN_ACE-1))))
|
||
barr_mix |= (1<<(OLV_AMBLIN_ACE-1));
|
||
}
|
||
else if(strcmp(tipent,olv_limp->camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_PEAT])==0)
|
||
{
|
||
ancho=olv_limp->anchos_def[OLV_ANCH_DEF_PEAT];//peatonal
|
||
|
||
olv_limp->ias[ia].info3=OLV_AMBLIN_PEAT;
|
||
}
|
||
else
|
||
ancho = OLV_LIMP_ANCH_DEF;
|
||
|
||
//si es tipo peatonal lo pone en los flags
|
||
if(strcmp(tipent,olv_limp->camps.atr_tip_ent[OLV_ATR_NOM_TIP_ENT_PEAT])==0)
|
||
{
|
||
olv_limp->ias[ia].flgs |= OLV_LIMP_FLG_PEAT;
|
||
}
|
||
}
|
||
olv_limp->ias[ia].info1=ancho;
|
||
if(log_debug)
|
||
wgeolog(LOG_TODO,"olv_limp_t","info aso a <20>mb %ld: ancho %lf",n+1, ancho);
|
||
|
||
olv_limp->ias[ia].info0=-1;
|
||
|
||
///////////////////////////////
|
||
//avisa de progreso
|
||
if((n%100==0) || (n==(olv_limp->n_amb-1)))
|
||
{
|
||
pon_mi_progre(OLV_TAREA_IMP, (int) (OliviaDef::GeneralDef::ProgrMax*
|
||
((1.0*(n+1)/olv_limp->n_amb)/3)+2/3));
|
||
wgeolog(LOG_TODO,"olv_limp_t","Rellenando info asociada a <20>mbitos, %ld de %ld",
|
||
n+1,olv_limp->n_amb);
|
||
}
|
||
|
||
if(!olv_limp->barr_mix)
|
||
olv_limp->barr_mix=(barr_mix>(1<<(OLV_AMBLIN_ACE-1)) && barr_mix<(1<<(OLV_AMBLIN_PEAT-1)));
|
||
}
|
||
|
||
if(n<olv_limp->n_amb)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al leer informaci<63>n asociada %ld en\n%s",n,nfile);
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Finaliza Matriz de info asociada a <20>mbitos");
|
||
|
||
fin:
|
||
if(obs)
|
||
free(obs);
|
||
if(anc)
|
||
free(anc);
|
||
if(tipent)
|
||
free(tipent);
|
||
if(tipap)
|
||
free(tipap);
|
||
|
||
return ret;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Replica los <20>mbitos cuando son tipo peatonal, a<>adiendo otro lineal igual que tendr<64> solo coste
|
||
* de desplazamiento, no de tratamiento, m<>s los segmentos que los unen, de coste 0
|
||
*/
|
||
BOOL Colv_limp_thr::replica_peat(int n_amb, int nias, Info_aso **ias_, Cobgeo *ob)
|
||
{
|
||
int i,n_peat,il,indx,npts,ip,max_npts,p,k;
|
||
double (*ptos)[3],(*ptos_aux)[][3];
|
||
Info_aso *ias_aux;
|
||
Objgeo lineal;
|
||
BOOL mal;
|
||
Info_aso *ias;
|
||
|
||
ptos_aux=NULL;
|
||
ias=*ias_;
|
||
|
||
//cuenta el n<>mero de peatonales
|
||
n_peat=0;
|
||
for(i=0;i<n_amb; i++)
|
||
{
|
||
if(!(ias[i].flgs & OLV_LIMP_FLG_PEAT))
|
||
continue;
|
||
n_peat++;
|
||
}
|
||
if(n_peat==0)
|
||
return TRUE;//no hay peatonales
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Replicando %ld calles peatonales",n_peat);
|
||
|
||
olv_limp->n_peat=n_peat;
|
||
|
||
//si hay peatonales, agranda el array de info asociada
|
||
//npeat*3 porque van la r<>plica del peatonal y sus dos segmentos
|
||
ias_aux = (Info_aso *)realloc(ias,(nias+n_peat*3)*sizeof(Info_aso));
|
||
if(!ias_aux)
|
||
{
|
||
return FALSE;
|
||
}
|
||
ias=ias_aux;
|
||
memset(&ias[nias],0,n_peat*3*sizeof(Info_aso));
|
||
|
||
//indica d<>nde empieza la info aso de las peatonales
|
||
olv_limp->n_ini_amb_iapr=nias;
|
||
|
||
//Inicializa el lineal con los par<61>mteros comunes
|
||
//crea el lineal
|
||
lineal.tipo = OBJ_LINEAL;
|
||
lineal.flags[0] = 0;
|
||
lineal.flags[1] = 0;
|
||
lineal.ev.id = 0;
|
||
lineal.pt.lin = (Linealgeo*) malloc (sizeof(Linealgeo));
|
||
if(!lineal.pt.lin)
|
||
{
|
||
return FALSE;
|
||
}
|
||
lineal.clase = OLV_ICLA_LIN_PEAT;
|
||
lineal.pt.lin->ptos=NULL;
|
||
/////////////////
|
||
mal=FALSE;
|
||
ip=0;
|
||
max_npts=0;
|
||
//replica las peatonales
|
||
for(i=0;i<n_amb && !mal; i++)
|
||
{
|
||
if(!(ias[i].flgs & OLV_LIMP_FLG_PEAT))
|
||
continue;
|
||
|
||
//apunta la l<>nea del <20>mbito
|
||
il=(*ob->objt)[i].indx;
|
||
npts = (*ob->lial)[il].n;
|
||
indx=(*ob->lial)[il].indx;
|
||
ptos = &(*ob->ptos)[indx];
|
||
|
||
//pone los valores
|
||
lineal.ia = nias + ip;
|
||
lineal.pt.lin->n= npts;
|
||
|
||
//pide memoria para los puntos si hace falta
|
||
if(npts>max_npts)
|
||
{
|
||
ptos_aux = (double (*)[][3]) realloc(lineal.pt.lin->ptos,npts * 3 * sizeof(double));
|
||
max_npts=npts;
|
||
}
|
||
if(!ptos_aux)
|
||
{
|
||
mal=TRUE;
|
||
continue;
|
||
}
|
||
lineal.pt.lin->ptos=ptos_aux;
|
||
|
||
//copia los puntos del <20>mbito
|
||
memcpy(lineal.pt.lin->ptos,ptos,npts*3*sizeof(double));
|
||
lineal.pt.lin->flags = 0;
|
||
if(ob->pon_obj(&lineal)<0)
|
||
{
|
||
mal=TRUE;
|
||
}
|
||
|
||
//reapunta el array de puntos
|
||
ptos = &(*ob->ptos)[indx];
|
||
|
||
//a<>ade los dos extremos, por si se ha movido memoria en el pon
|
||
for(k=0;k<2;k++)
|
||
{
|
||
lineal.ia = nias + ip + (k+1)*n_peat;
|
||
lineal.pt.lin->n= 2;
|
||
for(p=0;p<2;p++)
|
||
memcpy(&(*lineal.pt.lin->ptos)[p],ptos[k*(npts-1)],3*sizeof(double));
|
||
lineal.pt.lin->flags = 0;
|
||
if(ob->pon_obj(&lineal)<0)
|
||
{
|
||
mal=TRUE;
|
||
}
|
||
ptos = &(*ob->ptos)[indx];
|
||
}
|
||
|
||
//actualiza la info asociada
|
||
ias[nias+ip].flgs=OLV_LIMP_FLG_PEAT_REP;
|
||
ias[nias+ip].info0=i;
|
||
ias[nias+ip+n_peat].flgs=OLV_LIMP_FLG_PEAT_SEG;
|
||
ias[nias+ip+2*n_peat].flgs=OLV_LIMP_FLG_PEAT_SEG;
|
||
|
||
ip++;
|
||
}
|
||
ob->libera_objgeo(&lineal);
|
||
if(mal)
|
||
return FALSE;
|
||
|
||
*ias_ = ias;
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Replica las calles cuando son de doble sentido y se tienen en cuenta las restricciones
|
||
* de circulaci<63>n, para que se asignen los <20>mbitos s<>lo a la calle del sentido en el que est<73>n
|
||
*/
|
||
BOOL Colv_limp_thr::replica_doble_sent(Info_inw_dmin *inww, Info_aso **ias_, Cobgeo *ob)
|
||
{
|
||
int i,iaux,indx,npts,max_npts,n_doble,id,nias,KK,inw,ia,inwl;
|
||
double (*ptos)[3],(*ptos_aux)[3];
|
||
Info_aso *ias_aux;
|
||
Objgeo lineal;
|
||
BOOL mal;
|
||
Info_aso *ias;
|
||
|
||
ptos_aux=NULL;
|
||
ias=*ias_;
|
||
KK=olv_limp->tipo_ambit;
|
||
nias=olv_limp->n_nw+olv_limp->n_amb*(KK+1)+olv_limp->n_peat*3;
|
||
max_npts=0;
|
||
mal=FALSE;
|
||
|
||
olv_limp->n_ini_nw_2 = nias;
|
||
|
||
if(olv_limp->res_circ<OLV_RES_RECOGER_SOLO_LADO_Y_GIROS)
|
||
return TRUE;
|
||
|
||
//agranda el array de info asociada tanto como calles de doble sentido, aunque luego sean menos
|
||
//cuenta el n<>mero de calles de doble sentido
|
||
n_doble=0;
|
||
for(i=olv_limp->n_ini_nw;i<olv_limp->n_ini_nw+olv_limp->n_nw; i++)
|
||
{
|
||
if(ias[(*ob->objt)[i].ia].flgs & OLV_LIMP_FLG_CIRC_NO_DOB)
|
||
continue;
|
||
n_doble++;
|
||
}
|
||
if(n_doble==0)
|
||
return TRUE;//no hay calles de doble sentido
|
||
|
||
|
||
//si hay calles de doble sentido, agranda el array de info asociada
|
||
//n_doble porque va la r<>plica
|
||
ias_aux = (Info_aso *)realloc(ias,(nias+n_doble)*sizeof(Info_aso));
|
||
if(!ias_aux)
|
||
{
|
||
return FALSE;
|
||
}
|
||
ias=ias_aux;
|
||
memset(&ias[nias],0,n_doble*sizeof(Info_aso));
|
||
|
||
//Inicializa el lineal con los par<61>mteros comunes
|
||
//crea el lineal
|
||
lineal.tipo = OBJ_LINEAL;
|
||
lineal.flags[0] = 0;
|
||
lineal.flags[1] = 0;
|
||
lineal.ev.id = 0;
|
||
lineal.pt.lin = (Linealgeo*) malloc (sizeof(Linealgeo));
|
||
if(!lineal.pt.lin)
|
||
{
|
||
return FALSE;
|
||
}
|
||
lineal.clase = OLV_ICLA_LIN_NW_REP;
|
||
lineal.pt.lin->ptos=NULL;
|
||
///////////////////////////
|
||
|
||
id=0;
|
||
//cuenta el n<>mero de calles de doble sentido que hay que replicar
|
||
for(i=0;i<olv_limp->n_amb*KK; i++)
|
||
{
|
||
//apunta al nw m<>s cercano del <20>mbito actual
|
||
inw=inww[i].inw;
|
||
if((inw<0) || (inw<olv_limp->n_ini_nw))
|
||
continue;
|
||
ia=(*ob->objt)[inw].ia;
|
||
if((ias[ia].flgs & OLV_LIMP_FLG_NO_NW) ||
|
||
(ias[ia].flgs & OLV_LIMP_FLG_CIRC_NO_DOB))
|
||
continue;
|
||
|
||
//llega aqu<71> si es nw de doble sentido
|
||
inwl=(*ob->objt)[inw].indx;
|
||
npts = (*ob->lial)[inwl].n;
|
||
indx=(*ob->lial)[inwl].indx;
|
||
ptos = &(*ob->ptos)[indx];
|
||
|
||
//////////////////////////////////////////////
|
||
//se hace r<>plica
|
||
//pone los valores
|
||
lineal.ia = nias + id;
|
||
lineal.pt.lin->n= npts;
|
||
|
||
ptos_aux=(double (*)[3])lineal.pt.lin->ptos;
|
||
//pide memoria para los puntos si hace falta
|
||
if(npts>max_npts)
|
||
{
|
||
ptos_aux = (double (*)[3]) realloc(lineal.pt.lin->ptos,npts * 3 * sizeof(double));
|
||
max_npts=npts;
|
||
}
|
||
if(!ptos_aux)
|
||
{
|
||
mal=TRUE;
|
||
continue;
|
||
}
|
||
|
||
//copia los puntos de la calle
|
||
memcpy(ptos_aux,ptos,npts*3*sizeof(double));
|
||
|
||
//copia los puntos de la calle
|
||
lineal.pt.lin->ptos=(double (*)[][3])ptos_aux;
|
||
lineal.pt.lin->flags = 0;
|
||
if(ob->pon_obj(&lineal)<0)
|
||
{
|
||
mal=TRUE;
|
||
continue;
|
||
}
|
||
|
||
//actualiza la info asociada, les cambia el flag, ten<65>an los dos sentidos (flg 0),
|
||
//y se le pone uno de los dos
|
||
//el original
|
||
ias[ia].flgs|=OLV_LIMP_FLG_CIRC_FT;
|
||
//el nuevo
|
||
ias[nias + id].flgs|=OLV_LIMP_FLG_CIRC_TF|OLV_LIMP_FLG_NW_REP;
|
||
//copia ishp
|
||
ias[nias + id].ishp = ias[ia].ishp;
|
||
//copia velocidad
|
||
ias[nias + id].info1 = ias[ia].info1;
|
||
//copia nombre
|
||
ias[nias + id].info2 = (char*)malloc(OLV_LIMP_MAX_CAMP);
|
||
if(!ias[nias + id].info2)
|
||
{
|
||
return FALSE;
|
||
}
|
||
ias[ia].info2[OLV_LIMP_MAX_CAMP-1]=0;
|
||
strcpy_s(ias[nias + id].info2,OLV_LIMP_MAX_CAMP,ias[ia].info2);
|
||
//copia ishp
|
||
ias[nias + id].ishp = ias[ia].ishp;
|
||
|
||
//////////////////////////////////////////////
|
||
//a los que est<73>n a la izquiera les reapunta
|
||
iaux=i;
|
||
while((iaux<olv_limp->n_amb*KK) && (inww[iaux].inw==inw))
|
||
{
|
||
if(!(ias[inww[iaux].iamb+olv_limp->n_ini_amb_iai].flgs & OLV_LIMP_FLG_DER))
|
||
{
|
||
inww[iaux].inw=(ob->vect.nobj-1);//el lineal que acaba de a<>adir
|
||
//reapunta tambi<62>n el original
|
||
olv_limp->inww_amb[inww[iaux].iamb].inw=(ob->vect.nobj-1);
|
||
/////////////////////////////
|
||
|
||
ias[inww[iaux].iamb+olv_limp->n_ini_amb_iai].flgs |= OLV_LIMP_FLG_DER;
|
||
(*ob->objt)[inww[iaux].iamb].clase=-6;
|
||
//wgeolog(LOG_TODO,"olv_limp_t","<22>mbito %ld reapuntado a la derecha",inww[iaux].iamb);
|
||
|
||
}
|
||
iaux++;
|
||
|
||
}
|
||
i=iaux-1;
|
||
|
||
id++;
|
||
}
|
||
|
||
|
||
olv_limp->n_nw_dobl = id;
|
||
|
||
ob->libera_objgeo(&lineal);
|
||
if(mal)
|
||
return FALSE;
|
||
|
||
*ias_ = ias;
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Une la red navegable y los <20>mbitos
|
||
* 'soloi' es para debug, indica si se quiere realizar la uni<6E>n de un <20>nico <20>mbito pasado en soloi
|
||
*/
|
||
BOOL Colv_limp_thr::une_amb_nw(int soloi)
|
||
{
|
||
int i,k,KK;
|
||
//variables para apuntar al <20>mbito y nw en cuesti<74>n
|
||
int npt_amb, il_amb,iamb;
|
||
double (*pt_amb)[3];
|
||
BOOL log_debug=FALSE;
|
||
|
||
//////////////////
|
||
//coge el factor del tipo de <20>mbito, 1 si es puntual, 2 si es lineal
|
||
KK=olv_limp->tipo_ambit;
|
||
|
||
//////////////////
|
||
//replica las peatonales que sea necesario
|
||
if(KK==OLV_AMB_LIN)
|
||
{
|
||
int n_ias=(olv_limp->n_nw+olv_limp->n_amb*(KK+1));
|
||
if(!replica_peat(olv_limp->n_amb,n_ias,&olv_limp->ias,olv_limp->olv->olv_ob))
|
||
{
|
||
pon_mi_msg("Error al replicar peatonales: %s", err_str);
|
||
return FALSE;
|
||
}
|
||
}
|
||
//////////////////
|
||
|
||
//inicia cuando ya sabe si es tipo lineal o puntual
|
||
if(!olv_limp->inww_amb)
|
||
{
|
||
olv_limp->inww_amb = (Info_inw_dmin *)malloc(olv_limp->n_amb*KK*sizeof(Info_inw_dmin));
|
||
}
|
||
if(!olv_limp->inww_amb)
|
||
{
|
||
pon_mi_msg("Error, sin memoria para matriz de <20>ndices\nde <20>mbitos a carreteras");
|
||
return FALSE;
|
||
}
|
||
|
||
//rellena todos a no def
|
||
for(i=0;i<olv_limp->n_amb*KK;i++)
|
||
{
|
||
olv_limp->inww_amb[i].inw=OLV_LIMP_AMB_NW_NODEF;
|
||
olv_limp->inww_amb[i].iamb=i%olv_limp->n_amb;
|
||
olv_limp->inww_amb[i].dmin=(float)MAYUSCULO;
|
||
olv_limp->inww_amb[i].inw_old=NULL;
|
||
olv_limp->inww_amb[i].ip=olv_limp->inww_amb[i].flgs=0;
|
||
olv_limp->inww_amb[i].lamb=olv_limp->inww_amb[i].alpha=0;
|
||
olv_limp->inww_amb[i].pt[0]=olv_limp->inww_amb[i].pt[1]=olv_limp->inww_amb[i].pt[2]=0;
|
||
}
|
||
///////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Uniendo <20>mbitos a NW");
|
||
pon_mi_progre(OLV_TAREA_UNE_NW_AMB, 0);
|
||
pon_mi_msg("");
|
||
err_str[0]=0;
|
||
|
||
//Bucle por <20>mbito
|
||
for(i=0;i<olv_limp->n_amb && !pirate; i++)
|
||
{
|
||
if((soloi>-1) && (soloi<olv_limp->n_amb) && (i!=soloi))
|
||
continue;//para debug, si soloi apunta al <20>mbito que queremos calcular solo
|
||
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
|
||
//apunta el array de puntos al <20>mbito
|
||
il_amb=(*olv_limp->olv->olv_ob->objt)[i].indx;
|
||
if(KK==OLV_AMB_LIN)//para tipo lineal, obtiene los primeros puntos de los dos extremos
|
||
{
|
||
if((*olv_limp->olv->olv_ob->objt)[i].tipo != OBJ_LINEAL)
|
||
continue;//comprueba clases
|
||
npt_amb = (*olv_limp->olv->olv_ob->lial)[il_amb].n;
|
||
iamb=(*olv_limp->olv->olv_ob->lial)[il_amb].indx;
|
||
pt_amb = &(*olv_limp->olv->olv_ob->ptos)[iamb];
|
||
}
|
||
else if(KK==OLV_AMB_PUN) //para tipo puntual, es un <20>nico punto
|
||
{
|
||
if((*olv_limp->olv->olv_ob->objt)[i].tipo != OBJ_PUNTUAL)
|
||
continue;//comprueba clases
|
||
npt_amb = 1;
|
||
iamb=il_amb;
|
||
pt_amb = &(*olv_limp->olv->olv_ob->ptos)[iamb];
|
||
}
|
||
|
||
//rellena en inww_amb el inw y su info de la carretera del nw <20>legida como
|
||
//m<>s cercana al <20>mbito
|
||
busca_inw_dmin(i,olv_limp->n_amb, npt_amb,pt_amb,
|
||
olv_limp->n_ini_nw, olv_limp->n_nw,
|
||
KK,olv_limp->inww_amb , olv_limp->olv->olv_ob);
|
||
|
||
////////////////////////////////////////////
|
||
//comprueba en todos los <20>mbitos si va andando, si est<73>n asignados a una carretera muy lejos
|
||
//y tienen un <20>mbito m<>s cerca, les asigna ese (excepto en el caso ejes)
|
||
if((olv_limp->res_circ<OLV_RES_RECOGER_SOLO_LADO_Y_GIROS) && ((olv_limp->uds_tto!=OliviaDef::GeneralDef::OlvTipTtoMh_eje) &&
|
||
(olv_limp->uds_tto!=OliviaDef::GeneralDef::OlvTipTtoM2h_eje)))
|
||
comprueba_amb_lejos(i,olv_limp->n_amb, npt_amb,pt_amb,olv_limp->inww_amb,olv_limp->ias, olv_limp->olv->olv_ob);
|
||
|
||
//A<>ade los segmentos a clase NW_union
|
||
add_uniones_obj(i,olv_limp->n_amb,olv_limp->n_ini_nw,olv_limp->n_ini_amb_iai,olv_limp->n_ini_amb_iaf,npt_amb,KK,
|
||
olv_limp->inww_amb,olv_limp->ias, olv_limp->olv->olv_ob);
|
||
|
||
if(log_debug)
|
||
{
|
||
//loguea
|
||
for(k=0; k<KK;k++)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Dist <20>mb-nw %02ld, k %ld: dmin %lf, inw %ld, ip %ld, lamb %lf, alpha %lf",
|
||
i,k,
|
||
olv_limp->inww_amb[i + k*olv_limp->n_amb].dmin,
|
||
olv_limp->inww_amb[i + k*olv_limp->n_amb].inw,
|
||
olv_limp->inww_amb[i + k*olv_limp->n_amb].ip,
|
||
olv_limp->inww_amb[i + k*olv_limp->n_amb].lamb,
|
||
olv_limp->inww_amb[i + k*olv_limp->n_amb].alpha);
|
||
}
|
||
|
||
if((i%100==0) ||(i==(olv_limp->n_amb-1)))
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Uniendo <20>mbitos a NW, %ld de %ld",i+1,olv_limp->n_amb);
|
||
//avisa de progreso
|
||
pon_mi_progre(OLV_TAREA_UNE_NW_AMB, (int) ((OliviaDef::GeneralDef::ProgrMax*
|
||
1.0*(i+1)/olv_limp->n_amb)));
|
||
}
|
||
|
||
}
|
||
//cuida si ha salido antes por falta de memo
|
||
if(i<olv_limp->n_amb)
|
||
{
|
||
pon_mi_msg("Error en la uni<6E>n de <20>mbitos a red navegable");
|
||
return FALSE;
|
||
}
|
||
|
||
if(olv_limp->res_circ<OLV_RES_RECOGER_SOLO_LADO_Y_GIROS)
|
||
comprueba_aislados(olv_limp->inww_amb);
|
||
|
||
/////////////////////////////////////////////////////
|
||
//si hay alg<6C>n <20>mbito asignado a una carretera de prohibido circular
|
||
//se le quita el flag a la carretera
|
||
if(olv_limp->res_circ!=OLV_RES_NO)
|
||
{
|
||
for(i=0;i<olv_limp->n_amb && !pirate; i++)
|
||
{
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
for(k=0; k<KK;k++)
|
||
{
|
||
if(olv_limp->ias[(*olv->olv_ob->objt)[olv_limp->inww_amb[i + k*olv_limp->n_amb].inw].ia].flgs &
|
||
OLV_LIMP_FLG_CIRC_NONE)
|
||
{
|
||
//le quita el flag
|
||
olv_limp->ias[(*olv->olv_ob->objt)[olv_limp->inww_amb[i + k*olv_limp->n_amb].inw].ia].flgs =
|
||
olv_limp->ias[(*olv->olv_ob->objt)[olv_limp->inww_amb[i + k*olv_limp->n_amb].inw].ia].flgs & ~OLV_LIMP_FLG_CIRC_NONE;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Como se ha podido unir unos <20>mbitos a otros, revisa que no se hayan unido s<>lo entre s<>
|
||
* y no a ninguna carretera, en ese caso estar<61>an aislados. Lo revisa para, en esos casos,
|
||
* forzar a que apunte alguno a una carretera
|
||
*/
|
||
void Colv_limp_thr::comprueba_aislados(Info_inw_dmin *inww)
|
||
{
|
||
int i,KK,iamb,k,j;
|
||
BYTE *ambs_flgs;
|
||
int *ambs_cola;
|
||
int ncola;
|
||
BOOL aislado;
|
||
double dmin;
|
||
int iambmin;
|
||
int npt_amb;
|
||
|
||
#define FLG_VISTO 1
|
||
#define FLG_TEMP 2
|
||
|
||
KK=olv_limp->tipo_ambit;
|
||
//inicia el array de flags
|
||
ambs_flgs = (BYTE*)malloc(olv_limp->n_amb);
|
||
if(!ambs_flgs)
|
||
return;
|
||
memset(ambs_flgs,0,olv_limp->n_amb);
|
||
//inicia la cola
|
||
ambs_cola = (int*)malloc(olv_limp->n_amb*sizeof(int));
|
||
if(!ambs_cola)
|
||
return;
|
||
memset(ambs_cola,0,olv_limp->n_amb*sizeof(int));
|
||
ncola=0;
|
||
|
||
//bucle para cada <20>mbito
|
||
for(i=0;i<olv_limp->n_amb && !pirate; i++)
|
||
{
|
||
if(ambs_flgs[i] & FLG_VISTO)
|
||
continue;
|
||
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
aislado=TRUE;
|
||
//lo mete a la cola
|
||
ambs_cola[ncola]=i;
|
||
ncola=1;
|
||
|
||
while (ncola)
|
||
{
|
||
//saca <20>mbito de la cola
|
||
ncola--;
|
||
iamb=ambs_cola[ncola];
|
||
|
||
//le pone el flag temporal
|
||
ambs_flgs[iamb] |= FLG_TEMP;
|
||
|
||
//bucle en los dos extremos
|
||
for(k=0;k<KK;k++)
|
||
{
|
||
if(inww[iamb+k*olv_limp->n_amb].inw<olv_limp->n_amb)
|
||
{
|
||
//lo mete en la cola si su extremo es un <20>mbito
|
||
//no visto ni temporal
|
||
if(ambs_flgs[inww[iamb+k*olv_limp->n_amb].inw] & (FLG_TEMP | FLG_VISTO))
|
||
continue;
|
||
ambs_cola[ncola]=inww[iamb+k*olv_limp->n_amb].inw;
|
||
ncola++;
|
||
}
|
||
else
|
||
aislado=FALSE;
|
||
}
|
||
}
|
||
|
||
if(aislado)
|
||
{
|
||
//es una aislada o grupo de aisladas,
|
||
//deja apuntada a una nw la de distancia menor
|
||
dmin=MAYUSCULO;
|
||
iambmin=-1;
|
||
for(j=0;j<olv_limp->n_amb; j++)
|
||
{
|
||
if(!(ambs_flgs[j] & FLG_TEMP))
|
||
continue;
|
||
|
||
for(k=0;k<KK;k++)
|
||
{
|
||
if(!inww[j+k*olv_limp->n_amb].inw_old)
|
||
continue;//no deber<65>a
|
||
if(inww[j+k*olv_limp->n_amb].inw_old->dmin<dmin)
|
||
{
|
||
iambmin=j+k*olv_limp->n_amb;
|
||
dmin=inww[j+k*olv_limp->n_amb].inw_old->dmin;
|
||
}
|
||
}
|
||
}
|
||
if(dmin<MAYUSCULO && iambmin>=0)
|
||
{
|
||
//reapunta a la inw old
|
||
memcpy(&inww[iambmin],inww[iambmin].inw_old,sizeof(Info_inw_dmin));
|
||
free(inww[iambmin].inw_old);
|
||
inww[iambmin].inw_old=NULL;
|
||
|
||
//a<>ade el segmento de uni<6E>n
|
||
if(KK==OLV_AMB_LIN)//para tipo lineal, obtiene los primeros puntos de los dos extremos
|
||
npt_amb = (*olv_limp->olv->olv_ob->lial)[(*olv_limp->olv->olv_ob->objt)[iambmin].indx].n;
|
||
else if(KK==OLV_AMB_PUN) //para tipo puntual, es un <20>nico punto
|
||
npt_amb = 1;
|
||
|
||
add_uniones_obj(iambmin%olv_limp->n_amb,olv_limp->n_amb,olv_limp->n_ini_nw,olv_limp->n_ini_amb_iai,olv_limp->n_ini_amb_iaf,npt_amb,KK,
|
||
olv_limp->inww_amb,olv_limp->ias, olv_limp->olv->olv_ob);
|
||
}
|
||
}
|
||
|
||
//todos los estudiados, que son los del flag temporal, los pone como vistos
|
||
for(j=0;j<olv_limp->n_amb; j++)
|
||
{
|
||
if(ambs_flgs[j] & FLG_TEMP)
|
||
{
|
||
ambs_flgs[j] = ambs_flgs[j] & ~FLG_TEMP;
|
||
ambs_flgs[j] = ambs_flgs[j] | FLG_VISTO; //le quita el flag temporal y le pone el de visto
|
||
}
|
||
}
|
||
}
|
||
|
||
free(ambs_flgs);
|
||
free(ambs_cola);
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Comprueba en 'inww' si 'daux' es menor que las almacenadas.
|
||
* Devuelve la posici<63>n del array inww donde tiene que ir o -1 si no es menor
|
||
* y vac<61>a dicha posici<63>n, moviendo las dem<65>s, para que el siguiente guarde ah<61> lo que toca
|
||
*/
|
||
int Colv_limp_thr::is_dmin(double daux, Info_inw_dmin *inww)
|
||
{
|
||
int i=-1,k;
|
||
|
||
if(!inww)
|
||
return i;
|
||
|
||
for(i=0; i<OLV_LIMP_N_DMIN_NW;i++)
|
||
{
|
||
if(daux<inww[i].dmin)
|
||
{
|
||
for(k=OLV_LIMP_N_DMIN_NW-2;k>=i; k--)
|
||
{
|
||
memcpy(&inww[k+1], &inww[k],sizeof(Info_inw_dmin));
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
if(i>=OLV_LIMP_N_DMIN_NW)
|
||
i=-1;
|
||
|
||
return i;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Devuelve la distancia de un <20>mbito 'i_amb'(ya relativo al n_ini_amb) de 'npt_amb' puntos almacenados
|
||
* en 'pt_amb' a la carretera m<>s cercana, y rellena la info de dicha carretera en inww_amb.
|
||
* KK indica el tipo de <20>mbito, si es 1 es puntual, s<>lo se calcula una distancia a la carretera,
|
||
* si es 2, es lineal, se calculan la distancia al extremo inicial y al final
|
||
* 'n_amb' es el n<>mero total de <20>mbitos, ini_nw el inicial de carreteras y 'n_nw' el n<>mero de ellas.
|
||
* 'pb' es donde est<73>n las polil<69>neas tanto de carreteras como de <20>mbitos.
|
||
*/
|
||
BOOL Colv_limp_thr::busca_inw_dmin(int i_amb, int n_amb, int npt_amb, double (*pt_amb)[3], int ini_nw, int n_nw,
|
||
int KK, Info_inw_dmin *inww_amb, Cobgeo *ob)
|
||
{
|
||
//variables para apuntar al <20>mbito y nw en cuesti<74>n
|
||
int npt_nw, il_nw, i_nw, indx_nw;
|
||
double (*pt_nw)[3];
|
||
//variables locales
|
||
BOOL pinta_amb,pinta_nw,log_detalle;
|
||
double alphamin[2], daux, dtot, dist;
|
||
int i_inww, j, k, jmin[2];
|
||
double (*pt_amb_prime_i)[3], (*pt_amb_prime_f)[3], (*pt_prime)[3];
|
||
double pt_ang[2][3]; //almacena dos puntos para calcular el vector con el que forma el <20>ngulo el <20>mbito
|
||
Info_inw_dmin inwaux;
|
||
Info_inw_dmin inww[OLV_LIMP_N_DMIN_NW*2]; //Almacena las N mejores carreteras del punto inicial y las N del punto final
|
||
|
||
/////////////////////
|
||
pinta_amb=FALSE;
|
||
pinta_nw=FALSE;
|
||
log_detalle=FALSE;
|
||
|
||
//inicializa
|
||
pt_amb_prime_i=pt_amb_prime_f=pt_prime=NULL;
|
||
|
||
//inicializa array local para almacenamiento de las tres carreteras m<>s cercanas
|
||
memset(inww,0,sizeof(Info_inw_dmin)*OLV_LIMP_N_DMIN_NW*2);
|
||
for(int j=0; j<OLV_LIMP_N_DMIN_NW;j++)
|
||
inww[j].dmin=inww[j+OLV_LIMP_N_DMIN_NW].dmin=(float)MAYUSCULO;
|
||
|
||
////////////////////////////////////////////////////////////////////////
|
||
//inicia variables para c<>lculo de distancias, con respecto al <20>mbito actual
|
||
if(KK==OLV_AMB_LIN)//para tipo lineal, obtiene los primeros puntos de los dos extremos
|
||
{
|
||
//calcula los primeros nprime puntos con los que va a calcular la distancia media
|
||
dtot = long_linea((double (*)[][3]) pt_amb,npt_amb,NULL,NULL,NULL,NULL);
|
||
pt_amb_prime_i = (double (*)[3])malloc(OLV_LIMP_N_PTOS_MED*3*sizeof(double));
|
||
pt_amb_prime_f = (double (*)[3])malloc(OLV_LIMP_N_PTOS_MED*3*sizeof(double));
|
||
if(!pt_amb_prime_f || !pt_amb_prime_i)
|
||
return FALSE;
|
||
dist=min(OLV_LIMP_N_PTOS_DIST,dtot);
|
||
Colv_geom::dame_prime_ptos((double (*)[][3]) pt_amb,npt_amb,OLV_LIMP_N_PTOS_MED,dist,dtot,TRUE,(double (*)[][3])pt_amb_prime_i);
|
||
Colv_geom::dame_prime_ptos((double (*)[][3]) pt_amb,npt_amb,OLV_LIMP_N_PTOS_MED,dist,dtot,FALSE,(double (*)[][3])pt_amb_prime_f);
|
||
//////////////////////////////////////////////////
|
||
//pinta los primes puntos en los dos extremos
|
||
if(pinta_amb)
|
||
{
|
||
for(j=0; j<1;j++)
|
||
{
|
||
/////////////////////
|
||
//OJO, si entra aqu<71> (pinta_amb=true), hay que reapuntar los puntos despu<70>s de hacer cada pon_pto!!!
|
||
/////////////////////
|
||
Colv_geom::pon_pto((double(*)[3])pt_amb_prime_i[j],OLV_ICLA_PUN_AMB,0,olv->olv_ob);
|
||
Colv_geom::pon_pto((double(*)[3])pt_amb_prime_f[j],OLV_ICLA_PUN_AMB,0,olv->olv_ob);
|
||
}
|
||
}
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////
|
||
//Bucle por cada carretera de la nw
|
||
for(int inw=ini_nw; inw<n_nw+ini_nw && !pirate; inw++)
|
||
{
|
||
if((*ob->objt)[inw].clase != OLV_ICLA_LIN_NW)
|
||
continue; //no deber<65>a, pero por si acaso
|
||
|
||
il_nw=(*ob->objt)[inw].indx;
|
||
npt_nw = (*ob->lial)[il_nw].n;
|
||
indx_nw=(*ob->lial)[il_nw].indx;
|
||
pt_nw = &(*ob->ptos)[indx_nw];
|
||
inwaux.inw=inw;
|
||
|
||
//lo hace para punto inicial y final si es lineal, o solo una vez si es puntual
|
||
for(k=0; k<KK;k++)
|
||
{
|
||
inwaux.alpha=inwaux.lamb=0;
|
||
inwaux.ip=0;
|
||
inwaux.dmin=(float)MAYUSCULO;
|
||
|
||
if(KK==OLV_AMB_LIN)
|
||
{
|
||
//calcula la daux media de 3 puntos desde los extremos del <20>mbito
|
||
if(k==0)
|
||
pt_prime = pt_amb_prime_i;
|
||
else
|
||
pt_prime = pt_amb_prime_f;
|
||
daux = Colv_geom::dist_pto_poli_med((double (*)[][3])pt_prime, (double (*)[][3])pt_nw, OLV_LIMP_N_PTOS_MED, npt_nw,
|
||
&inwaux.ip, &inwaux.lamb);
|
||
}
|
||
else if(KK==OLV_AMB_PUN)
|
||
{
|
||
//calcula la daux media
|
||
daux = Colv_geom::dist_pto_poli((double (*)[3])pt_amb,(double (*)[][3])pt_nw,npt_nw,&inwaux.ip, &inwaux.lamb);
|
||
}
|
||
|
||
i_inww=is_dmin(daux,&inww[k*OLV_LIMP_N_DMIN_NW]);
|
||
if(i_inww>=0)
|
||
{
|
||
//Dist ptos-recta. Si dist mayor que la m<>nima guardada, descarta.
|
||
// Si todas dist similares y menores que una dada, se guarda
|
||
//inw->linea de la nw
|
||
inww[i_inww+k*OLV_LIMP_N_DMIN_NW].dmin=(float)daux;
|
||
inww[i_inww+k*OLV_LIMP_N_DMIN_NW].inw=inwaux.inw;
|
||
inww[i_inww+k*OLV_LIMP_N_DMIN_NW].ip = inwaux.ip;
|
||
inww[i_inww+k*OLV_LIMP_N_DMIN_NW].lamb=inwaux.lamb;
|
||
inww[i_inww+k*OLV_LIMP_N_DMIN_NW].pt[0]=inww[i_inww+k*OLV_LIMP_N_DMIN_NW].pt[1]=
|
||
inww[i_inww+k*OLV_LIMP_N_DMIN_NW].pt[2]=0;
|
||
}
|
||
}
|
||
}
|
||
if(pirate)
|
||
goto fin;
|
||
////////////////////////////////////////////////////////////////////////
|
||
//coger de los tres de inww el que del punto ip de nw al extremo de amb forme el <20>ngulo
|
||
//cuya diferencia con pi/2 sea menor (en el caso lineal)
|
||
//y ponerlo en inww_amb[i-olv_limp->n_ini_amb]
|
||
jmin[0]=jmin[1]=0;
|
||
alphamin[0]=alphamin[1]=MAYUSCULO;
|
||
for(j=0;j<OLV_LIMP_N_DMIN_NW;j++)
|
||
{
|
||
for(k=0; k<KK; k++)
|
||
{
|
||
//k=0, para el punto inicial
|
||
//k=1, para el punto final
|
||
i_nw=inww[j+k*OLV_LIMP_N_DMIN_NW].inw;
|
||
if(i_nw<0 || (i_nw>=n_nw+ini_nw)) //por si acaso
|
||
continue;
|
||
il_nw = (*ob->objt)[i_nw].indx;
|
||
npt_nw = (*ob->lial)[il_nw].n;
|
||
indx_nw=(*ob->lial)[il_nw].indx;
|
||
pt_nw = &(*ob->ptos)[indx_nw];
|
||
|
||
//calcula el punto del inw donde se da el m<>nimo
|
||
inww[j+k*OLV_LIMP_N_DMIN_NW].pt[2]=0;
|
||
inww[j+k*OLV_LIMP_N_DMIN_NW].pt[0]=pt_nw[inww[j+k*OLV_LIMP_N_DMIN_NW].ip][0]+
|
||
(pt_nw[inww[j+k*OLV_LIMP_N_DMIN_NW].ip+1][0]-pt_nw[inww[j+k*OLV_LIMP_N_DMIN_NW].ip][0])*
|
||
inww[j+k*OLV_LIMP_N_DMIN_NW].lamb;
|
||
inww[j+k*OLV_LIMP_N_DMIN_NW].pt[1]=pt_nw[inww[j+k*OLV_LIMP_N_DMIN_NW].ip][1]+
|
||
(pt_nw[inww[j+k*OLV_LIMP_N_DMIN_NW].ip+1][1]-pt_nw[inww[j+k*OLV_LIMP_N_DMIN_NW].ip][1])*
|
||
inww[j+k*OLV_LIMP_N_DMIN_NW].lamb;
|
||
|
||
if(inww[j+k*OLV_LIMP_N_DMIN_NW].pt[0]==0 || inww[j+k*OLV_LIMP_N_DMIN_NW].pt[1]==0)
|
||
int a=0;
|
||
|
||
//solo para tipo lineal, elige el de distancia menor y que el <20>ngulo que forma el <20>mbito con
|
||
//el punto m<>s cercano de la nw sea el m<>s ortogonal
|
||
if(KK==OLV_AMB_LIN)
|
||
{
|
||
if(k==0)
|
||
pt_prime = pt_amb_prime_i;
|
||
else
|
||
pt_prime = pt_amb_prime_f;
|
||
//el <20>ngulo se calcula entre el extremo del <20>mbito con el vector que forman dicho extremo del
|
||
//<2F>mbito con el punto del inw donde se da el m<>nimo
|
||
pt_ang[0][0] = pt_prime[0][0];
|
||
pt_ang[0][1] = pt_prime[0][1];
|
||
pt_ang[0][2] = pt_prime[0][2];
|
||
pt_ang[1][0] = inww[j+k*OLV_LIMP_N_DMIN_NW].pt[0];
|
||
pt_ang[1][1] = inww[j+k*OLV_LIMP_N_DMIN_NW].pt[1];
|
||
pt_ang[1][2] = inww[j+k*OLV_LIMP_N_DMIN_NW].pt[2];
|
||
|
||
inww[j+k*OLV_LIMP_N_DMIN_NW].alpha=(float)fabs(Colv_geom::prod_esc((double(*)[][3])pt_prime,
|
||
(double(*)[][3])pt_ang));
|
||
}
|
||
}
|
||
}
|
||
if(KK==OLV_AMB_LIN)
|
||
{
|
||
//<2F>nicamente si el segundo m<>s cercano (el de la pos '1') tiene alpha menor, y una distancia no mucho mayor (*)
|
||
//lo coge,
|
||
//si no, se queda el m<>s cercano
|
||
for(k=0; k<KK; k++)
|
||
{
|
||
if((inww[1+k*OLV_LIMP_N_DMIN_NW].alpha<=inww[k*OLV_LIMP_N_DMIN_NW].alpha) &&
|
||
(inww[1+k*OLV_LIMP_N_DMIN_NW].dmin<(inww[k*OLV_LIMP_N_DMIN_NW].dmin * 1000)))
|
||
jmin[k]=1;
|
||
}
|
||
}
|
||
|
||
if(olv_limp->res_circ!=OLV_RES_NO)
|
||
{
|
||
//si hay restricciones de circulaci<63>n, y se va a coger como dmin una carretera peatonal, coge la siguiente de dmin
|
||
for(k=0; k<KK; k++)
|
||
{
|
||
if((olv_limp->ias[(*ob->objt)[inww[k*OLV_LIMP_N_DMIN_NW].inw].ia].info1 ==0) &&
|
||
(olv_limp->ias[(*ob->objt)[inww[1+k*OLV_LIMP_N_DMIN_NW].inw].ia].info1 !=0))
|
||
jmin[k]=1;
|
||
}
|
||
}
|
||
|
||
//copia el m<>nimo que ha encontrado
|
||
//para el punto inicial y final, o solo una vez si es puntual
|
||
for(k=0; k<KK; k++)
|
||
{
|
||
|
||
if(inww[jmin[k]+k*OLV_LIMP_N_DMIN_NW].pt[0]==0 || inww[jmin[k]+k*OLV_LIMP_N_DMIN_NW].pt[1]==0)
|
||
int a=0;
|
||
|
||
memcpy(&inww_amb[i_amb+k*n_amb],&inww[jmin[k]+k*OLV_LIMP_N_DMIN_NW],sizeof(Info_inw_dmin));
|
||
inww_amb[i_amb+k*n_amb].iamb=i_amb;
|
||
|
||
if(pinta_nw) //pinta el m<>nimo que ha encontrado
|
||
{
|
||
/////////////////////
|
||
//OJO, si entra aqu<71> (pinta_amb=true), hay que reapuntar los puntos despu<70>s de hacer cada pon_pto!!!
|
||
/////////////////////
|
||
Colv_geom::pon_pto((double(*)[3])&inww[jmin[k]+k*OLV_LIMP_N_DMIN_NW].pt,OLV_ICLA_PUN_AMB_T,0,ob);
|
||
}
|
||
}
|
||
|
||
//loguea
|
||
if(log_detalle && KK==OLV_AMB_LIN)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Distancia <20>mbito %02ld - jmin Ini %ld jmin Fin %ld",i_amb,jmin[0],jmin[1]);
|
||
|
||
for(j=0;j<OLV_LIMP_N_DMIN_NW;j++)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Distancia <20>mbito %02ld - %ld. Ini : dmin %lf, inw %ld, ip %ld, lamb %lf, alpha %lf" \
|
||
". Fin : dmin %lf, inw %ld, ip %ld, lamb %lf, alpha %lf",i_amb, j,
|
||
inww[j].dmin,
|
||
inww[j].inw-ini_nw,
|
||
inww[j].ip,
|
||
inww[j].lamb,
|
||
inww[j].alpha,
|
||
inww[j+OLV_LIMP_N_DMIN_NW].dmin,
|
||
inww[j+OLV_LIMP_N_DMIN_NW].inw-ini_nw,
|
||
inww[j+OLV_LIMP_N_DMIN_NW].ip,
|
||
inww[j+OLV_LIMP_N_DMIN_NW].lamb,
|
||
inww[j+OLV_LIMP_N_DMIN_NW].alpha);
|
||
}
|
||
}
|
||
fin:
|
||
free(pt_amb_prime_i);
|
||
free(pt_amb_prime_f);
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Dado un <20>mbito 'i_amb' (ya relativo al n_ini_amb) de un total de n_amb,
|
||
* de 'npt_amb' puntos almacenados en 'pt_amb',
|
||
* a<>ade al 'ob' las uniones del mismo con la carretera 'pt_nw'
|
||
* de los dos extremos si es lineal o uno si es puntual, indicado por 'KK'
|
||
*/
|
||
void Colv_limp_thr::add_uniones_obj(int i_amb, int n_amb, int ini_nw, int n_ini_ia_i, int n_ini_ia_f, int npt_amb,
|
||
int KK, Info_inw_dmin *inww_amb, Info_aso *ias, Cobgeo *ob)
|
||
{
|
||
int nptos;
|
||
double ptos[2][3];
|
||
int icla,iass,ia,inw,il_nw,indx_nw,il_amb,indx_amb,npt_nw;
|
||
double (*pt_amb)[3], (*pt_nw)[3];
|
||
|
||
nptos=2; //siempre a<>ade segmentos
|
||
ia=(*ob->objt)[i_amb].ia;
|
||
//////////////////////////
|
||
for(int k=0; k<KK; k++)
|
||
{
|
||
//apunta al nw m<>s cercano del <20>mbito actual que se acaba de encontrar
|
||
inw=olv_limp->inww_amb[i_amb+k*n_amb].inw;
|
||
if(inw<0 || inw>=(olv_limp->n_nw+ini_nw)) //por si acaso
|
||
continue;
|
||
il_nw = (*olv_limp->olv->olv_ob->objt)[inw].indx;
|
||
indx_nw=(*olv_limp->olv->olv_ob->lial)[il_nw].indx;
|
||
pt_nw = &(*olv_limp->olv->olv_ob->ptos)[indx_nw];
|
||
npt_nw = (*olv_limp->olv->olv_ob->lial)[il_nw].n;
|
||
|
||
//apunta el array de puntos al <20>mbito
|
||
il_amb=(*olv_limp->olv->olv_ob->objt)[i_amb].indx;
|
||
if(KK==OLV_AMB_LIN)//para tipo lineal, obtiene los primeros puntos de los dos extremos
|
||
{
|
||
npt_amb = (*olv_limp->olv->olv_ob->lial)[il_amb].n;
|
||
indx_amb=(*olv_limp->olv->olv_ob->lial)[il_amb].indx;
|
||
pt_amb = &(*olv_limp->olv->olv_ob->ptos)[indx_amb];
|
||
}
|
||
else if(KK==OLV_AMB_PUN) //para tipo puntual, es un <20>nico punto
|
||
{
|
||
npt_amb = 1;
|
||
indx_amb=il_amb;
|
||
pt_amb = &(*olv_limp->olv->olv_ob->ptos)[indx_amb];
|
||
}
|
||
|
||
//calcula donde est<73> ya la info de los segmentos
|
||
iass=ia+(1-k)*n_ini_ia_i+k*n_ini_ia_f;//sus flags indican que es segmento y si es final o no
|
||
|
||
//mira a ver si est<73> a la derecha el punto del <20>mbito
|
||
//k=0; solo un punto, k=1, el punto final, por si es lineal
|
||
if(Colv_geom::is_der((double (*)[][3])&pt_nw[inww_amb[i_amb+k*n_amb].ip], pt_amb[(npt_amb-1)*k]))
|
||
{
|
||
if((inw<ini_nw) || ((inw>=ini_nw)&& !(olv_limp->ias[(*ob->objt)[inw].ia].flgs & OLV_LIMP_FLG_CIRC_TF)))
|
||
{
|
||
icla=OLV_ICLA_LIN_NW_UD;
|
||
ias[iass].flgs |= OLV_LIMP_FLG_DER; //FT o both
|
||
}
|
||
else
|
||
icla=OLV_ICLA_LIN_NW_UI;
|
||
|
||
}
|
||
else
|
||
{
|
||
if((inw<ini_nw) || ((inw>=ini_nw)&& (olv_limp->ias[(*ob->objt)[inw].ia].flgs & OLV_LIMP_FLG_CIRC_TF)))
|
||
{
|
||
icla=OLV_ICLA_LIN_NW_UD;
|
||
ias[iass].flgs |= OLV_LIMP_FLG_DER; //tf
|
||
}
|
||
else
|
||
icla=OLV_ICLA_LIN_NW_UI;
|
||
}
|
||
|
||
if(inw<ini_nw)
|
||
ias[iass].flgs |= OLV_LIMP_FLG_SEG_AMB; //le pone en flag que es segmento que une <20>mbitos
|
||
|
||
//rellena el segmento
|
||
//el primer punto es el de la carretera m<>s cercano al <20>mbito
|
||
memcpy(ptos[0],inww_amb[i_amb+k*n_amb].pt,3*sizeof(double));
|
||
//el segundo punto es el propio del <20>mbito (inicio y final si es lineal)
|
||
memcpy(ptos[1],pt_amb[(npt_amb-1)*k],3*sizeof(double));
|
||
//lo a<>ade al obgeo
|
||
Colv_geom::pon_lin(nptos, (double (*)[][3])ptos, icla, iass, ob);
|
||
}
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Comprueba, si es <20>mbito, si la carretera est<73> muy lejos.
|
||
* Si es que s<>, o bien busca otro <20>mbito m<>s cercano, o lo deja vac<61>o
|
||
*/
|
||
void Colv_limp_thr::comprueba_amb_lejos(int i_amb, int n_amb, int npt_amb, double (*pt_amb)[3],
|
||
Info_inw_dmin *inww_amb, Info_aso *ias, Cobgeo *ob)
|
||
{
|
||
int i,k,h,npt_amb_aux, iaux,is_fin,npt_amb_min, lejos;
|
||
double dist_aux,dist_aux2,dmin,dmax;
|
||
double (*pt_amb_aux)[3],(*pt_amb_min)[3];
|
||
BOOL ya_ini;
|
||
BOOL modo_solouno;
|
||
BOOL modo_unolibre;
|
||
Info_inw_dmin *inwaux=NULL;
|
||
|
||
////////////////////////
|
||
dmax=OLV_DIST_MAX_AMB_NW;// m de separaci<63>n max entre peatonal y calle
|
||
///////////////////////
|
||
|
||
ya_ini=FALSE;
|
||
modo_unolibre=(olv_limp->ias[i_amb].flgs & OLV_LIMP_FLG_PEAT); //Solo para las peatonales permite dejar un lado sin apuntar
|
||
modo_solouno=FALSE;
|
||
lejos=0;
|
||
//Calcula la distancia del principio y del final a la nw
|
||
for(k=0;k<olv_limp->tipo_ambit;k++)
|
||
{
|
||
dist_aux2 = Colv_geom::dist_pto_pto((double (*)[3])pt_amb[(npt_amb-1)*k], (double (*)[3])inww_amb[i_amb+k*n_amb].pt);
|
||
|
||
if(dist_aux2<dmax)
|
||
continue;
|
||
|
||
//Distancia muy grande
|
||
//Recorre el resto de <20>mbitos buscando uno m<>s cercana
|
||
//Bucle por <20>mbito
|
||
dmin=MAYUSCULO;
|
||
for(i=0;i<olv_limp->n_amb; i++)
|
||
{
|
||
if(i==i_amb)
|
||
continue;
|
||
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
|
||
if(olv_limp->tipo_ambit==OLV_AMB_LIN)//para tipo lineal, obtiene los primeros puntos de los dos extremos
|
||
{
|
||
npt_amb_aux = (*ob->lial)[(*ob->objt)[i].indx].n;
|
||
pt_amb_aux = &(*ob->ptos)[(*ob->lial)[(*ob->objt)[i].indx].indx];
|
||
}
|
||
else if(olv_limp->tipo_ambit==OLV_AMB_PUN) //para tipo puntual, es un <20>nico punto
|
||
{
|
||
npt_amb_aux = 1;
|
||
pt_amb_aux = &(*ob->ptos)[(*ob->objt)[i].indx];
|
||
}
|
||
|
||
for(h=0;h<olv_limp->tipo_ambit;h++)
|
||
{
|
||
dist_aux=Colv_geom::dist_pto_pto((double (*)[3])pt_amb[(npt_amb-1)*k], (double (*)[3])pt_amb_aux[(npt_amb_aux-1)*h]);
|
||
if(dist_aux<dmin)
|
||
{
|
||
dmin=dist_aux;
|
||
iaux=i;
|
||
is_fin = h;
|
||
npt_amb_min= npt_amb_aux;
|
||
pt_amb_min = pt_amb_aux;
|
||
}
|
||
}
|
||
|
||
}
|
||
///////////////////
|
||
if((dmin<dist_aux2) && (!modo_solouno || (modo_solouno && !ya_ini)))
|
||
{
|
||
//ha encontrado uno cercano, lo apunta
|
||
//antes guarda la info anterior
|
||
inwaux = new Info_inw_dmin;
|
||
if(!inwaux)
|
||
break;
|
||
memcpy(inwaux,&inww_amb[i_amb+k*n_amb],sizeof(Info_inw_dmin));
|
||
inww_amb[i_amb+k*n_amb].inw_old = inwaux;
|
||
////////////////////////////////////////////
|
||
inww_amb[i_amb+k*n_amb].dmin = (float)dmin;
|
||
inww_amb[i_amb+k*n_amb].inw = iaux;
|
||
inww_amb[i_amb+k*n_amb].ip = (npt_amb_min-1)*is_fin;
|
||
inww_amb[i_amb+k*n_amb].lamb = 0;
|
||
memcpy(inww_amb[i_amb+k*n_amb].pt,pt_amb_min[inww_amb[i_amb+k*n_amb].ip],3*sizeof(double));
|
||
ya_ini=TRUE;
|
||
}
|
||
else if(!modo_solouno)
|
||
{
|
||
//si est<73> todav<61>a m<>s lejos, lo apunta a su principio
|
||
lejos|=1<<k;
|
||
}
|
||
}
|
||
if(!modo_unolibre)
|
||
return;
|
||
//comprueba si ha dejado alguna sin apuntar
|
||
if(lejos & (1<<0))
|
||
{
|
||
//si ha dejado los dos o s<>lo el primero
|
||
inww_amb[i_amb].inw = i_amb;
|
||
inww_amb[i_amb].ip =0;
|
||
memcpy(inww_amb[i_amb].pt,pt_amb[inww_amb[i_amb].ip],3*sizeof(double));
|
||
}
|
||
else if(lejos & (1<<1))
|
||
{
|
||
//si ha dejado s<>lo el segundo
|
||
inww_amb[i_amb+n_amb].inw = i_amb;
|
||
inww_amb[i_amb+n_amb].ip = npt_amb-1;
|
||
memcpy(inww_amb[i_amb+n_amb].pt,pt_amb[inww_amb[i_amb+n_amb].ip],3*sizeof(double));
|
||
}
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Comprueba si hay <20>mbitos a un lado que se supone deber<65>an estar al otro
|
||
*/
|
||
BOOL Colv_limp_thr::comprueba_latelaridad(Info_inw_dmin *inww_amb_aux )
|
||
{
|
||
int sent;
|
||
int id;
|
||
BOOL sigue_msg=TRUE;
|
||
|
||
if(olv_limp->res_circ<OLV_RES_RECOGER_SOLO_LADO_Y_GIROS)
|
||
return TRUE;
|
||
if(olv_limp->lateral<=0)
|
||
return TRUE;
|
||
|
||
char msg_[OLV_MAX_MSG_PROCE];
|
||
char nfile[MAX_PATH];
|
||
|
||
strcpy_s(nfile,MAX_PATH,olv->paths.path_data);
|
||
cambiaext(nfile,".shp",".dbf");
|
||
|
||
|
||
msg_[0]=0;
|
||
|
||
///////////////////LATELARIDAD
|
||
//recorres inww_amb_aux, que est<73> ordenado por inw
|
||
//solo en puntuales
|
||
//si res_cir<solo_lados_y_giros, pirate
|
||
//si calle un <20>nico sentido: ias[(*ob->objt)[inww_amb_aux[i].inw].ia].flgs & OLV_LIMP_FLG_CIRC_FT //fronto mismo sentido que lineal
|
||
//si lateral==derecha y amb a la izquierda, descarta
|
||
//amb -> ias[inww_amb_aux[<5B>].iamb].flgs & OLV_LIMP_FLG_DER
|
||
//o si lateral==izda y amb a la derecga, descarta
|
||
|
||
for(int ia=0; ia<olv_limp->n_amb; ia++)
|
||
{
|
||
sent=0;
|
||
if(olv_limp->ias[(*olv_limp->olv->olv_ob->objt)[inww_amb_aux[ia].inw].ia].flgs & OLV_LIMP_FLG_CIRC_FT )
|
||
sent++;
|
||
if(olv_limp->ias[(*olv_limp->olv->olv_ob->objt)[inww_amb_aux[ia].inw].ia].flgs & OLV_LIMP_FLG_CIRC_TF )
|
||
sent++;
|
||
if(sent!=1)
|
||
continue;
|
||
//comprueba lateralidad
|
||
if(olv_limp->ias[inww_amb_aux[ia].iamb+olv_limp->n_ini_amb_iai].flgs & OLV_LIMP_FLG_DER)//ambito a la derecha
|
||
{
|
||
if(olv_limp->lateral==1) //lateralidad derecha
|
||
continue;
|
||
}
|
||
else//ambito a la izquierda
|
||
{
|
||
if(olv_limp->lateral==2) //lateralidad izquierda
|
||
continue;
|
||
}
|
||
|
||
//lee el objectid del <20>mbito
|
||
olv_limp->olv->olv_sh->dame_col_int_dbf(nfile,inww_amb_aux[ia].iamb,inww_amb_aux[ia].iamb+1,&id,"OBJECTID",err_str,OLV_MAX_ERR);
|
||
wgeolog(LOG_TODO,"olv_limp_t","<EFBFBD>mbito %ld lateralidad err<72>nea",id);
|
||
|
||
//imprime
|
||
if(msg_[0]==0)
|
||
sprintf_s(msg_,OLV_MAX_MSG_PROCE,"Encontrados contenedores con lateralidad err<72>nea: ");
|
||
if(sigue_msg)
|
||
sprintf_s(msg_,OLV_MAX_MSG_PROCE,"%s %ld,",msg_,id);
|
||
if(sigue_msg && strlen(msg_)+10>=OLV_MAX_MSG_PROCE)
|
||
sigue_msg=FALSE;//para que no se pase del largo
|
||
|
||
}
|
||
if(!sigue_msg && ((strlen(msg_)+5)<OLV_MAX_MSG_PROCE))
|
||
sprintf_s(msg_,"%s %s",msg_,"y mas");
|
||
if(msg_[0]!=0)
|
||
{
|
||
pon_mi_msg(msg_);
|
||
Sleep (OLV_T_SLEEP_MSG);
|
||
}
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Realiza el <20>nalisis topol<6F>gico a la red navegable junto con los <20>mbitos y los segmentos
|
||
* que les unen, para incluir los mismos en la red navegable
|
||
*/
|
||
BOOL Colv_limp_thr::topo_nw()
|
||
{
|
||
int npt_nw, indx_nw,KK,npt_nw_aux;
|
||
int ia,inwil,inwi,iat,nt,iaso,ia_aux,icla;
|
||
BOOL log_debug, mal;
|
||
double (*pt_nw)[3];
|
||
Cobgeo *ob;
|
||
int MAXPTONW=0,maxptonw_aux=0;
|
||
double (*pt_nw_aux)[3]=NULL;
|
||
Info_inw_dmin *inww_amb_aux;
|
||
|
||
/////////////////
|
||
ob = olv_limp->olv->olv_ob;
|
||
KK=olv_limp->tipo_ambit;
|
||
npt_nw_aux=0;
|
||
log_debug=FALSE;
|
||
mal=FALSE;
|
||
inww_amb_aux=NULL;
|
||
/////////////////
|
||
wgeolog(LOG_TODO,"olv_limp_t","Generando topolog<6F>a con los segmentos de uni<6E>n");
|
||
pon_mi_progre(OLV_TAREA_TOPO_NW, 0);
|
||
pon_mi_msg("");
|
||
err_str[0]=0;
|
||
|
||
//inicializa la matriz auxiliar para ordenaci<63>n
|
||
inww_amb_aux = (Info_inw_dmin *)malloc(olv_limp->n_amb*KK*sizeof(Info_inw_dmin));
|
||
if(!inww_amb_aux)
|
||
{
|
||
pon_mi_msg("Error, sin memoria para matriz de <20>ndices\nde <20>mbitos a carreteras");
|
||
return FALSE;
|
||
}
|
||
memcpy(inww_amb_aux,olv_limp->inww_amb,olv_limp->n_amb*KK*sizeof(Info_inw_dmin));
|
||
|
||
//////////////////////////////////////////////////
|
||
//ordena la matriz de info de inw, va de punto m<>s cercano
|
||
//al inicio del inw inicial al m<>s lejano, y aumentando en inw
|
||
//dentro del mismo inw, ordena por ip y a igual ip, por lamb
|
||
qsort(inww_amb_aux,olv_limp->n_amb*KK,sizeof(Info_inw_dmin),Colv_limp_thr::compara_inww_amb);
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Generando topolog<6F>a: Matriz de info de inw dmin ordenada:");
|
||
if(log_debug)
|
||
{
|
||
for(ia=0;ia<olv_limp->n_amb*KK;ia++)
|
||
wgeolog(LOG_TODO,"olv_limp_t","ia %02d, inw %03d, ip %ld, lamb %lf",ia,
|
||
inww_amb_aux[ia].inw-olv_limp->n_ini_nw,inww_amb_aux[ia].ip,inww_amb_aux[ia].lamb);
|
||
}
|
||
|
||
//////////////////////
|
||
//mira a ver si tiene que replicar calles de doble sentido
|
||
if(!replica_doble_sent(inww_amb_aux, &olv_limp->ias, ob))
|
||
{
|
||
pon_mi_msg("Errores al replicar doble sentido");
|
||
return FALSE;
|
||
}
|
||
|
||
////////////////////
|
||
if(KK<2)//en recogida, se mira si hay que comprobar la lateralidad
|
||
comprueba_latelaridad(inww_amb_aux);
|
||
|
||
//hay que volver a ordenar
|
||
qsort(inww_amb_aux,olv_limp->n_amb*KK,sizeof(Info_inw_dmin),Colv_limp_thr::compara_inww_amb);
|
||
///////////////
|
||
|
||
////////////////////////////////////////////////////////////////////////
|
||
//Bucle por cada item del array inww_amb, para ir troceando las carreteras que cortan
|
||
ia=0;
|
||
while(ia<olv_limp->n_amb*KK && !pirate)
|
||
{
|
||
|
||
///////////////////////////////
|
||
ia_aux=ia;
|
||
inwi=inww_amb_aux[ia_aux].inw;
|
||
|
||
if(olv_limp->ias[inww_amb_aux[ia_aux].iamb].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
{
|
||
ia++;
|
||
continue;
|
||
}
|
||
if(inwi<olv_limp->n_ini_nw) //si es menor es que se ha reapuntado a otro <20>mbito por ser peatonal lejana
|
||
{
|
||
ia++;
|
||
continue;
|
||
}
|
||
inwil=(*ob->objt)[inwi].indx;
|
||
npt_nw = (*ob->lial)[inwil].n;
|
||
indx_nw=(*ob->lial)[inwil].indx;
|
||
pt_nw = &(*ob->ptos)[indx_nw];
|
||
iaso=(*ob->objt)[inwi].ia;
|
||
///////////////////////////////
|
||
if(npt_nw>MAXPTONW)
|
||
{
|
||
pt_nw_aux = (double (*)[3])realloc(pt_nw_aux,3*npt_nw*sizeof(double));
|
||
if(!pt_nw_aux)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Sin memoria en topo_nw");
|
||
mal=TRUE;
|
||
break;
|
||
}
|
||
MAXPTONW=npt_nw;
|
||
}
|
||
memset(pt_nw_aux,0,3*MAXPTONW*sizeof(double));
|
||
///////////////////////////////
|
||
|
||
iat=ia;
|
||
nt=1;
|
||
//primero cuenta los tramos de esa inwi, nt
|
||
while((ia<olv_limp->n_amb*KK) && (inww_amb_aux[ia].inw==inwi))
|
||
{
|
||
ia++;
|
||
nt++;
|
||
}
|
||
|
||
if(nt<2) //tiene que haber siempre m<>nimo 2 tramos, ya que en todos los inw de este array hay alg<6C>n <20>mbito asignado
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Gen. Topo. Inw %03d mal, se obtienen %ld tramos, no suficientes",inwi-olv_limp->n_ini_nw,nt);
|
||
mal=TRUE;
|
||
ia++;
|
||
continue;
|
||
}
|
||
|
||
if(log_debug)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Gen. Topo. Inw %03d de %ld puntos se parte en %ld tramos",inwi-olv_limp->n_ini_nw,npt_nw,nt);
|
||
|
||
//ya se saben los tramos, se va troceando la carretera
|
||
ia=iat;
|
||
iat=0;
|
||
inww_amb_aux[ia].flgs=nt;
|
||
while(iat<nt)
|
||
{
|
||
/////////////////////////////////////////////////
|
||
memset(pt_nw_aux,0,3*MAXPTONW*sizeof(double));
|
||
//recorre la carretera inwi y la parte en trozos acorde a los <20>mbitos
|
||
if(iat==0)//hace el primer tramo, del extremo inicial al primer <20>mbito
|
||
{
|
||
npt_nw_aux=inww_amb_aux[ia].ip+2;
|
||
if(npt_nw_aux>MAXPTONW)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Gen. Topo. Inw %03d mal, se excede m<>ximo de puntos",inwi-olv_limp->n_ini_nw);
|
||
mal=TRUE;
|
||
ia++;
|
||
iat++;
|
||
continue;
|
||
}
|
||
if(memcmp(&pt_nw[0],&inww_amb_aux[ia].pt,3*1*sizeof(double))==0)
|
||
{
|
||
//no se hace tramo porque est<73> unido por el extremo
|
||
inww_amb_aux[ia].flgs--;
|
||
iat++;
|
||
ia++;
|
||
if(nt==2)
|
||
{
|
||
iat++;//si solo eran dos tramos, pasa
|
||
ia++;
|
||
}
|
||
continue;
|
||
}
|
||
//los primeros puntos son los de la carretera hasta el <20>mbito
|
||
memcpy(&pt_nw_aux[0],&pt_nw[0],3*(npt_nw_aux-1)*sizeof(double));
|
||
//el punto final es el del <20>mbito
|
||
memcpy(&pt_nw_aux[npt_nw_aux-1],&inww_amb_aux[ia].pt,3*1*sizeof(double));
|
||
|
||
if(log_debug)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Gen. Topo. Inw %03d, tramo inicial %ld, %ld puntos, ip %ld, ia %ld",inwi-olv_limp->n_ini_nw,iat,
|
||
npt_nw_aux,inww_amb_aux[ia].ip,ia);
|
||
}
|
||
else if(iat==(nt-1))//hace el <20>ltimo tramo, del <20>ltimo <20>mbito al extremo final
|
||
{
|
||
npt_nw_aux=npt_nw-inww_amb_aux[ia-1].ip;
|
||
if(npt_nw_aux>MAXPTONW)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Gen. Topo. Inw %03d mal, se excede m<>ximo de puntos",inwi-olv_limp->n_ini_nw);
|
||
mal=TRUE;
|
||
ia++;
|
||
iat++;
|
||
continue;
|
||
}
|
||
if(memcmp(&pt_nw[npt_nw-1],&inww_amb_aux[ia-1].pt,3*1*sizeof(double))==0)
|
||
{
|
||
//no se hace tramo porque est<73> unido por el extremo
|
||
inww_amb_aux[ia-1].flgs--;
|
||
iat++;
|
||
ia++;
|
||
continue;
|
||
}
|
||
//el primer punto es el del <20>mbito anterior
|
||
memcpy(&pt_nw_aux[0],&inww_amb_aux[ia-1].pt,3*1*sizeof(double));
|
||
//los siguientes puntos son los de la carretera hasta el final
|
||
memcpy(&pt_nw_aux[1],&pt_nw[inww_amb_aux[ia-1].ip+1],3*(npt_nw_aux-1)*sizeof(double));
|
||
|
||
if(log_debug)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Gen. Topo. Inw %03d, tramo final %ld, %ld puntos, ip %ld, ia %ld",inwi-olv_limp->n_ini_nw,iat,
|
||
npt_nw_aux,inww_amb_aux[ia-1].ip+1,ia-1);
|
||
}
|
||
else //hace los tramos de enmedio
|
||
{
|
||
npt_nw_aux=inww_amb_aux[ia].ip-inww_amb_aux[ia-1].ip+2;
|
||
if(npt_nw_aux>MAXPTONW)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Gen. Topo. Inw %03d mal, se excede m<>ximo de puntos",inwi-olv_limp->n_ini_nw);
|
||
mal=TRUE;
|
||
ia++;
|
||
iat++;
|
||
continue;
|
||
}
|
||
//el primer punto es el del primer <20>mbito
|
||
memcpy(&pt_nw_aux[0],&inww_amb_aux[ia-1].pt,3*1*sizeof(double));
|
||
//los siguientes puntos son los de la carretera
|
||
memcpy(&pt_nw_aux[1],&pt_nw[inww_amb_aux[ia-1].ip+1],3*(npt_nw_aux-2)*sizeof(double));
|
||
//el <20>ltimo punto es el del <20>mbito siguiente
|
||
memcpy(&pt_nw_aux[npt_nw_aux-1],&inww_amb_aux[ia].pt,3*1*sizeof(double));
|
||
|
||
if(log_debug)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Gen. Topo. Inw %03d, tramo medio %ld, %ld puntos, ip %ld, ia %ld",inwi-olv_limp->n_ini_nw,iat,
|
||
npt_nw_aux,inww_amb_aux[ia].ip,ia);
|
||
}
|
||
|
||
iat++;
|
||
ia++;
|
||
//a<>ade el tramo al ob, le pone el <20>ndice a la misma info asociada que la carretera original
|
||
if(olv_limp->ias[iaso].flgs & OLV_LIMP_FLG_AMB)
|
||
icla=OLV_ICLA_LIN_AMB;//por si est<73> troceando <20>mbito peatonal
|
||
else if(olv_limp->ias[iaso].flgs & OLV_LIMP_FLG_NW_REP)
|
||
icla=OLV_ICLA_LIN_NW_REP;
|
||
else
|
||
icla=OLV_ICLA_LIN_NW;
|
||
Colv_geom::pon_lin(npt_nw_aux, (double (*)[][3])pt_nw_aux, icla, iaso, ob);
|
||
|
||
//reapunta al inw por si ha habido reallocs en pon_obj
|
||
inwi=inww_amb_aux[ia_aux].inw;
|
||
inwil=(*ob->objt)[inwi].indx;
|
||
npt_nw = (*ob->lial)[inwil].n;
|
||
indx_nw=(*ob->lial)[inwil].indx;
|
||
pt_nw = &(*ob->ptos)[indx_nw];
|
||
iaso=(*ob->objt)[inwi].ia;
|
||
}
|
||
ia--; //decrementa para cuando se ha pasado
|
||
|
||
if((ia%100==0) || (ia==(olv_limp->n_amb*KK)))
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Generando topolog<6F>a, %ld de %ld",ia,olv_limp->n_amb*KK);
|
||
//avisa de progreso
|
||
pon_mi_progre(OLV_TAREA_TOPO_NW, (int) ((OliviaDef::GeneralDef::ProgrMax*
|
||
1.0*(ia)/(olv_limp->n_amb*KK))));
|
||
}
|
||
}
|
||
if(mal)
|
||
{
|
||
pon_mi_msg("Errores en el an<61>lisis topol<6F>gico");
|
||
}
|
||
if(mal || pirate)
|
||
{
|
||
if(inww_amb_aux)
|
||
free(inww_amb_aux);
|
||
return FALSE;
|
||
}
|
||
|
||
//borra los nw que ha dividido en tramos
|
||
//que son los que estaban asignados a los <20>mbitos
|
||
//recorriendo el array de infos para borrar solo dichos inwi
|
||
ia=0;
|
||
int nnul=0;
|
||
while(ia<olv_limp->n_amb*KK)
|
||
{
|
||
///////////////////////////////
|
||
inwi=inww_amb_aux[ia].inw;
|
||
if(olv_limp->ias[inww_amb_aux[ia].iamb].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
{
|
||
ia++;
|
||
continue;
|
||
}
|
||
iaso=(*ob->objt)[inwi].ia;
|
||
if((inwi<0) || (inwi<olv_limp->n_ini_nw) || (inww_amb_aux[ia].flgs<2))
|
||
{
|
||
ia++;
|
||
continue;
|
||
}
|
||
|
||
(*ob->objt)[inwi].flags[1] = (*ob->objt)[inwi].flags[1] | B1_OBJ_NULO;
|
||
nnul++;
|
||
//avanza hasta el siguiente inwi
|
||
while((ia<olv_limp->n_amb*KK) && (inww_amb_aux[ia].inw==inwi))
|
||
{
|
||
ia++;
|
||
}
|
||
}
|
||
|
||
ob->limpia();
|
||
ia=0;
|
||
//cuenta cu<63>ntas entidades lineales se han quedado en la red
|
||
for(inwi=0;inwi<olv_limp->olv->olv_ob->vect.nobj;inwi++)
|
||
{
|
||
if((*ob->objt)[inwi].tipo==OBJ_LINEAL)
|
||
ia++;
|
||
|
||
}
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Generada topolog<6F>a, %ld entidades lineales en la red",ia);
|
||
|
||
if(inww_amb_aux)
|
||
free(inww_amb_aux);
|
||
|
||
if(!pon_nodos_planta(olv_limp->coor_instal))
|
||
{
|
||
pon_mi_msg("Error, No se ha podido incluir planta en red");
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Compara las estructuras inww_amb. Las ordena por inw, a mismo inw por ip, y a mismo ip por lamb
|
||
*/
|
||
int Colv_limp_thr::compara_inww_amb (const void * a, const void * b)
|
||
{
|
||
//si a<b devuelve negativo, si son iguales 0, y si es mayor positivo
|
||
int r;
|
||
double dd;
|
||
//es menor el de menor inw
|
||
r=((Info_inw_dmin*) a)->inw - ((Info_inw_dmin*) b)->inw;
|
||
if(r==0)
|
||
{
|
||
//a mismo inw, es menor el de menor ip
|
||
r=((Info_inw_dmin*) a)->ip - ((Info_inw_dmin*) b)->ip;
|
||
if(r==0)
|
||
{
|
||
//a mismo ip, es menor el de menor lamb
|
||
dd=((Info_inw_dmin*) a)->lamb - ((Info_inw_dmin*) b)->lamb;
|
||
if(dd<0)
|
||
r=-1;
|
||
else if(dd>0)
|
||
r=1;
|
||
else
|
||
r=0;
|
||
}
|
||
}
|
||
|
||
return r;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* A<>ade a la red de conjunciones en qu<71> conjunci<63>n est<73> la planta y la instalaci<63>n
|
||
*/
|
||
BOOL Colv_limp_thr::pon_nodos_planta(double pt[3])
|
||
{
|
||
int il,npts,indx,i,npts_aux,no;
|
||
short ip;
|
||
double (*ptos)[3],pt_proy_nw[3];
|
||
Cobgeo *ob;
|
||
double d, dmin;
|
||
float lamb;
|
||
BOOL mal =FALSE;
|
||
int MAXPTONW;
|
||
double (*ptos_aux)[3]=NULL;
|
||
Info_inw_dmin inww;
|
||
|
||
ob=olv_limp->olv->olv_ob;
|
||
no=ob->vect.nobj;
|
||
|
||
if((pt[0]==0) && (pt[1]==0))
|
||
return TRUE;//no hay instalaci<63>n, no se pone
|
||
|
||
////////////////////////////////////////////////////////////////////////
|
||
//Bucle por cada carretera de la nw
|
||
|
||
dmin=MAYUSCULO;
|
||
for(i=0; i<no && !pirate; i++)
|
||
{
|
||
if((*ob->objt)[i].tipo != OBJ_LINEAL)
|
||
continue;
|
||
if(olv_limp->ias[(*ob->objt)[i].ia].flgs & OLV_LIMP_FLG_NO_NW)
|
||
continue;
|
||
|
||
il=(*ob->objt)[i].indx;
|
||
npts = (*ob->lial)[il].n;
|
||
indx=(*ob->lial)[il].indx;
|
||
ptos = &(*ob->ptos)[indx];
|
||
|
||
//calcula la distancia al punto de la instalaci<63>n
|
||
d = Colv_geom::dist_pto_poli((double (*)[3])pt,(double (*)[][3])ptos,npts,&ip, &lamb);
|
||
if(d<dmin)
|
||
{
|
||
dmin=d;
|
||
inww.dmin=(float)d;
|
||
inww.inw=i;
|
||
inww.ip=ip;
|
||
inww.lamb=lamb;
|
||
}
|
||
}
|
||
if(dmin>=MAYUSCULO)
|
||
return FALSE;
|
||
|
||
/////////////////////////////////////////////////
|
||
//ya tiene el inw de la distancia m<>nima
|
||
|
||
//apunta al que ha encontrado m<>nimo
|
||
il=(*ob->objt)[inww.inw].indx;
|
||
npts = (*ob->lial)[il].n;
|
||
indx=(*ob->lial)[il].indx;
|
||
ptos = &(*ob->ptos)[indx];
|
||
|
||
//calcula el punto del inw donde se da el m<>nimo
|
||
pt_proy_nw[2]=0;
|
||
pt_proy_nw[0]=ptos[inww.ip][0]+(ptos[inww.ip+1][0]-ptos[inww.ip][0])*inww.lamb;
|
||
pt_proy_nw[1]=ptos[inww.ip][1]+(ptos[inww.ip+1][1]-ptos[inww.ip][1])*inww.lamb;
|
||
|
||
//sustituye las coords por el punto proyectado en la nw
|
||
memcpy(pt,pt_proy_nw,3*sizeof(double));
|
||
|
||
if(!Colv_geom::pon_pto((double (*)[3])pt_proy_nw, 10001, -1, ob))
|
||
return FALSE;
|
||
|
||
//hace dos tramos
|
||
//apunta al que ha encontrado m<>nimo
|
||
il=(*ob->objt)[inww.inw].indx;
|
||
indx=(*ob->lial)[il].indx;
|
||
ptos = &(*ob->ptos)[indx];
|
||
//primer tramo
|
||
npts_aux=inww.ip+2;
|
||
MAXPTONW = max(npts_aux,npts-inww.ip);
|
||
ptos_aux = (double (*)[3])malloc(3*MAXPTONW*sizeof(double));
|
||
if(!ptos_aux)
|
||
return FALSE;
|
||
memset(ptos_aux,0,3*MAXPTONW*sizeof(double));
|
||
//los primeros puntos son los de la carretera hasta el <20>mbito
|
||
memcpy(ptos_aux[0],ptos[0],3*(npts_aux-1)*sizeof(double));
|
||
//el punto final es el del <20>mbito
|
||
memcpy(ptos_aux[npts_aux-1],pt_proy_nw,3*1*sizeof(double));
|
||
|
||
if(!Colv_geom::pon_lin(npts_aux, (double (*)[][3])ptos_aux, OLV_ICLA_LIN_NW_REP, (*ob->objt)[inww.inw].ia, ob))
|
||
{
|
||
free(ptos_aux);
|
||
return FALSE;
|
||
}
|
||
|
||
////////////////////////////////
|
||
//segundo tramo
|
||
//apunta al que ha encontrado m<>nimo
|
||
il=(*ob->objt)[inww.inw].indx;
|
||
indx=(*ob->lial)[il].indx;
|
||
ptos = &(*ob->ptos)[indx];
|
||
///
|
||
memset(ptos_aux,0,3*MAXPTONW*sizeof(double));
|
||
npts_aux=npts-inww.ip;
|
||
//el primer punto es el del <20>mbito anterior
|
||
memcpy(ptos_aux[0],pt_proy_nw,3*1*sizeof(double));
|
||
//los siguientes puntos son los de la carretera hasta el final
|
||
memcpy(ptos_aux[1],ptos[inww.ip+1],3*(npts_aux-1)*sizeof(double));
|
||
|
||
if(!Colv_geom::pon_lin(npts_aux, (double (*)[][3])ptos_aux, OLV_ICLA_LIN_NW_REP, (*ob->objt)[inww.inw].ia, ob))
|
||
{
|
||
free(ptos_aux);
|
||
return FALSE;
|
||
}
|
||
|
||
(*ob->objt)[inww.inw].flags[1] = (*ob->objt)[inww.inw].flags[1] | B1_OBJ_NULO;
|
||
if(!ob->limpia())
|
||
{
|
||
free(ptos_aux);
|
||
return FALSE;
|
||
}
|
||
|
||
free(ptos_aux);
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Apunta en qu<71> nodos est<73> la planta y la instalaci<63>n
|
||
*/
|
||
BOOL Colv_limp_thr::busca_conjs_planta(Info_conjs *conjs, double pt[3], int *nod)
|
||
{
|
||
int ic;
|
||
Cobgeo *ob;
|
||
BOOL mal=FALSE;
|
||
|
||
ob=olv_limp->olv->olv_ob;
|
||
|
||
if((pt[0]==0) && (pt[1]==0))
|
||
return TRUE;//no hay instalaci<63>n, no se pone
|
||
|
||
//busca ese punto en la lista de conjunciones
|
||
//busca la conjunci<63>n en la lista
|
||
//lo hace para los dos extremos de la l<>nea
|
||
for(ic=0; ic<conjs->n;ic++)
|
||
{
|
||
if((Colv_geom::pto_equals(pt,conjs->coor[ic])))
|
||
break;
|
||
}
|
||
if(ic==conjs->n)
|
||
{
|
||
return FALSE;
|
||
}
|
||
*nod=ic;
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Lanza sub-threads
|
||
*/
|
||
void Colv_limp_thr::lanza_subthrs(int tar, int nthr_def/*=-1*/)
|
||
{
|
||
char nomb[32];
|
||
Param_olv_limp_thr pp;
|
||
int nn;
|
||
if((nthr_def>0) && (nthr_def<n_subthr))
|
||
nn=nthr_def;
|
||
else
|
||
nn=n_subthr;
|
||
//Arranca los subthreads
|
||
for(int i=0;i<nn;i++)
|
||
{
|
||
if(!subthrs[i])
|
||
subthrs[i]=new Colv_limp_thr(olv_limp);
|
||
sprintf_s(nomb,32,"limp_subth_%ld",i);
|
||
pp.id_e=i;
|
||
subthrs[i]->thr_padre=this;
|
||
subthrs[i]->n_subthr = nn;
|
||
subthrs[i]->prog_subthr = 0;
|
||
subthrs[i]->pirate=FALSE;
|
||
subthrs[i]->inicia(OLV_MILIS_COLA,&cola_proc,-1,nomb);
|
||
subthrs[i]->encola(tar,&pp,FALSE);
|
||
}
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Para sub-threads
|
||
*/
|
||
void Colv_limp_thr::para_subthrs()
|
||
{
|
||
//Para los subthreads
|
||
for(int i=0;i<n_subthr;i++)
|
||
{
|
||
if(subthrs[i])
|
||
{
|
||
subthrs[i]->pirate=pirate;
|
||
subthrs[i]->termina();
|
||
}
|
||
}
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la matriz de costes entre todas las conjunciones
|
||
*/
|
||
BOOL Colv_limp_thr::calcula_cost_conj()
|
||
{
|
||
int i, j;
|
||
////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Rellenando matriz de costes entre conjunciones");
|
||
pon_mi_progre(OLV_TAREA_COST_AMB, 0);
|
||
pon_mi_msg("");
|
||
err_str[0]=0;
|
||
|
||
//calcula el n<>mero de nodos de la red
|
||
//que es el n<>mero de intersecciones de la red navegable, incluyendo el n<>mero de <20>mbitos x2 porque
|
||
//aparecen el punto del <20>mbito y el proyectado en la carretera m<>s pr<70>xima (y x2 si son lineales)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Comienza a buscar conjunciones");
|
||
if(!busca_conjs(olv_limp->tipo_ambit, olv_limp->ias, olv_limp->olv->olv_ob,&olv_limp->conjs))
|
||
{
|
||
pon_mi_msg("Error, sin memoria para matriz de conjunciones en busca_conjs");
|
||
return FALSE;
|
||
}
|
||
|
||
//pide memoria para el array de distancias entre conjunciones
|
||
///mira a ver con cu<63>ntos nvect puede calcular la matriz
|
||
CoptiMemo oo;
|
||
int nvect = oo.calc_nvect_master(olv_limp->conjs.n);
|
||
if(nvect<0)
|
||
{
|
||
pon_mi_msg("Error, sin memoria para matriz de conjunciones en c<>lculo de nvect");
|
||
return FALSE;
|
||
}
|
||
wgeolog(LOG_TODO,"olv_limp_t","Se va a ejecutar con nvect=%ld de %ld",nvect,olv_limp->conjs.n);
|
||
olv_limp->cost_conj.clear();
|
||
olv_limp->tip_conj.clear();
|
||
olv_limp->cost_conj.inicializa(olv_limp->conjs.n,n_subthr,nvect);
|
||
olv_limp->tip_conj.inicializa(olv_limp->conjs.n,n_subthr,nvect);
|
||
|
||
//revisa las calles cortadas, y les pone que son tipo doble sentido a sus replicas
|
||
for(i=0;i<olv_limp->conjs.n;i++)
|
||
{
|
||
if(olv_limp->conjs.inc[i].n==1)
|
||
{
|
||
//busca las que tienen esa calle y les cambia el flag
|
||
for(j=0;j<olv_limp->olv->olv_ob->vect.nobj;j++)
|
||
{
|
||
if(((*olv_limp->olv->olv_ob->objt)[j].tipo == OBJ_LINEAL) &&
|
||
(!(olv_limp->ias[(*olv_limp->olv->olv_ob->objt)[j].ia].flgs & OLV_LIMP_FLG_NO_NW)) &&
|
||
(olv_limp->ias[(*olv_limp->olv->olv_ob->objt)[j].ia].ishp==olv_limp->conjs.inc[i].inw0) &&
|
||
(olv_limp->ias[(*olv_limp->olv->olv_ob->objt)[j].ia].flgs & (OLV_LIMP_FLG_CIRC_FT | OLV_LIMP_FLG_CIRC_TF)))
|
||
olv_limp->ias[(*olv_limp->olv->olv_ob->objt)[j].ia].flgs &= ~OLV_LIMP_FLG_CIRC_FT & ~OLV_LIMP_FLG_CIRC_TF;
|
||
}
|
||
}
|
||
}
|
||
|
||
//lanza los threads
|
||
lanza_subthrs(OLV_LIMP_EV_COST_CONJ_SUB);
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Comprueba la memoria para las conjunciones
|
||
*/
|
||
BOOL Colv_limp_thr::add_conj(Info_conjs *conjs, double coor[3])
|
||
{
|
||
if(!cuida_memo_conj(conjs))
|
||
return FALSE;
|
||
|
||
memcpy(conjs->coor[conjs->n],coor,3*sizeof(double));
|
||
conjs->n++;
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Comprueba la memoria para las conjunciones
|
||
*/
|
||
BOOL Colv_limp_thr::cuida_memo_conj(Info_conjs *conjs)
|
||
{
|
||
double (*coor2)[3];
|
||
Info_conjs_inw *inc2;
|
||
|
||
if((conjs->n+1)>conjs->m)
|
||
{
|
||
conjs->m+=OLV_LIMP_M_CONJ;
|
||
|
||
//primero las coordenadas
|
||
coor2 = (double (*)[3])realloc(conjs->coor,conjs->m*3*sizeof(double));
|
||
if(!coor2)
|
||
{
|
||
free(conjs->coor);
|
||
return FALSE;
|
||
}
|
||
conjs->coor=coor2;
|
||
memset(&conjs->coor[conjs->m-OLV_LIMP_M_CONJ],0,OLV_LIMP_M_CONJ*3*sizeof(double));
|
||
|
||
//primero las incidencias
|
||
inc2 = (Info_conjs_inw *)realloc(conjs->inc,conjs->m*sizeof(Info_conjs_inw));
|
||
if(!inc2)
|
||
{
|
||
free(conjs->inc);
|
||
return FALSE;
|
||
}
|
||
conjs->inc=inc2;
|
||
//inicializa
|
||
for(int i=conjs->m-OLV_LIMP_M_CONJ;i<conjs->m;i++)
|
||
{
|
||
conjs->inc[i].n=conjs->inc[i].inw0=-1;
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la matriz de conjunciones entre la red navegable.
|
||
* Que est<73> almacenada en 'ob', y la info de las conjunciones se rellena en 'conjs'
|
||
*/
|
||
BOOL Colv_limp_thr::busca_conjs(int KK, Info_aso *ias, Cobgeo *ob, Info_conjs *conjs)
|
||
{
|
||
int i,il,npt,ic,k,ics[2],io,nn;
|
||
double (*ptos)[3];
|
||
BOOL mal=FALSE;
|
||
BOOL log_debug=FALSE;
|
||
BOOL modo_ejes=FALSE;
|
||
|
||
if(!ob || !conjs)
|
||
return FALSE;
|
||
|
||
if((olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoMh_eje) ||
|
||
(olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoM2h_eje))
|
||
modo_ejes=TRUE;
|
||
|
||
//bucle por cada entidad de la carto
|
||
//si es modos de <20>mbitos normales, lineales o puntuales, se va de inicio a final del obg, en orden
|
||
//y se van buscando las conjs de los <20>mbitos, los nw, y los segmentos
|
||
//si es un modo en el que los <20>mbitos son ejes, se va al rev<65>s, a<>adiendo primero las conjunciones de
|
||
//los segmentos y la nw, y por <20>ltimo las de los ejes. Se hace para que en el siguiente paso, al buscar,
|
||
//aparezca primero la conjunci<63>n de la carretera, porque es de la que no se tiene constancia ic_ini/ic_fin
|
||
io=0;
|
||
if(modo_ejes)
|
||
i=ob->vect.nobj-1;
|
||
else
|
||
i=0;
|
||
while((io<ob->vect.nobj) && !mal && !pirate)
|
||
{
|
||
if(((*ob->objt)[i].tipo == OBJ_LINEAL) && !(((ias[(*ob->objt)[i].ia].flgs & OLV_LIMP_FLG_PEAT_SEG) ||
|
||
(ias[(*ob->objt)[i].ia].flgs & OLV_LIMP_FLG_EJE_SEG))))
|
||
{
|
||
//almacena las coordenadas ordenadas en el array de conjs si no est<73>n ya
|
||
il=(*ob->objt)[i].indx;
|
||
npt = (*ob->lial)[il].n;
|
||
ptos = &(*ob->ptos)[(*ob->lial)[il].indx];
|
||
|
||
for(k=0; k<2; k++)
|
||
{
|
||
if((ias[(*ob->objt)[i].ia].flgs & OLV_LIMP_FLG_PEAT_REP) ||
|
||
(ias[(*ob->objt)[i].ia].flgs & OLV_LIMP_FLG_EJE) )
|
||
{
|
||
//en estos casos replica las conjunciones
|
||
//llega la segunda vez
|
||
ic=conjs->n;
|
||
if(!add_conj(conjs,ptos[k*(npt-1)]))
|
||
{
|
||
mal=TRUE;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//busca la conjunci<63>n en la lista
|
||
//lo hace para los dos extremos de la l<>nea
|
||
for(ic=0; ic<conjs->n;ic++)
|
||
{
|
||
if((Colv_geom::pto_equals(ptos[k*(npt-1)],conjs->coor[ic])))
|
||
break;
|
||
}
|
||
if(ic==conjs->n)
|
||
{
|
||
//no lo ha encontrado, lo a<>ade
|
||
if(!add_conj(conjs,ptos[k*(npt-1)]))
|
||
{
|
||
mal=TRUE;
|
||
break;
|
||
}
|
||
}
|
||
if(log_debug)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Conjunci<EFBFBD>n %04ld, io %04d, x %lf y %lf",ic,
|
||
i,ptos[k*(npt-1)][0],ptos[k*(npt-1)][1]);
|
||
}
|
||
ics[k]=ic;
|
||
|
||
//si es carretera, le pone a la conjunci<63>n que llega una al menos
|
||
if(!(ias[(*ob->objt)[i].ia].flgs & OLV_LIMP_FLG_NO_NW))
|
||
{
|
||
if(conjs->inc[ic].n<0)
|
||
{
|
||
conjs->inc[ic].n=1;
|
||
conjs->inc[ic].inw0=ias[(*ob->objt)[i].ia].ishp;
|
||
}
|
||
else
|
||
conjs->inc[ic].n++;
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////
|
||
//////aprovecha para apuntar el <20>ndice de la conjunci<63>n de sus extremos
|
||
//////en todos los casos excepto en carreteras
|
||
//tampoco lo hace para los segmentos de uni<6E>n entre <20>mbitos
|
||
if((ias[(*ob->objt)[i].ia].flgs &
|
||
(OLV_LIMP_FLG_AMB | OLV_LIMP_FLG_SEG_PUN | OLV_LIMP_FLG_SEG_LIN | OLV_LIMP_FLG_PEAT_REP)) /*&&
|
||
!(ias[(*ob->objt)[i].ia].flgs & OLV_LIMP_FLG_SEG_AMB)*/)
|
||
{
|
||
ias[(*ob->objt)[i].ia].ic_ini=ics[0];
|
||
ias[(*ob->objt)[i].ia].ic_fin=ics[1];
|
||
if(ias[(*ob->objt)[i].ia].flgs & OLV_LIMP_FLG_SEG_PUN )
|
||
{
|
||
//si es segmento de <20>mbito puntual, el extremo final del segmento corresponde al <20>mbito puntual
|
||
ias[ias[(*ob->objt)[i].ia].ishp].ic_fin=ias[ias[(*ob->objt)[i].ia].ishp].ic_ini=ics[1];
|
||
}
|
||
if(ias[(*ob->objt)[i].ia].flgs & OLV_LIMP_FLG_PEAT_REP)
|
||
{
|
||
nn=olv_limp->n_peat;
|
||
//si es segmento de <20>mbito replicado, se ponen sus extremos a mano desde el <20>mbito replicado
|
||
ias[(*ob->objt)[i].ia+nn].ic_ini=ias[ias[(*ob->objt)[i].ia].info0].ic_ini;
|
||
ias[(*ob->objt)[i].ia+nn].ic_fin=ics[0];
|
||
ias[(*ob->objt)[i].ia+2*nn].ic_ini=ias[ias[(*ob->objt)[i].ia].info0].ic_fin;
|
||
ias[(*ob->objt)[i].ia+2*nn].ic_fin=ics[1];
|
||
}
|
||
}
|
||
if(log_debug)
|
||
wgeolog(LOG_TODO,"olv_limp_t","<EFBFBD>mb %03ld, conj %ld %ld",i,ics[0],ics[1]);
|
||
}
|
||
|
||
if(modo_ejes)
|
||
i--;
|
||
else
|
||
i++;
|
||
io++;
|
||
|
||
///////////////////////////////////////////////////////////////////////
|
||
|
||
}
|
||
if(io<ob->vect.nobj || mal)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Error, sin memoria para matriz de conjunciones en busca_conjs");
|
||
return FALSE;
|
||
}
|
||
|
||
if(pirate)
|
||
return FALSE;
|
||
|
||
if(modo_ejes)
|
||
{
|
||
for(io=0;io<ob->vect.nobj;io++)
|
||
{
|
||
if(((*ob->objt)[io].tipo != OBJ_LINEAL) || ((*ob->objt)[io].ia<0))
|
||
continue;
|
||
if(!(ias[(*ob->objt)[io].ia].flgs & OLV_LIMP_FLG_EJE_SEG))
|
||
continue;
|
||
|
||
i=ias[(*ob->objt)[io].ia].ishp;
|
||
il=(*ob->objt)[i].indx;
|
||
npt = (*ob->lial)[il].n;
|
||
ptos = &(*ob->ptos)[(*ob->lial)[il].indx];
|
||
//k=0 son inicios, k=1 son finales
|
||
k=0;
|
||
for(ic=0; ic<conjs->n && k<2;ic++)
|
||
{
|
||
if(Colv_geom::pto_equals(ptos[k*(npt-1)],conjs->coor[ic]))
|
||
{
|
||
ics[k]=ic;
|
||
k++;
|
||
ic=-1;//reinicia
|
||
}
|
||
}
|
||
if(ic==conjs->n)
|
||
{
|
||
break;
|
||
}
|
||
|
||
ias[olv_limp->n_ini_amb_iai+i].ic_ini=ics[0];
|
||
ias[olv_limp->n_ini_amb_iai+i].ic_fin=ias[i].ic_ini;
|
||
ias[olv_limp->n_ini_amb_iaf+i].ic_ini=ics[1];
|
||
ias[olv_limp->n_ini_amb_iaf+i].ic_fin=ias[i].ic_fin;
|
||
|
||
/*wgeolog(LOG_TODO,"olv_limp_t","ishp %ld ini_ini %ld ini_fin %ld fin_in %ld fin-fin %ld",
|
||
i,ics[0],ias[i].ic[0],ics[1],ias[i].ic[1]);*/
|
||
|
||
|
||
}
|
||
if(io<ob->vect.nobj)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Error, no se pudo asignar segmentos");
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
if(pirate)
|
||
return FALSE;
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Encontradas %ld conjunciones en la red navegable",conjs->n);
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Comienza a buscar las conjunciones de la planta");
|
||
|
||
if(!busca_conjs_planta(conjs,olv_limp->coor_instal, &olv_limp->nod_instal))
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","No se ha podido encontrar los nodos de la planta");
|
||
return FALSE;
|
||
}
|
||
wgeolog(LOG_TODO,"olv_limp_t","Encontradas las conjunciones de la planta");
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la matriz de distancias entre todas las conjunciones.
|
||
* El thread entra aqu<71> cuando los subthreads que realizan la tarea realmente han finalizado
|
||
*/
|
||
BOOL Colv_limp_thr::calcula_cost_conj_fin()
|
||
{
|
||
////////////////
|
||
//para los threads
|
||
para_subthrs();
|
||
//olv_limp->cost_conj.memAjust();
|
||
wgeolog(LOG_TODO,"olv_limp_t","FIN Matriz de dist entre conjs %ldx%ld",
|
||
olv_limp->conjs.n,olv_limp->conjs.n);
|
||
|
||
/*//mira a ver si tiene que ser multitask o no
|
||
INT64 sdj = olv_limp->conjs.n*olv_limp->conjs.n*sizeof(float);
|
||
if(sdj>=(INT64)OLV_TASKS_MAXMEMNOMULTI)
|
||
olv->modo_multitask=TRUE;*/
|
||
///////////////////////////////
|
||
if(olv_limp->res_circ==OLV_RES_NO)
|
||
{
|
||
//va directo a cost_amb, calcula ahora si va a ser multitask o no
|
||
//calcula si puede ser multitask o no
|
||
CoptiMemo oo;
|
||
olv->modo_multitask=oo.is_multi(olv_limp->conjs.n,n_subthr,sizeof(Djkt_elem_cola));
|
||
}
|
||
////////////////////////////////
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la matriz de distancias entre todas las conjunciones, es la parte de c<>lculos que
|
||
* realizan los subthreads. 'ithr' indica qu<71> thread es, para calcular qu<71> conjunciones le tocan.
|
||
*/
|
||
void Colv_limp_thr::calcula_cost_conj_sub(int ithr)
|
||
{
|
||
int ic,il,npt,KK,nc,nd,i,k,ics[2];
|
||
int n_ini, n_desp, n_fin, seg;
|
||
float cost,cost2;
|
||
Cobgeo *ob;
|
||
double (*ptos)[3];
|
||
BOOL mal=FALSE;
|
||
Param_olv_limp_thr pp;
|
||
Info_aso *ias;
|
||
float costaux,cost2aux;
|
||
|
||
////////////////
|
||
mal=FALSE;
|
||
pp.id_e=OLV_TAREA_COST_AMB;//manda de par<61>metro la tarea de la que es el progreso
|
||
KK=olv_limp->tipo_ambit;
|
||
ob=olv_limp->olv->olv_ob;
|
||
n_desp = (int)ceil(1.0*(ob->vect.nobj)/n_subthr);
|
||
n_ini=ithr*n_desp;
|
||
n_fin = min((ithr+1)*n_desp,ob->vect.nobj);
|
||
cost=cost2=0;
|
||
nc=nd=0;
|
||
ias=olv_limp->ias;
|
||
////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Entidades %04d a %04d", ithr,n_ini, n_fin);
|
||
|
||
seg = GetTickCount();
|
||
/////////////////////////////////////
|
||
//bucle por cada entidad de la carto
|
||
for(i=n_ini; i<n_fin && !mal && !pirate; i++)
|
||
{
|
||
if((*ob->objt)[i].ia<0)
|
||
continue;
|
||
if((ias[(*ob->objt)[i].ia].flgs &
|
||
(OLV_LIMP_FLG_AMB | OLV_LIMP_FLG_SEG_PUN | OLV_LIMP_FLG_SEG_LIN | OLV_LIMP_FLG_PEAT_REP |
|
||
OLV_LIMP_FLG_PEAT_SEG | OLV_LIMP_FLG_EJE_SEG)) && !(ias[(*ob->objt)[i].ia].flgs & OLV_LIMP_FLG_SEG_AMB))
|
||
{
|
||
//si es tipo <20>mbito o segmento ya se tiene sus conjunciones apuntadas
|
||
ics[0]=ias[(*ob->objt)[i].ia].ic_ini;
|
||
ics[1]=ias[(*ob->objt)[i].ia].ic_fin;
|
||
}
|
||
else
|
||
{
|
||
//es una carretera, hay que buscar sus conjunciones
|
||
il=(*ob->objt)[i].indx;
|
||
npt = (*ob->lial)[il].n;
|
||
ptos = &(*ob->ptos)[(*ob->lial)[il].indx];
|
||
|
||
for(k=0; k<2; k++)
|
||
{
|
||
//lo hace para los dos extremos de la l<>nea
|
||
for(ic=0; ic<olv_limp->conjs.n;ic++)
|
||
{
|
||
if(Colv_geom::pto_equals(ptos[k*(npt-1)],olv_limp->conjs.coor[ic]))
|
||
break;
|
||
}
|
||
if(ic>=olv_limp->conjs.n)
|
||
{
|
||
mal=TRUE;
|
||
break;
|
||
}
|
||
ics[k]=ic;
|
||
}
|
||
}
|
||
///////////////////
|
||
//pone en el array de tipos qu<71> es
|
||
//olv_limp->tip_conj[ics[0]][ics[1]]=olv_limp->tip_conj[ics[1]][ics[0]]=i;
|
||
olv_limp->tip_conj.set(ics[0],ics[1],i);
|
||
olv_limp->tip_conj.set(ics[1],ics[0],i);
|
||
///////////////////////////////////
|
||
nd+=2;
|
||
//ya tiene una l<>nea y sus dos extremos ic e ic2 localizados, calcula el coste
|
||
calcula_cost(i,ob,olv_limp->ias,&cost,&cost2);
|
||
|
||
//a<>ade los costes a la matriz
|
||
if(cost>olv_limp->cost_conj[ics[0]][ics[1]])
|
||
cost=olv_limp->cost_conj[ics[0]][ics[1]];
|
||
//olv_limp->cost_conj[ics[0]][ics[1]]=min(cost,olv_limp->cost_conj[ics[0]][ics[1]]);
|
||
olv_limp->cost_conj.set(ics[0],ics[1], min(cost,olv_limp->cost_conj[ics[0]][ics[1]]));
|
||
|
||
if(cost2>olv_limp->cost_conj[ics[1]][ics[0]])
|
||
cost2=olv_limp->cost_conj[ics[1]][ics[0]];
|
||
olv_limp->cost_conj.set(ics[1],ics[0],min(cost2,olv_limp->cost_conj[ics[1]][ics[0]]));
|
||
|
||
///////////////////////////////////
|
||
if(FALSE)
|
||
{
|
||
if(cost>=MAYUSCULO)
|
||
costaux=-1;
|
||
else
|
||
costaux=cost;
|
||
if(cost2>=MAYUSCULO)
|
||
cost2aux=-1;
|
||
else
|
||
cost2aux=cost2;
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, io %04d, cost %03.3f cost2 %03.3f",ithr,i,costaux,cost2aux);
|
||
}
|
||
/////////////////////////////////////
|
||
|
||
//avisa de progreso
|
||
if(((i-n_ini)%800==0) || ((i-n_ini)==(n_desp-1)))
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Rellenando matriz de dist entre conjs %ld de %ld", ithr,
|
||
(i-n_ini+1),n_desp);
|
||
//avisa de progreso
|
||
prog_subthr=((1.0*(i-n_ini+1)/n_desp)+0)/3;///3 porque es la tercera parte del progreso los costes de conjunciones y la otra mitad los costes de <20>mbitos
|
||
thr_padre->encola(OLV_LIMP_EV_SUBTHR_PROG,&pp,FALSE);
|
||
}
|
||
}
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Fin Matriz de dist entre conjs, %ld distancias, %.3f seg", ithr, nd,1.0*(GetTickCount()-seg)/1000);
|
||
|
||
thr_padre->encola(OLV_LIMP_EV_COST_CONJ_FIN,NULL,FALSE);
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Calcula el coste de la l<>nea io, cost en sentido ida y cost2 en sentido vuelta
|
||
*/
|
||
void Colv_limp_thr::calcula_cost(int io, Cobgeo *ob, Info_aso *ias, float *cost, float *cost2)
|
||
{
|
||
int il,ia, npt;
|
||
double (*ptos)[3];
|
||
double ltot;
|
||
|
||
*cost=*cost2=0;
|
||
////////////////////
|
||
ia=(*ob->objt)[io].ia;
|
||
ltot=0;
|
||
if((*ob->objt)[io].tipo == OBJ_LINEAL)
|
||
{
|
||
il=(*ob->objt)[io].indx;
|
||
npt = (*ob->lial)[il].n;
|
||
ptos = &(*ob->ptos)[(*ob->lial)[il].indx];
|
||
ltot=long_linea((double (*)[][3]) ptos,npt,NULL,NULL,NULL,NULL);
|
||
}
|
||
///////////////////
|
||
olv_limp->dame_cost(ltot,ia,cost,cost2);
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la matriz de <20>ngulos entre las conjunciones adyacentes a una dada
|
||
*/
|
||
BOOL Colv_limp_thr::calcula_ang_conj()
|
||
{
|
||
////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Rellenando matriz de <20>ngulos entre conjunciones");
|
||
pon_mi_progre(OLV_TAREA_COST_AMB, (int) (OliviaDef::GeneralDef::ProgrMax*1/3));
|
||
pon_mi_msg("");
|
||
err_str[0]=0;
|
||
|
||
//pide memoria para el array de distancias entre conjunciones
|
||
olv_limp->ang_conj = new Djkt_ang_ady[olv_limp->conjs.n];
|
||
|
||
//lanza los threads
|
||
lanza_subthrs(OLV_LIMP_EV_ANG_CONJ_SUB);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la matriz de <20>ngulos entre todas las conjunciones.
|
||
* El thread entra aqu<71> cuando los subthreads que realizan la tarea realmente han finalizado
|
||
*/
|
||
BOOL Colv_limp_thr::calcula_ang_conj_fin()
|
||
{
|
||
////////////////
|
||
//para los threads
|
||
para_subthrs();
|
||
|
||
revisa_calles_cortadas();
|
||
|
||
//////////////////////////////////
|
||
//calcula si va a ser multitask o no
|
||
CoptiMemo oo;
|
||
olv->modo_multitask=oo.is_multi(olv_limp->conjs.n,n_subthr,sizeof(Djkt_elem_cola));
|
||
//////////////////////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","FIN Matriz de ang entre conjs %ldx%ld",
|
||
olv_limp->conjs.n,olv_limp->conjs.n);
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la matriz de <20>ngulos entre todas las conjunciones adyacentes a una dada, es la parte de c<>lculos que
|
||
* realizan los subthreads. 'ithr' indica qu<71> thread es, para calcular qu<71> conjunciones le tocan.
|
||
*/
|
||
void Colv_limp_thr::calcula_ang_conj_sub(int ithr)
|
||
{
|
||
Cobgeo *ob;
|
||
Param_olv_limp_thr pp;
|
||
|
||
int i,j,nconj,KK,na,ic,nady;
|
||
int n_ini, n_desp, n_fin, seg;
|
||
BOOL mal=FALSE;
|
||
BYTE aa;
|
||
BYTE *conjs;
|
||
double ang;
|
||
|
||
////////////////
|
||
pp.id_e=OLV_TAREA_COST_AMB;//manda de par<61>metro la tarea de la que es el progreso
|
||
KK=olv_limp->tipo_ambit;
|
||
ob=olv_limp->olv->olv_ob;
|
||
nconj=olv_limp->conjs.n;
|
||
n_desp = (int)ceil(1.0*nconj/n_subthr);
|
||
n_ini=ithr*n_desp;
|
||
n_fin = min((ithr+1)*n_desp,nconj);
|
||
na=0;
|
||
conjs=NULL;
|
||
conjs=(BYTE*)malloc(olv_limp->conjs.n*sizeof(BYTE));
|
||
if(!conjs)
|
||
mal=TRUE;
|
||
else
|
||
memset(conjs,0,olv_limp->conjs.n*sizeof(BYTE));
|
||
////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, <20>ngulos de conjunciones %04d a %04d", ithr,n_ini, n_fin);
|
||
|
||
seg = GetTickCount();
|
||
/////////////////////////////////////
|
||
//bucle por cada conjunci<63>n de la carto
|
||
for(ic=n_ini; ic<n_fin && !mal && !pirate; ic++)
|
||
{
|
||
nady=0;
|
||
memset(conjs,0,olv_limp->conjs.n*sizeof(BYTE));
|
||
//Busca conjunciones adyacentes
|
||
for(i=0;i<nconj;i++)
|
||
{
|
||
if(i==ic)
|
||
continue;
|
||
|
||
if((olv_limp->cost_conj[i][ic]>=MAYUSCULO) && (olv_limp->cost_conj[ic][i]>=MAYUSCULO))
|
||
continue;
|
||
|
||
//marca las conjunciones que son adyacentes
|
||
conjs[i]=1;
|
||
|
||
for(j=i+1;j<nconj;j++)
|
||
{
|
||
if(j==ic)
|
||
continue;
|
||
|
||
if(olv_limp->cost_conj[ic][j]>=MAYUSCULO)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
//marca las conjunciones que son adyacentes
|
||
conjs[j]=1;
|
||
}
|
||
|
||
}
|
||
for(i=0;i<nconj;i++)
|
||
{
|
||
if(conjs[i])
|
||
nady++;
|
||
}
|
||
if(nady==0)
|
||
continue;
|
||
if(nady>16)
|
||
{
|
||
nady=nady;
|
||
}
|
||
//ya tiene las adyacentes de la conjunci<63>n ic, inicializa array de angulos
|
||
if(!olv_limp->ang_conj[ic].inicia(nady))
|
||
{
|
||
mal=TRUE;
|
||
break;
|
||
}
|
||
//Busca conjunciones adyacentes
|
||
for(i=0;i<nconj;i++)
|
||
{
|
||
if(!conjs[i])
|
||
continue;
|
||
|
||
for(j=0;j<nconj;j++)
|
||
{
|
||
if(!conjs[j])
|
||
continue;
|
||
|
||
|
||
if((olv_limp->cost_conj[i][ic]>=MAYUSCULO) || (olv_limp->cost_conj[ic][j]>=MAYUSCULO))
|
||
{
|
||
aa=0;
|
||
}
|
||
else
|
||
{
|
||
//si no hay restricciones de circulaci<63>n, se pone que se el <20>ngulo es ok siempre
|
||
//si no, se calcula, y el <20>ngulo es ok si es menor que el <20>ngulo l<>mite
|
||
if(olv_limp->res_circ!=OLV_RES_NO)
|
||
{
|
||
ang=dame_ang_conj(ic,i,j);
|
||
aa=(ang<=olv_limp->ang_lim);
|
||
}
|
||
}
|
||
olv_limp->ang_conj[ic].pon_ang_i_j(i,j,aa);
|
||
|
||
na++;
|
||
|
||
}
|
||
}
|
||
|
||
//avisa de progreso
|
||
if(((ic-n_ini)%500==0) || ((ic-n_ini)==(n_desp-1)))
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Rellenando matriz de ang entre conjs %ld de %ld", ithr,
|
||
(ic-n_ini+1),n_desp);
|
||
//avisa de progreso
|
||
prog_subthr=((1.0*(ic-n_ini+1)/n_desp)+1)/3;///3 porque es la tercera parte del progreso los costes de conjunciones
|
||
thr_padre->encola(OLV_LIMP_EV_SUBTHR_PROG,&pp,FALSE);
|
||
}
|
||
}
|
||
|
||
if(conjs)
|
||
free(conjs);
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Fin Matriz de ang entre conjs, %ld <20>ngulos, %.3f seg", ithr, na,1.0*(GetTickCount()-seg)/1000);
|
||
|
||
thr_padre->encola(OLV_LIMP_EV_ANG_CONJ_FIN,NULL,FALSE);
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Devuelve el <20>ngulo entre dos conjunciones
|
||
*/
|
||
double Colv_limp_thr::dame_ang_conj(int ic, int i, int j)
|
||
{
|
||
int k,il,npts,indx;
|
||
double v1[2],v2[2],(*ptos)[3],ang;
|
||
Cobgeo *ob=olv_limp->olv->olv_ob;
|
||
int tip_conj = olv_limp->tip_conj[i][ic];
|
||
ang=0;
|
||
if(i==j)
|
||
{
|
||
if(olv_limp->ias[(*ob->objt)[tip_conj].ia].flgs &
|
||
OLV_LIMP_FLG_NO_NW)
|
||
{
|
||
ang=0;//es un segmento o <20>mbito, s<> se puede
|
||
}
|
||
else if(olv_limp->res_circ==OLV_RES_NO)
|
||
{
|
||
ang=0;
|
||
}
|
||
else
|
||
{
|
||
ang=OLV_PI;//<2F>ngulo de 180<38> en carretera y sigue sentidos, no se puede (excepto si es calle cortada, que se revisa luego)
|
||
}
|
||
}
|
||
else if((olv_limp->ias[(*ob->objt)[tip_conj].ia].flgs &
|
||
(OLV_LIMP_FLG_SEG_LIN|OLV_LIMP_FLG_SEG_PUN|OLV_LIMP_FLG_PEAT_SEG|OLV_LIMP_FLG_EJE_SEG)) ||
|
||
(olv_limp->ias[(*ob->objt)[olv_limp->tip_conj[j][ic]].ia].flgs &
|
||
(OLV_LIMP_FLG_SEG_LIN|OLV_LIMP_FLG_SEG_PUN|OLV_LIMP_FLG_PEAT_SEG|OLV_LIMP_FLG_EJE_SEG)))
|
||
{
|
||
ang=0;
|
||
|
||
}
|
||
else if((!(olv_limp->ias[(*ob->objt)[tip_conj].ia].flgs &
|
||
OLV_LIMP_FLG_NO_NW)) && (!(olv_limp->ias[(*ob->objt)[olv_limp->tip_conj[j][ic]].ia].flgs &
|
||
OLV_LIMP_FLG_NO_NW)))
|
||
{
|
||
//las dos son carretera, si por coste no se puede ir,
|
||
if(olv_limp->res_circ<OLV_RES_SENTIDOS_CIRC)
|
||
ang=0;
|
||
else if((olv_limp->ias[(*ob->objt)[tip_conj].ia].ishp==olv_limp->ias[(*ob->objt)[olv_limp->tip_conj[ic][j]].ia].ishp) &&
|
||
((olv_limp->ias[(*ob->objt)[tip_conj].ia].flgs & OLV_LIMP_FLG_NW_REP) || (olv_limp->ias[(*ob->objt)[olv_limp->tip_conj[ic][j]].ia].flgs & OLV_LIMP_FLG_NW_REP)))
|
||
{
|
||
//si intenta ir de nw a r<>plica, pero de la misma calle
|
||
ang=OLV_PI;
|
||
}
|
||
else
|
||
{
|
||
|
||
//calcula los puntos pr<70>ximos a la conjunci<63>n
|
||
//llega aqu<71> si es nw de doble sentido
|
||
il=(*ob->objt)[tip_conj].indx;
|
||
npts = (*ob->lial)[il].n;
|
||
indx=(*ob->lial)[il].indx;
|
||
ptos = &(*ob->ptos)[indx];
|
||
if(Colv_geom::pto_equals(olv_limp->conjs.coor[ic], ptos[0]))
|
||
{
|
||
//la conjunci<63>n es el primer punto
|
||
for(k=0;k<2;k++)
|
||
{
|
||
v1[k]=ptos[1][k]-olv_limp->conjs.coor[ic][k];
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//la conjunci<63>n es el <20>ltimo punto
|
||
for(k=0;k<2;k++)
|
||
{
|
||
v1[k]=ptos[npts-2][k]-olv_limp->conjs.coor[ic][k];
|
||
}
|
||
}
|
||
|
||
//es carretera, calcula los puntos pr<70>ximos a la conjunci<63>n
|
||
//llega aqu<71> si es nw de doble sentido
|
||
il=(*ob->objt)[olv_limp->tip_conj[j][ic]].indx;
|
||
npts = (*ob->lial)[il].n;
|
||
indx=(*ob->lial)[il].indx;
|
||
ptos = &(*ob->ptos)[indx];
|
||
if(Colv_geom::pto_equals(olv_limp->conjs.coor[ic], ptos[0]))
|
||
{
|
||
//la conjunci<63>n es el primer punto
|
||
for(k=0;k<2;k++)
|
||
{
|
||
v2[k]=ptos[1][k]-olv_limp->conjs.coor[ic][k];
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//la conjunci<63>n es el <20>ltimo punto
|
||
for(k=0;k<2;k++)
|
||
{
|
||
v2[k]=ptos[npts-2][k]-olv_limp->conjs.coor[ic][k];
|
||
}
|
||
}
|
||
|
||
ang=Colv_geom::ang_vect(v1,v2);
|
||
ang=OLV_PI-ang;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ang=0;
|
||
}
|
||
|
||
return ang;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Resvisa los <20>ngulos, de forma que si hay alg<6C>n giro "prohibido" de 180<38>, en caso
|
||
* de que sean calles cortadas o sin salida, los pone a ok
|
||
*/
|
||
void Colv_limp_thr::revisa_calles_cortadas()
|
||
{
|
||
int ic,i,j,k,nady;
|
||
if(olv_limp->res_circ==OLV_RES_NO)
|
||
return;
|
||
for(ic=0;ic<olv_limp->conjs.n;ic++)
|
||
{
|
||
nady=olv_limp->ang_conj[ic].nady;
|
||
for(i=0;i<nady;i++)
|
||
{
|
||
for(j=0;j<nady;j++)
|
||
{
|
||
if(!olv_limp->ang_conj[ic].angs[i][j])
|
||
{
|
||
//si el <20>ngulo es prohibido, mira a ver si hay m<>s conjunciones
|
||
for(k=0;k<nady;k++)
|
||
{
|
||
if(olv_limp->ang_conj[ic].i_conjs[k]<0 || olv_limp->ang_conj[ic].i_conjs[k]>=olv_limp->conjs.n)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Ojo ang_conj fuera de l<>mites ic %ld, k %ld",ic,k);
|
||
continue;
|
||
}
|
||
if((olv_limp->ang_conj[ic].i_conjs[k]!=olv_limp->ang_conj[ic].i_conjs[i]) &&
|
||
(olv_limp->ang_conj[ic].i_conjs[k]!=olv_limp->ang_conj[ic].i_conjs[j]) &&
|
||
(olv_limp->cost_conj[ic][olv_limp->ang_conj[ic].i_conjs[k]]<MAYUSCULO) &&
|
||
(olv_limp->conjs.inc[olv_limp->ang_conj[ic].i_conjs[k]].n>1))
|
||
break;
|
||
}
|
||
if(k>=nady)//estos nodos son los <20>nicos que tiene para entrar y salir
|
||
{
|
||
olv_limp->ang_conj[ic].angs[i][j]=1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la matriz de costes entre todos los <20>mbitos
|
||
*/
|
||
BOOL Colv_limp_thr::calcula_cost_amb()
|
||
{
|
||
int i;
|
||
BOOL log_debug=FALSE;
|
||
////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Rellenando matriz de costes entre <20>mbitos");
|
||
pon_mi_progre(OLV_TAREA_COST_AMB, (int) (OliviaDef::GeneralDef::ProgrMax*2/3));
|
||
pon_mi_msg("");
|
||
err_str[0]=0;
|
||
char st[MAX_PATH];
|
||
char st1[MAX_PATH];
|
||
|
||
strcpy_s(st1,MAX_PATH,olv_limp->olv->paths.path_temp);
|
||
if(st1[strlen(st1)-1]=='\\')
|
||
{
|
||
st1[strlen(st1)-1]=0;
|
||
}
|
||
sprintf(st,"%s\\%s",st1,NOMB_ARCH_DIJ_DEF);
|
||
//inicia archivo para los djistra--------------
|
||
if(!olv_limp->arch_dj.inicia(st,!olv->modo_multitask,olv_limp->conjs.n))
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Error al iniciar archivo dj en directorio %s",st);
|
||
return FALSE;
|
||
}
|
||
if(!olv_limp->arch_dj.inicia_inf_amb(olv_limp->ias,olv_limp->n_amb,olv_limp->tipo_ambit,olv_limp->nod_instal, olv_limp->nod_plant))
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Error al iniciar info de ambitos en archivo de dj");
|
||
return FALSE;
|
||
}
|
||
//////////////////////////////////
|
||
//primero loguea la info asociada de los <20>mbitos a su <20>ndice a su conjunci<63>n incial y su conjunci<63>n final
|
||
if(log_debug)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Info asociada a <20>mbitos, conjs:");
|
||
for(i=0;i<olv_limp->n_amb;i++)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Info asociada a <20>mbitos, amb %03d: conj ini %04d conj fin %04d",i,
|
||
olv_limp->ias[i].ic_ini,olv_limp->ias[i].ic_fin);
|
||
}
|
||
}
|
||
|
||
////////////////////////////////////////////////
|
||
if(!inicia_cost_amb())
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if(!olv_limp->olv->modo_multitask)
|
||
{
|
||
//lanza los threads, tiene memo suficiente para todos los threads
|
||
lanza_subthrs(OLV_LIMP_EV_COST_AMB_SUB,n_subthr);
|
||
}
|
||
else
|
||
{
|
||
//wgeolog(LOG_TODO,"olv_limp_t","sizeof %ld %ld %ld %ld", sizeof(Head_dj_arch),sizeof(Djkt_nodo), sizeof(Djkt_ids_pdr),olv_limp->arch_dj.sizn);
|
||
|
||
//en modo multitask entra aqu<71> cuando ya han terminado las tasks
|
||
//se lee la matriz de <20>mbitos que han guardado las tasks
|
||
if(!olv_limp->arch_dj.lee_dis())
|
||
return FALSE;
|
||
if(!olv_limp->olv_tasks->lee_cost_amb(olv_limp->cost_amb))
|
||
return FALSE;
|
||
|
||
//borra los archivos temporales
|
||
borra_temp_files(FALSE);
|
||
|
||
//despu<70>s de leerla, encola el cost_amb_fin
|
||
for(int i=0;i<n_subthr;i++)
|
||
{
|
||
subthrs[i]->prog_subthr=0;//para que no d<> error
|
||
encola(OLV_LIMP_EV_COST_AMB_FIN,NULL,FALSE);
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
BOOL Colv_limp_thr::inicia_cost_amb()
|
||
{
|
||
int i,j;
|
||
|
||
//pide memoria para el array de distancias entre <20>mbitos
|
||
if(!olv_limp->cost_amb.inicia(olv_limp->n_amb,olv_limp->n_amb))
|
||
{
|
||
pon_mi_msg("Error, sin memoria para matriz de dist entre <20>mbitos");
|
||
return FALSE;
|
||
}
|
||
|
||
//inicializa todo a 0
|
||
for(i=0;i<olv_limp->n_amb;i++)
|
||
{
|
||
for(j=0;j<olv_limp->n_amb;j++)
|
||
olv_limp->cost_amb[i][j]=(float)MAYUSCULO;//porque se va a almacenar la minima
|
||
}
|
||
|
||
//Inicia el array de orden /secuencia
|
||
olv_limp->ord_sec=(Secu_amb*)malloc(sizeof(Secu_amb)*olv_limp->n_amb);
|
||
if(!olv_limp->ord_sec)
|
||
{
|
||
pon_mi_msg("Error, sin memoria para matriz de orden y secuencia");
|
||
return FALSE;
|
||
}
|
||
memset(olv_limp->ord_sec,0,sizeof(Secu_amb)*olv_limp->n_amb);
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la matriz de distancias entre todos los <20>mbitos.
|
||
* El thread entra aqu<71> cuando los subthreads que realizan la tarea realmente han finalizado
|
||
*/
|
||
BOOL Colv_limp_thr::calcula_cost_amb_fin()
|
||
{
|
||
////////////////
|
||
int ai=1;
|
||
|
||
if(!olv_limp->olv->modo_multitask)
|
||
{
|
||
//para los threads
|
||
para_subthrs();
|
||
}
|
||
|
||
if(pirate)
|
||
return FALSE;
|
||
|
||
////////////////
|
||
//mira si hay aislados
|
||
if(!avisa_aislados())
|
||
return FALSE;
|
||
|
||
//avisa aislados ha ido bien, no hay aislados
|
||
|
||
if(pirate)
|
||
return FALSE;
|
||
|
||
//calcula el coste a las plantas
|
||
if(!calcula_cost_plant())
|
||
{
|
||
pon_mi_msg("Error, planta o instalaci<63>n aisladas");
|
||
return FALSE;
|
||
}
|
||
|
||
olv_limp->nsec_act=olv_limp->nsec;
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","FIN Matriz de dist entre <20>mbitos %ldx%ld",
|
||
olv_limp->n_amb,olv_limp->n_amb);
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Dado el array relleno con los aislados, saca cartel avisando
|
||
*/
|
||
BOOL Colv_limp_thr::avisa_aislados()
|
||
{
|
||
int i,j,k,ii;
|
||
BYTE *ambs_ais;
|
||
char ais_msg[OLV_MAX_MSG_PROCE];
|
||
char nfile[MAX_PATH];
|
||
|
||
strcpy_s(nfile,MAX_PATH,olv->paths.path_data);
|
||
cambiaext(nfile,".shp",".dbf");
|
||
|
||
ambs_ais = (BYTE*)malloc(olv_limp->n_amb);
|
||
if(!ambs_ais)
|
||
{
|
||
pon_mi_msg("Error, sin memoria en fin de calcula coste <20>mbitos");
|
||
return FALSE;
|
||
}
|
||
memset(ambs_ais,0,olv_limp->n_amb);
|
||
|
||
//revisa costes de <20>mbitos
|
||
int nais;
|
||
for(i=0;i<olv_limp->n_amb; i++)
|
||
{
|
||
if(ambs_ais[i])
|
||
continue;
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
for(j=0;j<olv_limp->n_amb; j++)
|
||
{
|
||
if(i==j)
|
||
continue;
|
||
if(olv_limp->ias[j].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
if(ambs_ais[j])
|
||
continue;
|
||
if(olv_limp->cost_amb[i][j]>=MAYUSCULO)
|
||
{
|
||
//puede estar aislado i o j
|
||
nais=0;
|
||
for(k=0;k<olv_limp->n_amb;k++)
|
||
{
|
||
if(k==i)
|
||
continue;
|
||
if(olv_limp->cost_amb[k][j]>=MAYUSCULO)//comprueba si j est<73> aislado para los dem<65>s <20>mbitos tambi<62>n
|
||
{
|
||
nais=j;
|
||
break;
|
||
}
|
||
if(k==j)
|
||
continue;
|
||
if(olv_limp->cost_amb[i][k]>=MAYUSCULO)//comprueba si i est<73> aislado para los dem<65>s <20>mbitos tambi<62>n
|
||
{
|
||
nais=i;
|
||
break;
|
||
}
|
||
}
|
||
if(k<olv_limp->n_amb)
|
||
ambs_ais[nais]=1;
|
||
}
|
||
}
|
||
}
|
||
|
||
nais=0;
|
||
int inw;
|
||
for(i=0;i<olv_limp->n_amb;i++)
|
||
{
|
||
if(ambs_ais[i])
|
||
{
|
||
nais++;
|
||
Colv_geom::pon_pto((double (*)[3])olv_limp->conjs.coor[olv_limp->ias[i].ic[0]], OLV_ICLA_PUN_AIS, -1, olv_limp->olv->olv_ob);
|
||
olv_limp->olv->olv_sh->dame_col_int_dbf(nfile,i,i+1,&ii,"OBJECTID",err_str,OLV_MAX_ERR);
|
||
|
||
inw=olv_limp->inww_amb[i].inw;
|
||
wgeolog(LOG_TODO,"olv_limp_t","<EFBFBD>mbito %ld aislado, calle %ld ia %03d flags %02X",i,inw,inw,
|
||
olv_limp->ias[inw].flgs);
|
||
}
|
||
}
|
||
|
||
if(!nais)
|
||
{
|
||
free(ambs_ais);
|
||
return TRUE;
|
||
}
|
||
|
||
if(nais==1)
|
||
sprintf_s(ais_msg,"Encontrado %ld <20>mbito aislado %s: ", nais,olv_limp->igno_ais?"(Se ignora)":"");
|
||
else
|
||
sprintf_s(ais_msg,"Encontrados %ld <20>mbitos aislados %s: ",nais,olv_limp->igno_ais?"(Se ignoran)":"");
|
||
int inais=0;
|
||
for(i=0;i<olv_limp->n_amb;i++)
|
||
{
|
||
if(ambs_ais[i])
|
||
{
|
||
if(olv_limp->igno_ais)//si toca ignorar aislados, lo marca para ignorarlo en la sectorizaci<63>n
|
||
{
|
||
olv_limp->ias[i].flgs|=OLV_LIMP_FLG_AMB_NO;
|
||
}
|
||
|
||
olv_limp->olv->olv_sh->dame_col_int_dbf(nfile,i,i+1,&ii,"OBJECTID",err_str,OLV_MAX_ERR);
|
||
if(nais==1)
|
||
{
|
||
sprintf_s(ais_msg,"%s %ld",ais_msg,ii);
|
||
break;
|
||
}
|
||
else if(inais==nais-1)
|
||
sprintf_s(ais_msg,"%s y %ld",ais_msg,ii);
|
||
else if(inais>0 && inais%4==0)
|
||
sprintf_s(ais_msg,"%s %ld,\n",ais_msg,ii);
|
||
else
|
||
sprintf_s(ais_msg,"%s %ld,",ais_msg,ii);
|
||
if(strlen(ais_msg)+10>=OLV_MAX_MSG_PROCE)
|
||
break;
|
||
inais++;
|
||
|
||
}
|
||
}
|
||
if(i<olv_limp->n_amb && nais>1 && ((strlen(ais_msg)+5)<OLV_MAX_MSG_PROCE))
|
||
sprintf_s(ais_msg,"%s %s",ais_msg,"y mas");
|
||
|
||
pon_mi_msg(ais_msg);
|
||
if(olv_limp->igno_ais)
|
||
Sleep (OLV_T_SLEEP_MSG);
|
||
////////////////////////////
|
||
|
||
free(ambs_ais);
|
||
if(olv_limp->igno_ais)
|
||
return TRUE;
|
||
else
|
||
return FALSE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Apunta en qu<71> nodos est<73> la planta y la instalaci<63>n
|
||
*/
|
||
BOOL Colv_limp_thr::calcula_cost_plant()
|
||
{
|
||
int ic,ia,ka,nais,k;
|
||
Djkt_nodo *costes_nodos;
|
||
BOOL mal=FALSE;
|
||
|
||
if(olv_limp->nod_instal<0)
|
||
return TRUE;
|
||
|
||
//Inicia el array de orden /secuencia
|
||
olv_limp->ord_sec_plan=(Secu_amb*)malloc(sizeof(Secu_amb));
|
||
if(!olv_limp->ord_sec_plan)
|
||
{
|
||
pon_mi_msg("Error, sin memoria para matriz de orden y secuencia");
|
||
return FALSE;
|
||
}
|
||
memset(olv_limp->ord_sec_plan,0,sizeof(Secu_amb));
|
||
wgeolog(LOG_TODO,"olv_limp_t","Calculando coste a planta e instalaci<63>n");
|
||
|
||
costes_nodos=NULL;
|
||
k=0;
|
||
|
||
ic=olv_limp->nod_instal;
|
||
|
||
if(!Colv_geom::dijkstra_ang_inv_ok(olv_limp->cost_conj, olv_limp->ang_conj, olv_limp->conjs.n,
|
||
ic, &costes_nodos, &visto_ang))
|
||
{
|
||
pon_mi_msg("Error al calcular costes de <20>mbitos a instalaci<63>n");
|
||
return FALSE;
|
||
}
|
||
|
||
olv_limp->ord_sec_plan[k].ctnod[0]=costes_nodos;
|
||
olv_limp->ord_sec_plan[k].ctnod[1]=NULL;
|
||
|
||
costes_nodos=NULL;
|
||
|
||
//revisa si est<73> aislado de alg<6C>n <20>mbito
|
||
nais=0;
|
||
for(ia=0;ia<olv_limp->n_amb;ia++)
|
||
{
|
||
if(olv_limp->ias[ia].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
for(ka=0;ka<olv_limp->tipo_ambit;ka++)
|
||
{
|
||
if(olv_limp->ord_sec_plan[k].ctnod[0][olv_limp->ias[ia].ic[ka]].dis>=MAYUSCULO)
|
||
{
|
||
nais++;
|
||
break;
|
||
}
|
||
}
|
||
if(nais)
|
||
break;
|
||
}
|
||
if(ia<olv_limp->n_amb)
|
||
{
|
||
pon_mi_msg("Error al calcular costes de <20>mbitos a instalaci<63>n");
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la matriz de distancias entre todos los <20>mbitos, es la parte de c<>lculos que
|
||
* realizan los subthreads. 'ithr' indica qu<71> thread es, para calcular qu<71> <20>mbitos le tocan.
|
||
*/
|
||
void Colv_limp_thr::calcula_cost_amb_sub(int ithr)
|
||
{
|
||
int na_ini,na_fin,na_desp,na,i,k;
|
||
int KK, seg;
|
||
Cobgeo *ob;
|
||
BOOL log_debug=FALSE;
|
||
Djkt_nodo *costes_nodos;
|
||
double caux;
|
||
Param_olv_limp_thr pp;
|
||
BOOL mal=FALSE;
|
||
|
||
////////////////
|
||
pp.id_e=OLV_TAREA_COST_AMB;//manda de par<61>metro la tarea de la que es el progreso
|
||
KK=olv_limp->tipo_ambit;
|
||
na_desp = (int)ceil(1.0*(olv_limp->n_amb)/n_subthr);
|
||
na_ini=ithr*na_desp;
|
||
na_fin = min((ithr+1)*na_desp,olv_limp->n_amb);
|
||
ob=olv_limp->olv->olv_ob;
|
||
costes_nodos=NULL;
|
||
////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Ambs %04d a %04d", ithr,na_ini, na_fin);
|
||
|
||
seg = GetTickCount();
|
||
/////////////////////////////////////
|
||
//Bucle por cada <20>mbito de los que le tocan a este thread
|
||
/////////////////////////////////////
|
||
//el coste de un <20>mbito a s<> mismo es el de trabajar ese <20>mbito,
|
||
//que es el coste de ir de su conj inicial a la final
|
||
na=na_ini;
|
||
|
||
/////////////////////////////////////
|
||
for(na=na_ini;na<na_fin && !pirate; na++)
|
||
{
|
||
//En olv_limp->ias[i].ic_ini est<73> almacenado el <20>ndice de la conjunci<63>n del nodo inicial del <20>mbito
|
||
//y en olv_limp->ias[i].ic_fin el del final. Se puede acceder con i directamente al array ias porque
|
||
//la info asociada est<73> a<>adida por orden, primero los <20>mbitos
|
||
/////////////////////////////////////////////
|
||
//calcula el coste m<>ximo del <20>mbito na a todos los dem<65>s
|
||
//los a<>ade a la fila na de la matriz de costes
|
||
//es coste m<>ximo porque hace el m<>ximo de:
|
||
//inicio(na)->inicio(ni), inicio(na)->final(ni), final(na)->inicio(ni), final(na)->final(ni)
|
||
/////////////////////////////////////////////
|
||
//k==0, calcula las distancias del nodo inicial de ese <20>mbito a todas las dem<65>s conjunciones
|
||
//k==1, calucla las distancias del nodo final
|
||
for(k=0;k<KK;k++)
|
||
{
|
||
costes_nodos=NULL;
|
||
if(!Colv_geom::dijkstra_ang_inv_ok(olv_limp->cost_conj, olv_limp->ang_conj, olv_limp->conjs.n,
|
||
(1-k)*olv_limp->ias[na].ic_ini+k*olv_limp->ias[na].ic_fin,
|
||
&costes_nodos, &visto_ang))
|
||
{
|
||
mal=TRUE;
|
||
break;
|
||
}
|
||
|
||
//recorre todos los dem<65>s <20>mbitos buscando el coste a ellos en el array de costes devuelto, y los almacena
|
||
//almacena el coste a su nodo inicial y a su nodo final
|
||
if(olv_limp->ias[na].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
{
|
||
for (i=0; i<olv_limp->conjs.n; i++)
|
||
{
|
||
costes_nodos[i].dis=(float)MAYUSCULO;
|
||
costes_nodos[i].id_padre=-1;
|
||
costes_nodos[i].ids_ady.nady=0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for(i=0;i<olv_limp->n_amb;i++)
|
||
{
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
if(na==i)
|
||
{
|
||
//el coste de un <20>mbito a s<> mismo es el de trabajar ese <20>mbito
|
||
olv_limp->cost_amb[na][na]=olv_limp->cost_conj[olv_limp->ias[na].ic_ini][olv_limp->ias[na].ic_fin];
|
||
continue;
|
||
}
|
||
|
||
if(olv_limp->cost_amb[i][na]>costes_nodos[olv_limp->ias[i].ic_ini].dis)
|
||
olv_limp->cost_amb[i][na]=costes_nodos[olv_limp->ias[i].ic_ini].dis;
|
||
if(KK==OLV_AMB_LIN)
|
||
{
|
||
if(olv_limp->cost_amb[i][na]>costes_nodos[olv_limp->ias[i].ic_fin].dis)
|
||
olv_limp->cost_amb[i][na]=costes_nodos[olv_limp->ias[i].ic_fin].dis;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(!olv_limp->arch_dj.add_b(costes_nodos, na, k, TRUE))
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld,Error %ld no se ha podido guardar dj iref: %ld k: %ld", ithr,
|
||
GetLastError(),na,k);
|
||
}
|
||
|
||
for(i=0;i<olv_limp->conjs.n;i++)
|
||
{
|
||
costes_nodos[i].libera();
|
||
}
|
||
free(costes_nodos);
|
||
|
||
olv_limp->ord_sec[na].ctnod[k]=NULL;
|
||
if(KK==1)
|
||
olv_limp->ord_sec[na].ctnod[1]=NULL;
|
||
|
||
}
|
||
if(mal)
|
||
break;
|
||
|
||
//si es <20>mbito lineal calcula la distancia media de los cuatro nodos
|
||
if(na==1)
|
||
if(log_debug)
|
||
{
|
||
for(i=0;i<olv_limp->n_amb;i++)
|
||
{
|
||
if(olv_limp->cost_amb[na][i]>=MAYUSCULO)
|
||
caux=-1;
|
||
else
|
||
caux=olv_limp->cost_amb[na][i];
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Coste <20>mb %ld a <20>mb %ld es %lf", ithr,
|
||
na,i,caux);
|
||
}
|
||
}
|
||
|
||
//avisa de progreso
|
||
if(((na-na_ini)%100==0) || ((na-na_ini)==(na_desp-1)))
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Rellenando matriz de dist entre ambs %ld de %ld", ithr,
|
||
(na-na_ini+1),na_desp);
|
||
//avisa de progreso
|
||
prog_subthr=((1.0*(na-na_ini+1)/na_desp)+2)/3;///3 porque es la tercera parte del progreso los costes de conjunciones
|
||
thr_padre->encola(OLV_LIMP_EV_SUBTHR_PROG,&pp,FALSE);
|
||
}
|
||
}
|
||
|
||
if(visto_ang)
|
||
{
|
||
free(visto_ang);
|
||
visto_ang=NULL;
|
||
}
|
||
|
||
if(mal)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Error en c<>lculo de matriz de distancias entre <20>mbitos", ithr);
|
||
prog_subthr=-1;//para avisar al padre de que ha habido un error
|
||
}
|
||
else
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Fin Matriz de dist entre ambs, %.3f seg", ithr, 1.0*(GetTickCount()-seg)/1000);
|
||
}
|
||
thr_padre->encola(OLV_LIMP_EV_COST_AMB_FIN,NULL,FALSE);
|
||
|
||
/////////////////////////////////////
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Genera los sectores
|
||
*/
|
||
BOOL Colv_limp_thr::sectoriza()
|
||
{
|
||
int i,j;
|
||
BOOL res=TRUE;
|
||
|
||
if(olv_limp->n_amb<2)
|
||
{
|
||
pon_mi_msg("Error, n<>mero de <20>mbitos es %ld",olv_limp->n_amb);
|
||
return FALSE;
|
||
}
|
||
|
||
pon_mi_progre(OLV_TAREA_SECTORIZ, 0);
|
||
pon_mi_msg("");
|
||
err_str[0]=0;
|
||
|
||
if(!pide_memo_secto())
|
||
{
|
||
pon_mi_msg("Error, Sin memoria para sectorizaci<63>n");
|
||
return FALSE;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////
|
||
wgeotext(LOG_TODO,"olv_limp_t","Comienza sectorizaci<63>n %ld <20>mbitos en %ld sectores",
|
||
olv_limp->n_amb, olv_limp->nsec_act);
|
||
|
||
///////////////////////////////////////
|
||
//Algoritmo 1
|
||
if(!sectoriza_1())
|
||
{
|
||
pon_mi_msg("Errores producidos en sectorizaci<63>n: %s",err_str);
|
||
res=FALSE;
|
||
goto pinta;
|
||
}
|
||
|
||
///////////////////////////////////////
|
||
//Si es barrido mixto hay que copiar la info en las que no se ha sectorizado
|
||
if(olv_limp->barr_mix)
|
||
copia_info_barr_mix();
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
//Guarda el shape a<>adiendo la columna de sector
|
||
if(!guarda_dbf_sector(0))
|
||
{
|
||
pon_mi_msg("Errores producidos en sectorizaci<63>n: %s",err_str);
|
||
return FALSE;
|
||
}
|
||
//Guarda el shape a<>adiendo la columna de secuencia vac<61>a
|
||
if(!guarda_dbf_sector(1))
|
||
{
|
||
pon_mi_msg("Errores producidos en sectorizaci<63>n: %s",err_str);
|
||
return FALSE;
|
||
}
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
wgeotext(LOG_TODO,"olv_limp_t","Sector %ld, %03d <20>mbitos, coste total %lf",i,olv_limp->sec[i].namb, olv_limp->sec[i].cost_ac);
|
||
}
|
||
wgeotext(LOG_TODO,"olv_limp_t","Finalizada generacion de sectores--------------------------");
|
||
|
||
pinta:
|
||
//////////////////////////////////////////////////////////////
|
||
//pinta los sectores, solo en modo debug
|
||
for(j=0;j<olv_limp->n_amb;j++)
|
||
{
|
||
if(olv_limp->amb_sec[j].sec>=0)
|
||
(*olv_limp->olv->olv_ob->objt)[j].clase = 666 + olv_limp->amb_sec[j].sec;
|
||
}
|
||
|
||
return res;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Pide memoria e inicializa los arrays para la sectorizaci<63>n
|
||
*/
|
||
BOOL Colv_limp_thr::pide_memo_secto()
|
||
{
|
||
int i,j;
|
||
//////////////////////////////////////////////////////////////
|
||
//pide memoria para el array de distancias del sector
|
||
olv_limp->sec = (Info_sec *)malloc(olv_limp->nsec*sizeof(Info_sec));
|
||
if(!olv_limp->sec)
|
||
{
|
||
pon_mi_msg("Error, sin memoria para matriz de sectores");
|
||
return FALSE;
|
||
}
|
||
memset(olv_limp->sec,0,olv_limp->nsec*sizeof(Info_sec));
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
olv_limp->sec[i].iamb = (short *)malloc(olv_limp->n_amb*sizeof(short));
|
||
if(!olv_limp->sec[i].iamb)
|
||
{
|
||
pon_mi_msg("Error, sin memoria para matriz de sectores");
|
||
return FALSE;
|
||
}
|
||
}
|
||
//inicializa todo a may<61>sculo
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
olv_limp->sec[i].namb=0;
|
||
olv_limp->sec[i].iamb_ini_def=-1;
|
||
olv_limp->sec[i].t_despl[0]=olv_limp->sec[i].t_despl[1]=(float)olv_limp->t_despl;
|
||
for(j=0;j<olv_limp->n_amb;j++)
|
||
{
|
||
olv_limp->sec[i].iamb[j]=-1;
|
||
}
|
||
}
|
||
//////////////////////////////////////////////////////////////
|
||
//pide memoria para el array de <20>mbitos asignados al sector
|
||
olv_limp->amb_sec = (Info_amb_sec *)malloc(olv_limp->n_amb*sizeof(Info_amb_sec));
|
||
if(!olv_limp->amb_sec)
|
||
{
|
||
pon_mi_msg("Error, sin memoria para matriz de <20>mbitos en los sectores");
|
||
return FALSE;
|
||
}
|
||
memset(olv_limp->amb_sec,0,olv_limp->n_amb*sizeof(Info_amb_sec));
|
||
//inicializa todo
|
||
for(j=0;j<olv_limp->n_amb;j++)
|
||
{
|
||
olv_limp->amb_sec[j].sec=-1;
|
||
olv_limp->amb_sec[j].iseq=-1;
|
||
olv_limp->amb_sec[j].t=0;
|
||
}
|
||
|
||
olv_limp->nsec_orig=olv_limp->nsec;
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* A<>ade el <20>mbito 'i_amb' al sector 'i_sec', actualizando la info en todos los lugares necesarios
|
||
* Actualiza el coste que es el que lleva, mas el desplazamiento del que ya tiene al nuevo, m<>s el coste del nuevo
|
||
*/
|
||
BOOL Colv_limp_thr::add_amb_sec(int i_amb, int namb, int i_sec, Info_sec *ss, Info_amb_sec *aa, Matrix2d<float> &cost_amb, double cost_tot, int i_amb_p)
|
||
{
|
||
if(olv_limp->ias[i_amb].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
return FALSE;
|
||
ss[i_sec].iamb[ss[i_sec].namb]=i_amb;
|
||
ss[i_sec].namb++;
|
||
//apunta el <20>mbito al sector
|
||
aa[i_amb].sec=i_sec;
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Le quita el <20>mbito 'i_amb' al sector 'i_sec', actualizando la info en todos los lugares necesarios
|
||
* Actualiza el coste que es el que lleva, mas el desplazamiento del que ya tiene al nuevo, m<>s el coste del nuevo
|
||
* Al salir, hay que actualizar las distancias!
|
||
*/
|
||
void Colv_limp_thr::quita_amb_sec(int i_amb, int namb, int i_sec, Info_sec *ss, Info_amb_sec *aa, Matrix2d<float> &cost_amb, int i_amb_p)
|
||
{
|
||
int i,j;
|
||
for(i=0;i<ss[i_sec].namb;i++)
|
||
{
|
||
if(ss[i_sec].iamb[i]==i_amb)
|
||
break;
|
||
}
|
||
if(i>=ss[i_sec].namb)
|
||
return ; //no lo ten<65>a este sector
|
||
|
||
//le quita de su array de <20>ndices si tiene al menos uno posterior
|
||
for(j=i;j<ss[i_sec].namb-1;j++)
|
||
{
|
||
ss[i_sec].iamb[j]=ss[i_sec].iamb[j+1];
|
||
}
|
||
ss[i_sec].namb--;
|
||
|
||
//desapunta el <20>mbito
|
||
aa[i_amb].sec=-1;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Genera sectores en funci<63>n del <20>rbol. Asigna un <20>mbito a cada sector hasta nsec-1, y al <20>ltimo el resto de <20>mbitos
|
||
*/
|
||
BOOL Colv_limp_thr::genera_sectores3(int iamb_extr, int n_amb, int n_sec, Matrix2d<float> &cost_amb, Info_sec *ss, Info_amb_sec *aa)
|
||
{
|
||
int s, i,ii, j, k;
|
||
double d, dmax;
|
||
BOOL sec_cerc;
|
||
|
||
//busca elementos-------------------------------
|
||
add_amb_sec(iamb_extr,n_amb,0,ss,aa,cost_amb,MAYUSCULO,-1);
|
||
//busca ambitos extremos--------------------
|
||
for(s=1; s<n_sec; s++)
|
||
{
|
||
dmax=0;
|
||
k=-1;
|
||
sec_cerc=TRUE;
|
||
for (j=0; j<n_amb; j++)
|
||
{
|
||
if(aa[j].sec>=0)
|
||
continue;
|
||
if(olv_limp->ias[j].flgs & OLV_LIMP_FLG_AMB_NO)//se ha marcado para no usarse, por aislado o por carga insuficiente
|
||
{
|
||
aa[j].sec=-1;
|
||
continue;
|
||
}
|
||
|
||
for (ii=0; ii<aa[j].namb_cerca; ii++)
|
||
{
|
||
if(aa[aa[j].iamb_cerca[ii]].sec>=0)
|
||
break;
|
||
}
|
||
if(!sec_cerc && ii<aa[j].namb_cerca)
|
||
continue;
|
||
d=DBL_MAX;
|
||
for(i=0; i<s; i++)
|
||
{
|
||
if(cost_amb[ss[i].iamb[0]][j]<d)
|
||
d=cost_amb[ss[i].iamb[0]][j];
|
||
}
|
||
if(dmax<d)
|
||
{
|
||
dmax=d;
|
||
k=j;
|
||
sec_cerc=ii<aa[j].namb_cerca;
|
||
}
|
||
}
|
||
if(k<0)
|
||
{
|
||
return FALSE;//no deber<65>a
|
||
}
|
||
add_amb_sec(k,n_amb,s,ss,aa,cost_amb,MAYUSCULO,-1);
|
||
}
|
||
|
||
//asigna el resto de <20>mbitos al <20>ltimo sector s=n-1
|
||
for (j=0; j<n_amb; j++)
|
||
{
|
||
if(aa[j].sec>=0)
|
||
continue;
|
||
if(olv_limp->ias[j].flgs & OLV_LIMP_FLG_AMB_NO)//se ha marcado para no usarse, por aislado o por carga insuficiente
|
||
continue;
|
||
|
||
add_amb_sec(j,n_amb,n_sec-1,ss,aa,cost_amb,MAYUSCULO,-1);
|
||
k=j;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Prueba sectorizaci<63>n algoritmo 1, expansi<73>n seg<65>n cercan<61>a de <20>rbol de coste m<>nimo
|
||
*/
|
||
BOOL Colv_limp_thr::sectoriza_1()
|
||
{
|
||
double maxx,dd;
|
||
int iamb,i;
|
||
|
||
dd=0;
|
||
|
||
/////////////////////////////////////
|
||
//calcula el <20>rbol de coste m<>nimo para rellenar cercanos
|
||
//rellena_amb_cercanos_por_arbol(olv_limp->n_amb, olv_limp->cost_amb, olv_limp->amb_sec);
|
||
if(!rellena_amb_cercanos_por_carretera(olv_limp->n_amb, olv_limp->amb_sec, olv_limp->ord_sec))
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al rellenar ambitos cercanos por carretera");
|
||
return FALSE;
|
||
}
|
||
|
||
//comprueba islas
|
||
if(!quita_islas(olv_limp->n_amb, olv_limp->amb_sec, olv_limp->ord_sec))
|
||
{
|
||
wgeolog(LOG_TODO,"quita_islas","No consigue eliminar islas");
|
||
|
||
}
|
||
//////////////////////
|
||
//Como primer <20>mbito coge el m<>s extremo
|
||
//el de menor 'y+x'
|
||
maxx=MAYUSCULO;
|
||
for(i=0;i<olv_limp->n_amb;i++)
|
||
{
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
if((olv_limp->conjs.coor[olv_limp->ias[i].ic_ini][1]+olv_limp->conjs.coor[olv_limp->ias[i].ic_ini][0])<maxx)
|
||
{
|
||
maxx=olv_limp->conjs.coor[olv_limp->ias[i].ic_ini][1]+olv_limp->conjs.coor[olv_limp->ias[i].ic_ini][0];
|
||
iamb=i;
|
||
}
|
||
}
|
||
|
||
if((iamb<0) || (iamb>=olv_limp->n_amb))
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error no se ha encontrado ambito extremo");
|
||
return FALSE;
|
||
}
|
||
|
||
if(pirate)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Sale por peticion de usuario");
|
||
return FALSE;
|
||
}
|
||
|
||
//si se ha calculado el n<>mero de sectores ya se ha sectorizado inicialmente, no hay que llamar a genera_sectores
|
||
if(olv_limp->calc_nsec==0)
|
||
{
|
||
if(!genera_sectores3(iamb,olv_limp->n_amb,olv_limp->nsec,olv_limp->cost_amb,olv_limp->sec, olv_limp->amb_sec))
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al generar sectores");
|
||
return FALSE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//entra aqu<71> si ha calculado el n<>mero de sectores, y ya va a sectorizar
|
||
//en este modo, primero usa solo los dos primeros sectores, al primero le da un <20>mbito y al segundo el resto de <20>mbitos
|
||
if(!genera_sectores3(iamb,olv_limp->n_amb,olv_limp->nsec_act,olv_limp->cost_amb,olv_limp->sec, olv_limp->amb_sec))
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al generar sectores");
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
pon_mi_progre(OLV_TAREA_PERMU,0);
|
||
if(olv_limp->nsec>1)
|
||
{
|
||
if(olv_limp->calc_nsec==0)
|
||
{
|
||
dd=iguala_sectores4(olv_limp->n_amb, olv_limp->nsec, olv_limp->cost_amb, olv_limp->sec, olv_limp->amb_sec);
|
||
}
|
||
else
|
||
{
|
||
//entra aqu<71> si ha calculado el n<>mero de sectores, y ya va a sectorizar
|
||
dd=iguala_sectores5(iamb,olv_limp->n_amb, olv_limp->nsec, olv_limp->cost_amb, olv_limp->sec, olv_limp->amb_sec);
|
||
}
|
||
wgeotext(LOG_TODO,"olv_limp_t","Conseguida una desviaci<63>n de: %lf",dd);
|
||
}
|
||
else
|
||
{
|
||
olv_limp->sec[0].cost_ac=(float)calcula_cost_1sec_total(olv_limp->n_amb,olv_limp->sec,olv_limp->ias,olv_limp->ang_conj);
|
||
if(olv_limp->sec[0].cost_ac>=MAYUSCULO)
|
||
dd=-1;
|
||
}
|
||
|
||
if(dd<0)//si es -2, aislados, ya lo ha puesto el iguala_sectores4
|
||
{
|
||
if(dd==-2)
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Existen <20>mbitos aislados que\nno ha sido posible unir a la red");
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* parte del ambito central del sector y crea el arbol de camino minimo de dicho sector
|
||
marca en cada ambito quien es su padre y cuantos hijos tiene
|
||
devuelve el numero de ambitos frontera
|
||
**/
|
||
int Colv_limp_thr::asigna_padres(int amb_central, int namb, Matrix2d<float> &cost_amb, Info_sec *ss, Info_amb_sec *aa, int *buf, int nhijos_fron)
|
||
{
|
||
int i,j;
|
||
int psel,sel;
|
||
double d, dsel=MAYUSCULO;
|
||
int nn=1;
|
||
|
||
for (i=0; i<ss->namb; i++)
|
||
{
|
||
if(aa[ss->iamb[i]].iseq!=-1)
|
||
{
|
||
wgeotext(LOG_TODO,"olv_limp_t","Error en iasigna_padres, Ambito %d ya tiene padre asignados, sec %d",ss->iamb[i], aa[ss->iamb[i]].sec);
|
||
|
||
|
||
}
|
||
}
|
||
buf[0]=amb_central;
|
||
aa[amb_central].iseq=-2;
|
||
aa[amb_central].t=0;
|
||
while(nn<ss->namb)
|
||
{
|
||
dsel=MAYUSCULO;
|
||
sel=-1;
|
||
for (i=0; i<nn; i++)//recorre ambitos del arbol
|
||
{
|
||
|
||
for(j=0; j<ss->namb; j++)//recorre ambitos del sector
|
||
{
|
||
if(aa[ss->iamb[j]].iseq!=-1)
|
||
continue;
|
||
d=cost_amb[buf[i]][ss->iamb[j]];
|
||
if(d<dsel)
|
||
{
|
||
dsel=d;
|
||
sel=ss->iamb[j];
|
||
psel=buf[i];
|
||
}
|
||
}
|
||
}
|
||
if(sel<0)
|
||
{
|
||
wgeotext(LOG_TODO,"olv_limp_t","Error en iasigna_padres, no encontrado ambitos libres sin padres");
|
||
break;//terminado (esto no deberia pasar)
|
||
}
|
||
if(aa[psel].iseq<0)
|
||
aa[psel].iseq=sel;
|
||
buf[nn]=sel;
|
||
aa[sel].iseq=psel;
|
||
aa[sel].t+=1;
|
||
aa[psel].t+=1;
|
||
nn++;
|
||
}
|
||
//recorre ambitos para pillar los ambitos frontera----------------
|
||
d=0;
|
||
j=recorre_hijos(amb_central, namb, aa, NULL, 0, cost_amb, &d);
|
||
if((j+1)!=nn)
|
||
wgeotext(LOG_TODO,"olv_limp_t","Error en iasigna_padres,Existen hijos aislados");
|
||
|
||
nn=0;
|
||
for(j=0; j<ss->namb; j++)//recorre ambitos del sector
|
||
{
|
||
if(aa[ss->iamb[j]].t<=nhijos_fron)
|
||
buf[nn++]=ss->iamb[j];
|
||
}
|
||
|
||
|
||
return nn;
|
||
}
|
||
//*************************************************************************************
|
||
double Colv_limp_thr::dis_min_amb(int ids[2], int id_nod_ini, Secu_amb * ord_sec, BOOL res_nod, int iamb)
|
||
{
|
||
double dd=MAYUSCULO;
|
||
ids[0]=ids[1]=0;
|
||
|
||
//si puntuales, entra una vez, si lineales, entra cuatro
|
||
for(int k=0; k<3*olv_limp->tipo_ambit-2; k++)
|
||
{
|
||
if(dd>olv_limp->arch_dj.dame_dis(id_nod_ini, k/2, iamb,k%2))
|
||
{
|
||
ids[0]=k%2;
|
||
ids[1]=k/2;
|
||
dd=olv_limp->arch_dj.dame_dis(id_nod_ini, k/2, iamb,k%2);
|
||
}
|
||
}
|
||
if(res_nod)
|
||
{
|
||
ids[1]=olv_limp->ias[id_nod_ini].ic[ids[1]];
|
||
}
|
||
|
||
return dd;
|
||
}
|
||
//*************************************************************************************
|
||
typedef struct Dists
|
||
{
|
||
double dist;
|
||
int iamb;
|
||
}Dists;
|
||
//*************************************************************************************
|
||
BOOL Colv_limp_thr::quita_islas(int namb, Info_amb_sec *aa, Secu_amb * ord_sec)
|
||
{
|
||
int nis =-1, i;
|
||
if(namb<2)
|
||
return true;
|
||
short* islas = (short*) malloc(namb * sizeof(short));
|
||
|
||
if(!islas)
|
||
return false;
|
||
//marca todos los ambitos sin islas
|
||
for (i=0;i<namb;i++)
|
||
islas[i]=-1;
|
||
|
||
//detecta islas--------------------------------------------
|
||
std::stack<int> amb_pend;
|
||
for (i=0;i<namb;i++)
|
||
{
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
if(islas[i]>-1)
|
||
continue;
|
||
nis++;
|
||
amb_pend.push(i);
|
||
while(!amb_pend.empty())
|
||
{
|
||
int amb_act=amb_pend.top();
|
||
amb_pend.pop();
|
||
islas[amb_act]=nis;
|
||
//a<>ade cercanos a la pila
|
||
for (int k =0 ; k<aa[amb_act].namb_cerca; k++)
|
||
{
|
||
if(islas[aa[amb_act].iamb_cerca[k]]>-1)
|
||
continue;
|
||
amb_pend.push(aa[amb_act].iamb_cerca[k]);
|
||
}
|
||
|
||
}
|
||
}
|
||
wgeolog(LOG_TODO,"quita_islas","Numero de islas %ld",nis);
|
||
|
||
if(nis<1)
|
||
goto va_bien;
|
||
|
||
//quita islas
|
||
int iamb=-1;
|
||
int iamb_cerca=-1;
|
||
int oo[2];
|
||
double dis, dd;
|
||
for (int kis = nis; kis>0; kis--)
|
||
{
|
||
iamb=-1;
|
||
iamb_cerca=-1;
|
||
dis=MAYUSCULO;
|
||
for (i=0; i<namb; i++)
|
||
{
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
if(islas[i]!= kis)
|
||
continue;
|
||
for (int ii = 0; ii<namb; ii++)
|
||
{
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
if(islas[ii]== kis)
|
||
continue;
|
||
dd = dis_min_amb(oo,i,NULL, false,ii);
|
||
if(dd<dis && aa[i].namb_cerca<MAX_LEN_BUF_CERCANAS)
|
||
{
|
||
iamb=i;
|
||
iamb_cerca= ii;
|
||
dis=dd;
|
||
}
|
||
}
|
||
}
|
||
if(iamb<0)
|
||
goto va_mal;
|
||
aa[iamb].iamb_cerca[aa[iamb].namb_cerca++]=iamb_cerca;
|
||
for (i=0; i<namb; i++)
|
||
{
|
||
if(islas[i]!= kis)
|
||
continue;
|
||
islas[i] = islas[iamb_cerca];
|
||
}
|
||
}
|
||
|
||
|
||
va_bien:
|
||
free(islas);
|
||
return TRUE;
|
||
va_mal:
|
||
free(islas);
|
||
return FALSE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la info de <20>mbitos cercanos teniendo en cuenta la distancia por carretera entre ellos
|
||
*/
|
||
BOOL Colv_limp_thr::rellena_amb_cercanos_por_carretera(int namb, Info_amb_sec *aa, Secu_amb * ord_sec)
|
||
{
|
||
int i,j, n, r1, r2, cerca_p1=MAX_LEN_BUF_CERCANAS,rr,rmax;
|
||
int oo[2];
|
||
double dd;
|
||
int *secu1, *secu2;
|
||
int *conex=NULL;//matriz de conexi<78>n con <20>mbitos
|
||
const int RMAX_INI=2;
|
||
BOOL logdebug=FALSE;
|
||
|
||
secu1=(int*)malloc(sizeof(int)*2*olv_limp->conjs.n);
|
||
if(!secu1)
|
||
{
|
||
wgeolog(LOG_TODO,"rellena_amb_cercanos_por_carretera","Sin memoria para ambitos");
|
||
return FALSE;
|
||
}
|
||
|
||
Dists dis_[MAX_LEN_BUF_CERCANAS];
|
||
|
||
rmax=RMAX_INI;
|
||
|
||
//matriz de conexion con ambitos (te dice si una conjuncion esta conectada con un ambito y en ese caso con cual. -1 en caso contrario)
|
||
conex = (int*) malloc(olv_limp->conjs.n * sizeof(int));
|
||
if (!conex)
|
||
{
|
||
wgeolog(LOG_TODO,"rellena_amb_cercanos_por_carretera","Sin memoria para conjunciones");
|
||
return FALSE;
|
||
}
|
||
for (n=0;n<olv_limp->conjs.n;n++)
|
||
conex[n]=-1;
|
||
// matriz de distancias (olv_limp->cost_conj[][])
|
||
//olv_limp->tipo_ambit//indica que tipo de ambitos estamos tratando1 si es puntual 2 si es lineal
|
||
//olv_limp->ias[0].ic[0]id de la conjunion 1 del ambito 0
|
||
//olv_limp->ias[0].ic[1]id de la conjunion 2 del ambito 0
|
||
//bucle por todos los ambitos
|
||
//bucle por todos los nodos del ambito
|
||
//bucle por todos los nodos
|
||
//marcas en el array si el nodo es el del ambito o si tiene conexion directa con dicho <20>mbito
|
||
for (n=0;n<olv_limp->conjs.n;n++)
|
||
{
|
||
for (i=0;i<namb;i++)
|
||
{
|
||
for (j=0;j<olv_limp->tipo_ambit;j++)
|
||
{
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
if (olv_limp->ias[i].ic[j]==n )
|
||
{
|
||
//Ha encontrado que esta conjunci<63>n conecta con el <20>mbito i<>simo
|
||
conex[n]=i;
|
||
//Sale de los dos bucles
|
||
i=namb;
|
||
break;
|
||
}
|
||
else if(olv_limp->cost_conj[n][olv_limp->ias[i].ic[j]]!=(float)MAYUSCULO && conex[n]==-1)
|
||
{
|
||
conex[n]=i;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if(logdebug)
|
||
{
|
||
for(j=0;j<olv_limp->conjs.n;j++)
|
||
{
|
||
wgeolog(LOG_TODO,"rellena_amb_cercanos_por_carretera","n %ld conex[n] %ld",j, conex[j]);
|
||
}
|
||
}
|
||
|
||
secu2=&secu1[olv_limp->conjs.n];
|
||
for(j=0; j<namb; j++)
|
||
{
|
||
aa[j].namb_cerca=0;
|
||
}
|
||
Djkt_nodo *buf_aux[2];
|
||
BOOL cargado[2];
|
||
|
||
buf_aux[0]=olv_limp->arch_dj.dame_buf_nodos(FALSE);
|
||
buf_aux[1]=olv_limp->arch_dj.dame_buf_nodos(FALSE);
|
||
|
||
if(!buf_aux[0] || !buf_aux[1])
|
||
{
|
||
wgeolog(LOG_TODO,"rellena_amb_cercanos_por_carretera","Sin memoria para buffer de nodos");
|
||
goto va_mal;
|
||
}
|
||
|
||
for (j=0; j<namb; j++)
|
||
{
|
||
if(olv_limp->ias[j].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
cargado[0]=FALSE;
|
||
cargado[1]=FALSE;
|
||
for (i=0; i<namb; i++)
|
||
{
|
||
if(j==i)
|
||
continue;
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
//selecciona distancia minima de un ambito a otro
|
||
dd=dis_min_amb(oo,i,&ord_sec[j], TRUE, j);
|
||
if(dd>=MAYUSCULO)//sin conexion entre ambitos
|
||
continue;
|
||
|
||
//cargar ambito antes de archivo-------------------
|
||
if(!cargado[oo[0]])
|
||
{
|
||
olv_limp->arch_dj.get_b(j,oo[0],buf_aux[oo[0]]);
|
||
cargado[oo[0]]=TRUE;
|
||
}
|
||
//se verifica que en los cercanos no se pase por los mismos nodos
|
||
Colv_geom::ruta_dj_inv_ok(oo[1], secu1, buf_aux[oo[0]],olv_limp->conjs.n, &r1);
|
||
|
||
|
||
//Recorre los nodos de la ruta entre esos <20>mbitos para ver si alguno de los nodos no conecta directamente
|
||
//con alg<6C>n <20>mbito, en cuyo caso lo descarta
|
||
//o lo descarta tambi<62>n si lleva varios nodos de carretera seguidos
|
||
rr=0;
|
||
for (n=0;n<r1;n++)
|
||
{
|
||
if (conex[secu1[n]]!=-1
|
||
&& conex[secu1[n]]!=i
|
||
&& conex[secu1[n]]!=j)
|
||
break; //Esta conjunci<63>n conecta con un <20>mbito diferente. No vale
|
||
if(n>0 && conex[secu1[n]]==-1 && conex[secu1[n-1]]==-1)
|
||
rr++;
|
||
else if( n<(r1-2))
|
||
rr=0;
|
||
}
|
||
if (n<r1)
|
||
continue;
|
||
/////////
|
||
if(aa[i].namb_cerca>=MAX_LEN_BUF_CERCANAS)
|
||
continue;
|
||
|
||
aa[i].iamb_cerca[aa[i].namb_cerca]=j | (rr<<24);
|
||
aa[i].namb_cerca++;
|
||
}
|
||
}
|
||
|
||
//ordena-------------
|
||
for (i=0;i<namb;i++)
|
||
{
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
|
||
memset(dis_,0,sizeof(Dists)*MAX_LEN_BUF_CERCANAS);
|
||
if(aa[i].namb_cerca<=0)
|
||
{
|
||
aa[i].namb_cerca=aa[i].namb_cerca;
|
||
wgeolog(LOG_TODO,"rellena_amb_cercanos_por_carretera","iamb %ld 0 cercanos",i);
|
||
continue;
|
||
}
|
||
|
||
for(j=0;j<aa[i].namb_cerca;j++)
|
||
{
|
||
//selecciona distancia minima de un ambito a otro
|
||
//dis_[j].dist=(aa[i].iamb_cerca[j] & 0xff000000)>>24;
|
||
dis_[j].dist=dis_min_amb(oo,i,&ord_sec[aa[i].iamb_cerca[j] & 0x00ffffff], TRUE, aa[i].iamb_cerca[j] & 0x00ffffff);
|
||
dis_[j].iamb=aa[i].iamb_cerca[j];
|
||
}
|
||
|
||
qsort(dis_,aa[i].namb_cerca,sizeof(Dists),Colv_limp_thr::compara_dist_cerc);
|
||
|
||
if(logdebug)
|
||
{
|
||
for(j=0;j<aa[i].namb_cerca;j++)
|
||
{
|
||
wgeolog(LOG_TODO,"rellena_amb_cercanos_por_carretera","iamb %ld, iamb_cerca %ld, rr %ld, dismin %lf",
|
||
i,dis_[j].iamb & 0x00ffffff,(dis_[j].iamb & 0xff000000)>>24, dis_[j].dist);
|
||
}
|
||
}
|
||
|
||
for(j=0;j<aa[i].namb_cerca;j++)
|
||
aa[i].iamb_cerca[j]=dis_[j].iamb;
|
||
|
||
for(j=aa[i].namb_cerca-1; j>0 ;j--)
|
||
{
|
||
r1=(aa[i].iamb_cerca[j-1] & 0xff000000)>>24;
|
||
r2=(aa[i].iamb_cerca[j] & 0xff000000)>>24;
|
||
if(r1>0 || r2>0)
|
||
r1=r1;
|
||
if((r2-r1)>RMAX_INI)
|
||
aa[i].namb_cerca=j;
|
||
|
||
}
|
||
|
||
for(j=0;j<aa[i].namb_cerca;j++)
|
||
{
|
||
if(logdebug)
|
||
{
|
||
wgeolog(LOG_TODO,"rellena_amb_cercanos_por_carretera","iamb %ld, iamb_cerca_final %ld, rr %ld",
|
||
i,aa[i].iamb_cerca[j] & 0x00ffffff,(aa[i].iamb_cerca[j] & 0xff000000)>>24);
|
||
}
|
||
aa[i].iamb_cerca[j]= aa[i].iamb_cerca[j] & 0x00ffffff;
|
||
}
|
||
}
|
||
olv_limp->arch_dj.libera_buf(buf_aux[0]);
|
||
olv_limp->arch_dj.libera_buf(buf_aux[1]);
|
||
if(secu1)
|
||
free(secu1);
|
||
if(conex)
|
||
free(conex);
|
||
|
||
return TRUE;
|
||
va_mal:
|
||
olv_limp->arch_dj.libera_buf(buf_aux[0]);
|
||
olv_limp->arch_dj.libera_buf(buf_aux[1]);
|
||
|
||
if(conex)
|
||
free(conex);
|
||
if(secu1)
|
||
free(secu1);
|
||
return FALSE;
|
||
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Compara las estructuras Dist. Las ordena por distancia
|
||
*/
|
||
int Colv_limp_thr::compara_dist_cerc (const void * a, const void * b)
|
||
{
|
||
//si a<b devuelve negativo, si son iguales 0, y si es mayor positivo
|
||
|
||
return (int)(((Dists*) a)->dist - ((Dists*) b)->dist);
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Busca el sector m<>s cercano a un <20>mbito
|
||
* busca el ambito frontera de iamb mas cercano al sector id_sec
|
||
* si modo==1 busca se busca a cualquier sector menos id_sec
|
||
*/
|
||
int Colv_limp_thr::busca_sec_cerca_amb(Info_amb_sec *aa,int iamb, int id_sec, int modo)
|
||
{
|
||
int i,s,ia;
|
||
if(id_sec<0)
|
||
return -1;
|
||
for(i=0; i<aa[iamb].namb_cerca; i++)
|
||
{
|
||
s=aa[aa[iamb].iamb_cerca[i]].sec;
|
||
if(s<0)
|
||
continue;
|
||
if((modo==0 && s==id_sec)|| (modo==1 && s!=id_sec))
|
||
{
|
||
ia=aa[iamb].iamb_cerca[i];
|
||
return ia;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Ordena los sectores seg<65>n coste de mayor a menor
|
||
*/
|
||
int* Colv_limp_thr::ordena_sec( int n_sec, Info_sec *ss, int *buf )
|
||
{
|
||
int *isec, nord, j, i, k;
|
||
if(buf)
|
||
isec=buf;
|
||
else
|
||
isec=(int*)malloc(sizeof(int)*n_sec);
|
||
if(!isec)
|
||
return NULL;
|
||
|
||
nord=0;
|
||
/////////////////////////
|
||
for(j=0; j<n_sec; j++)
|
||
{
|
||
//busca posicion de sector j
|
||
for(i=0; i<nord; i++)
|
||
{
|
||
if(ss[isec[i]].cost_ac<ss[j].cost_ac)
|
||
break;
|
||
}
|
||
//despeja el lugar
|
||
for(k=nord-1; k>=i; k--)
|
||
isec[k+1]=isec[k];
|
||
isec[i]=j;
|
||
nord++;
|
||
}
|
||
return isec;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Algoritmo 5 de igualaci<63>n de sectores, pasando <20>mbitos de un sector a otro que tenga cerca
|
||
*/
|
||
double Colv_limp_thr::iguala_sectores5(int iamb, int n_amb, int n_sec, Matrix2d<float> &cost_amb, Info_sec *ss, Info_amb_sec *aa)
|
||
{
|
||
double desv;
|
||
int res;
|
||
enum Res{
|
||
RES_SALE_BIEN,
|
||
RES_SALE_MAL,
|
||
RES_NO_SALE,
|
||
RES_GENERA,
|
||
};
|
||
int i,j;
|
||
|
||
desv=0;
|
||
|
||
//llama al iguala_sect4 con, al principio s<>lo 2 sectores activos
|
||
//luego comprueba si el <20>ltimo de los nsec su coste es mayor que la jornada
|
||
//y si es as<61>, nsec_act++, cuidando que no pase de nsec
|
||
//se le a<>ade un <20>mbito, el m<>s lejano de nsec_act
|
||
//si su coste es cero, nsec_act--
|
||
//si es el coste es >0 y <= que el coste jornada, todo ok
|
||
do
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Iguala sectores 5 con %ld sectores", olv_limp->nsec_act);
|
||
desv=iguala_sectores4( n_amb, olv_limp->nsec_act, cost_amb, ss, aa);
|
||
if(desv<0)
|
||
{
|
||
//sale mal
|
||
res=RES_SALE_MAL;
|
||
continue;
|
||
}
|
||
if(ss[olv_limp->nsec_act-1].cost_ac==0)
|
||
{
|
||
if((olv_limp->nsec_act-1)<=0)
|
||
{
|
||
//sale bien, pero forzado, no deber<65>a salir por aqu<71>..
|
||
res=RES_SALE_BIEN;
|
||
continue;
|
||
}
|
||
olv_limp->nsec_act--;
|
||
res=RES_GENERA;
|
||
}
|
||
else if(ss[olv_limp->nsec_act-1].cost_ac>olv_limp->calc_nsec)
|
||
{
|
||
//a<>ade un sec activo, siempre que haya disponibles
|
||
if((olv_limp->nsec_act+1)>olv_limp->nsec)
|
||
{
|
||
//sale bien, pero forzado, no deber<65>a salir por aqu<71>..
|
||
res=RES_SALE_BIEN;
|
||
continue;
|
||
}
|
||
olv_limp->nsec_act++;
|
||
//llama de nuevo al genera_sectores
|
||
res=RES_GENERA;
|
||
}
|
||
else
|
||
{
|
||
//sale bien
|
||
res=RES_SALE_BIEN;
|
||
}
|
||
if(res==RES_GENERA)
|
||
{
|
||
//////////////////////////////////////////////////////////////
|
||
//reinicializa
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
olv_limp->sec[i].namb=0;
|
||
olv_limp->sec[i].iamb_ini_def=-1;
|
||
olv_limp->sec[i].t_despl[0]=olv_limp->sec[i].t_despl[1]=(float)olv_limp->t_despl;
|
||
for(j=0;j<olv_limp->n_amb;j++)
|
||
{
|
||
olv_limp->sec[i].iamb[j]=-1;
|
||
}
|
||
}
|
||
//reinicializa
|
||
for(j=0;j<olv_limp->n_amb;j++)
|
||
{
|
||
olv_limp->amb_sec[j].sec=-1;
|
||
olv_limp->amb_sec[j].iseq=-1;
|
||
olv_limp->amb_sec[j].t=0;
|
||
}
|
||
//////////////////////////////////////////////////////////////
|
||
if(!genera_sectores3(iamb,olv_limp->n_amb,olv_limp->nsec_act,olv_limp->cost_amb,olv_limp->sec, olv_limp->amb_sec))
|
||
{
|
||
//sale mal
|
||
res=RES_SALE_MAL;
|
||
}
|
||
}
|
||
|
||
} while (res>=RES_NO_SALE);
|
||
|
||
if(res==RES_SALE_MAL)
|
||
return -1;
|
||
|
||
//si sale bien, libera el espacio libre
|
||
if(olv_limp->nsec_act<olv_limp->nsec)
|
||
{
|
||
for(int i=olv_limp->nsec_act;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].cost_amb_sec)
|
||
free(olv_limp->sec[i].cost_amb_sec);
|
||
if(olv_limp->sec[i].cost_amb_sec_aux)
|
||
free(olv_limp->sec[i].cost_amb_sec_aux);
|
||
if(olv_limp->sec[i].iamb)
|
||
free(olv_limp->sec[i].iamb);
|
||
}
|
||
Info_sec* sec_aux;
|
||
sec_aux=(Info_sec*)realloc(olv_limp->sec,olv_limp->nsec_act*sizeof(Info_sec));
|
||
if(!sec_aux)
|
||
return -1;
|
||
olv_limp->sec=sec_aux;
|
||
olv_limp->nsec=olv_limp->nsec_act;
|
||
}
|
||
|
||
return desv;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Algoritmo 4 de igualaci<63>n de sectores, pasando <20>mbitos de un sector a otro que tenga cerca
|
||
*/
|
||
double Colv_limp_thr::iguala_sectores4(int n_amb, int n_sec, Matrix2d<float> &cost_amb, Info_sec *ss, Info_amb_sec *aa)
|
||
{
|
||
double desv;
|
||
double desv_last,cos_min, cos_min_last, cos_max, cos_max_last;
|
||
double desv_abs_old, desv_abs;
|
||
double d, d1;
|
||
BYTE* st=NULL;
|
||
int *isec=NULL, *iamb_r=NULL, j, i, ii, jj,k;
|
||
int sec_m=0;
|
||
int sselc=-1;
|
||
int iamb,ip, sec;
|
||
int nth=Colv_geom::dame_n_nucleos();
|
||
Secu_amb * ord_sec=olv_limp->ord_sec;
|
||
th_param_planif thp;
|
||
memset(&thp, 0, sizeof(thp));
|
||
thp.milis_sleep=1;
|
||
thp.namb_t=n_amb;
|
||
thp.abs=TRUE;
|
||
desv_last=dame_desv_sec(n_sec,ss, TRUE,&desv_abs_old);
|
||
BOOL log_debug=FALSE;
|
||
BOOL todo_ok=FALSE;
|
||
BOOL aisladas=FALSE;
|
||
char nfile[MAX_PATH];
|
||
BOOL nocalc=FALSE;
|
||
ii=jj=0;
|
||
|
||
strcpy_s(nfile,MAX_PATH,olv->paths.path_data);
|
||
cambiaext(nfile,".shp",".dbf");
|
||
|
||
|
||
////////////////////////////////////////////
|
||
//avisa de progreso
|
||
wgeolog(LOG_TODO,"olv_limp_t","Calculando permutaciones para mejorar al igualar sectores");
|
||
pon_mi_progre(OLV_TAREA_PERMU,0);
|
||
////////
|
||
|
||
thp.dth=(th_data_planif*)malloc(sizeof(th_data_planif)*nth);
|
||
memset(thp.dth, 0, sizeof(th_data_planif)*nth);
|
||
|
||
for (i=0; i<nth; i++)
|
||
{
|
||
thp.id_th=i;
|
||
thp.dth[i].activo=TRUE;
|
||
igt_sum_atm(&thp.nth,1);
|
||
AfxBeginThread(th_planificacion, (LPVOID)&thp, THREAD_PRIORITY_NORMAL, 0, 0, NULL);
|
||
while(thp.id_th>=0)
|
||
Sleep(1);
|
||
|
||
}
|
||
/////////////////////////////////////
|
||
|
||
desv=iguala_sectores3(n_amb, n_sec, cost_amb, ss, aa, ord_sec, &thp);
|
||
if(desv>=MAYUSCULO)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error en iguala_sect3");
|
||
goto salir;
|
||
}
|
||
desv_last=dame_desv_sec(n_sec,ss, TRUE, &desv_abs_old);
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Iguala sectores 4. Desv: %lf",desv_last);
|
||
|
||
if(olv_limp->calc_nsec<=0)
|
||
cos_max_last=dame_mima(n_sec, ss,&cos_min_last);
|
||
else
|
||
cos_max_last=cos_min_last=0;
|
||
iamb_r=(int*)malloc(sizeof(int)*n_amb*2);
|
||
if(!iamb_r)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al pedir memoria");
|
||
goto salir;
|
||
}
|
||
|
||
st=guarda_estado(n_amb,n_sec,aa,ss,st);
|
||
|
||
if(!st)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al guardar estado");
|
||
goto salir;
|
||
}
|
||
do
|
||
{
|
||
|
||
if((desv_last<OLV_DESV_MAX) || (desv_abs_old<=OLV_DESV_MAX_ABS) || fin_permu)
|
||
{
|
||
todo_ok=TRUE;
|
||
break;
|
||
}
|
||
//ordena sectores por coste--------------------------
|
||
isec=ordena_sec(n_sec,ss,isec);
|
||
//selecciona sector a bloquear
|
||
sselc=isec[sec_m];
|
||
//busca ambito mas peque<75>o posible
|
||
d=MAYUSCULO;
|
||
for (i=0; i<ss[sselc].namb; i++)
|
||
{
|
||
if(olv_limp->ias[ss[sselc].iamb[i]].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
for (j=0; j<aa[ss[sselc].iamb[i]].namb_cerca; j++)
|
||
{
|
||
k=aa[ss[sselc].iamb[i]].iamb_cerca[j];
|
||
if(aa[k].sec==sselc)
|
||
continue;
|
||
d1=cost_amb[ss[sselc].iamb[i]][ss[sselc].iamb[i]];
|
||
recorre_hijos(ss[sselc].iamb[i],n_amb,aa,iamb_r,0,cost_amb, &d1);
|
||
if(d1<d && aa[k].sec>=0)
|
||
{
|
||
d=d1;
|
||
iamb=ss[sselc].iamb[i];
|
||
ip=k;
|
||
sec=aa[k].sec;
|
||
}
|
||
}
|
||
}
|
||
if(d>=MAYUSCULO || sec<0)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error, no encuentra m<>s <20>mbitos cercanos");
|
||
if(desv<MAYUSCULO)
|
||
todo_ok=TRUE;//al menos ha conseguido hacer una igualaci<63>n
|
||
break;
|
||
}
|
||
k=recorre_hijos(iamb,n_amb,aa,iamb_r,0,cost_amb, &d1);
|
||
quita_amb_sec(iamb,n_amb,sselc,ss,aa,cost_amb,aa[iamb].iseq);
|
||
add_amb_sec(iamb,n_amb,sec,ss,aa,cost_amb,MAYUSCULO,ip);
|
||
for (i=0; i<k; i++)
|
||
{
|
||
quita_amb_sec(iamb_r[i*2],n_amb,sselc,ss,aa,cost_amb,iamb_r[i*2+1]);
|
||
add_amb_sec(iamb_r[i*2],n_amb,sec,ss,aa,cost_amb,MAYUSCULO,iamb_r[i*2+1]);
|
||
}
|
||
calcula_coste_1sec(ord_sec, &ss[sselc], olv_limp->ias, &thp,FALSE);
|
||
calcula_coste_1sec(ord_sec, &ss[sec], olv_limp->ias, &thp,FALSE);
|
||
//se pasa ambito mas peque del mayor sector al sector mas cercano
|
||
//se fija sector mas alto como bloqueado
|
||
ss[sselc].flags_tem|=OLV_LIMP_FLG_SEC_INFO_BLOCK;
|
||
|
||
iguala_sectores3(n_amb, n_sec, cost_amb, ss, aa, ord_sec, &thp);
|
||
|
||
//se desbloquea
|
||
ss[sselc].flags_tem&=~OLV_LIMP_FLG_SEC_INFO_BLOCK;
|
||
iguala_sectores3(n_amb, n_sec, cost_amb, ss, aa, ord_sec, &thp);
|
||
|
||
desv=dame_desv_sec(n_sec,ss, TRUE, &desv_abs);
|
||
|
||
if(desv>=desv_last)
|
||
{
|
||
if(olv_limp->calc_nsec<=0 && desv==desv_last)
|
||
cos_max=dame_mima(n_sec, ss, &cos_min);
|
||
else
|
||
cos_max=cos_min=0;
|
||
|
||
if( desv>desv_last || (((cos_max-cos_min)>= (cos_max_last-cos_min_last))))
|
||
|
||
{
|
||
//se vuelve a estado anterior
|
||
pon_estado(n_amb,n_sec,aa,ss,cost_amb,st);
|
||
|
||
desv=dame_desv_sec(n_sec,ss, TRUE);
|
||
if(desv!=desv_last)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Iguala sectores 4. Error no coincide desv anterior Desv: %lf Desv_old",desv, desv_last);
|
||
sec_m++;
|
||
if(sec_m>=n_sec-1)
|
||
{
|
||
todo_ok=TRUE;
|
||
break;
|
||
}
|
||
continue;
|
||
|
||
}
|
||
sec_m=0;
|
||
}
|
||
sec_m=0;
|
||
wgeolog(LOG_TODO,"olv_limp_t","Iguala sectores 4. Cambio mejora desv old: %lf, new %lf",desv_last, desv);
|
||
desv_last=desv;
|
||
desv_abs_old=desv_abs;
|
||
cos_max_last=cos_max;
|
||
cos_min_last=cos_min;
|
||
|
||
st=guarda_estado(n_amb,n_sec,aa,ss,st);
|
||
if(!st)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al guardar estado anterior");
|
||
goto salir;
|
||
}
|
||
} while (!pirate);
|
||
if(!todo_ok)
|
||
goto salir;
|
||
|
||
st=guarda_estado(n_amb,n_sec,aa,ss,st);
|
||
if(!st)
|
||
goto salir;
|
||
|
||
/*
|
||
if(olv_limp->calc_nsec>0)
|
||
todo_ok=FALSE;//se reinicia para ver si la siguiente parte todo_ok
|
||
while(olv_limp->calc_nsec>0 && !pirate)
|
||
{
|
||
if((desv_last<OLV_DESV_MAX))
|
||
{
|
||
todo_ok=TRUE;
|
||
break;
|
||
}
|
||
//selecciona sector a bloquear (el basura)
|
||
sselc=n_sec-1;
|
||
//busca ambito mas peque<75>o posible
|
||
d=MAYUSCULO;
|
||
for (i=0; i<ss[sselc].namb; i++)
|
||
{
|
||
for (j=0; j<aa[ss[sselc].iamb[i]].namb_cerca; j++)
|
||
{
|
||
k=aa[ss[sselc].iamb[i]].iamb_cerca[j];
|
||
if(aa[k].sec==sselc)
|
||
continue;
|
||
d1=cost_amb[ss[sselc].iamb[i]][ss[sselc].iamb[i]];
|
||
iamb=ss[sselc].iamb[i];
|
||
ip=k;
|
||
sec=aa[k].sec;
|
||
k=recorre_hijos(iamb,n_amb,aa,iamb_r,0,cost_amb, &d1);
|
||
if(d1>MAYUSCULO)
|
||
continue;
|
||
quita_amb_sec(iamb,n_amb,sselc,ss,aa,cost_amb,aa[iamb].iseq);
|
||
add_amb_sec(iamb,n_amb,sec,ss,aa,cost_amb,MAYUSCULO,ip);
|
||
|
||
for (ii=0; ii<k; ii++)
|
||
{
|
||
quita_amb_sec(iamb_r[ii*2],n_amb,sselc,ss,aa,cost_amb,iamb_r[ii*2+1]);
|
||
add_amb_sec(iamb_r[ii*2],n_amb,sec,ss,aa,cost_amb,MAYUSCULO,iamb_r[ii*2+1]);
|
||
}
|
||
//se fija sector mas alto como bloqueado
|
||
ss[sselc].flags_tem|=OLV_LIMP_FLG_SEC_INFO_BLOCK;
|
||
|
||
iguala_sectores3(n_amb, n_sec, cost_amb, ss, aa, ord_sec, &thp);
|
||
|
||
//se desbloquea
|
||
ss[sselc].flags_tem&=~OLV_LIMP_FLG_SEC_INFO_BLOCK;
|
||
|
||
iguala_sectores3(n_amb, n_sec, cost_amb, ss, aa, ord_sec, &thp);
|
||
|
||
desv=dame_desv_sec(n_sec,ss, TRUE);
|
||
|
||
if(desv>=desv_last)
|
||
{
|
||
//se vuelve a estado anterior
|
||
pon_estado(n_amb,n_sec,aa,ss,cost_amb,st);
|
||
|
||
desv=dame_desv_sec(n_sec,ss, TRUE);
|
||
if(desv!=desv_last)
|
||
desv_last=desv;
|
||
continue;
|
||
}
|
||
wgeolog(LOG_TODO,"olv_limp_t","Iguala sectores4. Cambio mejora desv old: %lf, new %lf",desv_last, desv);
|
||
desv_last=desv;
|
||
st=guarda_estado(n_amb,n_sec,aa,ss,st);
|
||
if(!st)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error al guardar estado");
|
||
goto salir;
|
||
}
|
||
break;
|
||
|
||
}
|
||
}
|
||
if(i>=ss[sselc].namb)
|
||
{
|
||
todo_ok=TRUE;
|
||
break;
|
||
}
|
||
}
|
||
*/
|
||
|
||
salir:
|
||
if(log_debug)
|
||
{
|
||
wgeotext(LOG_TODO,"olv_limp_t","------------------------------------------------");
|
||
for(i=0;i<n_sec;i++)
|
||
{
|
||
wgeotext(LOG_TODO,"olv_limp_t","Sector %ld, namb %03d, coste_ac %lf",i,ss[i].namb, ss[i].cost_ac);
|
||
}
|
||
wgeotext(LOG_TODO,"olv_limp_t","Finalizada igualaci<63>n de sectores4----------------");
|
||
}
|
||
|
||
//se bloquea y
|
||
thp.pirate=TRUE;
|
||
while(thp.nth>0)
|
||
Sleep(1);
|
||
if(iamb_r)
|
||
free(iamb_r);
|
||
if(st)
|
||
free(st);
|
||
free(isec);
|
||
|
||
if(thp.dth)
|
||
{
|
||
if(thp.dth[0].sec)
|
||
free(thp.dth[0].sec);
|
||
free(thp.dth);
|
||
|
||
}
|
||
|
||
if(!todo_ok)
|
||
{
|
||
wgeotext(LOG_TODO,"olv_limp_t","Errores varios en iguala_sectores4");
|
||
if(aisladas)
|
||
return -2;
|
||
return -1;
|
||
}
|
||
return desv_last;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Recorre los 'nesc' sectores igualando su coste
|
||
* La idea es poner ambitos a los sectores de menor coste manteniendo la condicion de no aisladas
|
||
*/
|
||
#define MAX_AMBI_IGUALA_SEC 500
|
||
double Colv_limp_thr::iguala_sectores3(int n_amb, int n_sec, Matrix2d<float> &cost_amb, Info_sec *ss, Info_amb_sec *aa, Secu_amb * ord_sec, th_param_planif *thp)
|
||
{
|
||
double desv,desv_last, desv_fut;//m<>xima desviaci<63>n permitida respecto a la media
|
||
BOOL hay_cambio,log_debug;
|
||
int *amb_fron;//indice a ambitos frontera de sectores
|
||
int *isec=NULL;//indice a sectores (ordenados de mayor a menor)
|
||
int *icerca;//indice a ambitos cercanos a los frontera de un sector
|
||
int *icamb;//indices a ambitos cambiados de sector en un pasp
|
||
int cambio[2][2];//[0]ambito y sector que se pasa al[1] ambito (padre) y sector
|
||
int siz_sec=(n_amb+1);
|
||
int j, i, k,kk, kkk;
|
||
int isec_min;
|
||
int ncerca;
|
||
int nhijos_frontera=10;
|
||
int namb_camb;
|
||
int ind_camb;
|
||
int nais=0;
|
||
//-------------------------------
|
||
|
||
log_debug=TRUE;
|
||
if(log_debug)
|
||
wgeotext(LOG_TODO,"olv_limp_t","Empieza igualacion de sectores 3");
|
||
isec=(int*)malloc(sizeof(int)*(1+n_sec*(n_amb+1)+n_sec+n_amb*5));
|
||
|
||
desv_last=MAYUSCULO;
|
||
|
||
if(!isec)
|
||
{
|
||
wgeotext(LOG_TODO,"olv_limp_t","Error en igualacion de sectores 3, sin memoria para bufferes");
|
||
return desv_last;//no deber<65>a pasar
|
||
}
|
||
icerca=&isec[n_sec+1];
|
||
icamb=&icerca[n_amb*2];
|
||
amb_fron=&icamb[n_amb*3];
|
||
|
||
//calcula media y desviacion de costes en sectores
|
||
//bucle
|
||
hay_cambio=TRUE;
|
||
ind_camb=-1;
|
||
for(j=0; j<n_sec; j++)
|
||
{
|
||
ss[j].flags_tem|= OLV_LIMP_FLG_SEC_CAMB;
|
||
}
|
||
do
|
||
{
|
||
if (!_CrtCheckMemory())
|
||
hay_cambio=hay_cambio;
|
||
//ordena sectores por coste-------------------------------------------------
|
||
if(hay_cambio)//se ha redistibuido ambitos entre sectores, se vuelve a intentar mejorar
|
||
{
|
||
nais=0;
|
||
//recorre sectores----------------------
|
||
//inicia todos los ambitos a -1 y numero de hijos a 0
|
||
for (i=0; i<n_amb; i++)
|
||
{
|
||
if(aa[i].sec<0)
|
||
{
|
||
nais++;
|
||
continue;
|
||
}
|
||
if(!(ss[aa[i].sec].flags_tem & OLV_LIMP_FLG_SEC_CAMB))
|
||
continue;
|
||
//solo resetea los que se han cambiado
|
||
aa[i].iseq=-1;//usada para almacenar indice al padre
|
||
aa[i].t=0;//usada para almacenar numero de hijos
|
||
}
|
||
i=0;
|
||
for(j=0; j<n_sec; j++)
|
||
{
|
||
if(ss[j].namb<=0)
|
||
continue;
|
||
if(!(ss[j].flags_tem & OLV_LIMP_FLG_SEC_CAMB))
|
||
{
|
||
i+=ss[j].namb;
|
||
continue;
|
||
}
|
||
|
||
//le quita el flag de cambio
|
||
ss[j].flags_tem &= ~OLV_LIMP_FLG_SEC_CAMB;
|
||
//asigna padres------------------------
|
||
nhijos_frontera=max(5,ss[j].namb);
|
||
amb_fron[j*siz_sec]=asigna_padres(ss[j].iamb[0], n_amb, cost_amb,&ss[j],aa,&amb_fron[j*siz_sec+1], nhijos_frontera);
|
||
//comprobacion de fronteras-------------------------------
|
||
for(k=0; k<amb_fron[j*siz_sec]; k++)
|
||
{
|
||
if(amb_fron[j*siz_sec+1+k]<0)
|
||
wgeotext(LOG_TODO,"olv_limp_t","Error en igualacion de sectores 3, calculo de fronteras erroneo en sector: %ld",j);
|
||
|
||
}
|
||
i+=ss[j].namb;
|
||
}
|
||
if(i!=n_amb-nais)
|
||
wgeotext(LOG_TODO,"olv_limp_t","Error en igualacion de sectores 3, ambitos mal asignados a sectores, la suma de los ambitos de los sectores no cuadra con los ambitos totales");
|
||
|
||
if(ord_sec && ind_camb<0)
|
||
calcula_coste_sectores(ord_sec, ss,n_sec, olv_limp->ias, thp);
|
||
if(desv_last<OLV_DESV_MAX || fin_permu)
|
||
break;
|
||
//ordena sectores por coste--------------------------
|
||
if(olv_limp->calc_nsec)
|
||
{
|
||
isec[0]=n_sec-1;
|
||
ordena_sec(n_sec-1, ss, &isec[1]);
|
||
isec_min=n_sec-1;
|
||
}
|
||
else
|
||
{
|
||
ordena_sec(n_sec, ss, isec);
|
||
isec_min=n_sec-1;
|
||
}
|
||
hay_cambio=FALSE;
|
||
if(log_debug && ind_camb>=0)
|
||
wgeotext(LOG_TODO,"olv_limp_t","Iguala sectores 3, mejorada desviacion tipica a %lf", desv_last);
|
||
}
|
||
else
|
||
{
|
||
isec_min--;
|
||
if(isec_min<=0)
|
||
break;//no se puede mejorar mas
|
||
}
|
||
//busca fronteras de otros sectores cercanas al sector isec_min
|
||
if(ss[isec[isec_min]].flags_tem& OLV_LIMP_FLG_SEC_INFO_BLOCK)
|
||
continue;
|
||
ncerca=0;
|
||
for(j=0; j<n_sec; j++)
|
||
{
|
||
if(ss[isec[j]].flags_tem& OLV_LIMP_FLG_SEC_INFO_BLOCK)
|
||
continue;
|
||
if(isec[j]==isec[isec_min])
|
||
{
|
||
//recorre frontera de j
|
||
kk=isec[j]*siz_sec+1;
|
||
for(i=amb_fron[isec[j]*siz_sec]-1; i>=0; i--)
|
||
{
|
||
//verifica que tenga ambitos cercanos de otros sectores
|
||
//si es asi a<>ade al array
|
||
k=busca_sec_cerca_amb(aa,amb_fron[kk+i], isec[isec_min],1);
|
||
if(k>=0)
|
||
{
|
||
icerca[ncerca*2]=k;
|
||
icerca[ncerca*2+1]=amb_fron[kk+i];
|
||
ncerca++;
|
||
}
|
||
}
|
||
continue;
|
||
}
|
||
//recore ambitos frontera de sector j
|
||
kk=isec[j]*siz_sec+1;
|
||
for(i=amb_fron[isec[j]*siz_sec]-1; i>=0; i--)
|
||
{
|
||
k=busca_sec_cerca_amb(aa,amb_fron[kk+i], isec[isec_min]);
|
||
if(k>=0)
|
||
{
|
||
icerca[ncerca*2]=amb_fron[kk+i];
|
||
icerca[ncerca*2+1]=k;
|
||
ncerca++;
|
||
}
|
||
}
|
||
}
|
||
if(ncerca<=0)
|
||
continue;//no se puede mejorar
|
||
if(ncerca>n_amb)
|
||
ncerca=ncerca;
|
||
desv_fut=MAYUSCULO;
|
||
ind_camb=-1;
|
||
for(i=0; i<ncerca; i++)
|
||
{
|
||
cambio[0][0]=icerca[i*2];//se pone este
|
||
cambio[0][1]=aa[cambio[0][0]].sec;
|
||
cambio[1][0]=icerca[i*2+1];//con padre este
|
||
cambio[1][1]=aa[cambio[1][0]].sec;
|
||
namb_camb=1;
|
||
icamb[0]=cambio[0][0];
|
||
icamb[1]=cambio[1][0];
|
||
icamb[2]=cambio[0][0];
|
||
if(cambio[0][1]<0)
|
||
continue;
|
||
//apuntar hijos em ambitos que se van a cambiar
|
||
for (j=0; j<namb_camb; j++)
|
||
{
|
||
k=icamb[j*3];
|
||
if(aa[icamb[j*3]].t<=1)
|
||
continue;
|
||
for(kk=0; kk<ss[cambio[0][1]].namb; kk++)
|
||
{
|
||
if(aa[ss[cambio[0][1]].iamb[kk]].iseq==k && aa[k].iseq!=ss[cambio[0][1]].iamb[kk])
|
||
{
|
||
icamb[namb_camb*3]=ss[cambio[0][1]].iamb[kk];
|
||
icamb[namb_camb*3+1]=k;
|
||
icamb[namb_camb++*3+2]=aa[icamb[namb_camb*3]].iseq;
|
||
}
|
||
}
|
||
|
||
}
|
||
for (j=0; j<n_sec; j++)
|
||
ss[j].cost_despl_aux=ss[j].cost_ac;
|
||
|
||
//modifica sectores--------------------------
|
||
for (j=0; j<namb_camb; j++)
|
||
{
|
||
k=icamb[j*3];
|
||
kk=icamb[j*3+1];
|
||
kkk=icamb[j*3+2];
|
||
quita_amb_sec(k, n_amb, cambio[0][1], ss, aa, cost_amb,kkk);
|
||
add_amb_sec(k,n_amb,cambio[1][1],ss,aa,cost_amb,MAYUSCULO,kk);
|
||
|
||
}
|
||
if(ord_sec)
|
||
{
|
||
thp->milis_sleep=0;
|
||
calcula_coste_1sec(ord_sec, &ss[cambio[0][1]], olv_limp->ias, thp,FALSE);
|
||
calcula_coste_1sec(ord_sec, &ss[cambio[1][1]], olv_limp->ias, thp,FALSE);
|
||
thp->milis_sleep=1;
|
||
}
|
||
//comprueba mejora o no-----------------------
|
||
desv=dame_desv_sec(n_sec,ss,TRUE);
|
||
|
||
if(desv<desv_last)
|
||
{
|
||
if(desv_fut>desv)
|
||
{
|
||
desv_fut=desv;
|
||
ind_camb=i;
|
||
}
|
||
}
|
||
//se deshace el cambio--------------------------
|
||
for (j=0; j<namb_camb; j++)
|
||
{
|
||
k=icamb[j*3];
|
||
kk=icamb[j*3+1];
|
||
kkk=icamb[j*3+2];
|
||
quita_amb_sec(k, n_amb, cambio[1][1], ss, aa, cost_amb,kk);
|
||
add_amb_sec(k,n_amb,cambio[0][1],ss,aa,cost_amb,MAYUSCULO,kkk);
|
||
|
||
}
|
||
|
||
for (j=0; j<n_sec; j++)
|
||
ss[j].cost_ac=ss[j].cost_despl_aux;
|
||
if(olv_limp->n_amb>=MAX_AMBI_IGUALA_SEC && ind_camb>=0)
|
||
break;
|
||
}
|
||
if(ind_camb>=0)
|
||
{
|
||
cambio[0][0]=icerca[ind_camb*2];//se pone este
|
||
cambio[0][1]=aa[cambio[0][0]].sec;
|
||
cambio[1][0]=icerca[ind_camb*2+1];//con padre este
|
||
cambio[1][1]=aa[cambio[1][0]].sec;
|
||
namb_camb=1;
|
||
icamb[0]=cambio[0][0];
|
||
icamb[1]=cambio[1][0];
|
||
icamb[2]=cambio[0][0];
|
||
for (j=0; j<n_sec; j++)
|
||
ss[j].cost_despl_aux=ss[j].cost_ac;
|
||
//apuntar hijos em ambitos que se van a cambiar
|
||
for (j=0; j<namb_camb; j++)
|
||
{
|
||
k=icamb[j*3];
|
||
if(aa[icamb[j*3]].t<=1)
|
||
continue;
|
||
for(kk=0; kk<ss[cambio[0][1]].namb; kk++)
|
||
{
|
||
if(aa[ss[cambio[0][1]].iamb[kk]].iseq==k && aa[k].iseq!=ss[cambio[0][1]].iamb[kk])
|
||
{
|
||
icamb[namb_camb*3]=ss[cambio[0][1]].iamb[kk];
|
||
icamb[namb_camb*3+1]=k;
|
||
icamb[namb_camb++*3+2]=aa[icamb[namb_camb*3]].iseq;
|
||
}
|
||
}
|
||
}
|
||
//modifica sectores--------------------------
|
||
for (j=0; j<namb_camb; j++)
|
||
{
|
||
k=icamb[j*3];
|
||
kk=icamb[j*3+1];
|
||
kkk=icamb[j*3+2];
|
||
quita_amb_sec(k, n_amb, cambio[0][1], ss, aa, cost_amb,kkk);
|
||
add_amb_sec(k,n_amb,cambio[1][1],ss,aa,cost_amb,MAYUSCULO,kk);
|
||
ss[cambio[0][1]].flags_tem|=OLV_LIMP_FLG_SEC_CAMB;
|
||
ss[cambio[1][1]].flags_tem|=OLV_LIMP_FLG_SEC_CAMB;
|
||
|
||
}
|
||
if(ord_sec)
|
||
{
|
||
thp->milis_sleep=0;
|
||
calcula_coste_1sec(ord_sec, &ss[cambio[0][1]], olv_limp->ias, thp,FALSE);
|
||
calcula_coste_1sec(ord_sec, &ss[cambio[1][1]], olv_limp->ias, thp,FALSE);
|
||
thp->milis_sleep=1;
|
||
}
|
||
//comprueba mejora o no-----------------------
|
||
double desv_lastold=desv_last;
|
||
desv_last=dame_desv_sec(n_sec,ss,TRUE);
|
||
|
||
if(desv_lastold<desv_last)
|
||
{
|
||
wgeotext(LOG_TODO,"olv_limp_t","Iguala sectores 3, --->OJO -->El cambio selec empeora des_act:%lf desv_obt: %lf",desv_lastold, desv_last);
|
||
//se deshace el cambio--------------------------
|
||
for (j=0; j<namb_camb; j++)
|
||
{
|
||
k=icamb[j*3];
|
||
kk=icamb[j*3+1];
|
||
kkk=icamb[j*3+2];
|
||
quita_amb_sec(k, n_amb, cambio[1][1], ss, aa, cost_amb,kk);
|
||
add_amb_sec(k,n_amb,cambio[0][1],ss,aa,cost_amb,MAYUSCULO,kkk);
|
||
|
||
}
|
||
|
||
for (j=0; j<n_sec; j++)
|
||
ss[j].cost_ac=ss[j].cost_despl_aux;
|
||
desv_last=dame_desv_sec(n_sec,ss,TRUE);
|
||
wgeotext(LOG_TODO,"olv_limp_t","Iguala sectores 3, --->OJO -->Se quita cambio y queda desv: %lf",desv_last);
|
||
hay_cambio=FALSE;
|
||
}
|
||
else
|
||
hay_cambio=TRUE;
|
||
}
|
||
else
|
||
{
|
||
hay_cambio=FALSE;
|
||
}
|
||
} while (TRUE);
|
||
//fin ----------------------------------------------------------
|
||
|
||
if(isec)
|
||
free(isec);
|
||
if(FALSE)
|
||
{
|
||
wgeotext(LOG_TODO,"olv_limp_t","------------------------------------------------");
|
||
|
||
for(i=0;i<n_sec;i++)
|
||
{
|
||
wgeotext(LOG_TODO,"olv_limp_t","Sector %ld, namb %03d, coste_ac %lf",i,ss[i].namb, ss[i].cost_ac);
|
||
}
|
||
|
||
}
|
||
if(log_debug)
|
||
wgeotext(LOG_TODO,"olv_limp_t","Finalizada igualaci<63>n de sectores 3----------------");
|
||
|
||
return desv_last;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Calcula la desviaci<63>n t<>pica entre los costes acumulados de los nsec sectores
|
||
* Si porc=true, la desviaci<63>n la devuelve en porcentaje respecto a la media, si no, absoluta
|
||
* en absol se mete la maxima desviacion encontrada
|
||
*/
|
||
double Colv_limp_thr::dame_desv_sec(int nsec, Info_sec *ss, BOOL porc /*=FALSE*/, double *absol)
|
||
{
|
||
int i=-1;
|
||
int j;
|
||
double costmax=MINUSCULO;
|
||
double cost_med,dd, cost_med2;
|
||
double cost_max, aux;
|
||
cost_med=cost_med2=0;
|
||
cost_max=-1;
|
||
//calcula la media
|
||
if(olv_limp->calc_nsec>0)
|
||
{
|
||
cost_med=olv_limp->calc_nsec; //impone el coste medio de los sectores, que es justo la jornada laboral
|
||
nsec--; //se quita un sector, el <20>ltimo, para el c<>lculo de la media
|
||
}
|
||
else
|
||
{
|
||
for(j=0;j<nsec;j++)
|
||
{
|
||
cost_med+=ss[j].cost_ac/nsec;
|
||
}
|
||
}
|
||
//calcula la desviaci<63>n t<>pica
|
||
for(j=0;j<nsec;j++)
|
||
{
|
||
dd=(ss[j].cost_ac-cost_med);
|
||
//si hay que fijar a la jornada, no se puede pasar de ese tiempo, as<61> que si la resta es positiva,
|
||
//aumenta la desviaci<63>n para falsear que esa soluci<63>n sea mala y no la coja
|
||
if((olv_limp->calc_nsec>0) && (dd>0))
|
||
{
|
||
dd+=cost_med*nsec*2;
|
||
}
|
||
aux=abs(dd);
|
||
if(aux>cost_max)
|
||
cost_max=aux;
|
||
cost_med2+=dd*dd/nsec;
|
||
}
|
||
if(olv_limp->calc_nsec>0)
|
||
{
|
||
if(((ss[nsec].cost_ac-cost_med)>0))//si est<73> en modo fijar jornada, tampoco queremos que se desmadre el <20>ltimo
|
||
{
|
||
aux=cost_med;
|
||
if(aux>cost_max)
|
||
cost_max=aux;
|
||
cost_med2+=cost_med*cost_med/nsec;
|
||
}
|
||
}
|
||
if(cost_med2>MINUSCULO)
|
||
cost_med2=sqrt(cost_med2);
|
||
else
|
||
cost_med2=0;
|
||
if(absol)
|
||
*absol=cost_max;
|
||
if(porc)
|
||
return cost_med2/cost_med;
|
||
else
|
||
return cost_med2;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Calcula diferencia minima y maxima de costes entre sectores
|
||
*/
|
||
double Colv_limp_thr::dame_mima(int nsec, Info_sec *ss, double *mini)
|
||
{
|
||
int i;
|
||
int j;
|
||
double costmax=-MAYUSCULO;
|
||
double costmin=MAYUSCULO;
|
||
double dd;
|
||
|
||
|
||
//calcula la desviaci<63>n t<>pica
|
||
for(j=0;j<nsec;j++)
|
||
{
|
||
for(i=j+1;i<nsec;i++)
|
||
|
||
dd=(ss[j].cost_ac-ss[i].cost_ac);
|
||
dd=max(dd,-dd);
|
||
//si hay que fijar a la jornada, no se puede pasar de ese tiempo, as<61> que si la resta es positiva,
|
||
//aumenta la desviaci<63>n para falsear que esa soluci<63>n sea mala y no la coja
|
||
if(dd>costmax)
|
||
costmax=dd;
|
||
if (dd<costmin)
|
||
costmax=dd;
|
||
|
||
|
||
}
|
||
if(mini)
|
||
*mini=costmin;
|
||
return costmax;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Guarda los datos necesarios para reconstuir el estado de la sectorizacion actual
|
||
*/
|
||
BYTE* Colv_limp_thr::guarda_estado( int namb,int n_sec, Info_amb_sec *aa, Info_sec *ss,BYTE *buf )
|
||
{
|
||
int a;
|
||
int k;
|
||
Info_est_amb *inf;
|
||
BYTE *res=buf;
|
||
if(!res)
|
||
res=(BYTE*)malloc(sizeof(Info_est_amb)*namb+sizeof(float)*n_sec);
|
||
if(!res)
|
||
return NULL;//sin memoria para guardar estado
|
||
memset(res,0,sizeof(Info_est_amb)*namb);
|
||
k=0;
|
||
|
||
for (a=0; a<namb ; a++)
|
||
{
|
||
inf=(Info_est_amb*)&res[k];
|
||
k+=sizeof(Info_est_amb);
|
||
inf->iseq=aa[a].iseq;
|
||
inf->sec=aa[a].sec;
|
||
inf->t=aa[a].t;
|
||
|
||
}
|
||
for (a=0; a<n_sec; a++)
|
||
{
|
||
*((float*)&res[k])=ss[a].cost_ac;
|
||
k+=sizeof(float);
|
||
}
|
||
return res;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Restaura el estado de la sectorizaci<63>n anterior
|
||
*/
|
||
BOOL Colv_limp_thr::pon_estado( int namb,int n_sec, Info_amb_sec *aa, Info_sec *ss, Matrix2d<float> &cost_amb, BYTE* st )
|
||
{
|
||
int i, k=0, s;
|
||
Info_est_amb *inf;
|
||
//prepara todo a 0---------------------
|
||
for (i=0; i<n_sec; i++)
|
||
{
|
||
ss[i].namb=0;
|
||
ss[i].iamb_cen=-1;
|
||
ss[i].flags_tem=0;
|
||
ss[i].cost_ac=0;
|
||
ss[i].cost_despl_aux=0;
|
||
ss[i].dis_med=0;
|
||
}
|
||
for (i=0; i<namb; i++)
|
||
{
|
||
inf=(Info_est_amb*)&st[k];
|
||
k+=sizeof(Info_est_amb);
|
||
aa[i].iseq=inf->iseq;
|
||
aa[i].t=inf->t;
|
||
aa[i].sec=inf->sec;
|
||
s=inf->sec;
|
||
if(s>=0)
|
||
ss[s].iamb[ss[s].namb++]=i;
|
||
}
|
||
for (i=0; i<n_sec; i++)
|
||
{
|
||
ss[i].cost_ac=*(float*)&st[k];
|
||
k+=sizeof(float);
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la lista de hijos de un nodo del <20>rbol
|
||
*/
|
||
int Colv_limp_thr::recorre_hijos( int iamb, int namb, Info_amb_sec *aa, int *iamb_r, int namb_r, Matrix2d<float> &cost_amb, double *cost, BOOL inicia)
|
||
{
|
||
int i, h;
|
||
if(inicia)
|
||
{
|
||
for (i=0; i<namb; i++)
|
||
aa[i].res=0;
|
||
}
|
||
aa[iamb].res=1;
|
||
if(aa[iamb].t<=0)//es frontera
|
||
return 0;
|
||
h=(int)(aa[iamb].t-1);
|
||
for (i=0; i<namb; i++)
|
||
{
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
if(aa[i].iseq!=iamb)
|
||
continue;
|
||
if(aa[i].res)
|
||
continue;
|
||
if(i==iamb)
|
||
continue;
|
||
aa[i].res=1;
|
||
*cost+=cost_amb[iamb][i]+cost_amb[i][i];
|
||
if(iamb_r)
|
||
{
|
||
iamb_r[namb_r*2]=i;
|
||
iamb_r[namb_r*2+1]=iamb;
|
||
}
|
||
namb_r++;
|
||
if(namb_r>namb)
|
||
namb_r=namb_r;
|
||
if(aa[i].t>1)
|
||
namb_r=recorre_hijos(i,namb, aa, iamb_r, namb_r, cost_amb, cost, FALSE);
|
||
h--;
|
||
if(h<=-2)
|
||
break;
|
||
}
|
||
return namb_r;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Actualiza la matriz de costes de los <20>mbitos a otros <20>mbitos
|
||
*/
|
||
BOOL Colv_limp_thr::actualiza_costes( int namb,int n_sec, Info_amb_sec *aa, Info_sec *ss, Matrix2d<float> &cost_amb )
|
||
{
|
||
|
||
int s, a, i, na, k, kk, p;
|
||
double d;
|
||
BOOL res=TRUE;
|
||
for (a=0; a<namb; a++)
|
||
{
|
||
aa[a].res=0;
|
||
}
|
||
for(s=0; s<n_sec; s++)
|
||
{
|
||
for (a=0; a<namb; a++)
|
||
{
|
||
if(aa[a].sec==s)
|
||
break;
|
||
}
|
||
if(a>=namb)
|
||
continue;
|
||
na=ss[s].namb;
|
||
ss[s].namb=1;
|
||
ss[s].iamb[0]=a;
|
||
ss[s].cost_ac=cost_amb[a][a];
|
||
aa[a].res=1;
|
||
while(TRUE)
|
||
{
|
||
k=-1;
|
||
d=MAYUSCULO;
|
||
for(i=0; i<ss[s].namb; i++)
|
||
{
|
||
kk=ss[s].iamb[i];
|
||
for (a=0; a<namb; a++)
|
||
{
|
||
if(aa[a].res || aa[a].sec!=s)
|
||
continue;
|
||
if (d>cost_amb[kk][a])
|
||
{
|
||
d=cost_amb[kk][a];
|
||
p=kk;
|
||
k=a;
|
||
}
|
||
}
|
||
}
|
||
if (k<0)
|
||
{
|
||
break;
|
||
}
|
||
ss[s].cost_ac+=cost_amb[p][k]+cost_amb[k][k];
|
||
aa[k].res=1;
|
||
ss[s].iamb[ss[s].namb++]=k;
|
||
}
|
||
if(na!=ss[s].namb)
|
||
res=FALSE;
|
||
|
||
|
||
}
|
||
|
||
return res;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Calcula el coste de desplazamiento de ir de ir por todos los ambitos sec desde ini hasta fin
|
||
*/
|
||
double Colv_limp_thr::dame_coste( Secu_amb * sec, int ini, int fin, Info_aso *ias , Info_sec *s, BOOL ind_abs)
|
||
{
|
||
double d=0;
|
||
int ind_cost,fin_old;
|
||
|
||
fin_old=fin;
|
||
|
||
while(ini<fin)
|
||
{
|
||
if (ind_abs)
|
||
ind_cost=s->iamb[sec[fin].iamb];
|
||
else
|
||
ind_cost=sec[fin].iamb;
|
||
|
||
d+=olv_limp->cost_amb[s->iamb[sec[fin].iamb]][s->iamb[sec[fin].iamb]];
|
||
d+=olv_limp->arch_dj.dame_dis(s->iamb[sec[fin-1].iamb],(sec[fin-1].entrada+1)%2,s->iamb[sec[fin].iamb],sec[fin].entrada);
|
||
fin--;
|
||
}
|
||
d+=olv_limp->cost_amb[s->iamb[sec[ini].iamb]][s->iamb[sec[ini].iamb]];
|
||
|
||
if(ini==0)//si ini es 0 falta sumar el coste de la planta al primer ambito
|
||
{
|
||
if (ind_abs)
|
||
ind_cost=s->iamb[sec[ini].iamb];
|
||
else
|
||
ind_cost=sec[ini].iamb;
|
||
if(olv_limp->nod_instal>=0)
|
||
{
|
||
int ee=0;
|
||
if(sec[ini].entrada>=0)
|
||
ee=sec[ini].entrada;
|
||
d+=olv_limp->arch_dj.dame_dis(olv_limp->arch_dj.id_instal,0,s->iamb[sec[ini].iamb],ee);
|
||
//d+=sec[ind_cost].ctnod[ee][olv_limp->nod_instal].dis;
|
||
}
|
||
else
|
||
d+=olv_limp->t_despl;
|
||
}
|
||
|
||
//suma el coste de ir del ultimo ambito a la instalaci<63>n
|
||
if(olv_limp->nod_instal>=0)
|
||
d+=olv_limp->ord_sec_plan[0].ctnod[0][ias[s->iamb[sec[fin_old].iamb]].ic[(sec[fin_old].entrada+1)%2]].dis;
|
||
else
|
||
d+=olv_limp->t_despl;
|
||
|
||
return d;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Calcula el coste de desplazamiento de ir por todos los ambitos sec desde ini hasta fin
|
||
* cambiando el <20>mbito de pos_old como si estuviera en pos_new
|
||
*/
|
||
double Colv_limp_thr::dame_coste_ex( Secu_amb * sec, int ini, int fin, Info_aso *ias, Info_sec *s, int pos_old, int pos_new, int entrada )
|
||
{
|
||
double d=0;
|
||
int sig, act;
|
||
int a_ent, s_ent;
|
||
|
||
while(ini<fin)
|
||
{
|
||
act=Colv_geom::dame_ind_per(ini,pos_old,pos_new);
|
||
sig=Colv_geom::dame_ind_per(ini+1,pos_old,pos_new);
|
||
if(act==pos_new)
|
||
a_ent=entrada;
|
||
|
||
else
|
||
a_ent=sec[act].entrada;
|
||
|
||
if(sig==pos_new)
|
||
s_ent=entrada;
|
||
|
||
else
|
||
s_ent=sec[sig].entrada;
|
||
d+=olv_limp->arch_dj.dame_dis(sec[act].iamb,a_ent,s->iamb[sec[sig].iamb],(s_ent+1)%2);
|
||
d+=olv_limp->cost_amb[s->iamb[sec[act].iamb]][s->iamb[sec[act].iamb]];
|
||
|
||
ini++;
|
||
}
|
||
|
||
act=Colv_geom::dame_ind_per(ini,pos_old,pos_new);
|
||
d+=olv_limp->cost_amb[s->iamb[sec[ini].iamb]][s->iamb[sec[ini].iamb]];
|
||
return d;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Lee la sectorizaci<63>n que viene como info asociada en el shp de entrada
|
||
*/
|
||
BOOL Colv_limp_thr::lee_secto()
|
||
{
|
||
BOOL ret;
|
||
int i,s;
|
||
char nfile[MAX_PATH];
|
||
int *info;
|
||
|
||
std::map<int,std::vector<int>> l_sec;
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Comienza lectura de sectorizaci<63>n");
|
||
pon_mi_progre(OLV_TAREA_LEE_SECTO, 0);
|
||
pon_mi_msg("");
|
||
err_str[0]=0;
|
||
|
||
/////////////////////////////////////
|
||
info = (int *)malloc(olv_limp->n_amb*sizeof(int));
|
||
if(!info)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error, sin memoria para info asociada");
|
||
return FALSE;
|
||
}
|
||
memset(info,0,olv_limp->n_amb*sizeof(int));
|
||
|
||
//lee dbf del shp la columna SECTOR
|
||
strcpy_s(nfile,MAX_PATH,olv->paths.path_data);
|
||
cambiaext(nfile,".shp",".dbf");
|
||
if(!olv_limp->olv->olv_sh->dame_col_int_dbf(nfile,0,olv_limp->n_amb,info,olv_limp->camps.campo_secto,err_str,OLV_MAX_ERR))
|
||
{
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
|
||
//rellena para cada sector info[i] qu<71> <20>mbitos tiene
|
||
for(i=0;i<olv_limp->n_amb; i++)
|
||
{
|
||
if(olv_limp->ias[i].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
|
||
l_sec[info[i]].push_back(i);
|
||
}
|
||
|
||
|
||
olv_limp->nsec=l_sec.size();
|
||
|
||
////////////////////////////////////////
|
||
//inicia los arrays para la sectorizaci<63>n
|
||
if(!pide_memo_secto())
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error, Sin memoria para lectura de sectorizaci<63>n");
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
|
||
i=-1;
|
||
int ia=0;
|
||
//mira cu<63>ntos sectores diferentes hay
|
||
for (std::map<int,std::vector<int>>::iterator it=l_sec.begin(); it!=l_sec.end(); ++it)
|
||
{
|
||
i++;
|
||
olv_limp->sec[i].namb = it->second.size();
|
||
for(int ia=0;ia<olv_limp->sec[i].namb;ia++)
|
||
{
|
||
olv_limp->sec[i].iamb[ia]=it->second[ia];
|
||
olv_limp->amb_sec[it->second[ia]].sec = i;
|
||
}
|
||
}
|
||
|
||
//////////////////////////////////////
|
||
//lee del dbf la columna SECUENCIA por si se ha puesto uno por defecto
|
||
if(!olv_limp->olv->olv_sh->dame_col_int_dbf(nfile,0,olv_limp->n_amb,info,"SECUENCIA",err_str,OLV_MAX_ERR))
|
||
{
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
//si hay alg<6C>n <20>mbito con secuencia "1" y no hay ya uno <20>mbito puesto como inicial en el sector, se pone
|
||
for(s=0;s<olv_limp->nsec;s++)
|
||
{
|
||
for(i=0;i<olv_limp->sec[s].namb;i++)
|
||
{
|
||
if(info[olv_limp->sec[s].iamb[i]]==1)
|
||
{
|
||
olv_limp->sec[s].iamb_ini_def=i;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
fin:
|
||
|
||
free(info);
|
||
|
||
if(!ret)
|
||
{
|
||
pon_mi_msg("Error en lectura de info de sectorizaci<63>n: %s",err_str);
|
||
}
|
||
else
|
||
{
|
||
//////////////////////////////////////////////////////////////
|
||
//pinta los sectores, solo en modo debug
|
||
for(int j=0;j<olv_limp->n_amb;j++)
|
||
{
|
||
if(olv_limp->amb_sec[j].sec>=0)
|
||
(*olv_limp->olv->olv_ob->objt)[j].clase = 666 + olv_limp->amb_sec[j].sec;
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Calcula el n<>mero de sectores <20>ptimo para los <20>mbitos dados
|
||
*/
|
||
BOOL Colv_limp_thr::calcula_n_sec()
|
||
{
|
||
BOOL ret;
|
||
int nsec;
|
||
double cost_tot,cost_sec;
|
||
|
||
////////////////
|
||
ret=TRUE;
|
||
nsec=-1;
|
||
////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Comienza c<>lculo del n<>mero de sectores");
|
||
pon_mi_progre(OLV_TAREA_CALC_SEC, 0);
|
||
pon_mi_msg("");
|
||
err_str[0]=0;
|
||
|
||
////////////////
|
||
olv_limp->nsec =olv_limp->nsec_act = 1; //se fija a un sector para planificar todo junto
|
||
|
||
if(!pide_memo_secto())
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error, Sin memoria");
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
|
||
//hace la sectorizaci<63>n con un sector para que lo asigne por <20>rbol
|
||
if(!sectoriza_1())//rellena Info_sec
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error en la primera sectorizaci<63>n");
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
////////////////////////////////
|
||
|
||
//calcula el coste de un sector con todos los <20>mbitos
|
||
cost_tot=olv_limp->sec[0].cost_ac;//calcula_cost_1sec_total(olv_limp->n_amb,olv_limp->sec,olv_limp->ias,olv_limp->conjs.n,olv_limp->cost_conj,olv_limp->ang_conj);
|
||
if(cost_tot>=MAYUSCULO)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error en el c<>lculo del coste total de los <20>mbitos");
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
|
||
//calcula el n<>mero de sectores, diviendo por el coste m<>ximo de un sector
|
||
cost_sec = dame_cost_jornada();
|
||
if(cost_sec<=0)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Tiempos de jornada, descanso y desplazamiento err<72>neos");
|
||
ret=FALSE;
|
||
goto fin;
|
||
}
|
||
nsec = (int)(cost_tot/cost_sec) + 1;
|
||
////////////////
|
||
olv_limp->calc_nsec=cost_sec; //se indica que el n<>mero de sectores es calculado, no impuesto
|
||
////////////////////////////////
|
||
|
||
//libera memoria
|
||
olv_limp->libera_memo_secto();
|
||
//pone el n<>mero de sectores calculado
|
||
if(nsec==1)
|
||
{
|
||
olv_limp->nsec =olv_limp->nsec_act = nsec;
|
||
}
|
||
else
|
||
{
|
||
olv_limp->nsec = nsec + 2;//elena abr 2018 coge un margen de 2, excepto si le ha salido que es 1
|
||
olv_limp->nsec_act = max(nsec,2);
|
||
}
|
||
/////////////////////////////////
|
||
|
||
fin:
|
||
if(!ret)
|
||
{
|
||
pon_mi_msg("Error en el c<>lculo del n<>mero de sectores: %s",err_str);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Calcula el tiempo efectivo de una jornada
|
||
*/
|
||
double Colv_limp_thr::dame_cost_jornada()
|
||
{
|
||
return olv_limp->t_conv-olv_limp->t_desc;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Lanza la planificaci<63>n de todos los <20>mbitos en un sector para calcular el coste total, y lo devuelve
|
||
* Devuelve tambi<62>n la secuencia de <20>mbitos planificada
|
||
*/
|
||
double Colv_limp_thr::calcula_cost_1sec_total(int n_amb, Info_sec *ss, Info_aso *ias, Djkt_ang_ady *ang_conj)
|
||
{
|
||
double coste;
|
||
int nth,n_sec,i;
|
||
Secu_amb *ord_sec;
|
||
th_param_planif thp;
|
||
BOOL log_debug;
|
||
BOOL nocalc;
|
||
|
||
////////////////
|
||
log_debug=TRUE;
|
||
n_sec=1;
|
||
nth=Colv_geom::dame_n_nucleos();
|
||
//inicia th
|
||
memset(&thp, 0, sizeof(thp));
|
||
thp.milis_sleep=1;
|
||
thp.namb_t=n_amb;
|
||
nocalc=FALSE;
|
||
coste=0;
|
||
////////////////
|
||
|
||
ord_sec=olv_limp->ord_sec;
|
||
|
||
//avisa de progreso
|
||
wgeolog(LOG_TODO,"olv_limp_t","Calculando permutaciones para mejorar al calcular coste de un sector total");
|
||
pon_mi_progre(OLV_TAREA_PERMU,0);
|
||
////////
|
||
|
||
thp.dth=(th_data_planif*)malloc(sizeof(th_data_planif)*nth);
|
||
memset(thp.dth, 0, sizeof(th_data_planif)*nth);
|
||
thp.abs=TRUE;
|
||
|
||
//lanza threads
|
||
for (i=0; i<nth; i++)
|
||
{
|
||
thp.id_th=i;
|
||
thp.dth[i].activo=TRUE;
|
||
igt_sum_atm(&thp.nth,1);
|
||
AfxBeginThread(th_planificacion, (LPVOID)&thp, THREAD_PRIORITY_NORMAL, 0, 0, NULL);
|
||
while(thp.id_th>=0)
|
||
Sleep(1);
|
||
}
|
||
|
||
if(!calcula_coste_sectores(ord_sec, ss, n_sec, ias, &thp, TRUE))
|
||
{
|
||
coste=MAYUSCULO;
|
||
goto salir;
|
||
}
|
||
coste=ss[0].cost_ac;
|
||
|
||
salir:
|
||
|
||
//se bloquea y
|
||
thp.pirate=TRUE;
|
||
while(thp.nth>0)
|
||
Sleep(1);
|
||
|
||
if(thp.dth)
|
||
{
|
||
if(thp.dth[0].sec)
|
||
free(thp.dth[0].sec);
|
||
free(thp.dth);
|
||
|
||
}
|
||
return coste;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Devuelve la planificaci<63>n de todos los sectores, en los que calcula la ruta <20>ptima o cercana a la <20>ptima
|
||
* que recorre los <20>mbitos de dicho sector
|
||
*/
|
||
BOOL Colv_limp_thr::planifica()
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Comienza planificaci<63>n");
|
||
pon_mi_progre(OLV_TAREA_PLANIF, 0);
|
||
pon_mi_msg("");
|
||
err_str[0]=0;
|
||
|
||
//revisa si alg<6C>n sector no tiene <20>mbitos
|
||
int ns=0;
|
||
for(int i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb>0)
|
||
ns++;
|
||
}
|
||
olv_limp->nsec=ns;
|
||
|
||
//inicializa el array de planificaciones
|
||
olv_limp->plan=(Info_planif*)malloc(olv_limp->nsec*sizeof(Info_planif));
|
||
if(!olv_limp->plan)
|
||
{
|
||
pon_mi_msg("Error, sin memoria en array de planificaci<63>n");
|
||
return FALSE;
|
||
}
|
||
memset(olv_limp->plan,0,olv_limp->nsec*sizeof(Info_planif));
|
||
|
||
//lanza los threads
|
||
lanza_subthrs(OLV_LIMP_EV_PLANIFICA_SUB);
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Devuelve la planificaci<63>n del sector i<>simo, que realiza el thread 'ithr'
|
||
*/
|
||
void Colv_limp_thr::planifica_sub_1(int ithr, Matrix2d<float> &cost_amb)
|
||
{
|
||
Info_sec *s;
|
||
Info_amb_sec *aa;
|
||
int i,iaux,is_ini,is_fin,is_desp,is,jmin;
|
||
BOOL log_debug=FALSE;
|
||
BOOL sal,sig;
|
||
Djkt_nodo *costes_nodos;
|
||
int nsecu,KK,ic_aux,ss,nsecu2;
|
||
Secu_amb *secu_ambi=NULL;
|
||
Param_olv_limp_thr pp;
|
||
Djkt_nodo* buf_nod=NULL;
|
||
costes_nodos=NULL;
|
||
int msecu1, msecu2;
|
||
msecu1 = msecu2 = olv_limp->conjs.n*2;
|
||
int *secu,*secu2;
|
||
secu=(int *)malloc(olv_limp->conjs.n*2*sizeof(int));
|
||
|
||
if(!secu)
|
||
{
|
||
sal=TRUE;
|
||
goto fin;
|
||
}
|
||
|
||
buf_nod=olv_limp->arch_dj.dame_buf_nodos();
|
||
if(!buf_nod)
|
||
{
|
||
sal=TRUE;
|
||
goto fin;
|
||
}
|
||
|
||
memset(secu,0,olv_limp->conjs.n*2*sizeof(int));
|
||
secu2=(int *)malloc(olv_limp->conjs.n*2*sizeof(int));
|
||
if(!secu2)
|
||
{
|
||
sal=TRUE;
|
||
goto fin;
|
||
}
|
||
memset(secu2,0,olv_limp->conjs.n*2*sizeof(int));
|
||
nsecu2=0;
|
||
//////////////////////////
|
||
pp.id_e=OLV_TAREA_PLANIF;//manda de par<61>metro la tarea de la que es el progreso
|
||
ic_aux=0;
|
||
KK=olv_limp->tipo_ambit;
|
||
sal=sig=FALSE;
|
||
jmin=0;
|
||
prog_subthr=0;
|
||
aa=olv_limp->amb_sec;
|
||
iaux=-1;
|
||
|
||
////////////////////////////////////////////////////
|
||
//mira a ver cu<63>ntos sectores le tocan a este thread
|
||
if(olv_limp->nsec<thr_padre->n_subthr)
|
||
{
|
||
//hay menos sectores que threads, o le toca uno o ninguno
|
||
if(ithr<olv_limp->nsec)
|
||
{
|
||
//solo hace un sector, el ithr-esimo
|
||
is_ini=ithr;
|
||
is_fin=ithr+1;
|
||
}
|
||
else
|
||
{
|
||
//no hace ning<6E>n sector, no hace falta
|
||
is_ini=0;
|
||
is_fin=0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//hay m<>s sectores que threads, le tocan m<>s de uno
|
||
is_desp=(int)ceil(1.0*(olv_limp->nsec)/n_subthr);
|
||
is_ini=ithr*is_desp;
|
||
is_fin=min((ithr+1)*is_desp,olv_limp->nsec);
|
||
}
|
||
//////////////////////////
|
||
if(is_fin==is_ini)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %02d, No Planifica ning<6E>n sector", ithr);
|
||
else if(is_fin-is_ini-1==0)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %02d, Planifica sector %02d", ithr,is_ini);
|
||
else
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %02d, Planifica sectores %02d a %02d", ithr,is_ini, is_fin-1);
|
||
|
||
|
||
//////////////////////////
|
||
//bucle en todos los sectores que le tocan al thread
|
||
for(is=is_ini;is<is_fin && !pirate && !sal;is++)
|
||
{
|
||
s = &olv_limp->sec[is];
|
||
if(s->namb<=0)
|
||
continue;
|
||
s->cost_despl_aux=0;
|
||
sig=FALSE;
|
||
|
||
//busca el <20>mbito inicial de la planificiaci<63>n
|
||
secu_ambi=planifica_sect(s,olv_limp->ang_conj, olv_limp->ias, OLV_LIMP_FACT_PERM);
|
||
if(!secu_ambi)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Imposible planificar sector %02d",ithr,is);
|
||
sal=TRUE;
|
||
continue;
|
||
}
|
||
if(esta_repe(secu_ambi, s->namb))
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Esta repe despues de planifica sec");
|
||
sal=TRUE;
|
||
continue;
|
||
}
|
||
|
||
///////////////////////////////////////////
|
||
//A<>ade la ruta de la instalaci<63>n al primer punto
|
||
if(olv_limp->nod_instal>=0 && olv_limp->ord_sec_plan)
|
||
{
|
||
olv_limp->arch_dj.get_b(s->iamb[secu_ambi[0].iamb],secu_ambi[0].entrada,buf_nod);
|
||
Colv_geom::ruta_dj_inv_ok(
|
||
olv_limp->nod_instal,//id conjuncion inicial
|
||
&secu2[0], //puntero a secuencia
|
||
buf_nod, //nodos djktra conj final
|
||
olv_limp->conjs.n,
|
||
&nsecu2);
|
||
|
||
if(!genera_planif_instala(is, 0, 0, nsecu2, secu2, OLV_IDA_INST))
|
||
sal=TRUE;
|
||
}
|
||
///////////////////////////////////////////
|
||
|
||
ss=1;
|
||
s->cost_despl_aux=olv_limp->cost_amb[s->iamb[secu_ambi[0].iamb]][s->iamb[secu_ambi[0].iamb]];
|
||
s->cost_despl_aux+=s->t_despl[0];//el desplazamiento de la instalaci<63>n al primer <20>mbito
|
||
secu[0]=olv_limp->ias[s->iamb[secu_ambi[0].iamb]].ic[secu_ambi[0].entrada];
|
||
|
||
//almacena el coste acumulado
|
||
aa[s->iamb[secu_ambi[0].iamb]].iseq=0;
|
||
double cc, cc1=0;
|
||
for (i=1; i<s->namb; i++)
|
||
{
|
||
olv_limp->arch_dj.get_b(s->iamb[secu_ambi[i].iamb],secu_ambi[i].entrada, buf_nod);
|
||
cc=Colv_geom::ruta_dj_inv_ok(
|
||
olv_limp->ias[s->iamb[secu_ambi[i-1].iamb]].ic[(secu_ambi[i-1].entrada+1)%2],//id conjuncion final
|
||
&secu[ss], //puntero a secuencia
|
||
buf_nod, //nodos djktra conj inicial
|
||
olv_limp->conjs.n,
|
||
&nsecu);
|
||
ss+=nsecu;
|
||
s->cost_despl_aux+=(float)cc;
|
||
s->cost_despl_aux+=olv_limp->cost_amb[s->iamb[secu_ambi[i].iamb]][s->iamb[secu_ambi[i].iamb]];
|
||
|
||
//almacena el coste acumulado
|
||
aa[s->iamb[secu_ambi[i].iamb]].iseq=i;
|
||
cc1+=olv_limp->arch_dj.dame_dis(s->iamb[secu_ambi[i-1].iamb],(secu_ambi[i-1].entrada+1)%2,s->iamb[secu_ambi[i].iamb], secu_ambi[i].entrada);
|
||
|
||
//////////////////
|
||
if((i%50)==0 || (i==s->namb-1))
|
||
{
|
||
//avisa de progreso
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Planificando sector %02d, amb %ld de %ld", ithr,is,
|
||
(i+1),(s->namb));
|
||
prog_subthr=(1.0*(i+1)/(s->namb))*((is+1)/(is_fin-is_ini)); //porque son varios sectores
|
||
thr_padre->encola(OLV_LIMP_EV_SUBTHR_PROG,&pp,FALSE);
|
||
}
|
||
/////////////////
|
||
|
||
}
|
||
if(olv_limp->tipo_ambit==OLV_AMB_LIN)//a<>ade el coste del <20>ltimo <20>mbito si es lineal
|
||
{
|
||
secu[ss++]=olv_limp->ias[s->iamb[secu_ambi[s->namb-1].iamb]].ic[(secu_ambi[s->namb-1].entrada+1)%2];
|
||
}
|
||
s->cost_despl_aux+=s->t_despl[1];//el desplazamiento del <20>ltimo <20>mbito a la instalaci<63>n
|
||
|
||
if(esta_repe(secu_ambi, s->namb, FALSE))
|
||
wgeolog(LOG_TODO,"olv_limp_t","Esta repe despues de planificar");
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Planificando sector %02d, coste total %lf",ithr,is,s->cost_despl_aux);
|
||
|
||
///////////////////////////////////////////
|
||
//Ruta del <20>ltimo punto a la instalaci<63>n
|
||
if(olv_limp->nod_instal>=0 && olv_limp->ord_sec_plan)
|
||
{
|
||
|
||
Colv_geom::ruta_dj_inv_ok(
|
||
olv_limp->ias[s->iamb[secu_ambi[s->namb-1].iamb]].ic[(secu_ambi[s->namb-1].entrada+1)%2],
|
||
&secu2[0], //puntero a secuencia
|
||
olv_limp->ord_sec_plan[0].ctnod[0], //nodos djktra conj final
|
||
olv_limp->conjs.n,
|
||
&nsecu2);
|
||
if(!genera_planif_instala(is, 0, 0, nsecu2, secu2, OLV_VUELTA_INST))
|
||
{
|
||
sal=TRUE;
|
||
break;
|
||
}
|
||
}
|
||
///////////////////////////////////////////
|
||
|
||
if(!pirate && !sal)
|
||
{
|
||
//////////////////////////////////
|
||
//genera la ruta y los puntos de control
|
||
if(!genera_planif(is,s->cost_despl_aux, ss, secu,OLV_PLAN_NORMAL))
|
||
sal=TRUE;
|
||
|
||
}
|
||
//////////////////////////////////
|
||
if( secu_ambi)
|
||
{
|
||
free(secu_ambi);
|
||
secu_ambi=NULL;
|
||
}
|
||
}
|
||
free(secu);
|
||
free(secu2);
|
||
fin:
|
||
//Ha terminado, encola al padre
|
||
olv_limp->arch_dj.libera_buf(buf_nod);
|
||
if(sal)
|
||
{
|
||
prog_subthr=-1;//para avisar al padre de que ha habido un error
|
||
}
|
||
thr_padre->encola(OLV_LIMP_EV_PLANIFICA_FIN,NULL,FALSE);
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Finaliza y centraliza tareas de planificar, cuando han acabado todos los threads
|
||
*/
|
||
BOOL Colv_limp_thr::planifica_fin()
|
||
{
|
||
|
||
//para los threads
|
||
para_subthrs();
|
||
err_str[0]=0;
|
||
|
||
///////////////////////////////////////
|
||
//Si es barrido mixto hay que copiar la info en las que no se ha sectorizado
|
||
if(olv_limp->barr_mix)
|
||
copia_info_barr_mix();
|
||
|
||
//Inicia los obg
|
||
ob_rut = new Cobgeo();
|
||
ob_ctrl = new Cobgeo();
|
||
ob_flech = new Cobgeo();
|
||
ob_inst = new Cobgeo();
|
||
ob_inst_fl= new Cobgeo();
|
||
memcpy(&ob_inst_fl->nvl,&olv_limp->olv->olv_ob->nvl,sizeof(Niveles));
|
||
memcpy(&ob_inst->nvl,&olv_limp->olv->olv_ob->nvl,sizeof(Niveles));
|
||
memcpy(&ob_rut->nvl,&olv_limp->olv->olv_ob->nvl,sizeof(Niveles));
|
||
memcpy(&ob_flech->nvl,&olv_limp->olv->olv_ob->nvl,sizeof(Niveles));
|
||
memcpy(&ob_ctrl->nvl,&olv_limp->olv->olv_ob->nvl,sizeof(Niveles));
|
||
|
||
///////////////////////////////////
|
||
//prepara los datos para guardarlos
|
||
if(!genera_obg_rut_ctrl(olv_limp->nsec, olv_limp->plan, ob_rut, ob_ctrl))
|
||
{
|
||
pon_mi_msg("Errores en la generaci<63>n de cartograf<61>a con ruta");
|
||
return FALSE;
|
||
}
|
||
//genera el listado del itinerario
|
||
if(!genera_list_rut_ctrl(ob_rut))
|
||
{
|
||
pon_mi_msg("Errores en la generaci<63>n del listado de la ruta: %s",err_str);
|
||
return FALSE;
|
||
}
|
||
//graba a archivo el obg
|
||
if(!guarda_shp_rut_ctrl(ob_rut, ob_ctrl))
|
||
{
|
||
pon_mi_msg("Errores en el guardado a shp de la ruta: %s",err_str);
|
||
return FALSE;
|
||
}
|
||
|
||
if(!guarda_dbf_sector(2))
|
||
{
|
||
pon_mi_msg("Errores en la generaci<63>n de informaci<63>n asociada de sector: %s",err_str);
|
||
return FALSE;
|
||
}
|
||
///////////////////////////////////
|
||
|
||
/////////////////////////////////////////////
|
||
//A continuaci<63>n genera y graba los archivos de los subtramos de cada ruta
|
||
if(!gen_guard_subtramos())
|
||
return FALSE;
|
||
///////////////////////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Planificaci<EFBFBD>n finalizada");
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Dada la secuencia de las conjunciones que sigue la ruta, genera la ruta diciendo por qu<71>
|
||
* elementos de la red pasa y coloca los puntos de control
|
||
*/
|
||
BOOL Colv_limp_thr::genera_planif(int is, double cost_sec, int nsecu, int *secu, int tip_plan)
|
||
{
|
||
int npt_ctrl,ipc;
|
||
double cost_ctrl;
|
||
Info_planif *pp;
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Almacenando planificaci<63>n sector %02d",is);
|
||
|
||
/////////////////
|
||
cost_ctrl=(cost_sec-olv_limp->sec[is].t_despl[0]-olv_limp->sec[is].t_despl[1])/(olv_limp->npts_ctrl-2+1);
|
||
ipc=0;
|
||
npt_ctrl=(olv_limp->npts_ctrl-2);
|
||
pp=&olv_limp->plan[is];
|
||
|
||
if(!genera_planif_aux(is,&olv_limp->sec[is], pp, nsecu, secu,tip_plan))
|
||
return FALSE;
|
||
|
||
pon_ptos_ctrl(pp, npt_ctrl, cost_ctrl);
|
||
|
||
//////////////////////////////////////////////////////////
|
||
|
||
olv_limp->sec[is].cost_ac=(float)cost_sec;
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
*/
|
||
void Colv_limp_thr::pon_ptos_ctrl(Info_planif *pp, int npt_ctrl, double cost_ctrl)
|
||
{
|
||
double cost_acum;
|
||
int i, ipc;
|
||
///////////////////////////////////////////////////////////////
|
||
//Inicializa el array de puntos de control
|
||
pp->pts_ctrl=(Info_planif_ctrl*)malloc((olv_limp->npts_ctrl-2+1)*sizeof(Info_planif_ctrl));
|
||
if(!pp->pts_ctrl)
|
||
return;
|
||
memset(pp->pts_ctrl,0,(olv_limp->npts_ctrl-2+1)*sizeof(Info_planif_ctrl));
|
||
ipc=0;
|
||
|
||
cost_acum=0;
|
||
for(i=0;i<pp->nelem;i++)
|
||
{
|
||
/////////////////////////////
|
||
cost_acum=pp->elem[i].coste;
|
||
//mira si toca punto de control
|
||
if((cost_acum-ipc*(cost_ctrl/*+olv_limp->t_desc*/))>(cost_ctrl+1))
|
||
{
|
||
if(ipc<npt_ctrl)
|
||
{
|
||
//a<>ade como punto de control
|
||
pp->pts_ctrl[ipc].ipt=i-1;
|
||
ipc++;
|
||
}
|
||
else
|
||
ipc=ipc;
|
||
}
|
||
}
|
||
|
||
for(i=0;i<npt_ctrl;i++)
|
||
{
|
||
if(pp->pts_ctrl[i].ipt<0)
|
||
pp->pts_ctrl[i].ipt=pp->nelem-1;
|
||
}
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Dada la secuencia de las conjunciones que sigue la ruta, genera la ruta diciendo por qu<71>
|
||
* elementos de la red pasa y coloca los puntos de control - Funci<63>n auxiliar
|
||
*/
|
||
BOOL Colv_limp_thr::genera_planif_aux(int is, Info_sec *ss, Info_planif *pp, int nsecu, int *secu, int tip_plan)
|
||
{
|
||
int i,j,npt,il,indx,npt_ctrl,nelesec,ia_nw,tp,namb,last_pt,dt,k,itr;
|
||
double (*ptos)[3], cost_parc_aux,ltot,cost, cost_perd;
|
||
Cobgeo *ob;
|
||
BOOL sal,sdire,log_debug,is_descarg,is_uno;
|
||
BYTE *ambs_sec;
|
||
|
||
/////////////////
|
||
ob=olv_limp->olv->olv_ob;
|
||
sal=FALSE;
|
||
npt_ctrl=(olv_limp->npts_ctrl-2);
|
||
cost_parc_aux=0;
|
||
nelesec=0;
|
||
namb=0;
|
||
log_debug=FALSE;
|
||
last_pt=-1;
|
||
is_descarg=FALSE;
|
||
is_uno=FALSE;
|
||
|
||
if(nsecu==1)
|
||
{
|
||
is_uno=TRUE;
|
||
nsecu=2;
|
||
}
|
||
|
||
//Inicializa los arrays de elementos
|
||
pp->nelem = nsecu-1;
|
||
//ielem
|
||
pp->elem=(Info_elem_planif*)malloc(pp->nelem*sizeof(Info_elem_planif));
|
||
if(!pp->elem)
|
||
return FALSE;
|
||
memset(pp->elem,0,pp->nelem*sizeof(Info_elem_planif));
|
||
//////////////////////////////////////////////////////////////////
|
||
itr=0;
|
||
|
||
//////////////////////////////////////////////////////////////////
|
||
//si es un <20>nico elemento
|
||
if(is_uno)
|
||
{
|
||
//recorre los <20>mbitos busc<73>ndolo
|
||
for(j=0;j<ob->vect.nobj;j++)
|
||
{
|
||
if((*ob->objt)[j].tipo != OBJ_LINEAL)
|
||
continue;
|
||
if(secu[0]==olv_limp->ias[(*ob->objt)[j].ia].ic_ini ||
|
||
secu[0]==olv_limp->ias[(*ob->objt)[j].ia].ic_fin)
|
||
break;
|
||
}
|
||
if(j>=ob->vect.nobj)
|
||
{
|
||
return FALSE;
|
||
}
|
||
i=olv_limp->ias[(*ob->objt)[j].ia].ishp;
|
||
cost=olv_limp->cost_amb[i][i];
|
||
dt=OLV_TTO;
|
||
|
||
//a<>ade la info del elemento
|
||
pp->elem[0].i=j;
|
||
pp->elem[0].k=0;
|
||
pp->elem[0].tp = OLV_PLAN_TIP_AMB;
|
||
pp->elem[0].ia_nw = 0;
|
||
pp->elem[0].coste = cost;
|
||
pp->elem[0].ltot = 0;
|
||
pp->t[dt]=cost;
|
||
pp->m[dt]=0;
|
||
return TRUE;
|
||
}
|
||
//////////////////////////////////////////////////////////////////
|
||
|
||
//////////////////////////////////////////////////////////////////
|
||
ambs_sec=(BYTE*)malloc(ss->namb);
|
||
if(!ambs_sec)
|
||
return FALSE;
|
||
memset(ambs_sec,0,ss->namb);
|
||
|
||
//bucle para cada conjunci<63>n de la secuencia
|
||
for(i=0;i<nsecu-1 && !sal;i++)
|
||
{
|
||
if(secu[i]==secu[i+1])
|
||
continue;//para los tipos puntuales
|
||
|
||
//bucle para cada elemento de la red, buscando esa conjunci<63>n
|
||
for(j=0;j<ob->vect.nobj;j++)
|
||
{
|
||
if((*ob->objt)[j].tipo != OBJ_LINEAL)
|
||
continue;
|
||
|
||
if((olv_limp->ias[(*ob->objt)[j].ia].flgs &
|
||
(OLV_LIMP_FLG_AMB | OLV_LIMP_FLG_SEG_PUN | OLV_LIMP_FLG_SEG_LIN | OLV_LIMP_FLG_PEAT_REP | OLV_LIMP_FLG_PEAT_SEG))&&
|
||
!(olv_limp->ias[(*ob->objt)[j].ia].flgs & OLV_LIMP_FLG_SEG_AMB))
|
||
{
|
||
//busca por las conjunciones almacenadas
|
||
sdire=((secu[i]==olv_limp->ias[(*ob->objt)[j].ia].ic_ini)&&
|
||
(secu[i+1]==olv_limp->ias[(*ob->objt)[j].ia].ic_fin));
|
||
if(sdire ||
|
||
(((secu[i+1]==olv_limp->ias[(*ob->objt)[j].ia].ic_ini)&&
|
||
(secu[i]==olv_limp->ias[(*ob->objt)[j].ia].ic_fin))))
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//es un segmento de carretera, hay que buscar la conjunci<63>n
|
||
il=(*ob->objt)[j].indx;
|
||
npt = (*ob->lial)[il].n;
|
||
indx=(*ob->lial)[il].indx;
|
||
ptos = &(*ob->ptos)[indx];
|
||
|
||
//busca el lineal que est<73> entre esta conjunci<63>n y la siguiente
|
||
sdire=(
|
||
((olv_limp->conjs.coor[secu[i]][0]==ptos[0][0]) &&
|
||
(olv_limp->conjs.coor[secu[i]][1]==ptos[0][1])) &&
|
||
((olv_limp->conjs.coor[secu[i+1]][0]==ptos[(npt-1)][0]) &&
|
||
(olv_limp->conjs.coor[secu[i+1]][1]==ptos[(npt-1)][1]))
|
||
);
|
||
if(sdire ||
|
||
(
|
||
((olv_limp->conjs.coor[secu[i]][0]==ptos[(npt-1)][0]) &&
|
||
(olv_limp->conjs.coor[secu[i]][1]==ptos[(npt-1)][1])) &&
|
||
((olv_limp->conjs.coor[secu[i+1]][0]==ptos[0][0]) &&
|
||
(olv_limp->conjs.coor[secu[i+1]][1]==ptos[0][1]))
|
||
))
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if(j>=ob->vect.nobj)
|
||
{
|
||
sal=TRUE;
|
||
continue;
|
||
}
|
||
|
||
//calcula la longitud
|
||
il=(*ob->objt)[j].indx;
|
||
npt = (*ob->lial)[il].n;
|
||
indx=(*ob->lial)[il].indx;
|
||
ptos = &(*ob->ptos)[indx];
|
||
ltot = long_linea((double (*)[][3]) ptos,npt,NULL,NULL,NULL,NULL);
|
||
cost=olv_limp->cost_conj[secu[i]][secu[i+1]];
|
||
dt=OLV_DT_N;
|
||
/////////////////////////////
|
||
//mira a ver si es carretera o amb para poner inw
|
||
if(olv_limp->ias[(*ob->objt)[j].ia].flgs & OLV_LIMP_FLG_AMB) //es <20>mbito
|
||
{
|
||
ia_nw=olv_limp->inww_amb[j+!sdire*olv_limp->n_amb].inw;
|
||
|
||
///////////////////////////////////
|
||
//si no pertenece a los <20>mbitos de este sector o ya ha pasado por <20>l,
|
||
//es que est<73> desplaz<61>ndose por <20>l, le pone tipo nw
|
||
for(k=0;k<ss->namb;k++)
|
||
{
|
||
if(ss->iamb[k]==(*ob->objt)[j].ia)
|
||
break;
|
||
}
|
||
if(k>=ss->namb || ambs_sec[k])
|
||
{
|
||
tp=OLV_PLAN_TIP_NW;
|
||
dt=OLV_DESP;
|
||
}
|
||
else
|
||
{
|
||
///////////////////////////////////
|
||
if(olv_limp->ias[(*ob->objt)[j].ia].flgs & OLV_LIMP_FLG_PEAT)
|
||
tp=OLV_PLAN_TIP_AMB_PEAT;
|
||
else
|
||
tp=OLV_PLAN_TIP_AMB;
|
||
|
||
dt=OLV_TTO;
|
||
namb++;
|
||
ambs_sec[k]=1;
|
||
}
|
||
|
||
}
|
||
else if(olv_limp->ias[(*ob->objt)[j].ia].flgs & OLV_LIMP_FLG_SEG_LIN) //es segmento de <20>mbito
|
||
{
|
||
if(olv_limp->ias[(*ob->objt)[j].ia].flgs & OLV_LIMP_FLG_FIN)
|
||
ia_nw=olv_limp->inww_amb[olv_limp->ias[(*ob->objt)[j].ia].ishp+olv_limp->n_amb].inw;
|
||
else
|
||
ia_nw = olv_limp->inww_amb[olv_limp->ias[(*ob->objt)[j].ia].ishp].inw;
|
||
tp=OLV_PLAN_TIP_SEG_LIN;
|
||
ltot=0;
|
||
}
|
||
else if(olv_limp->ias[(*ob->objt)[j].ia].flgs & OLV_LIMP_FLG_SEG_PUN)
|
||
{
|
||
ia_nw = olv_limp->inww_amb[olv_limp->ias[(*ob->objt)[j].ia].ishp].inw;
|
||
tp=OLV_PLAN_TIP_AMB;
|
||
ltot=0;
|
||
if((last_pt==olv_limp->ias[(*ob->objt)[j].ia].ishp) || (tip_plan==OLV_PLAN_INST))
|
||
{
|
||
cost=0;
|
||
tp=OLV_PLAN_TIP_NW;
|
||
}
|
||
else
|
||
{
|
||
cost=olv_limp->cost_amb[olv_limp->ias[(*ob->objt)[j].ia].ishp][olv_limp->ias[(*ob->objt)[j].ia].ishp];
|
||
last_pt=olv_limp->ias[(*ob->objt)[j].ia].ishp;
|
||
dt=OLV_TTO;
|
||
}
|
||
}
|
||
else if(olv_limp->ias[(*ob->objt)[j].ia].flgs & OLV_LIMP_FLG_PEAT_REP)
|
||
{
|
||
tp=OLV_PLAN_TIP_AMB_PEAT_DESP;
|
||
//en info0 se ha guardado la peatonal original
|
||
ia_nw=olv_limp->inww_amb[olv_limp->ias[(*ob->objt)[j].ia].info0+!sdire*olv_limp->n_amb].inw;
|
||
dt=OLV_DESP;
|
||
}
|
||
else if(olv_limp->ias[(*ob->objt)[j].ia].flgs & OLV_LIMP_FLG_PEAT_SEG)
|
||
{
|
||
continue;
|
||
}
|
||
else//es carretera
|
||
{
|
||
ia_nw=(*ob->objt)[j].ia;
|
||
tp=OLV_PLAN_TIP_NW;
|
||
dt=OLV_DESP;
|
||
}
|
||
|
||
////////////////////
|
||
if(is_descarg && (tp!=OLV_PLAN_TIP_AMB))
|
||
{
|
||
cost_perd+=cost;
|
||
cost=ltot=0;
|
||
}
|
||
////////////////////
|
||
if((ltot==0) && (dt!=OLV_TTO))
|
||
cost=0;
|
||
//////
|
||
//calcula coste acumulado
|
||
if(nelesec>0)
|
||
cost_parc_aux=pp->elem[nelesec-1].coste;
|
||
else
|
||
cost_parc_aux=0;
|
||
//a<>ade la info del elemento
|
||
pp->elem[nelesec].i=j;
|
||
pp->elem[nelesec].k=!sdire;
|
||
pp->elem[nelesec].tp = tp;
|
||
pp->elem[nelesec].ia_nw = ia_nw;
|
||
pp->elem[nelesec].coste = cost_parc_aux + cost;
|
||
pp->elem[nelesec].ltot = ltot;
|
||
pp->elem[nelesec].aux=0;
|
||
|
||
if(log_debug)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Plan sec, nelesec %03d j %04d k %ld t %ld ia_nw %04d cost %lf ",
|
||
nelesec,j,!sdire,tp,ia_nw,pp->elem[nelesec].coste);
|
||
|
||
|
||
//////////////
|
||
if(dt<OLV_DT_N)
|
||
{
|
||
if((olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoM2h) && (dt==OLV_TTO))
|
||
pp->m[dt]+=(ltot*olv_limp->ias[pp->elem[i].i].info1);
|
||
else
|
||
pp->m[dt]+=ltot;
|
||
pp->t[dt]+=cost;
|
||
}
|
||
|
||
//////////////
|
||
if((tip_plan==OLV_PLAN_RECO) && (tp==OLV_PLAN_TIP_AMB))
|
||
{
|
||
pp->elem[nelesec].aux=itr;//marca los tramos
|
||
if(comprueba_descarg(olv_limp->ias[(*ob->objt)[j].ia].ishp))
|
||
itr++;
|
||
if((!is_descarg && comprueba_descarg(olv_limp->ias[(*ob->objt)[j].ia].ishp))
|
||
|| (is_descarg && !comprueba_descarg(olv_limp->ias[(*ob->objt)[j].ia].ishp)))
|
||
{
|
||
cost_perd=0;
|
||
is_descarg=!is_descarg;
|
||
}
|
||
|
||
}
|
||
//////////////
|
||
nelesec++;
|
||
}
|
||
if(sal)
|
||
{
|
||
free(ambs_sec);
|
||
return FALSE;
|
||
}
|
||
|
||
pp->nelem = nelesec;
|
||
|
||
free(ambs_sec);
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Comprueba si en este elemento se va a descargar y en ese caso no se cuenta el desplazamiento hasta el siguiente
|
||
*/
|
||
BOOL Colv_limp_thr::comprueba_descarg(int iamb)
|
||
{
|
||
return FALSE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Dada la secuencia de las conjunciones que sigue la ruta para ir y volver de la instalaci<63>n, genera la planificaci<63>n
|
||
*/
|
||
BOOL Colv_limp_thr::genera_planif_instala(int is, int nvaciados, int ini, int fin, int *secu, int tip_viaje)
|
||
{
|
||
int i;
|
||
Info_planif *pp,*pp_insta;
|
||
Info_sec *ss;
|
||
|
||
ss=&olv_limp->sec[is];
|
||
pp=&olv_limp->plan[is];
|
||
pp_insta = pp->planif_insta;
|
||
if(!pp_insta)
|
||
{
|
||
//inicializa, s<>lo la primera vez
|
||
//cuenta el n<>mero de veces que va a vaciar
|
||
pp->ninsta=2;//inicialmente tiene la ida y la vuelta a la instalaci<63>n
|
||
if(nvaciados)
|
||
pp->ninsta+=nvaciados*2-1; //todos los vaciados son ida y vuelta
|
||
pp_insta = (Info_planif *)malloc(pp->ninsta*sizeof(Info_planif));
|
||
if(!pp_insta)
|
||
return FALSE;
|
||
memset(pp_insta,0,pp->ninsta*sizeof(Info_planif));
|
||
|
||
pp_insta[0].ninsta=OLV_IDA_INST;
|
||
pp_insta[pp->ninsta-1].ninsta=OLV_VUELTA_INST;
|
||
|
||
}
|
||
|
||
//busca cu<63>l le toca rellenar
|
||
for(i=0;i<pp->ninsta;i++)
|
||
{
|
||
if(pp_insta[i].nelem==0)
|
||
break;
|
||
}
|
||
if(i>=pp->ninsta)
|
||
return FALSE;
|
||
|
||
if(!genera_planif_aux(is,ss, &pp_insta[i],fin-ini,&secu[ini],OLV_PLAN_INST))
|
||
return FALSE;
|
||
|
||
pp_insta[i].ninsta=tip_viaje;
|
||
olv_limp->plan[is].planif_insta = pp_insta;
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Dadas las rutas de los sectores, genera la ruta en una <20>nica l<>nea en el obg
|
||
* y en otro coloca los puntos de control
|
||
*/
|
||
BOOL Colv_limp_thr::genera_obg_rut_ctrl(int ns, Info_planif *planif, Cobgeo *ob_rut, Cobgeo *ob_ctrl)
|
||
{
|
||
int is,il,npt,indx,i,k,ic,nmax_pts,ins;
|
||
Cobgeo *ob;
|
||
BOOL mal;
|
||
double (*ptos)[3], pt[3];
|
||
Objgeo *lineal;
|
||
Info_planif *pp;
|
||
Objgeo *lineal_fl;
|
||
double long_fl, long_max_fl;
|
||
|
||
////////////////
|
||
long_max_fl=15;
|
||
long_fl=1;
|
||
////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Generando lineales de las rutas en obg");
|
||
|
||
/////////////////
|
||
ob=olv_limp->olv->olv_ob;
|
||
mal=FALSE;
|
||
lineal=NULL;
|
||
nmax_pts=0;
|
||
/////////////////
|
||
|
||
//Inicializar
|
||
lineal= new Objgeo;
|
||
if(!lineal)
|
||
{
|
||
return FALSE;
|
||
}
|
||
lineal->tipo = OBJ_LINEAL;
|
||
lineal->flags[0] = 0;
|
||
lineal->flags[1] = 0;
|
||
lineal->ev.id = 0;
|
||
lineal->pt.lin = (Linealgeo*) malloc (sizeof(Linealgeo));
|
||
if(!lineal->pt.lin)
|
||
{
|
||
return FALSE;
|
||
}
|
||
lineal->pt.lin->n= 0;
|
||
lineal->pt.lin->flags=0;
|
||
lineal->pt.lin->ptos = NULL;
|
||
///////////////////////
|
||
//Inicializar flechas
|
||
lineal_fl= new Objgeo;
|
||
if(!lineal_fl)
|
||
{
|
||
return FALSE;
|
||
}
|
||
lineal_fl->tipo = OBJ_LINEAL;
|
||
lineal_fl->flags[0] = 0;
|
||
lineal_fl->flags[1] = 0;
|
||
lineal_fl->ev.id = 0;
|
||
lineal_fl->pt.lin = (Linealgeo*) malloc (sizeof(Linealgeo));
|
||
if(!lineal_fl->pt.lin)
|
||
{
|
||
return FALSE;
|
||
}
|
||
lineal_fl->pt.lin->n= 2;
|
||
lineal_fl->pt.lin->flags=0;
|
||
lineal_fl->pt.lin->ptos = (double (*)[][3]) malloc(2 * 3 * sizeof(double));
|
||
if(!lineal_fl->pt.lin->ptos)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
///////////////////////////////////////////////
|
||
//Genera el obg de la ruta, un lineal por sector (o varios por sector si hay idas a recogida)
|
||
for(is=0;is<ns && !mal;is++)
|
||
{
|
||
pp=&planif[is];
|
||
|
||
lineal->ia = is+1;//le suma uno para que sea empezando en 1 y no en 0
|
||
lineal->clase = OLV_ICLA_LIN_RUT+is;
|
||
|
||
lineal_fl->ia = is+1;//le suma uno para que sea empezando en 1 y no en 0
|
||
lineal_fl->clase=OLV_ICLA_LIN_RUT+is;
|
||
|
||
if(!genera_obg_rut_aux(pp, ob_rut, ob_flech,lineal,&nmax_pts, lineal_fl, FALSE,0,pp->nelem))
|
||
{
|
||
mal=TRUE;
|
||
break;
|
||
|
||
}
|
||
|
||
for(ins=0;ins<pp->ninsta;ins++)
|
||
{
|
||
//solo entra aqu<71> si hay ruta a las instalaciones
|
||
if(!genera_obg_rut_aux(&pp->planif_insta[ins], ob_inst, ob_inst_fl,lineal,&nmax_pts, lineal_fl, TRUE,0,pp->planif_insta[ins].nelem))
|
||
{
|
||
mal=TRUE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
ob_rut->libera_objgeo(lineal);
|
||
delete lineal;
|
||
lineal=NULL;
|
||
ob_rut->libera_objgeo(lineal_fl);
|
||
delete lineal_fl;
|
||
lineal_fl=NULL;
|
||
|
||
///////////////////////////////////////////////
|
||
//Genera el obg de los puntos
|
||
if(ob_ctrl)
|
||
{
|
||
int ie;
|
||
int isfin;
|
||
for(is=0;is<ns && !mal;is++)
|
||
{
|
||
pp=&planif[is];
|
||
|
||
for(i=0;i<olv_limp->npts_ctrl;i++)
|
||
{
|
||
if(pp->nelem==0)
|
||
{
|
||
memcpy(pt,ob_ctrl->nvl.ogtb,2*sizeof(double));//para rutas vac<61>as, lo rellena con 0
|
||
}
|
||
else
|
||
{
|
||
isfin=0;
|
||
if(i==0)
|
||
ie=0; //el punto de control primero est<73> en el primer elemento
|
||
else if(i==olv_limp->npts_ctrl-1)
|
||
{
|
||
ie=pp->nelem-1;//el punto de control <20>ltimo est<73> en el <20>ltimo elemento
|
||
isfin=1;
|
||
}
|
||
else
|
||
ie=pp->pts_ctrl[i-1].ipt;//los puntos de control intermedios, los que se han calculado
|
||
ic=pp->elem[ie].i;
|
||
|
||
il=(*ob->objt)[ic].indx;
|
||
indx=(*ob->lial)[il].indx;
|
||
npt = (*ob->lial)[il].n;
|
||
ptos = &(*ob->ptos)[indx];
|
||
k=(pp->elem[ie].k+isfin)%2; //porque si es el punto de control final, lo tiene que poner al final
|
||
//del tramo, no al principio, y
|
||
|
||
memcpy(pt,ptos[k*(npt-1)],3*sizeof(double));
|
||
}
|
||
mal=!Colv_geom::pon_pto((double(*)[3])pt, OLV_ICLA_PUN_CON+is,is+1, ob_ctrl);
|
||
}
|
||
}
|
||
|
||
if(lineal)
|
||
{
|
||
ob_rut->libera_objgeo(lineal);
|
||
delete lineal;
|
||
}
|
||
}
|
||
|
||
if(mal)
|
||
return FALSE;
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Dadas las rutas de los sectores, genera la ruta en una <20>nica l<>nea en el obg
|
||
* y en otro coloca los puntos de control - Funci<63>n auxiliar
|
||
*/
|
||
BOOL Colv_limp_thr::genera_obg_rut_aux(Info_planif *pp, Cobgeo *ob_rut, Cobgeo *ob_flech,Objgeo *lineal,int *nmax_pts, Objgeo *lineal_fl, BOOL is_insta, int ie_ini, int ie_fin)
|
||
{
|
||
int il,npt,indx,npt_tot,i,npt_parc,k;
|
||
Cobgeo *ob;
|
||
BOOL mal;
|
||
double (*ptos)[3], pt[3],(*ptos_aux)[3];
|
||
double (*pts_lin)[3];
|
||
double (*pts_lin_fl)[3];
|
||
double ltot, long_max_fl;
|
||
int nfl;
|
||
|
||
////////////////
|
||
long_max_fl=5;
|
||
////////////////
|
||
ob=olv_limp->olv->olv_ob;
|
||
mal=FALSE;
|
||
/////////////////
|
||
|
||
if(pp->nelem==0 && is_insta)
|
||
return TRUE;
|
||
if(pp->nelem==0 && !is_insta)
|
||
npt_tot=2;
|
||
else
|
||
{
|
||
npt_tot=0;
|
||
//Contar puntos
|
||
for(i=ie_ini;i<ie_fin;i++)
|
||
{
|
||
/////////////////////////////
|
||
il=(*ob->objt)[pp->elem[i].i].indx;
|
||
npt = (*ob->lial)[il].n;
|
||
npt_tot += npt-1;
|
||
}
|
||
npt_tot++;
|
||
}
|
||
|
||
lineal->pt.lin->n= npt_tot;
|
||
|
||
ptos_aux=(double (*)[3])lineal->pt.lin->ptos;
|
||
//pide memoria para los puntos si hace falta
|
||
if(npt_tot>*nmax_pts)
|
||
{
|
||
ptos_aux = (double (*)[3]) realloc(lineal->pt.lin->ptos,npt_tot * 3 * sizeof(double));
|
||
*nmax_pts=npt_tot;
|
||
}
|
||
if(!ptos_aux)
|
||
{
|
||
return FALSE;
|
||
}
|
||
pts_lin = ptos_aux;
|
||
|
||
npt_parc=0;//num de puntos parcial
|
||
double (*ptos_par)[3];
|
||
double d;
|
||
//A<>adir puntos
|
||
for(i=ie_ini;i<ie_fin;i++)
|
||
{
|
||
il=(*ob->objt)[pp->elem[i].i].indx;
|
||
indx=(*ob->lial)[il].indx;
|
||
npt = (*ob->lial)[il].n;
|
||
ptos = &(*ob->ptos)[indx];
|
||
ptos_par=NULL;
|
||
|
||
//si es carretera y es de doble sentido,
|
||
//hace la paralela a una distancia dada para que no se superpongan la ida y la vuelta
|
||
if((pp->elem[i].tp==OLV_PLAN_TIP_NW) && !((olv_limp->ias[pp->elem[i].ia_nw].flgs & OLV_LIMP_FLG_CIRC_NO_DOB)))
|
||
{
|
||
d=OLV_DIST_PARALELAS;
|
||
if(pp->elem[i].k==0)
|
||
d=d*(-1);//distancia negativa si es sentido contrario
|
||
Colv_geom::haz_paralela(ptos,npt,d,&ptos_par);
|
||
ptos=(double (*)[3])ptos_par;
|
||
}
|
||
|
||
memcpy(pts_lin[npt_parc],ptos,npt*3*sizeof(double));
|
||
|
||
/////////////////////////
|
||
//por si hay que darle la vuelta a los puntos
|
||
if(pp->elem[i].k==1)
|
||
{
|
||
for(k=0;k<npt/2;k++)
|
||
{
|
||
memcpy(pt,pts_lin[npt_parc+k],3*sizeof(double));
|
||
memcpy(pts_lin[npt_parc+k],pts_lin[npt_parc+npt-k-1],3*sizeof(double));
|
||
memcpy(pts_lin[npt_parc+npt-k-1],pt,3*sizeof(double));
|
||
}
|
||
}
|
||
/////////////////////////
|
||
npt_parc+=npt-1;
|
||
|
||
if(ptos_par)
|
||
free(ptos_par);
|
||
}
|
||
if(pp->nelem==0 && !is_insta)
|
||
{
|
||
memcpy(pts_lin,ob_rut->nvl.ogtb,2*sizeof(double));
|
||
}
|
||
lineal->pt.lin->ptos = (double (*)[][3])pts_lin;
|
||
lineal->pt.lin->flags = 0;
|
||
if(ob_rut->pon_obj(lineal)<0)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if(pp->nelem==0 && !is_insta)
|
||
{
|
||
pts_lin_fl= (double (*)[3])lineal_fl->pt.lin->ptos;
|
||
memcpy(pts_lin_fl[0],ob_rut->nvl.ogtb,2*sizeof(double));
|
||
memcpy(pts_lin_fl[1],ob_rut->nvl.ogtb,2*sizeof(double));
|
||
if(ob_flech->pon_obj(lineal_fl)<0)
|
||
{
|
||
return FALSE;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
/////////////////////////////////
|
||
//Pone las flechas a lo largo de la l<>nea
|
||
nfl=0;
|
||
pts_lin_fl= (double (*)[3])lineal_fl->pt.lin->ptos;
|
||
ltot=long_linea((double (*)[][3]) pts_lin,npt_tot,NULL,NULL,NULL,NULL);
|
||
nfl=(int)(ltot/long_max_fl);
|
||
for(i=0;i<nfl;i++)
|
||
{
|
||
for(k=0;k<2;k++)
|
||
Colv_geom::dame_pto_poli((double (*)[][3]) pts_lin, npt_tot, min(long_max_fl*i+k*long_max_fl,ltot),ltot, (double (*)[3])pts_lin_fl[k]);
|
||
lineal_fl->pt.lin->flags = 0;
|
||
if(ob_flech->pon_obj(lineal_fl)<0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
if(i<nfl)
|
||
return FALSE;
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Guarda a un archivo shape con path en la configuraci<63>n la ruta y los puntos de control
|
||
*/
|
||
BOOL Colv_limp_thr::guarda_shp_rut_ctrl(Cobgeo *ob_rut, Cobgeo *ob_ctrl)
|
||
{
|
||
char path_shp[MAX_PATH];
|
||
|
||
//antes ha tenido que generar un <20>nico lineal con la ruta
|
||
wgeolog(LOG_TODO,"olv_limp_t","Guardandoa shp los archivos de rutas");
|
||
|
||
//primero graba los archivos de la ruta de los sectores
|
||
//graba todos los sectores en un <20>nico path
|
||
strcpy_s(path_shp,MAX_PATH,olv_limp->olv->paths.path_res_rut);
|
||
cambiaext(path_shp,".shp","");
|
||
strcat_s(path_shp,"_R.shp");
|
||
if(!olv_limp->olv->olv_sh->guarda_shp(path_shp,ob_rut,TIPO_ENT_LINEA,olv_limp->camps.campo_secto,TIPO_IA_INT))
|
||
return FALSE;
|
||
if(!guarda_cols_ruta(path_shp))
|
||
return FALSE;
|
||
|
||
///////////////////////////////////////////////////////
|
||
//luego graba los archivos de los puntos de control
|
||
//graba todos los sectores en un <20>nico path
|
||
strcpy_s(path_shp,MAX_PATH,olv_limp->olv->paths.path_res_pt);
|
||
cambiaext(path_shp,".shp","");
|
||
strcat_s(path_shp,"_C.shp");
|
||
if(!olv_limp->olv->olv_sh->guarda_shp(path_shp,ob_ctrl,TIPO_ENT_PUNTO,olv_limp->camps.campo_secto,TIPO_IA_INT))
|
||
return FALSE;
|
||
if(!guarda_cols_ctrl(path_shp))
|
||
return FALSE;
|
||
|
||
/////////////////////////////////////////////
|
||
//A continuaci<63>n graba los archivos de las flechas
|
||
strcpy_s(path_shp,MAX_PATH,olv_limp->olv->paths.path_res_rut);
|
||
cambiaext(path_shp,".shp","");
|
||
strcat_s(path_shp,"_Raux.shp");
|
||
if(!olv_limp->olv->olv_sh->guarda_shp(path_shp,ob_flech,TIPO_ENT_LINEA,olv_limp->camps.campo_secto,TIPO_IA_INT))
|
||
return FALSE;
|
||
|
||
/////////////////////////////////////////////
|
||
//A continuaci<63>n graba los archivos de los viajes a las instalaciones
|
||
if(olv_limp->nod_instal>=0)
|
||
{
|
||
strcpy_s(path_shp,MAX_PATH,olv_limp->olv->paths.path_res_rut);
|
||
cambiaext(path_shp,".shp","");
|
||
strcat_s(path_shp,"_I.shp");
|
||
if(!olv_limp->olv->olv_sh->guarda_shp(path_shp,ob_inst,TIPO_ENT_LINEA,olv_limp->camps.campo_secto,TIPO_IA_INT))
|
||
return FALSE;
|
||
if(!guarda_cols_insta(path_shp))
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Genera y guarda el shp con las rutas en subtramos, para recogida porque se va a descargar
|
||
*/
|
||
BOOL Colv_limp_thr::gen_guard_subtramos()
|
||
{
|
||
int ntramos=0;
|
||
char path_shp[MAX_PATH];
|
||
|
||
ob_rut = new Cobgeo();
|
||
memcpy(&ob_rut->nvl,&olv_limp->olv->olv_ob->nvl,sizeof(Niveles));
|
||
ob_flech = new Cobgeo();
|
||
memcpy(&ob_flech->nvl,&olv_limp->olv->olv_ob->nvl,sizeof(Niveles));
|
||
|
||
//cuenta tramos
|
||
tramos=cuenta_tramos();
|
||
|
||
if(!genera_obg_rut_ctrl(olv_limp->nsec, olv_limp->plan, ob_rut, NULL))
|
||
{
|
||
pon_mi_msg("Errores en la generaci<63>n de cartograf<61>a con ruta de los subtramos");
|
||
return FALSE;
|
||
}
|
||
|
||
rellena_tramos();
|
||
|
||
if(olv_limp->tipo_shp_viaj==OLV_SHPRUTINST)
|
||
{
|
||
int ii=rellena_insta_tramos();
|
||
//combina los lineales de cada subtramo con la ida a descargar y la vuelta de descargar anterior
|
||
if(ii>0 && !combina_rut_insta(ob_rut, ob_inst))
|
||
{
|
||
pon_mi_msg("Errores en la combinaci<63>n de viajes con viajes a instalaci<63>n");
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
//graba los archivos de la ruta de los sectores
|
||
//graba todos los sectores en un <20>nico path
|
||
strcpy_s(path_shp,MAX_PATH,olv_limp->olv->paths.path_res_rut);
|
||
cambiaext(path_shp,".shp","");
|
||
strcat_s(path_shp,"_R2.shp");
|
||
if(!olv_limp->olv->olv_sh->guarda_shp(path_shp,ob_rut,TIPO_ENT_LINEA,olv_limp->camps.campo_secto,TIPO_IA_INT))
|
||
{
|
||
pon_mi_msg("Errores en el guardado del shp de la capa de viajes");
|
||
return FALSE;
|
||
}
|
||
|
||
if(!guarda_cols_ruta_tram(path_shp))
|
||
{
|
||
pon_mi_msg("Errores al guardar las columnas de la capa de viajes");
|
||
return FALSE;
|
||
}
|
||
|
||
/////////////////////////////////////////////
|
||
//A continuaci<63>n sobreescribe los archivos de las flechas
|
||
strcpy_s(path_shp,MAX_PATH,olv_limp->olv->paths.path_res_rut);
|
||
cambiaext(path_shp,".shp","");
|
||
strcat_s(path_shp,"_Raux.shp");
|
||
if(!olv_limp->olv->olv_sh->guarda_shp(path_shp,ob_flech,TIPO_ENT_LINEA,olv_limp->camps.campo_secto,TIPO_IA_INT))
|
||
{
|
||
pon_mi_msg("Errores en el guardado del shp de la capa de viajes aux");
|
||
return FALSE;
|
||
}
|
||
|
||
//guarda en los <20>mbitos una columna de "tramo al que pertenecen"
|
||
if(!guarda_dbf_sector(3))
|
||
{
|
||
pon_mi_msg("Errores al guardar la columna de viaje de cada cont");
|
||
return FALSE;
|
||
}
|
||
|
||
delete [] tramos;
|
||
tramos=NULL;
|
||
|
||
return TRUE;
|
||
}//*************************************************************************************
|
||
/**
|
||
* Como los viajes a instalaciones est<73>n ordenados, y los tramos tambi<62>n
|
||
* le corresponde a cada tramo it el viaje it y el it+1, excepto al <20>ltimo, que le pueden
|
||
* corresponder 3 viajes si la instalaci<63>n y la descarga no son en el mismo sitio
|
||
* Adem<65>s, actualiza el tiempo de los tramos
|
||
*/
|
||
int Colv_limp_thr::rellena_insta_tramos()
|
||
{
|
||
int it, nt, nins,ii;
|
||
Info_planif *pinsta;
|
||
Info_tramos *tramo;
|
||
|
||
ii=0; //para saber si hace alg<6C>n tramo o no
|
||
for(int is=0;is<olv_limp->nsec;is++)
|
||
{
|
||
nt=tramos[is].size();
|
||
nins = olv_limp->plan[is].ninsta;
|
||
if(!nins)
|
||
continue;
|
||
if(olv_limp->plan[is].planif_insta[nins-1].nelem==0)
|
||
nins--; //es porque la descarga y planta son la misma
|
||
pinsta = olv_limp->plan[is].planif_insta;
|
||
for(it=0;it<nt-1;it++)
|
||
{
|
||
tramo = &tramos[is][it];
|
||
tramo->iins[0]=2*it;
|
||
tramo->iins[1]=2*it+1;
|
||
|
||
///////////////////////////////////////
|
||
//Actualiza los tiempos del tramo sumando los tiempos del viaje a inst
|
||
tramo->t_ini -= (float)pinsta[tramo->iins[0]].elem[pinsta[tramo->iins[0]].nelem-1].coste;
|
||
tramo->t_fin += (float)pinsta[tramo->iins[1]].elem[pinsta[tramo->iins[1]].nelem-1].coste;
|
||
tramo->t_total_tr=(float) (tramo->t_fin-tramo->t_ini);
|
||
}
|
||
//para el <20>ltimo tramo
|
||
tramo = &tramos[is][it];
|
||
tramo->iins[0]=2*it;
|
||
tramo->iins[1]=nins-1;
|
||
tramo->t_ini -= (float)pinsta[tramo->iins[0]].elem[pinsta[tramo->iins[0]].nelem-1].coste;
|
||
tramo->t_fin += (float)pinsta[tramo->iins[1]].elem[pinsta[tramo->iins[1]].nelem-1].coste;
|
||
tramo->t_total_tr=(float) (tramo->t_fin-tramo->t_ini);
|
||
ii++;
|
||
}
|
||
return ii;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* A<>ade las columnas de informaci<63>n a la ruta, tiempos, longitudes, y dem<65>s
|
||
*/
|
||
BOOL Colv_limp_thr::guarda_cols_ruta_tram(char *path_shp)
|
||
{
|
||
char *info;
|
||
char path_dbf[MAX_PATH];
|
||
double tt;
|
||
int h,m,s;
|
||
int i, it,ntram,nt,nt_parc;
|
||
|
||
//cuenta el n<>mero de sectores no vac<61>os
|
||
ntram=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
ntram+=tramos[i].size();
|
||
}
|
||
|
||
//a<>ade una columna a la ruta de tiempo de ruta
|
||
strcpy_s(path_dbf,MAX_PATH,path_shp);
|
||
cambiaext(path_dbf,".shp",".dbf");
|
||
info = (char *)malloc(ntram*OLV_SHP_SZ_CAMP_CHAR);
|
||
if(!info)
|
||
{
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ntram*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//SECTOR ya viene
|
||
|
||
//TRATAMIENTO
|
||
nt_parc=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
nt=(int)tramos[i].size();
|
||
for(it=0;it<nt;it++)
|
||
{
|
||
sprintf_s(&info[(nt_parc+it)*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%s",olv_limp->nomb_tto);
|
||
}
|
||
nt_parc+=nt;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,ntram,TIPO_IA_CHAR,info,"TTO",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ntram*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//VIAJE
|
||
nt_parc=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
nt=(int)tramos[i].size();
|
||
for(it=0;it<nt;it++)
|
||
{
|
||
tt=it+1;
|
||
sprintf_s(&info[(nt_parc+it)*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%ld",(int)tt);
|
||
}
|
||
nt_parc+=nt;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,ntram,TIPO_IA_CHAR,info,"VIAJE",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ntram*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//H_INI
|
||
nt_parc=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
nt=(int)tramos[i].size();
|
||
for(it=0;it<nt;it++)
|
||
{
|
||
tt=tramos[i][it].t_ini;
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[(nt_parc+it)*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
}
|
||
nt_parc+=nt;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,ntram,TIPO_IA_CHAR,info,"H_INI",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ntram*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//H_FIN
|
||
nt_parc=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
nt=(int)tramos[i].size();
|
||
for(it=0;it<nt;it++)
|
||
{
|
||
tt=tramos[i][it].t_fin;
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[(nt_parc+it)*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
}
|
||
nt_parc+=nt;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,ntram,TIPO_IA_CHAR,info,"H_FIN",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ntram*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//T_TOTAL
|
||
nt_parc=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
nt=(int)tramos[i].size();
|
||
for(it=0;it<nt;it++)
|
||
{
|
||
tt=tramos[i][it].t_total_tr;//tramos[i][it].t_fin-tramos[i][it].t_ini;
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[(nt_parc+it)*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
}
|
||
nt_parc+=nt;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,ntram,TIPO_IA_CHAR,info,"T_TOTAL",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ntram*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//T_TTO
|
||
nt_parc=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
nt=(int)tramos[i].size();
|
||
for(it=0;it<nt;it++)
|
||
{
|
||
tt=tramos[i][it].t_tto_tr;
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[(nt_parc+it)*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
}
|
||
nt_parc+=nt;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,ntram,TIPO_IA_CHAR,info,"T_TTO",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ntram*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Cuenta los tramos que hay en la ruta del sector is, si va varias veces a descargar
|
||
*/
|
||
std::vector<Info_tramos>* Colv_limp_thr::cuenta_tramos()
|
||
{
|
||
std::vector<Info_tramos> *tramos = new std::vector<Info_tramos>[olv_limp->nsec];
|
||
Info_planif *pp;
|
||
Info_tramos tramo;
|
||
int ie,ii,ilast;
|
||
|
||
memset(&tramo,0,sizeof(Info_tramos));
|
||
tramo.iins[0]=tramo.iins[1]=-1;
|
||
|
||
for(int is=0;is<olv_limp->nsec;is++)
|
||
{
|
||
pp=&olv_limp->plan[is];
|
||
ii=0;
|
||
tramo.ie[0]=0;
|
||
for(ie=0;ie<pp->nelem;ie++)
|
||
{
|
||
if(pp->elem[ie].tp!=OLV_PLAN_TIP_AMB)
|
||
continue;
|
||
if(pp->elem[ie].aux!=ii)
|
||
{
|
||
tramo.ie[1]=ilast;
|
||
tramos[is].push_back(tramo);
|
||
ii++;
|
||
tramo.ie[0]=ie;
|
||
}
|
||
olv_limp->amb_sec[olv_limp->ias[(*olv->olv_ob->objt)[pp->elem[ie].i].ia].ishp].res=ii; //marca el tramo en el array de ambitos
|
||
ilast=ie;
|
||
}
|
||
tramo.ie[1]=pp->nelem-1;
|
||
tramos[is].push_back(tramo);
|
||
}
|
||
|
||
return tramos;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena la info de los tramos
|
||
*/
|
||
void Colv_limp_thr::rellena_tramos()
|
||
{
|
||
Info_planif *pp;
|
||
Info_tramos *tramo;
|
||
int ie,it,nt;
|
||
|
||
for(int is=0;is<olv_limp->nsec;is++)
|
||
{
|
||
pp=&olv_limp->plan[is];
|
||
nt=tramos[is].size();
|
||
for(it=0;it<nt;it++)
|
||
{
|
||
tramo = &tramos[is][it];
|
||
tramo->namb=0;
|
||
tramo->ncont=0;
|
||
for(ie=tramo->ie[0]; ie<=tramo->ie[1];ie++)
|
||
{
|
||
tramo->long_tr+=(float) pp->elem[ie].ltot;
|
||
if(pp->elem[ie].tp!=OLV_PLAN_TIP_AMB)
|
||
continue;
|
||
|
||
tramo->namb++;
|
||
}
|
||
|
||
tramo->t_tto_tr = (float)(pp->t[OLV_TTO]);
|
||
if(pp->planif_insta)
|
||
{
|
||
if(it==0)
|
||
tramo->t_ini = (float)(olv_limp->t_ini+olv_limp->t_sal+pp->planif_insta[0].elem[pp->planif_insta[0].nelem-1].coste);
|
||
else
|
||
tramo->t_ini = (float)(pp->planif_insta[2*it].t[OLV_TTO]+pp->planif_insta[2*it].elem[pp->planif_insta[2*it].nelem-1].coste);
|
||
tramo->t_fin = (float)pp->planif_insta[2*it+1].t[OLV_TTO];
|
||
}
|
||
else
|
||
{
|
||
tramo->t_ini = (float)(olv_limp->t_ini+olv_limp->t_sal);
|
||
tramo->t_fin = (float)(tramo->t_ini + pp->elem[pp->nelem-1].coste);
|
||
}
|
||
|
||
tramo->t_total_tr = (float) (tramo->t_fin-tramo->t_ini);
|
||
}
|
||
}
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Dadas las rutas de los sectores, genera la ruta en una <20>nica l<>nea en el obg
|
||
* y en otro coloca los puntos de control
|
||
*/
|
||
BOOL Colv_limp_thr::combina_rut_insta(Cobgeo *ob_rut, Cobgeo *ob_inst)
|
||
{
|
||
//en ob_rut ahora est<73>n todos los subtramos en orden:
|
||
//1 viaje del sector 1, 2 viaje del sector 1, 1 viaje del sector 2, etc
|
||
//hay que a<>adir al primer viaje de cada sector la ida desde instalaci<63>n y la ida a descargar (y la ida a instalaci<63>n
|
||
//si es un <20>nico viaje)
|
||
//al resto de viajes intermedios hay que a<>adirles la vuelta de descargar anterior y la ida a descargar
|
||
//al <20>ltimo viaje hay que a<>adirle la ida a descargar y la ida a instalaci<63>n
|
||
int is=0, it=0, nt=0, i=0, il, il2, npt_tot, npt, ntparc,ii;
|
||
int niparc, res, nmax_pts,npt_parc;
|
||
BOOL mal = false;
|
||
Info_planif *planif, *pp;
|
||
double (*ptos_aux)[3],(*ptos)[3];
|
||
Objgeo *lineal;
|
||
|
||
/////////////////
|
||
//Inicializar lineal
|
||
lineal= new Objgeo;
|
||
if(!lineal)
|
||
{
|
||
return FALSE;
|
||
}
|
||
lineal->tipo = OBJ_LINEAL;
|
||
lineal->flags[0] = 0;
|
||
lineal->flags[1] = 0;
|
||
lineal->ev.id = 0;
|
||
lineal->pt.lin = (Linealgeo*) malloc (sizeof(Linealgeo));
|
||
if(!lineal->pt.lin)
|
||
{
|
||
return FALSE;
|
||
}
|
||
lineal->pt.lin->n= 0;
|
||
lineal->pt.lin->flags=0;
|
||
lineal->pt.lin->ptos = NULL;
|
||
///////////////////////
|
||
|
||
planif= olv_limp->plan;
|
||
|
||
ntparc=0;
|
||
niparc=0;
|
||
nmax_pts=0;
|
||
for(is=0;is<olv_limp->nsec && !mal;is++)
|
||
{
|
||
pp=&planif[is];
|
||
nt=tramos[is].size();
|
||
lineal->ia = is+1;//le suma uno para que sea empezando en 1 y no en 0
|
||
lineal->clase = OLV_ICLA_LIN_RUT+is;
|
||
for(it=0;it<nt && !mal;it++)
|
||
{
|
||
npt_tot=0;
|
||
res=0;
|
||
il=(*ob_rut->objt)[it+ntparc].indx;
|
||
npt=(*ob_rut->lial)[il].n;
|
||
npt_tot+=npt;
|
||
for(ii=tramos[is][it].iins[0]; ii<=tramos[is][it].iins[1];ii++)
|
||
{
|
||
il=(*ob_inst->objt)[ii+niparc].indx;
|
||
npt=(*ob_inst->lial)[il].n;
|
||
npt_tot+=npt;
|
||
res++;
|
||
}
|
||
//dado que junta tramos, resta para no replicar los puntos de uni<6E>n
|
||
npt_tot=npt_tot-res;
|
||
|
||
////////////////////////////////////////////////////////////////////
|
||
//marca para borrar ese tramo
|
||
(*ob_rut->objt)[it+ntparc].flags[1] = (*ob_rut->objt)[it+ntparc].flags[1] | B1_OBJ_NULO;
|
||
//ya que tiene el total de puntos, actualiza el lineal de ese tramo
|
||
lineal->pt.lin->n= npt_tot;
|
||
ptos_aux=(double (*)[3])lineal->pt.lin->ptos;
|
||
if(npt_tot>nmax_pts)
|
||
{
|
||
ptos_aux = (double (*)[3]) realloc(lineal->pt.lin->ptos,npt_tot * 3 * sizeof(double));
|
||
nmax_pts=npt_tot;
|
||
}
|
||
if(!ptos_aux)
|
||
{
|
||
mal=TRUE;
|
||
continue;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////
|
||
//ahora copia en ptos_aux los lineales de los tramos que le corresponden
|
||
npt_parc=0;
|
||
for(ii=tramos[is][it].iins[0]; ii<=tramos[is][it].iins[1];ii++)
|
||
{
|
||
il=(*ob_inst->objt)[ii+niparc].indx;
|
||
npt=(*ob_inst->lial)[il].n;
|
||
il2=(*ob_inst->lial)[il].indx;
|
||
ptos = &(*ob_inst->ptos)[il2];
|
||
|
||
//copia el viaje al lineal total
|
||
memcpy(ptos_aux[npt_parc],ptos,npt*3*sizeof(double));
|
||
npt_parc+=npt-1;
|
||
if(ii==tramos[is][it].iins[1])
|
||
npt_parc++;
|
||
|
||
if(ii==tramos[is][it].iins[0])
|
||
{
|
||
//despu<70>s del primer viaje se copia el tramo de recogida
|
||
il=(*ob_rut->objt)[it+ntparc].indx;
|
||
npt=(*ob_rut->lial)[il].n;
|
||
il2=(*ob_rut->lial)[il].indx;
|
||
ptos = &(*ob_rut->ptos)[il2];
|
||
|
||
//copia el viaje al lineal total
|
||
memcpy(ptos_aux[npt_parc],ptos,npt*3*sizeof(double));
|
||
npt_parc+=npt-1;
|
||
}
|
||
}
|
||
//////////////////////////////////////////////////////////////////////
|
||
|
||
lineal->pt.lin->ptos = (double (*)[][3])ptos_aux;
|
||
lineal->pt.lin->flags = 0;
|
||
if(ob_rut->pon_obj(lineal)<0)
|
||
{
|
||
mal=TRUE; //entra por aqu<71>??
|
||
continue;
|
||
}
|
||
}
|
||
niparc+=ii; //ii apunta a la <20>ltima instalaci<63>n del primer sector
|
||
ntparc+=nt;
|
||
}
|
||
if(mal)
|
||
{
|
||
return FALSE;
|
||
}
|
||
ob_rut->limpia();
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* A<>ade las columnas de informaci<63>n a la ruta, tiempos, longitudes, y dem<65>s
|
||
*/
|
||
BOOL Colv_limp_thr::guarda_cols_ruta(char *path_shp)
|
||
{
|
||
char *info;
|
||
char path_dbf[MAX_PATH];
|
||
double tt;
|
||
int h,m,s;
|
||
char nombia[16];
|
||
int nsec, i, isec_novac;
|
||
|
||
//cuenta el n<>mero de sectores no vac<61>os
|
||
nsec=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb!=0)
|
||
nsec++;
|
||
}
|
||
|
||
////////////////////////////////////
|
||
//El coste_ac es lo mismo que el cost del <20>ltimo elemento de la planif
|
||
//m<>s el de desplazamientos inicial y final y de descargas
|
||
//Para el total, hay que a<>adir los descansos
|
||
/////////////////////////////////////
|
||
|
||
//a<>ade una columna a la ruta de tiempo de ruta
|
||
strcpy_s(path_dbf,MAX_PATH,path_shp);
|
||
cambiaext(path_dbf,".shp",".dbf");
|
||
info = (char *)malloc(nsec*OLV_SHP_SZ_CAMP_CHAR);
|
||
if(!info)
|
||
{
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//SECTOR ya viene
|
||
//TRATAMIENTO
|
||
isec_novac=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
{
|
||
continue;
|
||
}
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%s",olv_limp->nomb_tto);
|
||
isec_novac++;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,nsec,TIPO_IA_CHAR,info,"TTO",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info de hora inicial
|
||
isec_novac=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
{
|
||
continue;
|
||
}
|
||
tt=olv_limp->t_ini;
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
isec_novac++;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,nsec,TIPO_IA_CHAR,info,"H_INI",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info de hora final
|
||
isec_novac=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
{
|
||
continue;
|
||
}
|
||
tt=olv_limp->t_ini+ olv_limp->sec[i].cost_ac + olv_limp->t_desc;
|
||
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
isec_novac++;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,nsec,TIPO_IA_CHAR,info,"H_FIN",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info de duraci<63>n total
|
||
isec_novac=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
tt=olv_limp->sec[i].cost_ac+olv_limp->t_desc;
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
isec_novac++;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,nsec,TIPO_IA_CHAR,info,"T_TOTAL",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info de duraci<63>n de los desplazamientos
|
||
isec_novac=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
tt=olv_limp->sec[i].t_despl[0]+olv_limp->sec[i].t_despl[1];
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
isec_novac++;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,nsec,TIPO_IA_CHAR,info,"T_INSTA",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info de duraci<63>n de los descansos
|
||
isec_novac=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
tt=olv_limp->t_desc;
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
isec_novac++;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,nsec,TIPO_IA_CHAR,info,"T_DESCAN",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info de duraci<63>n de la ruta
|
||
isec_novac=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
tt=olv_limp->plan[i].elem[olv_limp->plan[i].nelem-1].coste;
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
isec_novac++;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,nsec,TIPO_IA_CHAR,info,"T_RUTA",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info de longitud de la ruta
|
||
isec_novac=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
tt=olv_limp->plan[i].m[0]+olv_limp->plan[i].m[1];
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%.2f",tt);
|
||
isec_novac++;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,nsec,TIPO_IA_CHAR,info,"M_RUTA",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena primero T DESP, M DESP, VELO DESP, T TRAT, M TRAT, VELO/T TRAT
|
||
int p;
|
||
for(int k=0;k<OLV_DT_N;k++)
|
||
{
|
||
for(p=0;p<3;p++)
|
||
{
|
||
isec_novac=0;
|
||
if(p==0)
|
||
{
|
||
strcpy_s(nombia,"T_");
|
||
|
||
//rellena la info de h
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
tt=olv_limp->plan[i].t[k];
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
isec_novac++;
|
||
}
|
||
}
|
||
else if(p==1)
|
||
{
|
||
if(k==OLV_TTO)
|
||
{
|
||
if(olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoM2h || olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoM2h_eje)
|
||
strcpy_s(nombia,"M2_");
|
||
else if(olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoMh || olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoMh_eje)
|
||
strcpy_s(nombia,"M_");
|
||
else if(olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoMin)
|
||
strcpy_s(nombia,"UDS_");
|
||
}
|
||
else
|
||
{
|
||
strcpy_s(nombia,"M_");
|
||
}
|
||
if((k==OLV_TTO) && (olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoMin))
|
||
{
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
tt=olv_limp->sec[i].namb;
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%ld",(int)tt);
|
||
isec_novac++;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
tt=olv_limp->plan[i].m[k];
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%.2f",tt);
|
||
isec_novac++;
|
||
|
||
}
|
||
}
|
||
}
|
||
else if(p==2)
|
||
{
|
||
if(k==OLV_TTO)
|
||
{
|
||
tt=olv_limp->t_tto;
|
||
if(olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoM2h || olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoM2h_eje)
|
||
strcpy_s(nombia,"M2_H_");
|
||
else if(olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoMh || olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoMh_eje)
|
||
strcpy_s(nombia,"M_H_");
|
||
else if(olv_limp->uds_tto==OliviaDef::GeneralDef::OlvTipTtoMin)
|
||
{
|
||
strcpy_s(nombia,"MIN_");
|
||
tt=tt/60;//para pasarlo a minutos
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
strcpy_s(nombia,"M_H_");
|
||
tt=olv_limp->v_despl;
|
||
}
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
if(tt)
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%.1f",tt);
|
||
else
|
||
sprintf_s(&info[isec_novac*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"Def. Vias");
|
||
isec_novac++;
|
||
}
|
||
}
|
||
if(k==OLV_TTO)
|
||
{
|
||
strcat_s(nombia,"TRAT");
|
||
}
|
||
else if(k==OLV_DESP)
|
||
{
|
||
strcat_s(nombia,"DESP");
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,nsec,TIPO_IA_CHAR,info,nombia,err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*OLV_SHP_SZ_CAMP_CHAR);
|
||
}
|
||
}
|
||
|
||
free(info);
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* A<>ade las columnas de informaci<63>n a los puntos de control
|
||
*/
|
||
BOOL Colv_limp_thr::guarda_cols_ctrl(char *path_shp)
|
||
{
|
||
char path_dbf[MAX_PATH];
|
||
int h,m,s,k;
|
||
double tt;
|
||
char *info;
|
||
int nsec, i, isec_novac;
|
||
|
||
//cuenta el n<>mero de sectores no vac<61>os
|
||
nsec=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb!=0)
|
||
nsec++;
|
||
}
|
||
|
||
//a<>ade una columna a los puntos de control de secuencia
|
||
strcpy_s(path_dbf,MAX_PATH,path_shp);
|
||
cambiaext(path_dbf,".shp",".dbf");
|
||
|
||
info = (char *)malloc(nsec*olv_limp->npts_ctrl*OLV_SHP_SZ_CAMP_CHAR);
|
||
if(!info)
|
||
{
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*olv_limp->npts_ctrl*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena el nombre del tto
|
||
k=0;
|
||
isec_novac=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
|
||
sprintf_s(&info[k*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,olv_limp->nomb_tto);
|
||
k++;
|
||
for(k;k<(isec_novac+1)*olv_limp->npts_ctrl-1;k++)
|
||
sprintf_s(&info[k*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,olv_limp->nomb_tto);
|
||
sprintf_s(&info[k*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,olv_limp->nomb_tto);
|
||
isec_novac++;
|
||
k++;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,nsec*olv_limp->npts_ctrl,TIPO_IA_CHAR,info,"TTO",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*olv_limp->npts_ctrl*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info
|
||
k=0;
|
||
isec_novac=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
sprintf_s(&info[k*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"Inicio");
|
||
k++;
|
||
for(k;k<(isec_novac+1)*olv_limp->npts_ctrl-1;k++)
|
||
sprintf_s(&info[k*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"Medio");
|
||
sprintf_s(&info[k*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"Fin");
|
||
isec_novac++;
|
||
k++;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,nsec*olv_limp->npts_ctrl,TIPO_IA_CHAR,info,"SECUENCIA",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,nsec*olv_limp->npts_ctrl*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info de tiempo
|
||
k=0;
|
||
isec_novac=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
tt= olv_limp->t_ini+olv_limp->sec[i].t_despl[0];
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[k*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
k++;
|
||
for(k;k<(isec_novac+1)*olv_limp->npts_ctrl-1;k++)
|
||
{
|
||
tt= olv_limp->plan[i].pts_ctrl[k-(isec_novac*olv_limp->npts_ctrl+1)].cost;
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[k*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
}
|
||
tt= olv_limp->plan[i].pts_ctrl[olv_limp->npts_ctrl-2].cost;
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[k*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
k++;
|
||
isec_novac++;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,nsec*olv_limp->npts_ctrl,TIPO_IA_CHAR,info,"HORA",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
free(info);
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* A<>ade las columnas de informaci<63>n a las rutas de viajes a la instalaci<63>n
|
||
*/
|
||
BOOL Colv_limp_thr::guarda_cols_insta(char *path_shp)
|
||
{
|
||
char path_dbf[MAX_PATH];
|
||
char *info;
|
||
double tt,ttt;
|
||
int h,m,s,insta,i,ninsta,ninsta_parc,ninsta_novac;
|
||
char tray[OLV_SHP_SZ_CAMP_CHAR];
|
||
|
||
//a<>ade una columna
|
||
strcpy_s(path_dbf,MAX_PATH,path_shp);
|
||
cambiaext(path_dbf,".shp",".dbf");
|
||
|
||
//cuenta el n<>mero de instalaciones
|
||
ninsta=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
for(insta=0;insta<olv_limp->plan[i].ninsta;insta++)
|
||
{
|
||
if(olv_limp->plan[i].planif_insta[insta].nelem!=0)
|
||
ninsta++;
|
||
}
|
||
}
|
||
|
||
info = (char *)malloc(ninsta*OLV_SHP_SZ_CAMP_CHAR);
|
||
if(!info)
|
||
{
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ninsta*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena el nombre del tto
|
||
ninsta_parc=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
ttt=0;
|
||
ninsta_novac=0;
|
||
for(insta=0;insta<olv_limp->plan[i].ninsta;insta++)
|
||
{
|
||
if(olv_limp->plan[i].planif_insta[insta].nelem==0)
|
||
continue;
|
||
|
||
sprintf_s(&info[(insta+ninsta_parc)*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%s",olv_limp->nomb_tto);
|
||
ninsta_novac++;
|
||
}
|
||
ninsta_parc+=ninsta_novac;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,ninsta,TIPO_IA_CHAR,info,"TTO",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ninsta*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info de tipo de trayecto
|
||
ninsta_parc=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
ninsta_novac=0;
|
||
for(insta=0;insta<olv_limp->plan[i].ninsta;insta++)
|
||
{
|
||
if(olv_limp->plan[i].planif_insta[insta].nelem==0)
|
||
continue;
|
||
|
||
switch(olv_limp->plan[i].planif_insta[insta].ninsta)
|
||
{
|
||
case OLV_IDA_INST:
|
||
strcpy_s(tray,"Ida desde instalacion"); //quitado acento para evitar que salga mal
|
||
break;
|
||
case OLV_VUELTA_INST:
|
||
strcpy_s(tray,"Vuelta a instalacion");
|
||
break;
|
||
case OLV_IDA_PLANT_ULT:
|
||
strcpy_s(tray,"Ultima ida a descargar");
|
||
break;
|
||
case OLV_IDA_PLANT:
|
||
strcpy_s(tray,"Ida a descargar");
|
||
break;
|
||
case OLV_VUELTA_PLANT:
|
||
strcpy_s(tray,"Vuelta de descargar");
|
||
break;
|
||
}
|
||
sprintf_s(&info[(insta+ninsta_parc)*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%s",tray);
|
||
ninsta_novac++;
|
||
}
|
||
ninsta_parc+=ninsta_novac;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,ninsta,TIPO_IA_CHAR,info,"TRAYECTO",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ninsta*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info de tipo de hora
|
||
ninsta_parc=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
ninsta_novac=0;
|
||
for(insta=0;insta<olv_limp->plan[i].ninsta;insta++)
|
||
{
|
||
if(olv_limp->plan[i].planif_insta[insta].nelem==0)
|
||
continue;
|
||
|
||
switch(olv_limp->plan[i].planif_insta[insta].ninsta)
|
||
{
|
||
case OLV_IDA_INST:
|
||
tt=olv_limp->t_ini;
|
||
break;
|
||
case OLV_VUELTA_INST:
|
||
tt=olv_limp->t_ini+olv_limp->sec[i].cost_ac-olv_limp->sec[i].t_despl[1]+olv_limp->t_desc;
|
||
olv_limp->plan[i].planif_insta[insta].t[OLV_TTO]=tt;
|
||
break;
|
||
case OLV_IDA_PLANT:
|
||
case OLV_IDA_PLANT_ULT:
|
||
tt=olv_limp->plan[i].planif_insta[insta].t[OLV_TTO];
|
||
break;
|
||
case OLV_VUELTA_PLANT:
|
||
tt=olv_limp->plan[i].planif_insta[insta].t[OLV_TTO];
|
||
break;
|
||
}
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[(insta+ninsta_parc)*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
ninsta_novac++;
|
||
}
|
||
ninsta_parc+=ninsta_novac;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,ninsta,TIPO_IA_CHAR,info,"H_TRAY",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ninsta*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info de duraci<63>n
|
||
ninsta_parc=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
ttt=0;
|
||
ninsta_novac=0;
|
||
for(insta=0;insta<olv_limp->plan[i].ninsta;insta++)
|
||
{
|
||
if(olv_limp->plan[i].planif_insta[insta].nelem==0)
|
||
continue;
|
||
|
||
tt=olv_limp->plan[i].planif_insta[insta].elem[olv_limp->plan[i].planif_insta[insta].nelem-1].coste;
|
||
ttt+=tt;
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(&info[(insta+ninsta_parc)*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%02d:%02d:%02d h",h,m,s);
|
||
ninsta_novac++;
|
||
}
|
||
ninsta_parc+=ninsta_novac;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,ninsta,TIPO_IA_CHAR,info,"T_TRAY",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ninsta*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
//rellena la info de longitud
|
||
ninsta_parc=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
ninsta_novac=0;
|
||
for(insta=0;insta<olv_limp->plan[i].ninsta;insta++)
|
||
{
|
||
if(olv_limp->plan[i].planif_insta[insta].nelem==0)
|
||
continue;
|
||
|
||
tt=olv_limp->plan[i].planif_insta[insta].m[OLV_DESP];
|
||
sprintf_s(&info[(insta+ninsta_parc)*OLV_SHP_SZ_CAMP_CHAR],OLV_SHP_SZ_CAMP_CHAR,"%.2f",tt);
|
||
ninsta_novac++;
|
||
}
|
||
ninsta_parc+=ninsta_novac;
|
||
}
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,ninsta,TIPO_IA_CHAR,info,"M_TRAY",err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
memset(info,0,ninsta*OLV_SHP_SZ_CAMP_CHAR);
|
||
|
||
free(info);
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Recorre la ruta y genera un listado en csv donde guarda las calles por las que va pasando la ruta
|
||
* El archivo se llama como el shape, concatenando el n<>mero de sector y L, en formato csv
|
||
*/
|
||
BOOL Colv_limp_thr::genera_list_rut_ctrl(Cobgeo *ob_rut)
|
||
{
|
||
Info_planif *pp;
|
||
Colv_csv cc;
|
||
char tto_desp[32],observ[32],calle[1024],path_csv[MAX_PATH],fila[256],fila0[256];
|
||
int i,j,h,m,seg,ii,dt;
|
||
double ltot,ltot0,tt,t0;
|
||
BOOL mal;
|
||
|
||
double lttt;
|
||
|
||
mal=FALSE;
|
||
strcpy_s(path_csv,MAX_PATH,olv_limp->olv->paths.path_data);
|
||
cambiaext(path_csv,".shp","_L.csv");
|
||
////////////
|
||
if(!cc.inicia(path_csv))
|
||
{
|
||
sprintf_s(err_str, "Error al iniciar archivo %s",path_csv);
|
||
return FALSE;
|
||
}
|
||
//Inicia el archivo csv donde va a guardar las calles del itinerario
|
||
if(!cc.escribe("Ruta;Secuencia;Calle;Observaciones;Tratamiento/Desplazamiento;Longitud (m);Tiempo acumulado (h);\r\n"))
|
||
mal=TRUE;
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Escribiendo listados de las rutas en csv");
|
||
|
||
//graba los listados de la ruta de los sectores
|
||
for(int s=0; s<olv_limp->nsec && !mal;s++)
|
||
{
|
||
lttt=0;
|
||
ltot0=0;
|
||
pp=&olv_limp->plan[s];
|
||
if(pp->nelem==0)
|
||
continue;
|
||
ii=1;
|
||
i=0;
|
||
t0=olv_limp->t_ini + olv_limp->sec[s].t_despl[0];
|
||
|
||
//////////////////////////////////////////////
|
||
//primer punto de control e instalaci<63>n
|
||
if(i==0)
|
||
{
|
||
dame_h_m_s(olv_limp->t_ini, &h, &m, &seg);
|
||
sprintf_s(fila0,256,"%02d;%04d;%s;%s;%s;%s;%02d:%02d:%02d;\r\n",s+1,ii,"","","Instalación","",h,m,seg);
|
||
if(!cc.escribe(fila0))
|
||
{
|
||
mal=TRUE;
|
||
continue;;
|
||
}
|
||
dame_h_m_s(t0, &h, &m, &seg);
|
||
sprintf_s(fila0,256,"%02d;%04d;%s;%s;%s;%s;%02d:%02d:%02d;\r\n",s+1,ii,"","","Control","",h,m,seg);
|
||
if(!cc.escribe(fila0))
|
||
{
|
||
mal=TRUE;
|
||
continue;;
|
||
}
|
||
}
|
||
//////////////////////////////////////////////
|
||
|
||
for(i=0;i<pp->nelem;i++)
|
||
{
|
||
if(pp->elem[i].tp==OLV_PLAN_TIP_SEG_LIN)
|
||
goto ctrl;
|
||
|
||
if((pp->elem[i].ltot ==0) && (i>1) && (pp->elem[i].coste==pp->elem[i-1].coste))
|
||
continue;
|
||
|
||
if(i<(pp->nelem-1))
|
||
{
|
||
if(((pp->elem[i].ia_nw == pp->elem[i+1].ia_nw) ||
|
||
(((olv_limp->ias[pp->elem[i].ia_nw].info2 && olv_limp->ias[pp->elem[i+1].ia_nw].info2)
|
||
&& (strcmp(olv_limp->ias[pp->elem[i].ia_nw].info2,olv_limp->ias[pp->elem[i+1].ia_nw].info2)==0))))
|
||
&& (pp->elem[i].tp == pp->elem[i+1].tp) )
|
||
{
|
||
ltot0+=pp->elem[i].ltot;
|
||
lttt+=pp->elem[i].ltot;
|
||
goto ctrl;
|
||
}
|
||
}
|
||
|
||
strcpy_s(observ,32,"");
|
||
strcpy_s(tto_desp,32,"");
|
||
switch(pp->elem[i].tp)
|
||
{
|
||
case OLV_PLAN_TIP_NW:
|
||
strcpy_s(tto_desp,32,"Desplazamiento");
|
||
dt=OLV_DESP;
|
||
break;
|
||
case OLV_PLAN_TIP_AMB_PEAT_DESP:
|
||
strcpy_s(tto_desp,32,"Despl. por peatonal");
|
||
dt=OLV_DESP;
|
||
break;
|
||
case OLV_PLAN_TIP_AMB_PEAT:
|
||
strcpy_s(observ,32,"Peatonal");//pasa al siguiente para poner tto tambi<62>n
|
||
case OLV_PLAN_TIP_AMB:
|
||
case OLV_PLAN_TIP_SEG_PUN:
|
||
strcpy_s(tto_desp,32,"Tratamiento");
|
||
dt=OLV_TTO;
|
||
break;
|
||
case OLV_PLAN_TIP_SEG_LIN:
|
||
goto ctrl;
|
||
}
|
||
|
||
if(pp->elem[i].ia_nw>0 && olv_limp->ias[pp->elem[i].ia_nw].info2)
|
||
strcpy_s(calle,1024,olv_limp->ias[pp->elem[i].ia_nw].info2);
|
||
else if((pp->elem[i].ia_nw>0) && (pp->elem[i].ia_nw<olv_limp->n_ini_nw) && (pp->elem[i].tp == OLV_PLAN_TIP_AMB_PEAT))
|
||
strcpy_s(calle,1024,"Parque---");
|
||
else
|
||
calle[0]=0;
|
||
|
||
tt=pp->elem[i].coste+t0; //a todos los costes de la ruta se a<>ade el tiempo de desplazamiento
|
||
ltot=ltot0+pp->elem[i].ltot;
|
||
ltot0=0;
|
||
lttt+=pp->elem[i].ltot;
|
||
|
||
//////////////////////////////////////////////
|
||
//mira si tiene que poner observaciones por si fuera contendor
|
||
if(((olv_limp->ias[(*olv_limp->olv->olv_ob->objt)[pp->elem[i].i].ia].flgs & OLV_LIMP_FLG_SEG_PUN)) && (pp->elem[i].tp==OLV_PLAN_TIP_AMB))
|
||
dame_observ_cont(olv_limp->ias[(*olv_limp->olv->olv_ob->objt)[pp->elem[i].i].ia].ishp, observ);
|
||
//////////////////////////////////////////////
|
||
|
||
|
||
dame_h_m_s(tt, &h, &m, &seg);
|
||
if((olv_limp->tipo_ambit==OLV_AMB_PUN) && (pp->elem[i].tp==OLV_PLAN_TIP_AMB))
|
||
sprintf_s(fila,256,"%02d;%04d;%s;%s;%s;%s;%02d:%02d:%02d;\r\n",s+1,ii,calle,observ,tto_desp,"",h,m,seg);
|
||
else
|
||
sprintf_s(fila,256,"%02d;%04d;%s;%s;%s;%.1f;%02d:%02d:%02d;\r\n",s+1,ii,calle,observ,tto_desp,ltot,h,m,seg);
|
||
|
||
//////////////////////////////////////////////
|
||
//escribe fila de paso
|
||
if(!cc.escribe(fila))
|
||
{
|
||
mal=TRUE;
|
||
continue;
|
||
}
|
||
|
||
ctrl:
|
||
//////////////////////////////////////////////
|
||
//puntos de control intermedios
|
||
for(j=0;j<olv_limp->npts_ctrl-2 && !mal;j++)
|
||
{
|
||
if(pp->pts_ctrl[j].ipt==i)
|
||
{
|
||
t0+=olv_limp->t_desc/(olv_limp->npts_ctrl-2);
|
||
tt+=olv_limp->t_desc/(olv_limp->npts_ctrl-2);
|
||
pp->pts_ctrl[j].cost = tt;
|
||
dame_h_m_s(tt, &h, &m, &seg);
|
||
sprintf_s(fila0,256,"%02d;%04d;%s;%s;%s;%s;%02d:%02d:%02d;\r\n",s+1,ii,"","","Control","",h,m,seg);
|
||
if(!cc.escribe(fila0))
|
||
{
|
||
mal=TRUE;
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
//////////////////////////////////////////////
|
||
//viajes a vaciar intermedios
|
||
if((olv_limp->ias[(*olv_limp->olv->olv_ob->objt)[pp->elem[i].i].ia].flgs & OLV_LIMP_FLG_SEG_PUN)&& (pp->elem[i].tp==OLV_PLAN_TIP_AMB))
|
||
{
|
||
if(!genera_list_fila_vaci(&cc, fila0,
|
||
olv_limp->ias[(*olv_limp->olv->olv_ob->objt)[pp->elem[i].i].ia].ishp,
|
||
pp->elem[i].i, s,ii,tt, &t0,FALSE))
|
||
{
|
||
mal=TRUE;
|
||
break;
|
||
}
|
||
}
|
||
//////////////////////////////////////////////
|
||
|
||
ii++;
|
||
}
|
||
//////////////////////////////////////////////
|
||
//<2F>ltimo punto de control e instalaci<63>n
|
||
if((i==(pp->nelem))&& !mal)
|
||
{
|
||
dame_h_m_s(tt, &h, &m, &seg);
|
||
sprintf_s(fila0,256,"%02d;%04d;%s;%s;%s;%s;%02d:%02d:%02d;\r\n",s+1,ii,calle,"","Control","",h,m,seg);
|
||
if(!cc.escribe(fila0))
|
||
{
|
||
mal=TRUE;
|
||
continue;
|
||
}
|
||
pp->pts_ctrl[olv_limp->npts_ctrl-2].cost = tt;
|
||
|
||
//////////////////////////////////////////////
|
||
//<2F>ltimo viaje a vaciar
|
||
if(olv_limp->ias[(*olv_limp->olv->olv_ob->objt)[pp->elem[i-1].i].ia].flgs & OLV_LIMP_FLG_SEG_PUN)
|
||
{
|
||
if(!genera_list_fila_vaci(&cc, fila0,
|
||
olv_limp->ias[(*olv_limp->olv->olv_ob->objt)[pp->elem[i-1].i].ia].ishp,
|
||
pp->elem[i-1].i, s,ii,tt, &t0,TRUE))
|
||
{
|
||
mal=TRUE;
|
||
break;
|
||
}
|
||
}
|
||
//////////////////////////////////////////////
|
||
|
||
t0+=olv_limp->sec[s].t_despl[1]; //<2F>ltimo punto de instalaci<63>n, le a<>ade el t_desplazamiento/2
|
||
tt=pp->elem[pp->nelem-1].coste+t0;
|
||
dame_h_m_s(tt, &h, &m, &seg);
|
||
sprintf_s(fila0,256,"%02d;%04d;%s;%s;%s;%s;%02d:%02d:%02d;\r\n",s+1,ii,"","","Instalación","",h,m,seg);
|
||
if(!cc.escribe(fila0))
|
||
{
|
||
mal=TRUE;
|
||
continue;;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
cc.cierra();
|
||
|
||
if(mal)
|
||
{
|
||
sprintf_s(err_str, "Error al escribir fila en archivo %s",path_csv);
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* A<>ade una l<>nea al listado csv con el viaje a vaciar y vuelta
|
||
*/
|
||
void Colv_limp_thr::dame_h_m_s(double tt, int *h_, int *m_, int *s_)
|
||
{
|
||
int h,m,s;
|
||
|
||
h=(int)(tt/3600);
|
||
m=(int)((tt-h*3600)/60);
|
||
s=(int)(tt-m*60-h*3600);
|
||
h=h%24;
|
||
|
||
*h_=h;
|
||
*m_=m;
|
||
*s_=s;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* A<>ade una l<>nea al listado csv con el viaje a vaciar y vuelta
|
||
*/
|
||
BOOL Colv_limp_thr::genera_list_fila_vaci(Colv_csv *cc, char *fila0,int iamb, int ielem, int s, int ii, double tt, double *t0,BOOL is_fin)
|
||
{
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* A<>ade una columna de observaci<63>n al listado si es contenedores
|
||
*/
|
||
void Colv_limp_thr::dame_observ_cont(int iamb,char *observ)
|
||
{
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Modifica el dbf del shp original para poner la sectorizaci<63>n,
|
||
* que es el mismo que de entrada con una columna m<>s,
|
||
* SECTOR (modo 0) o SECUENCIA VAC<41>A (modo 1) o SECUENCIA BUENA (modo 2) o TRAMO al que pertenece (modo 3)
|
||
*/
|
||
BOOL Colv_limp_thr::guarda_dbf_sector(int modo)
|
||
{
|
||
int *info;
|
||
char path_dbf[MAX_PATH];
|
||
char nom_ia[16];
|
||
|
||
//primero graba los archivos de la ruta de los sectores
|
||
//graba todos los sectores en un <20>nico path
|
||
strcpy_s(path_dbf,MAX_PATH,olv_limp->olv->paths.path_data);
|
||
cambiaext(path_dbf,".shp",".dbf");
|
||
|
||
info = (int *)malloc(olv_limp->n_amb*sizeof(int));
|
||
if(!info)
|
||
{
|
||
sprintf_s(err_str,OLV_MAX_ERR,"Error, sin memoria para info asociada");
|
||
return FALSE;
|
||
}
|
||
|
||
//rellena la info
|
||
for(int i=0;i<olv_limp->n_amb;i++)
|
||
{
|
||
if(modo==0)//sector
|
||
info[i]=olv_limp->amb_sec[i].sec+1;
|
||
else if(modo==1)//secuencia vac<61>a
|
||
info[i]=0;
|
||
else if(modo==2)//secuencia buena
|
||
{
|
||
info[i]=olv_limp->amb_sec[i].iseq+1;
|
||
//wgeolog(LOG_TODO,"olv_limp_t","seq i %ld %ld",i,info[i]);
|
||
}
|
||
else if(modo==3)//tramo al que pertenece (cuando en recogida hay varios tramos)
|
||
{
|
||
info[i]=olv_limp->amb_sec[i].res+1;
|
||
}
|
||
}
|
||
|
||
//pone el nombre de la columna
|
||
if(modo==0)//sector
|
||
strcpy_s(nom_ia,16,"SECTOR");
|
||
else if((modo==1)|| (modo==2))//secuencia
|
||
strcpy_s(nom_ia,16,"SECUENCIA");
|
||
else if(modo==3)
|
||
strcpy_s(nom_ia,16,"VIAJE");
|
||
|
||
if(!olv_limp->olv->olv_sh->add_col_dbf(path_dbf,olv_limp->n_amb,TIPO_IA_INT,(char*)info,nom_ia,err_str,OLV_MAX_ERR))
|
||
{
|
||
free(info);
|
||
return FALSE;
|
||
}
|
||
|
||
free(info);
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Planifica o calcula el orden en el que hay que recorrer los ambitos del sector s
|
||
* la idea es partir de una solucion factible (la cual se consigue por distancias minimas)
|
||
* una vez que se tenga se realizan peque<75>os cambios en dicho orden para ver si mejora, si es asi se deja dicho cambio como permanente
|
||
* si no se quita y se intenta otro cambio
|
||
*/
|
||
Secu_amb * Colv_limp_thr::planifica_sect(Info_sec *s, Djkt_ang_ady *ang_conj, Info_aso *ias, int npermu)
|
||
{
|
||
int i,k, j, nsec;
|
||
BOOL res=FALSE;
|
||
BOOL camb;
|
||
th_param_planif thp;
|
||
int nth=Colv_geom::dame_n_nucleos();
|
||
int obset=0;
|
||
double ca, cold;
|
||
Secu_amb *sec;
|
||
BOOL nocalc=FALSE;
|
||
|
||
sec=(Secu_amb*)malloc(s->namb*sizeof(Secu_amb));
|
||
if(!sec)
|
||
goto sal;
|
||
memset(sec,0,s->namb*sizeof(Secu_amb));
|
||
|
||
//prepara arrays----------------------
|
||
memset(&thp,0,sizeof(thp));
|
||
|
||
//copia la info del sector
|
||
|
||
for (i=0; i<s->namb && !pirate; i++)
|
||
{
|
||
for(k=0;k<2;k++)
|
||
{
|
||
sec[i].ctnod[k]=NULL;
|
||
}
|
||
}
|
||
if(pirate)
|
||
goto sal;
|
||
|
||
//consigue solucion factible------------------------------
|
||
nsec=0;
|
||
sec[nsec].iamb=dame_planif_iamb_ini(s,olv_limp->cost_amb,&sec[nsec].entrada );
|
||
//sec[nsec].entrada=-1;
|
||
sec[sec[nsec].iamb].flags=1;
|
||
if(sec[nsec].iamb<0)
|
||
goto sal;
|
||
nsec++;
|
||
while(nsec<s->namb)
|
||
{
|
||
if(!busca_cercano(s,ias, sec, nsec-1, TRUE))//se pilla el minimo local
|
||
break;
|
||
nsec++;
|
||
}
|
||
|
||
if(nsec<s->namb)
|
||
goto sal;
|
||
//mejora solucion---------------------
|
||
//prepara thread------------
|
||
thp.dth=(th_data_planif*)malloc(sizeof(th_data_planif)*nth);
|
||
thp.ias=ias;
|
||
thp.sec=sec;
|
||
thp.tl=this;
|
||
|
||
thp.namb=s->namb;
|
||
thp.namb_t=s->namb;
|
||
thp.s=s;
|
||
thp.abs=TRUE;//cambio ger
|
||
if(!thp.dth)
|
||
goto sigue;
|
||
thp.dth[0].sec=(Secu_amb *)malloc(s->namb*nth*sizeof(Secu_amb));
|
||
if(!thp.dth[0].sec)
|
||
goto sigue;
|
||
for (i=1; i<nth; i++)
|
||
thp.dth[i].sec=&thp.dth[0].sec[s->namb*i];
|
||
//lanza--------------------
|
||
for (i=0; i<nth; i++)
|
||
{
|
||
thp.id_th=i;
|
||
thp.dth[i].activo=TRUE;
|
||
igt_sum_atm(&thp.nth,1);
|
||
AfxBeginThread(th_planificacion, (LPVOID)&thp, THREAD_PRIORITY_NORMAL, 0, 0, NULL);
|
||
while(thp.id_th>=0)
|
||
Sleep(1);
|
||
|
||
}
|
||
ca=dame_coste(sec,0,s->namb-1,ias, s,TRUE);
|
||
do
|
||
{
|
||
thp.modo=2;
|
||
cold=ca;
|
||
camb=FALSE;
|
||
|
||
//bucle hasta recorrer todos los elementos de sec
|
||
//movimientos de elementos puntuales (cambio de posicion)
|
||
for (i=1; i<s->namb; i++)
|
||
{
|
||
thp.param[0]=i;
|
||
thp.a_currar();
|
||
//espera thread
|
||
while(!thp.terminado())
|
||
Sleep(thp.milis_sleep);
|
||
//elije la mejor permuta
|
||
j=thp.dame_min();
|
||
|
||
if(j<0 || ca <=thp.dth[j].coste)
|
||
continue;
|
||
cambia_elem(sec, i, thp.dth[j].pos[0], thp.dth[j].pos[1]);
|
||
ca=thp.dth[j].coste;
|
||
|
||
cold=ca;
|
||
camb=TRUE;
|
||
}
|
||
//permutaciones de npermu elementos
|
||
/*thp.modo=1;
|
||
cold=ca;
|
||
//camb=FALSE;
|
||
for (i=npermu+obset; i<s->namb; i++)
|
||
{
|
||
thp.param[0]=max(i-npermu, obset);
|
||
thp.param[1]=i;
|
||
thp.a_currar();
|
||
while(!thp.terminado())
|
||
Sleep(1);
|
||
j=thp.dame_min();
|
||
if(j<0 || ca <=thp.dth[j].coste || thp.dth[j].pos[0]<0)
|
||
continue;
|
||
ca =thp.dth[j].coste;
|
||
memcpy(sec, thp.dth[j].sec, s->namb*sizeof(Secu_amb));
|
||
wgeolog(LOG_TODO,"olv_limp_t","Permu Mejora coste de %lf a %lf actu: %lf",
|
||
cold, ca, dame_coste(sec,0,s->namb-1,ias, s));
|
||
cold=ca;
|
||
camb=TRUE;
|
||
}*/
|
||
} while (camb);
|
||
thp.milis_sleep=1;
|
||
|
||
//fuera thread
|
||
thp.pirate=TRUE;
|
||
while(thp.nth>0)
|
||
Sleep(1);
|
||
|
||
//----------------------------------------------------------
|
||
sigue:
|
||
if (thp.dth)
|
||
{
|
||
if(thp.dth[0].sec)
|
||
free(thp.dth[0].sec);
|
||
free(thp.dth);
|
||
}
|
||
|
||
|
||
pon_t_desp(s, ias, sec);
|
||
|
||
|
||
res=TRUE;
|
||
sal:
|
||
if(!res)
|
||
{
|
||
if(sec)
|
||
free(sec);
|
||
sec=NULL;
|
||
}
|
||
|
||
return sec;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena los tiempos de desplazamiento
|
||
*/
|
||
void Colv_limp_thr::pon_t_desp(Info_sec *s, Info_aso *ias, Secu_amb *sec)
|
||
{
|
||
if((olv_limp->nod_instal>=0) && (s->namb>1))
|
||
{
|
||
s->t_despl[0]=olv_limp->arch_dj.dame_dis(olv_limp->arch_dj.id_instal,0,s->iamb[sec[0].iamb],sec[0].entrada);
|
||
s->t_despl[1]=olv_limp->ord_sec_plan[0].ctnod[0][ias[s->iamb[sec[s->namb-1].iamb]].ic[(sec[s->namb-1].entrada+1)%2]].dis;
|
||
}
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Rellena el siguiente nodo en la secuencia
|
||
*/
|
||
BOOL Colv_limp_thr::busca_cercano(Info_sec *s, Info_aso *ias, Secu_amb *sec, int isec, BOOL ind_abs)
|
||
{
|
||
double d=MAYUSCULO;
|
||
int nam, nsal, nent;
|
||
int k, kk, i, j;
|
||
int ic, ind_cost;
|
||
ic=sec[isec].entrada;
|
||
if(isec==0)
|
||
isec=isec;
|
||
if(ic<0)
|
||
kk=olv_limp->tipo_ambit;
|
||
else
|
||
kk=1;
|
||
|
||
for (k=0; k<kk; k++)
|
||
{
|
||
ic=(ic+1)%2;
|
||
for (i=0; i<s->namb; i++)
|
||
{
|
||
if(sec[i].flags &1)
|
||
continue;///ya esta en la secuencia
|
||
if (ind_abs)
|
||
ind_cost=s->iamb[i];
|
||
else
|
||
ind_cost=i;
|
||
for (j=0; j<olv_limp->tipo_ambit; j++)
|
||
{
|
||
if(d>olv_limp->arch_dj.dame_dis(s->iamb[sec[isec].iamb],ic,s->iamb[i],j))
|
||
{
|
||
d=olv_limp->arch_dj.dame_dis(s->iamb[sec[isec].iamb],ic,s->iamb[i],j);
|
||
nent=j;
|
||
nsal=ic;
|
||
nam=i;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
if(d>=MAYUSCULO)
|
||
return FALSE;
|
||
|
||
sec[isec++].entrada=(nsal+1)%2;
|
||
sec[isec].entrada=nent;
|
||
sec[isec].iamb=nam;
|
||
sec[nam].flags=1;
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Da el <20>mbito inicial por el que empezar la planificaci<63>n, en funci<63>n del modo
|
||
*/
|
||
short Colv_limp_thr::dame_planif_iamb_ini(Info_sec *s, Matrix2d<float> &cost_amb, short *ent/*=NULL*/)
|
||
{
|
||
int i,j,iaux,ient,nn;
|
||
float aux, dist, dist1;
|
||
int modo;
|
||
double a, b,c,d,e;
|
||
|
||
//cost_amb=olv_limp->cost_amb;
|
||
iaux=-1;
|
||
modo=3;
|
||
////////////////////////////////////////////////////
|
||
//Coge el <20>mbito por defecto que se le hubiera dado en la columna secuencia
|
||
//Si no, busca el <20>mbito m<>s cercano a la instalaci<63>n, si la hubiera configurada,
|
||
//Si no, coge el de mayor coste (modo 1)
|
||
//O el de 'y+x' menor (modo 2)
|
||
//O el m<>s alejado del centro (modo 3)
|
||
if(s->iamb_ini_def!=-1)
|
||
{
|
||
iaux=s->iamb_ini_def;
|
||
ient=0;
|
||
//busca el nodo m<>s cercano a la instalaci<63>n, si tiene 2 nodos y hay instalaci<63>n
|
||
if(olv_limp->tipo_ambit==OLV_AMB_LIN && olv_limp->nod_instal>=0)
|
||
{
|
||
//comprueba los dos nodos
|
||
dist=olv_limp->arch_dj.dame_dis(olv_limp->arch_dj.id_instal,0,s->iamb[iaux],ient);
|
||
dist1=olv_limp->arch_dj.dame_dis(olv_limp->arch_dj.id_instal,0,s->iamb[iaux],1);
|
||
if(dist1<dist)
|
||
{
|
||
ient=1;
|
||
}
|
||
}
|
||
if(ent)
|
||
*ent=ient;
|
||
}
|
||
else if(olv_limp->nod_instal>=0)
|
||
{
|
||
aux=(float)MAYUSCULO;
|
||
//se coge de punto inicial el m<>s cercano a la instalaci<63>n
|
||
for(i=0;i<s->namb;i++)
|
||
{
|
||
if(olv_limp->ias[s->iamb[i]].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
//calcula la distancia de la instalaci<63>n al inicio del <20>mbito
|
||
ient=0;
|
||
dist=olv_limp->arch_dj.dame_dis(olv_limp->arch_dj.id_instal,0,s->iamb[i],ient);
|
||
if(olv_limp->tipo_ambit==OLV_AMB_LIN)
|
||
{
|
||
//comprueba los dos nodos
|
||
|
||
dist1=olv_limp->arch_dj.dame_dis(olv_limp->arch_dj.id_instal,0,s->iamb[i],1);
|
||
|
||
|
||
if(dist1<dist)
|
||
{
|
||
dist=dist1;
|
||
ient=1;
|
||
}
|
||
}
|
||
|
||
//calcula la distancia de la instalaci<63>n al final del <20>mbito, y se queda con la menor
|
||
//en caso de los puntuales, va a ser igual
|
||
|
||
//busca el menor
|
||
if(dist<aux)
|
||
{
|
||
aux=dist;
|
||
iaux=i;
|
||
if(ent)
|
||
*ent=ient;
|
||
}
|
||
}
|
||
|
||
}
|
||
else if(modo==1)
|
||
{
|
||
aux=(float)MINUSCULO;
|
||
//se coge de punto inicial el de mayor coste
|
||
for(i=0;i<s->namb;i++)
|
||
{
|
||
if(olv_limp->ias[s->iamb[i]].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
//calcula la distancia de mayor entre dos <20>mbitos
|
||
for(j=0;j<s->namb;j++)
|
||
{
|
||
if(i==j)
|
||
continue;
|
||
|
||
if(olv_limp->ias[s->iamb[j]].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
|
||
dist=cost_amb[s->iamb[i]][s->iamb[j]];
|
||
//busca el mayor
|
||
if(dist>aux)
|
||
{
|
||
aux=dist;
|
||
iaux=i;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if(modo==2)
|
||
{
|
||
/////////////////////////////////////
|
||
//////////////////////
|
||
//Como primer <20>mbito coge el m<>s extremo
|
||
//el de menor 'y+x'
|
||
aux=(float)MAYUSCULO;
|
||
for(i=0;i<s->namb;i++)
|
||
{
|
||
if(olv_limp->ias[s->iamb[i]].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
if((olv_limp->conjs.coor[olv_limp->ias[s->iamb[i]].ic_ini][1]+olv_limp->conjs.coor[olv_limp->ias[s->iamb[i]].ic_ini][0])<aux)
|
||
{
|
||
aux=(float)(olv_limp->conjs.coor[olv_limp->ias[s->iamb[i]].ic_ini][1]+
|
||
olv_limp->conjs.coor[olv_limp->ias[s->iamb[i]].ic_ini][0]);
|
||
iaux=i;
|
||
}
|
||
}
|
||
}
|
||
else if(modo==3)
|
||
{
|
||
//////////////////////
|
||
a=0;
|
||
b=0;
|
||
c=0;
|
||
d=0;
|
||
e=-1;
|
||
nn=0;
|
||
//Como primer <20>mbito coge el m<>s alejado del centro
|
||
//coge la x y la y media, el centro
|
||
for(i=0;i<s->namb;i++)
|
||
{
|
||
if(olv_limp->ias[s->iamb[i]].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
a+=olv_limp->conjs.coor[olv_limp->ias[s->iamb[i]].ic_ini][1];
|
||
b+=olv_limp->conjs.coor[olv_limp->ias[s->iamb[i]].ic_ini][0];
|
||
nn++;
|
||
}
|
||
a=a/nn;
|
||
b=b/nn;
|
||
//busca el m<>s alejado de la x e y media
|
||
for(i=0;i<s->namb;i++)
|
||
{
|
||
if(olv_limp->ias[s->iamb[i]].flgs & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
c=olv_limp->conjs.coor[olv_limp->ias[s->iamb[i]].ic_ini][1]-a;
|
||
c=c*c;
|
||
d=olv_limp->conjs.coor[olv_limp->ias[s->iamb[i]].ic_ini][0]-b;
|
||
d=d*d;
|
||
if((c+d)>e)
|
||
{
|
||
e=(c+d);
|
||
iaux=i;
|
||
if(ent)
|
||
*ent=0;
|
||
}
|
||
}
|
||
}
|
||
return (short)iaux;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Permuta los elementos de sec en sec_out, desde el indice ini hasta fin aplicando la permutacion p-esima
|
||
*/
|
||
BOOL Colv_limp_thr::permuta(Secu_amb * sec, int ini, int fin, int p, Secu_amb * sec_out)
|
||
{
|
||
int n=fin-ini-1;//numero de elementos a permutar
|
||
int nn, i, j, k;
|
||
|
||
nn=Colv_geom::fact(n);
|
||
for (i=ini; i<fin; i++)
|
||
sec_out[i].flags=0;
|
||
for(i=ini; i<fin; i++)
|
||
{
|
||
k=p/nn;
|
||
p-=k*nn;
|
||
nn=nn/n;
|
||
n=max(n-1,1);
|
||
for (j=ini; j<fin; j++)
|
||
{
|
||
if (!sec_out[j].flags)
|
||
{
|
||
k--;
|
||
if(k<0)
|
||
break;
|
||
}
|
||
}
|
||
if (k>=0)
|
||
return FALSE;//Error al permutar
|
||
sec_out[j].flags=1;
|
||
sec_out[i].entrada=sec[j].entrada;
|
||
sec_out[i].iamb=sec[j].iamb;
|
||
}
|
||
return TRUE;
|
||
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Cambia de lugar el elemento de la pos_old a la pos_new en la secuencia de elementos sec
|
||
*/
|
||
void Colv_limp_thr::cambia_elem( Secu_amb * sec,int pos_old, int pos_new, int entr )
|
||
{
|
||
int i;
|
||
Secu_amb s;
|
||
s.entrada=entr;
|
||
s.iamb=sec[pos_old].iamb;
|
||
if(pos_old>pos_new)
|
||
{
|
||
for (i=pos_old; i>pos_new; i--)
|
||
{
|
||
sec[i].entrada=sec[i-1].entrada;
|
||
sec[i].iamb=sec[i-1].iamb;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (i=pos_old; i<pos_new; i++)
|
||
{
|
||
sec[i].entrada=sec[i+1].entrada;
|
||
sec[i].iamb=sec[i+1].iamb;
|
||
}
|
||
}
|
||
sec[pos_new].entrada=s.entrada;
|
||
sec[pos_new].iamb=s.iamb;
|
||
}
|
||
//*************************************************************************************
|
||
BOOL Colv_limp_thr::calcula_coste_1sec( Secu_amb * ord_sec, Info_sec *ss, Info_aso *ias, th_param_planif *thp, BOOL loguear )
|
||
{
|
||
int nsecuencia;
|
||
int obset=0;
|
||
int i, k;
|
||
double ca, cold;
|
||
BOOL permu=FALSE;
|
||
BOOL camb;
|
||
|
||
if(!thp)
|
||
goto npermu;
|
||
|
||
thp->ias=ias;
|
||
thp->sec=ord_sec;
|
||
thp->tl=this;
|
||
thp->abs=TRUE;
|
||
|
||
if(!thp->dth[0].sec)
|
||
thp->dth[0].sec=(Secu_amb *)malloc(thp->namb_t*thp->nth*sizeof(Secu_amb));
|
||
if(!thp->dth[0].sec)
|
||
goto npermu;
|
||
|
||
for (i=1; i<thp->nth; i++)
|
||
{
|
||
thp->dth[i].sec=&thp->dth[0].sec[thp->namb_t*i];
|
||
}
|
||
|
||
permu=TRUE;
|
||
npermu:
|
||
|
||
for (nsecuencia=0; nsecuencia<ss->namb; nsecuencia++)
|
||
ord_sec[nsecuencia].flags =0;
|
||
nsecuencia=0;
|
||
|
||
if(ss->namb<=0)
|
||
{
|
||
ss->cost_ac=0;
|
||
return TRUE;
|
||
}
|
||
//calcula ambito inicial------------
|
||
ord_sec[nsecuencia].iamb=dame_planif_iamb_ini(ss,olv_limp->cost_amb, &ord_sec[nsecuencia].entrada);
|
||
if(ord_sec[nsecuencia].iamb<0)
|
||
return FALSE;
|
||
ord_sec[ord_sec[nsecuencia].iamb].flags=1;
|
||
nsecuencia++;
|
||
while(nsecuencia<ss->namb)
|
||
{
|
||
if(!busca_cercano(ss,ias, ord_sec, nsecuencia-1,TRUE))//se pilla el minimo local
|
||
break;
|
||
nsecuencia++;
|
||
}
|
||
if (nsecuencia>=ss->namb)
|
||
{
|
||
ss->cost_ac=(float)dame_coste(ord_sec, 0, ss->namb-1, ias , ss, TRUE);
|
||
}
|
||
else
|
||
return FALSE;
|
||
|
||
//mira a ver si tiene que pertmutar o no. Si un sector tiene casi todos los <20>mbitos, no se permuta
|
||
int namb_m, nsec;
|
||
if(olv_limp->n_amb>=OLV_DESV_MAX_NAMB_MIN)
|
||
{
|
||
if(olv_limp->calc_nsec)
|
||
{
|
||
if(olv_limp->nsec_act>1)
|
||
namb_m = olv_limp->n_amb/(olv_limp->nsec_act-1);
|
||
else
|
||
namb_m= olv_limp->n_amb;
|
||
}
|
||
else
|
||
namb_m= olv_limp->n_amb/olv_limp->nsec;
|
||
namb_m+=(int)(namb_m*OLV_DESV_MAX_NAMB);
|
||
nsec=olv_limp->nsec;
|
||
if(olv_limp->calc_nsec>0)
|
||
nsec--;
|
||
for(int p=0;p<nsec;p++)
|
||
{
|
||
if(olv_limp->sec[p].namb>namb_m)
|
||
{
|
||
permu=FALSE;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(!permu)
|
||
return TRUE;
|
||
|
||
//mejora solucion---------------------
|
||
//prepara thread------------
|
||
thp->namb=ss->namb;
|
||
thp->s=ss;
|
||
ca=dame_coste(ord_sec, 0, ss->namb-1, ias , ss, TRUE);
|
||
if(loguear)
|
||
wgeolog(LOG_TODO,"olv_limp_t","coste de partida %lf",ca);
|
||
do
|
||
{
|
||
thp->modo=2;
|
||
cold=ca;
|
||
camb=FALSE;
|
||
|
||
//bucle hasta recorrer todos los elementos de sec
|
||
//movimientos de elementos puntuales (cambio de posicion)
|
||
for (i=1; i<ss->namb; i++)
|
||
{
|
||
thp->param[0]=i;
|
||
thp->a_currar();
|
||
//espera thread
|
||
while(!thp->terminado())
|
||
Sleep(thp->milis_sleep);
|
||
//elije la mejor permuta
|
||
k=thp->dame_min();
|
||
if(loguear && k>=0)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Candidato cal_costes cambia %ld, a %ld, costes: %lf ",
|
||
i, thp->dth[k].pos[0], thp->dth[k].coste);
|
||
if(k<0 || ca <=thp->dth[k].coste)
|
||
continue;
|
||
|
||
cambia_elem(ord_sec, i, thp->dth[k].pos[0], thp->dth[k].pos[1]);
|
||
ca=thp->dth[k].coste;
|
||
if(loguear)
|
||
wgeolog(LOG_TODO,"olv_limp_t","Mejora coste cambia %ld, a %ld, costes: %lf a %lf",
|
||
i, thp->dth[k].pos[0], cold, ca);
|
||
cold=ca;
|
||
camb=TRUE;
|
||
}
|
||
//permutaciones de npermu elementos
|
||
/*thp.modo=1;
|
||
cold=ca;
|
||
//camb=FALSE;
|
||
for (i=npermu+obset; i<s->namb; i++)
|
||
{
|
||
thp.param[0]=max(i-npermu, obset);
|
||
thp.param[1]=i;
|
||
thp.a_currar();
|
||
while(!thp.terminado())
|
||
Sleep(1);
|
||
j=thp.dame_min();
|
||
if(j<0 || ca <=thp.dth[j].coste || thp.dth[j].pos[0]<0)
|
||
continue;
|
||
ca =thp.dth[j].coste;
|
||
memcpy(sec, thp.dth[j].sec, s->namb*sizeof(Secu_amb));
|
||
wgeolog(LOG_TODO,"olv_limp_t","Permu Mejora coste de %lf a %lf actu: %lf",
|
||
cold, ca, dame_coste(sec,0,s->namb-1,ias, s));
|
||
cold=ca;
|
||
camb=TRUE;
|
||
}*/
|
||
} while (camb && !pirate);
|
||
|
||
pon_t_desp(ss, ias, ord_sec);
|
||
|
||
ss->cost_ac=(float)ca;
|
||
if(loguear)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Coste %lf",ss->cost_ac);
|
||
if(esta_repe(thp->sec, thp->namb, TRUE))
|
||
wgeolog(LOG_TODO,"olv_limp_t","Esta repe en calcula costes");
|
||
}
|
||
|
||
return TRUE;
|
||
|
||
//fuera thread
|
||
/*if(permu)
|
||
{
|
||
thp->pirate=TRUE;
|
||
while(thp->nth>0)
|
||
Sleep(1);
|
||
}*/
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Calcula el coste de los sectores mediante planificaci<63>n de sus <20>mbitos
|
||
*/
|
||
BOOL Colv_limp_thr::calcula_coste_sectores( Secu_amb * ord_sec,Info_sec *ss,int n_sec, Info_aso *ias, th_param_planif *thp, BOOL loguear )
|
||
{
|
||
int obset=0;
|
||
int i;
|
||
BOOL res=FALSE;
|
||
int j;
|
||
|
||
if(!thp)
|
||
goto npermu;
|
||
|
||
thp->ias=ias;
|
||
thp->sec=ord_sec;
|
||
thp->tl=this;
|
||
thp->abs=TRUE;
|
||
thp->milis_sleep=0;
|
||
|
||
if(!thp->dth[0].sec)
|
||
thp->dth[0].sec=(Secu_amb *)malloc(thp->namb_t*thp->nth*sizeof(Secu_amb));
|
||
if(!thp->dth[0].sec)
|
||
goto npermu;
|
||
|
||
for (i=1; i<thp->nth; i++)
|
||
{
|
||
thp->dth[i].sec=&thp->dth[0].sec[thp->namb_t*i];
|
||
}
|
||
|
||
npermu:
|
||
|
||
for (j=0; j<n_sec; j++)
|
||
{
|
||
if(loguear)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Calcula costes Sector %ld----------------------------------", j);
|
||
}
|
||
if(!calcula_coste_1sec( ord_sec, &ss[j], ias, thp, loguear ))
|
||
break;
|
||
if(loguear)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Ruta Sector %ld----------------------------------", j);
|
||
for (int i=0; i<ss[j].namb; i++)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","pos %ld, ida %ld, ent:%ld",i,ss[j].iamb[ord_sec[i].iamb], ord_sec[i].entrada);
|
||
}
|
||
wgeolog(LOG_TODO,"olv_limp_t","Fin Ruta Sector %ld----------------------------------", j);
|
||
}
|
||
}
|
||
if(j>=n_sec)
|
||
res=TRUE;
|
||
|
||
|
||
thp->milis_sleep=1;
|
||
|
||
return res;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Comprueba si hay elementos repetidos en las permutaciones
|
||
*/
|
||
BOOL Colv_limp_thr::esta_repe( Secu_amb *sec, int nsec, BOOL log )
|
||
{
|
||
BOOL res=FALSE;
|
||
int i;
|
||
for (i=0; i<nsec; i++)
|
||
sec[i].flags=-1;
|
||
for (i=0; i<nsec; i++)
|
||
{
|
||
if(log)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","secu: %ld, amb: %ld",i,sec[i].iamb);
|
||
|
||
}
|
||
if(sec[sec[i].iamb].flags>=0)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Esta repe la secuencia %ld, en posiciones %ld, %ld ",sec[i].iamb, i, sec[sec[i].iamb].flags);
|
||
res=TRUE;
|
||
}
|
||
sec[sec[i].iamb].flags=i;
|
||
}
|
||
return res;
|
||
}
|
||
//*************************************************************************************
|
||
/**
|
||
* Escribe la info resultado de la planificaci<63>n
|
||
*/
|
||
void Colv_limp_thr::pon_info_resul()
|
||
{
|
||
char msg_[OLV_MAX_MSG_PROCE];
|
||
char msg_aux[64];
|
||
int i,h,m,s;
|
||
double tt;
|
||
int nsec=0;
|
||
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb!=0)
|
||
nsec++;
|
||
}
|
||
|
||
if(olv_limp->olv->modo_ejec==OLV_EJEC_SECT)
|
||
{
|
||
//si se ha ejecutado en modo c<>lculo de sectorizaci<63>n
|
||
if(olv_limp->calc_nsec>0)
|
||
{
|
||
//se ha pedido proponer n<>mero de sectores <20>ptimo
|
||
sprintf_s(msg_,OLV_MAX_MSG_PROCE,
|
||
"Se ha calculado la sectorizaci<63>n para el n<>mero de sectores <20>ptimo\ndada la conf. elegida, que es de %ld, de tiempos:\n",
|
||
nsec);
|
||
}
|
||
else
|
||
{
|
||
//se ha impuesto el n<>mero de sectores
|
||
sprintf_s(msg_,OLV_MAX_MSG_PROCE,"Se ha calculado la sectorizaci<63>n para %ld sectores, de tiempos:\n",
|
||
nsec);
|
||
}
|
||
}
|
||
else if(olv_limp->olv->modo_ejec==OLV_EJEC_PLAN)
|
||
{
|
||
sprintf_s(msg_,OLV_MAX_MSG_PROCE,"Se ha calculado la planificaci<63>n para %ld sectores, de tiempos:\n",
|
||
nsec);
|
||
}
|
||
else if(olv_limp->olv->modo_ejec==OLV_EJEC_TODO)
|
||
{
|
||
sprintf_s(msg_,OLV_MAX_MSG_PROCE,"Resultados de todo el proceso para %ld sectores, de tiempos:\n",
|
||
nsec);
|
||
}
|
||
else
|
||
msg_[0]=0;
|
||
for(i=0;i<olv_limp->nsec;i++)
|
||
{
|
||
if(olv_limp->sec[i].namb==0)
|
||
continue;
|
||
tt=olv_limp->sec[i].cost_ac+olv_limp->t_desc;
|
||
dame_h_m_s(tt, &h, &m, &s);
|
||
sprintf_s(msg_aux,64,"Sector %ld: %02d:%02d:%02d h, %03d elementos\n",i+1,h,m,s,olv_limp->sec[i].namb);
|
||
strcat_s(msg_,OLV_MAX_MSG_PROCE,msg_aux);
|
||
}
|
||
pon_mi_msg(msg_);
|
||
pon_mi_progre(tarea,100);
|
||
}
|
||
//*************************************************************************************
|
||
/*
|
||
* Lanza los multi procesos para el c<>lculo de cost_amb
|
||
*/
|
||
BOOL Colv_limp_thr::lanza_tasks(int nthr_def/*=-1*/)
|
||
{
|
||
int nn;
|
||
char comline[256];
|
||
char app_path[MAX_PATH];
|
||
char app_path_aux[MAX_PATH];
|
||
BOOL ret=TRUE;
|
||
|
||
if(nthr_def>0)
|
||
nn=nthr_def;
|
||
else
|
||
nn=n_subthr;
|
||
|
||
comline[0]=0;
|
||
app_path[0]=0;
|
||
app_path_aux[0]=0;
|
||
|
||
olv_limp->olv_tasks->get_dll_dir(app_path_aux);
|
||
if(!app_path_aux[0])
|
||
return FALSE;
|
||
|
||
char *pch=strrchr(app_path_aux,'\\');
|
||
if(!pch)
|
||
return FALSE;
|
||
|
||
*pch=0;
|
||
|
||
sprintf(app_path,"%s\\%s\\%s",app_path_aux,TASKS_FOLDER_NAME,TASKS_APP_NAME);
|
||
|
||
//Arranca los tasks
|
||
for(int i=0;i<nn && ret;i++)
|
||
{
|
||
//lanza el ejecutable y le manda como comandos la tarea y el task que es
|
||
sprintf_s(comline, "%s %s %ld %ld",
|
||
"params",
|
||
olv_limp->olv->olv_sock->ip,
|
||
TASKS_PORT,
|
||
i);
|
||
|
||
if(!olv_limp->olv_tasks->lanza_app(app_path, comline))
|
||
ret=FALSE;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
//*************************************************************************************
|
||
/*
|
||
* Guarda a disco la matriz de dist entre conjunciones y de <20>ngulos
|
||
*/
|
||
BOOL Colv_limp_thr::guarda_mats()
|
||
{
|
||
pon_mi_progre(OLV_TAREA_GUARD_MAT, 0);
|
||
olv_limp->olv_tasks->inidirs(olv_limp->olv->paths.path_temp);
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Guardando matrices");
|
||
|
||
//lanza los threads
|
||
lanza_subthrs(OLV_LIMP_EV_GUARD_MATS_SUB);
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/*
|
||
* Cada thread de los que guardan a disco la matriz de dist entre conjunciones y de <20>ngulos
|
||
*/
|
||
void Colv_limp_thr::guarda_mats_sub(int ithr)
|
||
{
|
||
int nconj,ic;
|
||
int n_ini, n_desp, n_fin, seg;
|
||
BOOL mal=FALSE;
|
||
Param_olv_limp_thr pp;
|
||
HeadCostConj hd;
|
||
HeadCostAng hda;
|
||
|
||
////////////////
|
||
pp.id_e=OLV_TAREA_GUARD_MAT;//manda de par<61>metro la tarea de la que es el progreso
|
||
nconj=olv_limp->conjs.n;
|
||
//las conjunciones que va a hacer
|
||
n_desp = (int)ceil(1.0*nconj/n_subthr);
|
||
n_ini=ithr*n_desp;
|
||
n_fin = min((ithr+1)*n_desp,nconj);
|
||
|
||
memset(&hd,0,sizeof(HeadCostConj));
|
||
memset(&hda,0,sizeof(HeadCostAng));
|
||
////////////////
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Guardando filas de matrices %04d a %04d", ithr,n_ini, n_fin);
|
||
|
||
seg = GetTickCount();
|
||
/////////////////////////////////////
|
||
//bucle por cada conjunci<63>n de la carto
|
||
Cgarray<MapDataFloat> bufer;
|
||
for(ic=n_ini; ic<n_fin && !mal && !pirate; ic++)
|
||
{
|
||
if(!olv_limp->cost_conj[ic].guarda(hd,ic,olv_limp->olv_tasks->path_cconj,TASKS_EXT_MAT,&bufer))
|
||
{
|
||
mal=TRUE;
|
||
continue;
|
||
}
|
||
|
||
if(olv_limp->ang_conj)
|
||
{
|
||
if(!olv_limp->ang_conj[ic].guarda(hda,ic,olv_limp->olv_tasks->path_ang, TASKS_EXT_MAT))
|
||
{
|
||
mal=TRUE;
|
||
continue;
|
||
}
|
||
}
|
||
|
||
//avisa de progreso
|
||
if(((ic-n_ini)%500==0) || ((ic-n_ini)==(n_desp-1)))
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Guardando matrices, %ld de %ld", ithr,
|
||
(ic-n_ini+1),n_desp);
|
||
//avisa de progreso
|
||
prog_subthr=(1.0*(ic-n_ini+1)/n_desp);///
|
||
thr_padre->encola(OLV_LIMP_EV_SUBTHR_PROG,&pp,FALSE);
|
||
}
|
||
}
|
||
if(mal)
|
||
goto va_mal;
|
||
|
||
va_mal:
|
||
if(mal)
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Error en guardado de matrices", ithr);
|
||
prog_subthr=-1;//para avisar al padre de que ha habido un error
|
||
}
|
||
else
|
||
{
|
||
wgeolog(LOG_TODO,"olv_limp_t","Subthr %ld, Fin guardado matriz, %.3f seg", ithr, 1.0*(GetTickCount()-seg)/1000);
|
||
}
|
||
|
||
thr_padre->encola(OLV_LIMP_EV_GUARD_MATS_FIN,NULL,FALSE);
|
||
|
||
}
|
||
//*************************************************************************************
|
||
/*
|
||
* Cada thread de los que guardan a disco la matriz de dist entre conjunciones y de <20>ngulos
|
||
*/
|
||
BOOL Colv_limp_thr::guarda_mats_fin()
|
||
{
|
||
////////////////
|
||
//para los threads
|
||
para_subthrs();
|
||
|
||
//guarda matriz de info aso
|
||
guarda_iaso();
|
||
wgeolog(LOG_TODO,"olv_limp_t","Guardada matriz de info aso");
|
||
|
||
//libera esta memoria que ya no le hace falta
|
||
olv_limp->tip_conj.clear();
|
||
|
||
wgeolog(LOG_TODO,"olv_limp_t","FIN Guardado Matrices");
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
/*
|
||
* Guarda los ic de la info aso del <20>mbito ia
|
||
*/
|
||
BOOL Colv_limp_thr::guarda_iaso()
|
||
{
|
||
HANDLE hfile = INVALID_HANDLE_VALUE;
|
||
int nb, i;
|
||
HeadInfoAso hd;
|
||
|
||
//crea archivo-----------------------------------
|
||
hfile = CreateFile(olv_limp->olv_tasks->file_iaso, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||
if (hfile == INVALID_HANDLE_VALUE)
|
||
{
|
||
i=GetLastError();
|
||
return FALSE;
|
||
}
|
||
memset(&hd,0,sizeof(HeadInfoAso));
|
||
hd.nint=olv_limp->n_amb*3;
|
||
//graba cabecera------------
|
||
nb = sizeof(hd);
|
||
//calcula el nb
|
||
if (nb != _lwrite((int)hfile, (LPCCH)&hd, nb))
|
||
{
|
||
goto va_mal;
|
||
}
|
||
|
||
nb=sizeof(int);
|
||
//se embucla en los <20>mbitos guardando sus flags ic[0] e ic[1]
|
||
for(i=0;i<olv_limp->n_amb;i++)
|
||
{
|
||
if (nb != _lwrite((int)hfile, (LPCCH)&olv_limp->ias[i].ic[0], nb))
|
||
break;
|
||
if (nb != _lwrite((int)hfile, (LPCCH)&olv_limp->ias[i].ic[1], nb))
|
||
break;
|
||
if (nb != _lwrite((int)hfile, (LPCCH)&olv_limp->ias[i].flgs, nb))
|
||
break;
|
||
}
|
||
if(i<olv_limp->n_amb)
|
||
goto va_mal;
|
||
|
||
CloseHandle(hfile);
|
||
return TRUE;
|
||
|
||
va_mal:
|
||
CloseHandle(hfile);
|
||
return FALSE;
|
||
}
|
||
//*************************************************************************************
|
||
void Colv_limp_thr::ini_infotask(int ntasks)
|
||
{
|
||
InfoIniTask ii;
|
||
memset(&ii,0,sizeof(InfoIniTask));
|
||
ii.KK = olv_limp->tipo_ambit;
|
||
ii.n = olv_limp->conjs.n;
|
||
ii.namb = olv_limp->n_amb;
|
||
ii.nthr=n_subthr;
|
||
ii.usa_angs = (olv_limp->ang_conj!=NULL);
|
||
ii.id_instal = olv_limp->nod_instal;
|
||
ii.id_planta = olv_limp->nod_plant;
|
||
strcpy_s(ii.path_temp,MAX_PATH,olv_limp->olv_tasks->path_temp);
|
||
strcpy_s(ii.path_cconj,MAX_PATH,olv_limp->olv_tasks->path_cconj);
|
||
strcpy_s(ii.path_costamb,MAX_PATH,olv_limp->olv_tasks->path_costamb);
|
||
strcpy_s(ii.path_ang,MAX_PATH,olv_limp->olv_tasks->path_ang);
|
||
strcpy_s(ii.file_iaso,MAX_PATH,olv_limp->olv_tasks->file_iaso);
|
||
strcpy_s(ii.ext,8,TASKS_EXT_MAT);
|
||
memcpy(&olv_limp->olv->infotask,&ii,sizeof(InfoIniTask));
|
||
}
|
||
//*************************************************************************************
|
||
BOOL Colv_limp_thr::task_dj_escucha()
|
||
{
|
||
////////////////////////////////////////////////
|
||
//lanza las tasks
|
||
//ejecuta n veces OliviaTasks, cada una va a calcular una parte de la matriz de costes entre ambitos
|
||
//con sus correspondientes dijkstras y lo va a escribir en disco
|
||
//antes de eso, se han guardado en disco la matriz (o maps) de costes entre conjunciones y de <20>ngulos entre conjunciones
|
||
////////////////////////////////////////////////
|
||
|
||
int ntasks=1;
|
||
pon_mi_progre(OLV_TAREA_MULTITASK, 0);
|
||
wgeolog(LOG_TODO,"olv_limp_t","Comienza ejecuci<63>n Multitask");
|
||
ini_infotask(ntasks);
|
||
|
||
//lanza la escucha
|
||
olv_limp->soc = new Csock_svThread();
|
||
olv_limp->soc->escucha=olv_limp->olv_tasks;
|
||
|
||
if(!olv_limp->soc->liseningThread(TASKS_PORT,olv_limp->olv->olv_sock->ip))
|
||
{
|
||
goto mal;
|
||
}
|
||
|
||
//////////////////////////////////////
|
||
if(!lanza_tasks(ntasks))
|
||
{
|
||
pon_mi_msg("Error al lanzar multitask para el c<>lculo de costes entre <20>mbitos");
|
||
return FALSE;
|
||
}
|
||
for(int i=ntasks;i<n_subthr;i++)
|
||
subthrs[i]->prog_subthr = 0;
|
||
|
||
for(int i=0;i<n_subthr-ntasks;i++)
|
||
encola(OLV_LIMP_EV_TASK_FIN,NULL,FALSE); //fuerza fin para que avance olivia
|
||
|
||
|
||
|
||
return TRUE;
|
||
|
||
mal:
|
||
olv_limp->soc->close();
|
||
delete olv_limp->soc;
|
||
olv_limp->soc=NULL;
|
||
return FALSE;
|
||
}
|
||
//*************************************************************************************
|
||
BOOL Colv_limp_thr::task_dj_fin()
|
||
{
|
||
//debe iniciar la matriz cost_amb y leerla lo que han rellenado los tasks, y combinarla
|
||
|
||
return TRUE;
|
||
}
|
||
//*************************************************************************************
|
||
void Colv_limp_thr::borra_temp_files(BOOL todo/*=TRUE*/)
|
||
{
|
||
Cdir_manager dm;
|
||
if(todo)
|
||
{
|
||
//borra los archivos de dijkstra
|
||
dm.borra_archivos(olv_limp->olv->paths.path_temp,EXT_ARCH_DIJ_DEFAULT);
|
||
}
|
||
//borra los archivos asociados al multitask
|
||
dm.borra_archivos(olv_limp->olv->paths.path_temp,TASKS_EXT_MAT,TRUE);
|
||
dm.borra_archivos(olv_limp->olv->paths.path_temp,TASKS_EXT_DIS,TRUE);
|
||
}
|
||
//*************************************************************************************
|
||
//*************************************************************************************
|
||
//*************************************************************************************
|
||
//*************************************************************************************
|
||
/**
|
||
* Thread para c<>lculo multiproceso de la planificaci<63>n
|
||
*/
|
||
UINT th_planificacion(LPVOID pp)
|
||
{
|
||
th_param_planif *p=(th_param_planif*)pp;
|
||
int id_th=p->id_th;
|
||
int id_curro=p->id_curro;
|
||
int ini, fin, i, j, entr, entr_m;
|
||
int mm[2];
|
||
double d, dm;
|
||
p->id_th=-1;
|
||
while(!p->pirate)
|
||
{
|
||
if(id_curro==p->id_curro)
|
||
{
|
||
//no curro
|
||
Sleep(p->milis_sleep);
|
||
continue;
|
||
}
|
||
id_curro=p->id_curro;
|
||
//ha currar
|
||
switch(p->modo)
|
||
{
|
||
case (0)://cambio de un elemento en la ruta
|
||
i=p->namb/p->nth;
|
||
ini=max(i*id_th, 1);
|
||
if(id_th+1==p->nth)
|
||
fin=p->namb;
|
||
else
|
||
fin=ini+i;
|
||
i=-1;
|
||
dm=MAYUSCULO;
|
||
entr=0;
|
||
while(ini<fin)
|
||
{
|
||
if(ini==p->param[0])
|
||
{
|
||
|
||
d=p->tl->dame_coste(p->sec, 0,p->namb-1, p->ias, p->s, p->abs);
|
||
|
||
}
|
||
else
|
||
d=p->tl->dame_coste_ex(p->sec,0,p->namb-1,p->ias, p->s,p->param[0],ini, entr);
|
||
if(d<dm)
|
||
{
|
||
dm=d;
|
||
i=ini;
|
||
entr_m=entr;
|
||
}
|
||
if (entr>=1 || (ini==p->param[0]))
|
||
{
|
||
ini++;
|
||
entr=0;
|
||
}
|
||
else
|
||
entr=1;
|
||
|
||
}
|
||
p->dth[id_th].coste=dm;
|
||
p->dth[id_th].pos[0]=i;
|
||
p->dth[id_th].pos[1]=entr_m;
|
||
|
||
break;
|
||
case (1)://permutaciones de elementos
|
||
i=Colv_geom::fact(p->param[1]-p->param[0]);
|
||
j=i/p->nth;
|
||
ini=max(i*id_th, 1);
|
||
if(id_th+1==p->nth)
|
||
fin=i;
|
||
else
|
||
fin=ini+j;
|
||
i=-1;
|
||
dm=MAYUSCULO;
|
||
while(ini<fin)
|
||
{
|
||
if(!p->tl->permuta(p->sec, p->param[0], p->param[1], ini, p->dth[id_th].sec))
|
||
{
|
||
ini++;
|
||
continue;
|
||
}
|
||
d=p->tl->dame_coste(p->dth[id_th].sec, 0,p->namb-1, p->ias, p->s, p->abs);
|
||
if(d<dm)
|
||
{
|
||
dm=d;
|
||
i=ini;
|
||
}
|
||
ini++;
|
||
}
|
||
if(i<0 || !p->tl->permuta(p->sec, p->param[0], p->param[1], i, p->dth[id_th].sec))
|
||
{
|
||
p->dth[id_th].coste=MAYUSCULO;
|
||
}
|
||
else
|
||
p->dth[id_th].coste=dm;
|
||
p->dth[id_th].pos[0]=i;
|
||
break;
|
||
case (2)://cambio de un elemento en la ruta (cambiandolo de verdad)
|
||
//pilla un entorno de como mucho +-100 ambitos para las permu
|
||
//-----------------------------------------------
|
||
/*i=p->namb/p->nth;
|
||
ini=max(i*id_th, 1);
|
||
if(id_th+1==p->nth)
|
||
fin=p->namb;
|
||
else
|
||
fin=ini+i;*/
|
||
mm[0]=max(p->param[0]-50,0);
|
||
mm[1]=min(mm[0]+101,p->namb);
|
||
i=(mm[1]-mm[0])/p->nth;
|
||
ini=mm[0]+max(i*id_th, 1);
|
||
if(id_th+1==p->nth)
|
||
fin=mm[1];
|
||
else
|
||
fin=ini+i;
|
||
//-----------------------------------------------
|
||
|
||
i=-1;
|
||
dm=MAYUSCULO;
|
||
entr=entr_m=0;
|
||
while(ini<fin)
|
||
{
|
||
if(ini==p->param[0])
|
||
{
|
||
d=p->tl->dame_coste(p->sec, 0,p->namb-1, p->ias, p->s, p->abs);
|
||
|
||
}
|
||
else
|
||
{
|
||
memcpy(p->dth[id_th].sec,p->sec, p->namb_t*sizeof(Secu_amb));
|
||
p->tl->cambia_elem(p->dth[id_th].sec, p->param[0],ini, entr);
|
||
d=p->tl->dame_coste(p->dth[id_th].sec, 0,p->namb-1, p->ias, p->s, p->abs);
|
||
}
|
||
if(d<dm)
|
||
{
|
||
dm=d;
|
||
i=ini;
|
||
entr_m=entr;
|
||
}
|
||
if (entr>=1 || (ini==p->param[0]))
|
||
{
|
||
ini++;
|
||
entr=0;
|
||
}
|
||
else
|
||
entr=1;
|
||
|
||
}
|
||
p->dth[id_th].coste=dm;
|
||
p->dth[id_th].pos[0]=i;
|
||
p->dth[id_th].pos[1]=entr_m;
|
||
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
p->dth[id_th].currando=FALSE;
|
||
}
|
||
//salida de thread-------------------------
|
||
p->dth[id_th].activo=FALSE;
|
||
igt_sum_atm(&p->nth,-1);
|
||
|
||
return 0;
|
||
}
|
||
//*************************************************************************************
|
||
//*************************************************************************************
|
||
//*************************************************************************************
|
||
//*************************************************************************************
|
||
//*************************************************************************************
|
||
#endif |