198 lines
4.2 KiB
C++
198 lines
4.2 KiB
C++
#include "stdafx.h"
|
||
#include "CartoBaseTopologyManager.h"
|
||
#include <GeometryFunction.h>
|
||
|
||
CartoBaseTopologyManager::CartoBaseTopologyManager(void)
|
||
{
|
||
tolerancia = 0.01;
|
||
ncorrecciones = 0;
|
||
terminado = true;
|
||
nthread = 0;
|
||
}
|
||
|
||
CartoBaseTopologyManager::~CartoBaseTopologyManager(void)
|
||
{
|
||
}
|
||
|
||
bool CartoBaseTopologyManager::DivideLineVirtual(int ie, int ipun)
|
||
{
|
||
CartoBaseEntity* entity = cad->_entities.get(ie);
|
||
if (entity->type != CartoBaseTypes::Line)
|
||
return false;
|
||
CartoBaseLine* lin = cad->_lines.get(entity->id);
|
||
CartoBaseLine nlin;
|
||
CartoBaseEntity nent;
|
||
|
||
nent = *entity;
|
||
nlin.ini = lin->ini + ipun;
|
||
nlin.n = lin->n - ipun;
|
||
lin->n = ipun + 1;
|
||
nent.id = cad->add(&nlin);
|
||
|
||
if (nent.id < 0)
|
||
return false;
|
||
int nn = cad->add(&nent);
|
||
if (nn >= 0)
|
||
{
|
||
referencias[cad->_entities.get(nn)->ref] = entity->ref;
|
||
//cad->_entities.get(nn)->ref = entity->ref;//pisa la referencia (ojo peligorso)
|
||
}
|
||
return (nn >= 0);
|
||
}
|
||
bool CartoBaseTopologyManager::DivideLine(int ie, int ipun)
|
||
{
|
||
CartoBaseEntity* rawEntity = cad->_entities.get(ie);
|
||
CartoBaseInfoEntity entity = cad->getEntity(ie);
|
||
if (!entity.line() )
|
||
return false;
|
||
CartoBaseLine* lin = cad->_lines.get(rawEntity->id);
|
||
linebuff.set(&entity);
|
||
linebuff.ia = rawEntity->ia;
|
||
linebuff.pts.remove(0, ipun);
|
||
|
||
lin->n = ipun + 1;
|
||
return cad->add(linebuff);
|
||
}
|
||
|
||
bool CartoBaseTopologyManager::RevisaTopo(int ini, int fin)
|
||
{
|
||
bool res = true;
|
||
CartoBaseInfoEntity ent;
|
||
for (int i = ini; i < fin; i++)
|
||
{
|
||
ent=cad->getEntity(i);
|
||
if (!ent.line())
|
||
continue;
|
||
res=revisa(&ent);
|
||
|
||
}
|
||
if (!res)
|
||
{
|
||
lcorreccines.entro();
|
||
conErrores = false;
|
||
lcorreccines.salgo();
|
||
|
||
}
|
||
return res;
|
||
}
|
||
|
||
bool CartoBaseTopologyManager::revisa(CartoBaseInfoEntity* ent)
|
||
{
|
||
CartoBaseInfoEntity enta=cad->get(0);
|
||
double* pto1 = ent->getPto(0);
|
||
double* pto2 = ent->getPto(ent->getNumberPtos()-1);
|
||
double* aux;
|
||
while (enta.isValid())
|
||
{
|
||
if (enta.line())
|
||
{
|
||
int n = enta.getNumberPtos()-1;
|
||
|
||
for (int ii = 1; ii < n; ii++)
|
||
{
|
||
aux= enta.getPto(ii);
|
||
if (GeometryFunction::Dist2d(aux, pto1) < tolerancia || GeometryFunction::Dist2d(aux, pto2) < tolerancia)
|
||
{
|
||
if (!AddCorreccion(enta.i_entity, ii))
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
enta = enta.next();
|
||
}
|
||
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
bool CartoBaseTopologyManager::AddCorreccion(int ie, int pto)
|
||
{
|
||
lcorreccines.entro();
|
||
ncorrecciones++;
|
||
Cgarray_ord<int, int>* pts;
|
||
if (correcciones.find(ie) == correcciones.end())
|
||
{
|
||
pts = new Cgarray_ord<int, int>();
|
||
pts->f_ord = &comint;
|
||
pts->fcomp = &comint;
|
||
}
|
||
else
|
||
{
|
||
pts = correcciones[ie];
|
||
}
|
||
bool res = (*pts) + pto;
|
||
correcciones[ie] = pts;
|
||
if (!res)
|
||
strcpy(error, "Error al a<>adir correcci<63>n de topologia.");
|
||
|
||
lcorreccines.salgo();
|
||
return res;
|
||
}
|
||
void CartoBaseTopologyManager::AplicaCorrecciones()
|
||
{
|
||
if (ncorrecciones <= 0 || conErrores)
|
||
return;
|
||
std::map<int, Cgarray_ord<int, int>*>::iterator elem;
|
||
int ult = -1;
|
||
cad->_entities += ncorrecciones;//pide memoria extra que va a necesitar en total
|
||
bool res = true;
|
||
for (elem = correcciones.begin(); elem != correcciones.end(); ++elem) {
|
||
ult = -1;
|
||
for (int ii=0; ii<elem->second->ind.n; ii++)
|
||
{
|
||
CartoBaseEntity *e=cad->_entities.get(elem->first);
|
||
int pt = *elem->second->get(elem->second->ind.n-1-ii);//divide de mayor a menor
|
||
if (pt != ult)
|
||
{
|
||
res = res && DivideLineVirtual(elem->first, pt);
|
||
ult = pt;
|
||
}
|
||
|
||
}
|
||
Cgarray_ord<int, int>* pts = correcciones[elem->first];
|
||
correcciones[elem->first] = NULL;
|
||
delete pts;
|
||
}
|
||
if (!res)
|
||
{
|
||
conErrores = true;
|
||
strcpy(error, "Error alaplicar correcciones de topologia.");
|
||
}
|
||
}
|
||
bool CartoBaseTopologyManager::revisaTopologia(CartoBase* carto, int numthread)
|
||
{
|
||
error[0] = 0;
|
||
nthread = numthread;
|
||
cad = carto;
|
||
terminado = false;
|
||
conErrores = false;
|
||
referencias.clear();
|
||
int ne = cad->getNumberEntities();
|
||
int nt = (int)(ne * 1. / numthread);
|
||
if (!(ne % numthread))
|
||
nt = nt + 1;
|
||
|
||
CthRevisaTopologia* th = new CthRevisaTopologia[numthread];
|
||
int ini = 0;
|
||
correcciones.clear();
|
||
ncorrecciones = 0;
|
||
|
||
for (int i = 0; i < numthread; i++)
|
||
{
|
||
th[i].ini = i * nt;
|
||
th[i].fin = min(th[i].ini + nt, ne);
|
||
th[i].topo = this;
|
||
th[i].lanza();
|
||
}
|
||
while (nthread > 0)
|
||
Sleep(100);
|
||
while (!terminado)
|
||
{
|
||
Sleep(100);
|
||
}
|
||
//delete th;
|
||
|
||
return !conErrores;
|
||
|
||
} |