From 704edec15201390fecc74fa5ff6f620916a45e65 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Sun, 12 Nov 2023 22:28:13 +0100 Subject: [PATCH] Creaccion de manager topologia --- CartoBase.cpp | 20 +++- CartoBase.h | 3 + CartoBaseTopologyManager.cpp | 198 +++++++++++++++++++++++++++++++++++ CartoBaseTopologyManager.h | 65 ++++++++++++ mapmatrix.h | 2 +- utiles.vcxproj | 2 + utiles.vcxproj.filters | 6 ++ 7 files changed, 294 insertions(+), 2 deletions(-) create mode 100644 CartoBaseTopologyManager.cpp create mode 100644 CartoBaseTopologyManager.h diff --git a/CartoBase.cpp b/CartoBase.cpp index 7039531..c3be508 100644 --- a/CartoBase.cpp +++ b/CartoBase.cpp @@ -682,7 +682,25 @@ void CartoBase::setNameIa( char *name ) strcpy(iaName, name); } //***************************************************************************************** +/*bool CartoBase::DivideLineVirtual(CartoBaseEntity* entity, int ipun) +{ + if (entity->type != CartoBaseTypes::Line) + return false; + CartoBaseLine *lin = _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 = add(&nlin); + + if (nent.id < 0) + return false; + return (add(&nent) >= 0); +}*/ +//***************************************************************************************** CartoBaseInfoEntity FiterCartoBase::getEntity( int i ) { return cb->get(ind[i]); @@ -692,4 +710,4 @@ int FiterCartoBase::getNumberEntities() { return ind.n; } -//***************************************************************************************** \ No newline at end of file +//***************************************************************************************** diff --git a/CartoBase.h b/CartoBase.h index f5311a7..043032b 100644 --- a/CartoBase.h +++ b/CartoBase.h @@ -22,6 +22,7 @@ class UTILES_EXPORT CartoBase: public SetEntities, public SetPtsR, public DataIa friend class CartoBaseInfoBuilder; friend class CartoPto; friend class CartoLine; + friend class CartoBaseTopologyManager; private: //info interna------------------------------- int ref;//referencia para el siguiente elemento @@ -106,6 +107,8 @@ public: virtual bool IaGetVal( int refEnt, int icol, int* v ); virtual bool IaFinW(){return true;} + + private: int add(CartoBaseEntity* src); diff --git a/CartoBaseTopologyManager.cpp b/CartoBaseTopologyManager.cpp new file mode 100644 index 0000000..ef9040c --- /dev/null +++ b/CartoBaseTopologyManager.cpp @@ -0,0 +1,198 @@ +#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; + +} \ No newline at end of file diff --git a/CartoBaseTopologyManager.h b/CartoBaseTopologyManager.h new file mode 100644 index 0000000..81ce4fe --- /dev/null +++ b/CartoBaseTopologyManager.h @@ -0,0 +1,65 @@ +#pragma once + +#ifndef CartoBaseTopologyManager_H +#define CartoBaseTopologyManager_H +#include "base_head.h" +#include "garray_ord.h" +#include "CartoBase.h" +#include "th.h" +class UTILES_EXPORT CartoBaseTopologyManager +{ + CartoBase* cad; + CartoLine linebuff; + std::map*> correcciones; + + long ncorrecciones; + Clock lcorreccines; +public: + std::map referencias; + long nthread; + double tolerancia; + bool terminado; + bool conErrores; + char error[128]; + static int comint(int* i1, int* i2) + { + return *i1 - *i2; + } + + CartoBaseTopologyManager(void); + ~CartoBaseTopologyManager(void); + + //funciones topologicas-------------------- + bool revisaTopologia(CartoBase* carto, int nthread); + + + //funciones topologicas aux-------------------------------------------- + bool DivideLineVirtual(int ie, int ipun); + bool DivideLine(int ie, int ipun); + bool RevisaTopo(int ini, int fin); + bool revisa(CartoBaseInfoEntity* ent); + + bool AddCorreccion(int ie, int pto); + + void AplicaCorrecciones(); +}; + +class UTILES_EXPORT CthRevisaTopologia : public Cth +{ +public: + CartoBaseTopologyManager* topo; + int ini, fin; + bool resul; + virtual void run() + { + resul=topo->RevisaTopo(ini, fin); + if (!lck_sum_atm(&topo->nthread, -1)) + { + //finalizada revision, toca aplicar correccion + topo->AplicaCorrecciones(); + topo->terminado = true; + } + + } +}; +#endif diff --git a/mapmatrix.h b/mapmatrix.h index 8daf54a..78fdb5e 100644 --- a/mapmatrix.h +++ b/mapmatrix.h @@ -32,7 +32,7 @@ typedef struct MapDataInt{ int v; }MapDataInt; #pragma pack(16) -#define MAX_THREAD_LEE 8 +#define MAX_THREAD_LEE 24 //matixFloat--------------------------------------------- class UTILES_EXPORT CmapRowFloat { diff --git a/utiles.vcxproj b/utiles.vcxproj index 9cbeee2..0d71371 100644 --- a/utiles.vcxproj +++ b/utiles.vcxproj @@ -248,6 +248,7 @@ copy $(OutDir)utiles.lib ..\lib\$(IntDir) + @@ -307,6 +308,7 @@ copy $(OutDir)utiles.lib ..\lib\$(IntDir) + diff --git a/utiles.vcxproj.filters b/utiles.vcxproj.filters index 30d8c94..ec07fac 100644 --- a/utiles.vcxproj.filters +++ b/utiles.vcxproj.filters @@ -210,6 +210,9 @@ Source Files\carto + + Source Files\carto + @@ -395,6 +398,9 @@ Header Files\carto + + Header Files\carto +