utiles_v2017/CartoBase.cpp

695 lines
16 KiB
C++
Raw Blame History

#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<int,int> indsl;
int il,ip,ic, id;
std::map<int,int> indsp;
std::map<int,int> indsc;
std::map<int,int> 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<nn; ii++)
{
if(indsp.find(aux+ii) == indsp.end())
indsp[aux+ii] = ip++;
}
_lines[_entities[i].id].ini = indsp[aux];
_entities[i].id = indsl[_entities[i].id];
break;
}
}
}
//recolocacion---------------------
for (std::map<int, int>::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<int, int>::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<int, int>::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<int, int>::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<CartoBasePoint> points;//coordenadas
Cgarray<CartoBaseLine> lines;//lineas
Cgarray<CartoBasePaintedProps> paintedProps;//propiedades de pintado
Cgarray<CartoBaseColor> 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; jj<e.line()->n; 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);
}
//*****************************************************************************************
CartoBaseInfoEntity FiterCartoBase::getEntity( int i )
{
return cb->get(ind[i]);
}
//*****************************************************************************************
int FiterCartoBase::getNumberEntities()
{
return ind.n;
}
//*****************************************************************************************