#include "stdafx.h" #include "CartoBaseTopologyManager.h" #include 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* pts; if (correcciones.find(ie) == correcciones.end()) { pts = new Cgarray_ord(); 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ón de topologia."); lcorreccines.salgo(); return res; } void CartoBaseTopologyManager::AplicaCorrecciones() { if (ncorrecciones <= 0 || conErrores) return; std::map*>::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; iisecond->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* 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; }