714 lines
17 KiB
C++
714 lines
17 KiB
C++
#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);
|
||
}
|
||
//*****************************************************************************************
|
||
/*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;
|
||
}
|
||
//*****************************************************************************************
|