#include "StdAfx.h" #include "CartoBase.h" #include "CartoBaseShpManager.h" #include "CartoBaseDBFManager.h" #include "dir_manager.h" #include "Fdbf.h" //***************************************************************************************** CartoBase::CartoBase(void) { ref = 0; typeIA = IntIa; strcpy(iaName, "Ia"); iaEx =this; } //***************************************************************************************** CartoBase::~CartoBase(void) { } //***************************************************************************************** int CartoBase::getNumberEntities() { return _entities.n; } //***************************************************************************************** double* CartoBase::getPto(int i) { return _points[i].pts; } //***************************************************************************************** int CartoBase::getNumberPtos() { return _points.n; } //***************************************************************************************** CartoBaseInfoEntity CartoBase::getEntity(int i) { return get(i); } //***************************************************************************************** CartoBaseInfoEntity CartoBase::get(int i) { return CartoBaseInfoBuilder::get(i, this); } //***************************************************************************************** CartoBaseInfoEntity CartoBase::getRef(int r) { return CartoBaseInfoBuilder::get(refIndex[r], this); } //***************************************************************************************** int CartoBase::getEntityRef( int ientity ) { return _entities[ientity].ref; } //***************************************************************************************** bool CartoBase::add(CartoEntity& element) { bool res = 0<=element.CopyInTo(this); if(res && iaEx && typeIA != NIa) iaEx->IaAdd(_entities[_entities.n-1].ref); return res; } //***************************************************************************************** bool CartoBase::add(CartoBase& cad) { return false; } //***************************************************************************************** bool CartoBase::grabar(char *path) { Cb_file f; if(!f.abre(path,2,1)) return false; return grabar(&f); } //***************************************************************************************** bool CartoBase::leer(char *path) { Cb_file f; if(!f.abre(path,1,0,true)) return false; return leer(&f); } //***************************************************************************************** bool CartoBase::grabar(Cb_file *f) { char st[16]; int version; memset(st,0,16); strcpy(st,TYPE_FILE); if(!f->escribe(st, 16)) return false; version = VERSION_CART_BASE; if(!f->escribe(&version, sizeof(version))) return false; if(!f->escribe(&_defaultColor, sizeof(_defaultColor))) return false; if(!f->escribe(&_defaultpaintedProps, sizeof(_defaultpaintedProps))) return false; if(!_entities.graba(f)) return false; if(!_points.graba(f)) return false; if(!_lines.graba(f)) return false; if(!_paintedProps.graba(f)) return false; if(!_colors.graba(f)) return false; return true; } //***************************************************************************************** bool CartoBase::leer (Cb_file* f) { char st[16]; int version; memset(st,0,16); if(!f->lee(st, 16) || strcmp(st, TYPE_FILE)) return false; if(!f->lee(&version, sizeof(version)) || version!= VERSION_CART_BASE) return false; if(!f->lee(&_defaultColor, sizeof(_defaultColor))) return false; if(!f->lee(&_defaultpaintedProps, sizeof(_defaultpaintedProps))) return false; _entities.n = 0; if(!_entities.leer(f)) return false; _points.n = 0; if(!_points.leer(f)) return false; _lines.n = 0; if(!_lines.leer(f)) return false; _paintedProps.n = 0; if(!_paintedProps.leer(f)) return false; _colors.n = 0; if(!_colors.leer(f)) return false; iniIndexRef(); return true; } //***************************************************************************************** int CartoBase::add(CartoBaseEntity* src) { if(_entities+(*src)) { _entities[_entities.n-1].ref = ref; refIndex[ref++] = _entities.n-1; return _entities.n-1; } return -1; } //***************************************************************************************** int CartoBase::add(CartoBasePoint* src) { if(_points+(*src)) return _points.n-1; return -1; } //***************************************************************************************** int CartoBase::add(CartoBaseLine* src) { if(_lines+(*src)) return _lines.n-1; return -1; } //***************************************************************************************** int CartoBase::add(CartoBasePaintedProps* src) { if(_paintedProps+(*src)) return _paintedProps.n-1; return -1; } //***************************************************************************************** int CartoBase::add(CartoBaseColor* src) { if(_colors+(*src)) return _colors.n-1; return -1; } //***************************************************************************************** int CartoBase::addDefaultPaintedProps() { _defaultpaintedProps.color = _colors.n; _colors+_defaultColor; _paintedProps+_defaultpaintedProps; _defaultpaintedProps.color = -1; return _paintedProps.n-1; } //***************************************************************************************** void CartoBase::del() { _entities.n=0; _points.n=0; _lines.n=0; _paintedProps.n=0; _colors.n=0; } //***************************************************************************************** EntitiesArray* CartoBase::filter(EntitiesArray* dst, FilterEntities* filter) { CartoBaseInfoEntity e = get(0); while(e.isValid()) { if(filter->IsSeletedEntity(&e)) { if(!((*dst)+e)) return 0; } e = e.next(); } return dst; } //***************************************************************************************** bool CartoBase::remove(int i) { if(i<_entities.n) { _entities[i].flagsInt |= CARTOBASE_DELETED_ENTITY; if(iaEx) iaEx->IaRemove(_entities[i].ref); return true; } return false; } //***************************************************************************************** bool CartoBase::removeRef(int r) { return remove(refIndex[r]); } //***************************************************************************************** bool CartoBase::clear() { return false;//no funciona //verifica entidades int ind =0; std::map indsl; int il,ip,ic, id; std::map indsp; std::map indsc; std::map indsd;//indices de pintado il = ip=ic=id = 0; //borra entidades marcadas for(int i =0; i<_entities.n; i++) { if(_entities[i].flagsInt & CARTOBASE_DELETED_ENTITY) continue; if(i == ind) { ind++; continue; } _entities[ind++]=_entities[i]; } //si borrados if(ind == _entities.n) goto ajus_mem; //verifica _entities.n = ind; for(int i =0; i<_entities.n; i++) { int aux = _entities[i].idPaintp; //revisa propiedades de pintado if(indsd.find(aux) == indsd.end()) { indsd[aux] = id++; //revisa color if(indsc.find(_paintedProps[i].color) == indsc.end()) indsc[_paintedProps[i].color] =ic++; _paintedProps[i].color = indsc[_paintedProps[i].color]; } _entities[i].idPaintp = indsd[aux]; //segun tipo de entidad aux =_entities[i].id; switch(_entities[i].type) { case(CartoBaseTypes::Point): { if(indsp.find(aux) == indsp.end()) indsp[aux] = ip++; _entities[i].id = indsp[aux]; break; } case(CartoBaseTypes::Line): { if(indsl.find(aux) == indsl.end()) { indsl[aux] = il++; } int nn = _lines[aux].n; aux= _lines[aux].ini; for(int ii =0; ii::iterator iid = indsp.begin(); iid != indsp.end(); ++iid) { if(iid->second ==iid->first) continue; _points[iid->second] = _points[iid->first]; } _points.n=(int)indsp.size(); for (std::map::iterator iid = indsl.begin(); iid != indsl.end(); ++iid) { if(iid->second ==iid->first) continue; _lines[iid->second] = _lines[iid->first]; } _lines.n=(int)indsl.size(); for (std::map::iterator iid = indsd.begin(); iid != indsd.end(); ++iid) { if(iid->second ==iid->first) continue; _paintedProps[iid->second] = _paintedProps[iid->first]; } _paintedProps.n=(int)indsd.size(); for (std::map::iterator iid = indsc.begin(); iid != indsc.end(); ++iid) { if(iid->second ==iid->first) continue; _colors[iid->second] = _colors[iid->first]; } _colors.n=(int)indsc.size(); ajus_mem: //ajusta memoria if(!_entities.ajusta_mem()) return false; if(!_points.ajusta_mem()) return false; if(!_lines.ajusta_mem()) return false; if(!_paintedProps.ajusta_mem()) return false; if(!_colors.ajusta_mem()) return false; indexRef(); return true; } //***************************************************************************************** bool CartoBase::FastClear() { //verifica entidades int ind =0; //borra entidades marcadas for(int i =0; i<_entities.n; i++) { if(_entities[i].flagsInt & CARTOBASE_DELETED_ENTITY) continue; if(i == ind) { ind++; continue; } _entities[ind++]=_entities[i]; } _entities.n =ind; reIndexRef(); return true; } //***************************************************************************************** bool CartoBase::MemClear() { if(!FastClear()) return false; int npts =0; int nlin=0; //cuenta tipos de entidades----------- for(int i =0; i< _entities.n; i++) { switch(_entities[i].type) { case(CartoBaseTypes::Point): npts++; break; case(CartoBaseTypes::Line): nlin++; npts+=_lines[_entities[i].id].n; break;; default: break; } } for(int i =0; i<_paintedProps.n; i++) _paintedProps[i].flags &= ~0x1; for(int i =0; i<_colors.n; i++) _colors[i].flags &= ~0x1; Cgarray points;//coordenadas Cgarray lines;//lineas Cgarray paintedProps;//propiedades de pintado Cgarray colors; //pide memoria para arrays auxiliares if(!(points+=npts)) return false; if(!(lines+=nlin)) return false; for(int i =0; i<_entities.n; i++) { CartoBaseInfoEntity e =get(i); switch(e.entity()->type) { case(CartoBaseTypes::Point): points+ *e.pto(); e.entity()->id = points.n-1; break; case(CartoBaseTypes::Line): lines+*e.line(); lines[lines.n-1].ini = points.n; for(int jj =0; jjn; jj++) points+ e.pto()[jj]; e.entity()->id = lines.n-1; break; default: break; } //revisa propiedades de pintado if(e.paintp()->flags & 0x1) { e.entity()->idPaintp = e.paintp()->color; continue; } paintedProps+*e.paintp(); //revisa color if(e.color()->flags & 0x1) { paintedProps[paintedProps.n-1].color = e.color()->color; } else { paintedProps[paintedProps.n-1].color = colors.n; colors+*e.color(); e.color()->flags |=0x1 ; e.color()->color = colors.n-1; } e.paintp()->flags |= 0x1; e.entity()->idPaintp = paintedProps.n; } if(_colors.ptr) free(_colors.ptr); _colors = colors; colors.ptr = NULL; if(_lines.ptr) free(_lines.ptr); _lines = lines; lines.ptr = NULL; if(_paintedProps.ptr) free(_paintedProps.ptr); _paintedProps = paintedProps; paintedProps.ptr = NULL; if(_points.ptr) free(_points.ptr); _points = points; points.ptr = NULL; //ajusta memoria if(!_entities.ajusta_mem()) return false; if(!_points.ajusta_mem()) return false; if(!_lines.ajusta_mem()) return false; if(!_paintedProps.ajusta_mem()) return false; if(!_colors.ajusta_mem()) return false; return true; } //***************************************************************************************** bool CartoBase::importShp(char* path) { CartoBaseShpManager shp; Cb_file f; char patdbf[256]; if(!f.abre(path,1,0,1)) return false; shp.set(this); int oldia =typeIA ; typeIA = NIa; if(!shp.ImportShp(&f)) { typeIA = oldia; return false; } typeIA = oldia; if(typeIA== NIa || typeIA == IntIa) return true; CartoBaseDBFManager dbf; return dbf.leer(Cdir_manager::cambia_extension_archivo(path,patdbf,"dbf"),this); } //***************************************************************************************** bool CartoBase::exportShp(char* path) { return fexportShp(path); } //***************************************************************************************** bool CartoBase::ptosExportShp(char* path) { return fexportShp(path, CartoBaseTypes::Point); } //***************************************************************************************** bool CartoBase::linesExportShp(char* path) { return fexportShp(path, CartoBaseTypes::Line); } //***************************************************************************************** bool CartoBase::fexportShp(char* path, int type) { char patdbf[256]; CartoBaseShpManager shp; Cb_file f; Cb_file fshx; if(!f.abre(path,2,1)) return false; if(!fshx.abre(Cdir_manager::cambia_extension_archivo(path,patdbf,"shx"),2,1)) return false; if(!shp.ExportShp(&f,&fshx,this, type)) return false; if(typeIA== NIa) return true; CartoBaseDBFManager dbf; FiterCartoBase enti; if(type == CartoBaseTypes::Ndef) type = _entities[0].type; for(int i =0; i<_entities.n; i++) { if(_entities[i].type == type) enti.ind+i; } enti.cb = this; return dbf.grabar(Cdir_manager::cambia_extension_archivo(path,patdbf,"dbf"), this,&enti); //exporta dbf; } //***************************************************************************************** void CartoBase::iniIndexRef() { refIndex.clear(); for(int i=0; i<_entities.n; i++) { _entities[i].ref=i; refIndex[i]=i; } ref = _entities.n; } //***************************************************************************************** void CartoBase::reIndexRef() { refIndex.clear(); for(int i=0; i<_entities.n; i++) { refIndex[_entities[i].ref]=i; } } //***************************************************************************************** void CartoBase::indexRef(bool buscaRepes) { refIndex.clear(); int ref_max=-1; int r; bool repes =false; //busca maximo u si hay repes for(int i=0; i<_entities.n; i++) { r =_entities[i].ref; refIndex[r]=i; if(r>ref_max) ref_max = r; } if(ref<= ref_max) ref = ref_max; if(!buscaRepes) return; for(int i=0; i<_entities.n; i++) { r =_entities[i].ref; if(refIndex[r]!= i) { //referencias repetidas _entities[i].ref =ref; refIndex[ref] = i; ref++; } } } //***************************************************************************************** void* CartoBase::getIa( int refEnt ) { if(iaEx) return iaEx->IaGet(refEnt); return NULL; } //***************************************************************************************** void CartoBase::setExIa( DataIaCartoBase* ia ) { typeIA = ExIa; iaEx=ia; iaEx->CBSet(this); //aņade a ia entidades existentes for (int i =0; i<_entities.n; i++) { if(_entities[i].flagsInt & CARTOBASE_DELETED_ENTITY) continue; iaEx->IaAdd((_entities[i].ref)); } } //***************************************************************************************** bool CartoBase::IaGetSize( int *ncolm ) { *ncolm =1; return true; } //***************************************************************************************** bool CartoBase::IaGetColm( int icol, char* name, BYTE *type, int *size, int*ndecimal ) { if(icol!=0) return false; *size = 10; *ndecimal=0; *type = DBF_TYPE_DATA_I; strcpy(name,iaName); return true; } //***************************************************************************************** bool CartoBase::IaGetVal( int refEnt, int icol, int* v ) { if(icol!=0) return false; *v =getRef(refEnt).entity()->ia; return true; } //***************************************************************************************** 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]); } //***************************************************************************************** int FiterCartoBase::getNumberEntities() { return ind.n; } //*****************************************************************************************