static int SetAndCloseMap( MAP *m, const ATTRIBUTES *a) { double angle; if (! (IS_MV_REAL8(&(a->angle)))) { if (a->angle < 0) angle = -Deg2Rad(-a->angle); else angle = Deg2Rad(a->angle); } if (RuseAs(m, CR_REAL8)) goto error2; if (a->projection != PT_UNDEFINED) MputProjection(m,a->projection); if (! (IS_MV_REAL8(&(a->xUL)))) RputXUL(m, a->xUL); if (! (IS_MV_REAL8(&(a->yUL)))) RputYUL(m, a->yUL); if (! (IS_MV_REAL8(&(a->angle)))) RputAngle(m, angle); if (! (IS_MV_REAL8(&(a->cellSize)))) RputCellSize(m, a->cellSize); if(a->gisFileId != MV_UINT4) MputGisFileId(m,a->gisFileId); if (Merrno) goto error2; return 0; error2: return RetError(1,"Can not write to '%s': %s",MgetFileName(m),MstrError()); }
/* Wrapper around fread * returns * -1 in case of error. * short (item) count: conforming to fread() return value. If a short item * count is encountered, first ferror is checked and Error is called if ferror is true and * -1 is returned, if ferror is false and shortItemCountIsError is set then Error() is also called * and -1 returned. */ int FileRead( void *ptr, /* buffer filled */ size_t size, /* size of each element */ size_t nmemb, /* number of elements */ FILE *f, /* file to read from */ BOOL shortItemCountIsError) /* TRUE if an error must be emitted if there are less * than nmemb members read, FALSE otherwise */ { int r = fread(ptr,size,nmemb,f); if (r != (int)nmemb) { if (ferror(f)) return RetError(-1,"file read error:%s",strerror(errno)); else if (shortItemCountIsError) return RetError(-1,"file read error: expected file to be larger"); } return r; }
static int CreateMap( const char *name, const ATTRIBUTES *a) { UINT1 *buf; size_t i; double angle; MAP *m; size_t CELLMAX = (long int)(pow(2,30) - 1); if(((size_t)a->nrRows * (size_t)a->nrCols) > CELLMAX){ printf("WARNING:\n The specified amount of cells exceeds 2^30 - 1.\n Not all PCRaster applications accept maps of this size.\n"); } if (a->angle < 0) angle = -Deg2Rad(-a->angle); else angle = Deg2Rad(a->angle); m = Rcreate(name,(size_t)a->nrRows,(size_t)a->nrCols, a->cellRepr, a->valueScale, a->projection, a->xUL, a->yUL, angle, a->cellSize); if (m == NULL) goto error1; PRECOND(a->gisFileId != MV_UINT4); if (MputGisFileId(m,a->gisFileId) == MV_UINT4) goto error2; if (RuseAs(m, CR_UINT1)) goto error2; buf = (UINT1 *)Rmalloc(m, (size_t)a->nrCols); if (buf == NULL) { Mclose(m); remove(name); return 1; } for(i=0; i < a->nrRows; i++) { memset(buf,1,(size_t)a->nrCols); RputRow(m,i,buf); } Free(buf); Mclose(m); return 0; error2: Mclose(m); remove(name); error1: return RetError(1,"Can not create '%s': %s",name,MstrError()); }
static int SetOption( const char **names, int nrNames, const ATTRIBUTES *opt) { ATTRIBUTES a; MAP **maps; int i; if (DefaultCloneAttr(&a)) return 1; if (FileStat(names[0]) == 2) { /* non-existing */ MergeOptAttr(&a, opt); if (nrNames > 1) return RetError(1,"-s: only one new map or multiple existing maps allowed"); if (a.nrRows == MV_UINT4 || a.nrCols == MV_UINT4) return RetError(1,"-s: -R and/or -C not specified"); return CreateMap(names[0], &a); } else { /* set all */ if (opt->nrRows != MV_UINT4 || opt->nrCols != MV_UINT4) return RetError(1,"-s: can not change number of rows or columns of an existing map"); if (opt->valueScale != VS_UNDEFINED) return RetError(1,"-s: can not change data type of an existing map"); maps = OpenCopyOrSetMaps(&a,FALSE,names,nrNames); if (maps == NULL) return 1; for(i=0; i < nrNames; i++) SetAndCloseMap(maps[i], opt); Free(maps); return 0; } }
static int EditOption( const char *name) { ATTRIBUTES a; MAP *in = Mopen(name, M_READ_WRITE); if (in == NULL || ReadAttr(&a,in,FALSE)) { if (in != NULL) Mclose(in); return RetError(1,"while reading '%s': %s",name,MstrError()); } if (a.version != 2) return RetError(1,"'%s' is not a version 2 map, no edits possible"); a.cloneCreation = FALSE; switch(MakeCloneMenu(&a, name)) { case 0: return 0; case 1: return SetAndCloseMap(in, &a); case 2: fprintf(stderr,"No map attributes written\n"); return 0; } POSTCOND(FALSE); return 1; }
int MoveColumn(const char *outputName, const char *inputName, size_t colNr) { LOOK_UP_TABLE *t; FILE *f; size_t r; PRECOND(outputName != NULL); PRECOND(inputName != NULL); PRECOND(colNr > 0); colNr--; f = fopen(inputName, "r"); if (f == NULL) return RetError(1, "Failure to open '%s'", inputName); t = ReadLookupTable(f, NULL, (size_t)0, VS_UNDEFINED); fclose(f); if (t == NULL) return RetError(1, "While reading '%s'", inputName); if (t->nrKeys < colNr) { Error("Can't move columns '%d', '%s' has only '%d' columns", colNr + 1, inputName, t->nrKeys + 1); FreeLookupTable(t); return 1; } for (r = 0; r < t->nrRecords; r++) { LOOK_UP_KEY k = t->records[r][colNr]; memmove(t->records[r] + colNr, t->records[r] + (colNr + 1), (t->nrKeys - colNr) * sizeof(LOOK_UP_KEY)); t->records[r][t->nrKeys] = k; } return WriteLookupTable(outputName, t); }
static int CloneOption( const char *name) { ATTRIBUTES a; if (FileStat(name) != 2) { return RetError(1,"file '%s' exists, give new (non-existing) name",name); } if (DefaultCloneAttr(&a)) return 1; a.cloneCreation = TRUE; switch(MakeCloneMenu(&a, name)) { case 0: return 1; case 1: return CreateMap(name, &a); case 2: fprintf(stderr,"No map created\n"); return 0; } POSTCOND(FALSE); return 1; }
static int DefaultCloneAttr( ATTRIBUTES *a) { MAP *in; if (appClone != NULL) { char *dummy; in = AppOpenClone(&dummy, NULL); if (in == NULL ) return 1; if (ReadAttr(a,in,FALSE)) { Mclose(in); return RetError(1,"while reading clone map '%s': %s",appClone,MstrError()); } Mclose(in); } else DefaultAttr(a); return 0; }
/* checks if the dataset is allowed for this version * LimitedVersionCheck checks all limitations of * the evaluation version, Each restriction that is set * negative (-1) is not checked * * returns * 0 if dataset is allowed * non zero if dataset is not allowed */ int LimitedVersionCheck( int nrRows, /* number of rows limit: 60 */ int nrCols, /* number of columns limit: 60 */ int nrSteps, /* number of timesteps limit: 360 */ int nrLookupRecs, /* number of records in lookup tables limit 20 */ int nrXYZRecs, /* number of XYZ records in pointfile limit 3600 */ int nrOps) /* number of operations, limit not set yet */ { #ifdef EVAL_VERSION int noLimits = 0; #else int noLimits = 1; #endif if (noLimits) return 0; if (nrRows > 60) return RetError(1,"%s only 60 rows allowed (not '%d')",MSG,nrRows); if (nrCols > 60) return RetError(1,"%s only 60 columns allowed (not '%d')",MSG,nrCols); if (nrSteps > 360) return RetError(1,"%s only 360 timesteps allowed (not '%d')",MSG,nrSteps); if ( (nrRows > 0) && (nrCols > 0) && (nrSteps > 0) && ((nrRows*nrCols*nrSteps) > 240000) ) { int i = nrRows*nrCols*nrSteps; return RetError(1, "%s nr.timesteps*nr.cells may not exceed 240000 (not '%d')",MSG,i); } if (nrLookupRecs > 20) return RetError(1,"%s only 20 records\\tuples allowed in a table (not '%d')", MSG, nrLookupRecs); if (nrXYZRecs > 3600) return RetError(1,"%s only 3600 records\\tuples allowed in point data column file (not '%d')", MSG, nrXYZRecs); (void)nrOps; // Shut up compiler return 0; }
/* Spreads from each nonzero point in points map. * First all cells that have a point value > 0, are * put in a list. These cells are the points from which is spread. * Returns 1 if an error occurs, 0 otherwise. */ int SpreadMax( MAP_REAL8 *outCost, /* read-write output map */ MAP_INT4 *outId, /* read-write output map */ const MAP_INT4 *points, /* points to be spread */ const MAP_REAL8 *cost, /* initial costs */ const MAP_REAL8 *friction, /* friction of each cell */ const MAP_REAL8 *maxCost) /* maximum cost before cell is read */ { NODE *coordList = NULL; /* list with cells to be checked */ INT4 pointVal; /* value in points map of cell */ REAL8 costVal,s, f; /* s = initial cost, f = friction of cell */ int r, nrRows = points->NrRows(points); int c, nrCols = points->NrCols(points); inList = NewBitMatrix((size_t)nrRows,(size_t)nrCols); if (inList == NULL) return 1; SetAllBitMatrix(inList,nrRows, nrCols, 0); /* not in list */ /* Fill outCostBuf with MV, this is the initial value */ outCost->PutAllMV(outCost); /* Fill outIdBuf with 0, this is the initial value */ for (r = 0; r < nrRows; r++) for (c = 0; c < nrCols; c++) outId->Put(0, r, c, outId); /* algorithm wants points->Get() and all others to * return FALSE if a value is a missing value */ points->SetGetTest(GET_MV_TEST, points); friction->SetGetTest(GET_MV_TEST, friction); cost->SetGetTest(GET_MV_TEST, cost); outId->SetGetTest(GET_MV_TEST, outId); outCost->SetGetTest(GET_MV_TEST, outCost); maxCost->SetGetTest(GET_MV_TEST, maxCost); /* breadth - first */ for(r = 0; r < nrRows; r++) { for(c = 0; c < nrCols; c++) { if(points->Get(&pointVal, r, c, points) && (friction->Get(&f, r, c, friction))) { if (f < 0) return RetError(1,"spread: Domain error on parameters"); if(pointVal != 0) { /* put spread points in coordlist */ if(! cost->Get(&s, r, c, cost)) goto putMv; outCost->Put(s, r, c, outCost); outId->Put(pointVal, r, c, outId); coordList = AddToList(coordList, r, c); if(coordList == NULL) return 1; } } else { putMv: outId->PutMV(r, c, outId); outCost->PutMV(r, c, outCost); } } AppDynamicProgress(); } if(PerformSpread(outCost, outId, coordList, friction,maxCost)) return 1; /* cost is not computed for ouside maxCost rangge set to 0 */ for (r = 0; r < nrRows; r++) for (c = 0; c < nrCols; c++) if(points->Get(&pointVal, r, c, points) && (friction->Get(&f, r, c, friction))) { /* under above condition we dis spread so now * test for these cells if cost is computed */ if(!outCost->Get(&costVal, r, c, outCost)) outCost->Put(0.0, r, c, outCost); } AppEndDynamicProgress(); Free2d((void **)inList, (size_t)nrRows); return 0; /* successful terminated */ }
int IBNGauss( MAP_REAL8 *out, const MAP_REAL8 *units, const MAP_REAL8 *range, const MAP_REAL8 *nrPackages) { int rSrc,nrRows= units->NrRows(units); int cSrc,nrCols= units->NrCols(units); REAL8 unitsValSrc,rangeValSrc,nrPackValSrc; /* algorithm wants points->Get() and all others to * return FALSE if a value is a missing value */ out->SetGetTest(GET_MV_TEST, out); units->SetGetTest(GET_MV_TEST, units); nrPackages->SetGetTest(GET_MV_TEST, nrPackages); range->SetGetTest(GET_MV_TEST, range); /* set all to 0 or MV * check range of rangeValSrc */ for(rSrc = 0; rSrc < nrRows; rSrc++) for(cSrc = 0; cSrc < nrCols; cSrc++) { if(units->Get(&unitsValSrc, rSrc, cSrc, units) && nrPackages->Get(&nrPackValSrc, rSrc, cSrc, nrPackages) && range->Get(&rangeValSrc, rSrc, cSrc, range)) { /* init with remainder */ REAL8 remainder = unitsValSrc - floor(unitsValSrc); out->Put(remainder, rSrc, cSrc, out); if (rangeValSrc < 0) return RetError(1,"ibngauss: Domain error on parameters"); } else /* some of the units maps are MV */ out->PutMV(rSrc, cSrc, out); } for(rSrc = 0; rSrc < nrRows; rSrc++) for(cSrc = 0; cSrc < nrCols; cSrc++) if(units->Get(&unitsValSrc, rSrc, cSrc, units) && nrPackages->Get(&nrPackValSrc, rSrc, cSrc, nrPackages) && range->Get(&rangeValSrc, rSrc, cSrc, range) ) { int i,nrInputUnits = (int)floor(unitsValSrc); int nrPackages = (int)nrPackValSrc; /* round to integer */ int packageSize; int nrPackagesWithOneMore; if (nrPackages <= 0 || nrPackages > nrInputUnits) { nrPackages=nrInputUnits; packageSize=1; nrPackagesWithOneMore=0; } else { packageSize=nrInputUnits/nrPackages; /* integer division */ nrPackagesWithOneMore= nrInputUnits%nrPackages; /* integer modulo */ } rangeValSrc /= Side(); /* transform to pixel lengths */ for(i=0; i < nrPackages; i++) { /* GasDev returns value from normal distribution mean=0,sd=1 */ REAL8 length = GasDev()*rangeValSrc; /* Ran() return an uniform number * we create an angle between 0 and 180 degrees */ REAL8 angle =Ran()*M_PI; /* now since length can be negative or positive we * generate a receiving cell address having an angle * with the src cell between 0 and 360 degrees */ int xColDest = cSrc+(int)(length*cos(angle)); int yRowDest = rSrc+(int)(length*sin(angle)); REAL8 valDest; if (out->Get(&valDest, yRowDest, xColDest, out)) { /* destination is defined area */ valDest+=packageSize; if (i < nrPackagesWithOneMore) { /* the first nrPackagesWithOneMore package do 1 more */ valDest+=1; } out->Put(valDest, yRowDest, xColDest, out); } } /* for all packages */ } /* eo for all cells */ return 0; /* successful terminated */ }
static int PrintOption( const char **names, int nrNames) { ATTRIBUTES *a = (ATTRIBUTES *)ChkMalloc(sizeof(ATTRIBUTES) * nrNames); int *colLen = (int *)ChkMalloc(sizeof(int) * nrNames); int i; if (a == NULL || colLen == NULL) return 1; for(i = 0 ; i < nrNames; i++) { MAP *m= Mopen(names[i],M_READ); if (m == NULL) { Free(a); return RetError(1,"while reading map '%s': %s",names[i],MstrError()); } ReadAttr(a+i,m,TRUE); colLen[i] = MAX(11, strlen(names[i])); Mclose(m); } if (printDataType) { for(i = 0 ; i < nrNames; i++) { int c; switch(a[i].valueScale) { case VS_LDD : c = 'L'; break; case VS_SCALAR : c = 'S'; break; case VS_BOOLEAN : c = 'B'; break; case VS_NOMINAL : c = 'N'; break; case VS_ORDINAL : c = 'O'; break; case VS_DIRECTION : c = 'D'; break; default : c = ' '; break; } printf("%c",c); } return 1; } printf("%s",HEAD); for(i = 0 ; i < nrNames; i++) printf(" %-*s", colLen[i], names[i]); printf("\n"); printf("%s",printLabels[ATTR_nrRows]); for(i = 0 ; i < nrNames; i++) printf(" %-*u", colLen[i], a[i].nrRows); printf("\n"); printf("%s",printLabels[ATTR_nrCols]); for(i = 0 ; i < nrNames; i++) printf(" %-*u", colLen[i], a[i].nrCols); printf("\n"); printf("%s",printLabels[ATTR_cellSize]); for(i = 0 ; i < nrNames; i++) printf(" %-*g", colLen[i], a[i].cellSize); printf("\n"); printf("%s",printLabels[ATTR_valueScale]); for(i = 0 ; i < nrNames; i++) printf(" %-*s", colLen[i], RstrValueScale(a[i].valueScale)); printf("\n"); printf("%s",printLabels[ATTR_cellRepr]); for(i = 0 ; i < nrNames; i++) { const char *cStr; switch(a[i].cellRepr) { case CR_UINT1 : cStr = "small"; break; case CR_INT4 : cStr = "large"; break; case CR_REAL4 : cStr = "single"; break; case CR_REAL8 : cStr = "double"; break; default : cStr = RstrCellRepr(a[i].cellRepr); } printf(" %-*s", colLen[i], cStr); } printf("\n"); printf("%s",printLabels[ATTR_projection]); for(i = 0 ; i < nrNames; i++) printf(" %-*s", colLen[i], a[i].projection ? "yb2t" : "yt2b" ); printf("\n"); printf("%s",printLabels[ATTR_angle]); for(i = 0 ; i < nrNames; i++) printf(" %-*g", colLen[i], a[i].angle); printf("\n"); printf("%s",printLabels[ATTR_xUL]); for(i = 0 ; i < nrNames; i++) printf(" %-*g", colLen[i], a[i].xUL); printf("\n"); printf("%s",printLabels[ATTR_yUL]); for(i = 0 ; i < nrNames; i++) printf(" %-*g", colLen[i], a[i].yUL); printf("\n"); printf("%s",printLabels[ATTR_minVal]); for(i = 0 ; i < nrNames; i++) if (IS_MV_REAL8(&(a[i].minVal))) printf(" %-*s", colLen[i], "mv"); else { if ((a[i].cellRepr) & CSF_FLOAT_MASK) printf(" %-*g", colLen[i], a[i].minVal); else printf(" %-*d", colLen[i], (int)a[i].minVal); } printf("\n"); printf("%s",printLabels[ATTR_maxVal]); for(i = 0 ; i < nrNames; i++) if (IS_MV_REAL8(&(a[i].maxVal))) printf(" %-*s", colLen[i], "mv"); else { if ((a[i].cellRepr) & CSF_FLOAT_MASK) printf(" %-*g", colLen[i], a[i].maxVal); else printf(" %-*d", colLen[i], (int)a[i].maxVal); } printf("\n"); printf("%s",printLabels[ATTR_version]); for(i = 0 ; i < nrNames; i++) printf(" %-*u", colLen[i], a[i].version); printf("\n"); printf("%s",printLabels[ATTR_gisFileId]); for(i = 0 ; i < nrNames; i++) printf(" %-*u", colLen[i], a[i].gisFileId); printf("\n"); printf("%s",printLabels[ATTR_byteOrder]); for(i = 0 ; i < nrNames; i++) printf(" %-*s", colLen[i], a[i].byteOrder == 1 ? "y" : "n"); printf("\n"); printf("%s",printLabels[ATTR_attrTable]); for(i = 0 ; i < nrNames; i++) printf(" %-*s", colLen[i], a[i].attrTable == 0 ? "n" : "y"); printf("\n"); return 0; }