/* delete attribute from map * MdelAttribute deletes an attribute * from a map, if the attribute is available. * returns * the id argument if the attribute is succesfully deleted, * or 0 in case of error or if the attribute is not found. * * Merrno * NOACCESS * WRITE_ERROR */ CSF_ATTR_ID MdelAttribute( MAP *m, /* map handle */ CSF_ATTR_ID id) /* identification of attribute */ { ATTR_CNTRL_BLOCK b; CSF_FADDR32 pos; if (! WRITE_ENABLE(m)) { M_ERROR(NOACCESS); goto error; } pos = CsfGetAttrBlock(m, id, &b); if (pos == 0) goto error; b.attrs[CsfGetAttrIndex(id, &b)].attrId = ATTR_NOT_USED; if (CsfWriteAttrBlock(m, pos, &b)) { M_ERROR(WRITE_ERROR); goto error; } return id ; error: return 0 ; /* not found or an error */ }
/* change the x value of upper left co-ordinate * RputXUL changes the x value of upper left co-ordinate. * returns the new x value of upper left co-ordinate or 0 * case of an error. * * Merrno * NOACCESS */ REAL8 RputXUL( MAP *map, /* map handle */ REAL8 xUL) /* new x value of top left co-ordinate */ { CHECKHANDLE_GOTO(map, error); if(! WRITE_ENABLE(map)) { M_ERROR(NOACCESS); goto error; } map->raster.xUL = xUL; return(xUL); error: return(0); }
/* change projection type of map * MputProjection type changes the projection type of a map. * In version 2, projections are simplified. We only discern between * a projection with y increasing (PT_YINCT2B=0) and decreasing (PT_YDECT2B=1) * from top to bottom. * All old constants that denote a projection with y decreasing are nonzero. * And the old constant that denote a projection with y decreasing (PT_XY) is 0. * returns the new projection (PT_YINCT2B or PT_YDECT2B) or MV_UINT2 if an * error occurred. * * Merrno * NOACCESS */ CSF_PT MputProjection( MAP *map, /* map handle */ CSF_PT p) /* projection type, all nonzero values are mapped to * 1 (PT_YDECT2B) */ { CHECKHANDLE_GOTO(map, error); if(! WRITE_ENABLE(map)) { M_ERROR(NOACCESS); goto error; } map->main.projection = (p) ? PT_YDECT2B : PT_YINCT2B; return map->main.projection; error: return(MV_UINT2); }
/* make all cells missing value in map * RputAllMV writes a missing values to all the cells in a * map. For this is allocates a buffer to hold one row at a * time. * returns 1 if succesfull, 0 in case of an error */ int RputAllMV( MAP *m) { size_t i,nc,nr; void *buffer; CSF_CR cr; CHECKHANDLE_GOTO(m, error); if(! WRITE_ENABLE(m)) { M_ERROR(NOACCESS); goto error; } cr = RgetCellRepr(m); nc = RgetNrCols(m); buffer = Rmalloc(m,nc); if(buffer == NULL) { M_ERROR(NOCORE); goto error; } /* Fill buffer with determined Missingvalue*/ SetMemMV(buffer, nc, cr); nr = RgetNrRows(m); for(i = 0 ; i < nr; i++) if (RputRow(m, i, buffer) != nc) { M_ERROR(WRITE_ERROR); goto error_f; } CSF_FREE(buffer); CsfSetVarTypeMV( &(m->raster.minVal), cr); CsfSetVarTypeMV( &(m->raster.maxVal), cr); return(1); error_f: CSF_FREE(buffer); error: return(0); }
/* put cell size * returns the new cell size or -1 * in case of an error. * * Merrno * ILLHANDLE * NOACCESS * ILL_CELLSIZE */ REAL8 RputCellSize( MAP *map, /* map handle */ REAL8 cellSize) /* new cell size */ { CHECKHANDLE_GOTO(map, error); if(! WRITE_ENABLE(map)) { M_ERROR(NOACCESS); goto error; } if (cellSize <= 0.0) { M_ERROR(ILL_CELLSIZE); goto error; } map->raster.cellSize = cellSize; map->raster.cellSizeDupl = cellSize; return(cellSize); error: return(-1.0); }
int RuseAs( MAP *m, /* map handle */ CSF_CR useType) /* CR_UINT1,CR_INT4, CR_REAL4, CR_REAL8, VS_BOOLEAN or VS_LDD */ { CSF_CR inFileCR = RgetCellRepr(m); CSF_VS inFileVS = RgetValueScale(m); int hasInFileCellReprType2 = HasInFileCellReprType2(inFileCR); /* it is very unconvenient that both, VS and CR are taken as arguments * for this function, and previously were used in the switch statement * now, at least 'special conversions' handled first */ if((int)useType == VS_BOOLEAN){ switch(inFileVS) { case VS_LDD: case VS_DIRECTION: { M_ERROR(CANT_USE_AS_BOOLEAN); return 1; } case VS_BOOLEAN: { POSTCOND(inFileCR == CR_UINT1); m->appCR = CR_UINT1; m->file2app = same; m->app2file = same; return 0; } default: { if((!hasInFileCellReprType2) && WRITE_ENABLE(m)) { /* cellrepr is old one, we can't write that */ M_ERROR(CANT_USE_WRITE_BOOLEAN); return 1; } m->appCR = CR_UINT1; m->file2app = ConvFuncBool(inFileCR); m->app2file = ConvFunc(inFileCR, CR_UINT1); return 0; } } } else if ((int)useType == VS_LDD){ switch(inFileVS) { case VS_LDD: { POSTCOND(inFileCR == CR_UINT1); m->appCR = CR_UINT1; m->file2app = same; m->app2file = same; return 0; } case VS_CLASSIFIED: case VS_NOTDETERMINED: { switch(inFileCR) { case CR_UINT1: { m->appCR = CR_UINT1; m->file2app = UINT1tLdd; m->app2file = same; return 0; } case CR_INT2: { if(WRITE_ENABLE(m)) { M_ERROR(CANT_USE_WRITE_LDD); return 1; } m->appCR = CR_UINT1; m->file2app = INT2tLdd; m->app2file = illegal; return 0; } default: { /* This should never happen. * Shut up compiler. */ assert(0); } } } default: { M_ERROR(CANT_USE_AS_LDD); return 1; } } } switch(useType) { case CR_UINT1: case CR_INT4 : case CR_REAL4: case CR_REAL8: { if((!hasInFileCellReprType2) && WRITE_ENABLE(m)) { /* cellrepr is old one, we can't write that */ M_ERROR(CANT_USE_WRITE_OLDCR); return 1; } m->appCR = useType; m->file2app = ConvFunc(useType, inFileCR); m->app2file = ConvFunc(inFileCR, useType); POSTCOND(m->file2app != NULL); return 0; } default: { M_ERROR(ILLEGAL_USE_TYPE); return 1; } } /* NOTREACHED */ }
/* seek to space for attribute (LIBRARY_INTERNAL) * CsfSeekAttrSpace seeks to the a point in the file where * the attribute must be stored and update the attribute control * blocks accordingly. * Writing can still fail since there is no check if that space is really * avalaible on the device. After this call returns the file is already * seeked to the point the functions returns. * returns the file position or 0 in case of error. * * Merrno * ATTRDUPL * NOACCESS * WRITE_ERROR */ CSF_FADDR32 CsfSeekAttrSpace( MAP *m, /* map handle */ CSF_ATTR_ID id, /* attribute identification only for check if avalaible */ size_t size) /* size to be seeked to */ { ATTR_CNTRL_BLOCK b; CSF_FADDR32 currBlockPos, prevBlockPos=USED_UNINIT_ZERO, newPos, endBlock, resultPos=0; int noPosFound; int i; if (MattributeAvail(m ,id)) { M_ERROR(ATTRDUPL); goto error; } if (! WRITE_ENABLE(m)) { M_ERROR(NOACCESS); goto error; } currBlockPos = m->main.attrTable; noPosFound = 1; while (noPosFound) { if (currBlockPos == 0) { if (m->main.attrTable == 0) { /* FIRST BLOCK */ newPos =( (CSF_FADDR)(m->raster.nrRows)* (CSF_FADDR)(m->raster.nrCols)* (CSF_FADDR)(CELLSIZE(RgetCellRepr(m)))) + ADDR_DATA; m->main.attrTable = newPos; } else { /* NEW/NEXT BLOCK */ newPos = b.attrs[LAST_ATTR_IN_BLOCK].attrOffset + b.attrs[LAST_ATTR_IN_BLOCK].attrSize; b.next = newPos; if (CsfWriteAttrBlock(m, prevBlockPos, &b)) { M_ERROR(WRITE_ERROR); resultPos = 0; } } InitBlock(&b); b.attrs[0].attrOffset = newPos + SIZE_OF_ATTR_CNTRL_BLOCK; currBlockPos = newPos; noPosFound = 0; } else CsfReadAttrBlock(m, currBlockPos, &b); i = 0; /* this is also the right index if a new block is added ! */ while (noPosFound && i < NR_ATTR_IN_BLOCK) switch (b.attrs[i].attrId) { case END_OF_ATTRS: POSTCOND(i >= 1); /* i >= 1 , no block otherwise */ b.attrs[i].attrOffset = b.attrs[i-1].attrOffset + b.attrs[i-1].attrSize; noPosFound = 0; break; case ATTR_NOT_USED: if (i == NR_ATTR_IN_BLOCK) endBlock = b.next; else endBlock = b.attrs[i+1].attrOffset; if ( (size_t)( endBlock - b.attrs[i].attrOffset) >= size) /* this position can hold the attr */ noPosFound = 0; else i++; break; default: i++; } /* switch */ /* if (b.next == 0) ? When did I change this CW remember this block position since it may be have to rewritten */ prevBlockPos = currBlockPos; if (noPosFound) currBlockPos = b.next; } /* while */ b.attrs[i].attrSize = size; b.attrs[i].attrId = id; resultPos = b.attrs[i].attrOffset; if (CsfWriteAttrBlock(m, currBlockPos, &b)) { M_ERROR(WRITE_ERROR); resultPos = 0; } fseek(m->fp, (long)resultPos, SEEK_SET); /* fsetpos() is better */ error: return resultPos; } /* CsfSeekAttrSpace */