pihmRasterLIBS/gridio.cpp

Go to the documentation of this file.
00001 /***********************************************************/
00002 /*                                                         */
00003 /* gridio.c                                                */
00004 /*                                                         */
00005 /* I/O routines for terrain stability mapping              */
00006 /*                                                         */
00007 /***********************************************************/
00008 
00009 
00010 #include "gridio.h"
00011 /*  Nameadd(..)  Utility for adding suffixes to file names prior to
00012    "." extension   */
00013 int nameadd(char *full,char *arg,char *suff)
00014   {
00015         char *ext;
00016         int nmain;
00017     ext=strrchr(arg,'.');
00018     if(ext == NULL)
00019         {
00020                 nmain=strlen(arg);
00021                 sprintf(full,"%s%s",arg,suff);
00022         }
00023         else
00024         {
00025                 nmain=strlen(arg)-strlen(ext);
00026                 strcpy(full,"");
00027                 strncat(full,arg,nmain);
00028                 strcat(full,suff);
00029                 strcat(full,ext);
00030         }
00031         return(nmain);
00032   }
00033 
00034 int readline(FILE *fp,char *fline)
00035 {
00036   int i = 0, ch;
00037 
00038   for(i=0; i< MAXLN; i++)
00039   {
00040     ch = getc(fp);
00041 
00042     if(ch == EOF) { *(fline+i) = '\0'; return(EOF); }
00043     else          *(fline+i) = (char)ch;
00044 
00045     if((char)ch == '\n') { *(fline+i) = '\0'; return(0); }
00046 
00047   }
00048 }
00049 
00050 /*
00051   matalloc(...) allocates memory for matrix navigation pointer
00052   and for matrix data, then returns matrix navigation pointer
00053   Modification of matrixalloc by DGT to not use so many pointers
00054   7/1/97
00055 */
00056 void **matalloc(int nx,int ny,int datatype)
00057 {
00058     int i,arrsize;
00059     void **mat;
00060     void *data;
00061     int **imat;
00062     short **smat;
00063     float **fmat;
00064 
00065     /* allocate memory for array navigation pointers */
00066     if(datatype == 1)
00067     {
00068       mat = (void **)malloc(sizeof(short *)*(nx));
00069       arrsize = sizeof(short)*(nx)*(ny);
00070     }
00071     else if(datatype == 2)
00072     {
00073       mat = (void **)malloc(sizeof(int *)*(nx));
00074       arrsize = sizeof(int)*(nx)*(ny);
00075     }
00076     else if(datatype == 3)
00077     {
00078       mat = (void **)malloc(sizeof(float *)*(nx));
00079       arrsize = sizeof(float)*(nx)*(ny);
00080     }
00081 
00082     if(mat == NULL)
00083     {
00084       printf("\nError: Cannot allocate memory for matrix navigation pointers");
00085       printf("\n       nx = %d, ny = %d\n\n",nx,ny);
00086       exit(2);
00087     }
00088     
00089     data = malloc(arrsize);
00090     
00091     if(data == NULL)
00092     {
00093       printf("\nError: Cannot allocate memory for matrix of dimension");
00094       printf("\n       nx = %d, ny = %d\n\n",nx,ny);
00095       exit(3);
00096     }
00097     
00098     switch(datatype)
00099     {
00100       case 1:
00101         smat = (short **)mat;
00102         for(i=0; i<(nx); i++)
00103         {
00104           smat[i] = &(((short *)(data))[i*(ny)]);
00105         }
00106         break;
00107       case 2:
00108         imat = (int **)mat;
00109         for(i=0; i<(nx); i++)
00110         {
00111           imat[i] = &(((int *)(data))[i*(ny)]);
00112         }
00113         break;
00114       case 3:
00115         fmat = (float **)mat;
00116         for(i=0; i<(nx); i++)
00117         {
00118           fmat[i] = &(((float *)(data))[i*(ny)]);
00119         }
00120         break;
00121       default:
00122         break;
00123     }
00124     return(mat);
00125 }
00126 
00127 int gridread(char *file, void ***data, int datatype, int *nx, int *ny,
00128  float *dx, float *dy, double bndbox[4], double *csize, float *nodata, int *filetype)
00129 {
00130 FILE *fp;
00131 int channel1,type,iesri;
00132 
00133     int i, j, hdrlines = 0;
00134     float value;
00135     char fline[MAXLN], keyword[21], utmetag, utmntag;
00136     float **farr;
00137     int **iarr;
00138     short **sarr;
00139     double adjbndbox[4],utme,utmn;
00140     CELLTYPE *rowbuf;
00141     float floatNull;
00142 
00143       
00144     if(iesri = GridIOSetup() >= 0)
00145         /*
00146         Open input cell layer with no evaluation        (5)
00147         */
00148         if ((channel1 = 
00149               CellLayerOpen(file,READONLY,ROWIO,
00150                             &type,csize)) >= 0 )
00151     {
00152 /*  The success of these means the file could be opened as an ESRI grid file  */
00153         *filetype=1;
00154 /*  File types are
00155     0=ASCII   
00156     1= ARCVIEW grid via the ESRI Application Programmers Interface  */ 
00157 /*  here is the ESRI grid file read stuff - following copyrow example */
00158         *dx = *dy = (float) *csize;
00159         if(type == CELLINT && datatype == RPFLTDTYPE)
00160         {
00161            printf("%s File contains integer data but was read as float\n",file);
00162         }
00163         if(type == CELLFLOAT && datatype != RPFLTDTYPE)
00164         {
00165            printf("%s File contains Float data but was read as Integer\n",file);
00166         } 
00167         /*
00168         Get the bounding box of the input cell layer            (7)
00169         */
00170         if (BndCellRead (file, bndbox) < 0)
00171         {
00172                 printf ("could not read bounding box of input grid\n");
00173                 CellLyrClose(channel1);
00174                 GridIOExit();
00175                 return(1);
00176         }
00177 /*        printf("%f %f %f %f %g\n",bndbox[0],bndbox[1],bndbox[2],bndbox[3],*nodata) */; 
00178 /*  Bounding box is xllcorner, yllcorner, xurcorner, yurcorner   */
00179       
00180         /*
00181         Set the Window to the output bounding box and cellsize  (9)
00182         */
00183         if (AccessWindowSet (bndbox, *csize, adjbndbox) < 0)
00184         {
00185                 printf ("Could not set Window\n");
00186                 CellLyrClose(channel1);
00187                 GridIOExit();
00188                 return(2);
00189         }
00190         /*
00191         Get the number of rows and columns                      (10)
00192         in the window
00193         */
00194         *nx = WindowCols();
00195         *ny = WindowRows();
00196 
00197         /*  Allocate memory and set all type pointers  */
00198         *data = matalloc(*nx, *ny, datatype);
00199         farr = (float **) (*data);
00200         iarr = (int **) (*data);
00201         sarr = (short **) (*data);
00202         GetMissingFloat(&floatNull);
00203  
00204         *nodata = (datatype == RPFLTDTYPE) ? floatNull: -9999.; 
00205 
00206         /*
00207         Allocate row buffer                                     (11)
00208         */
00209         if ((rowbuf = (CELLTYPE *)
00210                         CAllocate1 ( *nx, sizeof(CELLTYPE)))
00211                         == NULL )
00212         {
00213                 printf ("Could not allocate memory\n");
00214                 CellLyrClose(channel1);
00215                 GridIOExit();
00216                 return(3);
00217         }
00218         /*
00219         Now copy row into array                 (12)
00220         */
00221         for (i=0; i < *ny; i++)
00222         {
00223              GetWindowRow (channel1, i, rowbuf);
00224              if(type == CELLINT)
00225              {
00226                 register int *buf = (int *)rowbuf;
00227                 if(datatype == RPSHRDTYPE)
00228                 {
00229                    for(j=0; j < *nx; j++)
00230                    {
00231                       sarr[j][i]=(buf[j] == MISSINGINT) ? (short) *nodata : (short) buf[j];    
00232                    }
00233                  }
00234                  else if(datatype == RPINTDTYPE)
00235                     {
00236                    for(j=0; j < *nx; j++)
00237                    {
00238                       iarr[j][i]=(buf[j] == MISSINGINT) ? (int) *nodata : buf[j]; 
00239                    }
00240                  }   
00241                      else
00242                     {
00243                    for(j=0; j < *nx; j++)
00244                    {
00245                       farr[j][i]=(buf[j] == MISSINGINT) ? *nodata: (float) buf[j];  
00246                    }
00247                 }
00248              }
00249              else
00250              {
00251                 register float *buf = (float *)rowbuf;
00252                                                                 
00253 /*     This is all repeated to get right the typecasting of data from ESRI file into the format 
00254        we want   */
00255                 if(datatype == RPSHRDTYPE)
00256                 {
00257                    for(j=0; j < *nx; j++)
00258                    {
00259                       sarr[j][i]=(buf[j] == floatNull) ? (short) *nodata : (short) buf[j];    
00260                    }
00261                  }
00262                  else if(datatype == RPINTDTYPE)
00263                     {
00264                    for(j=0; j < *nx; j++)
00265                    {
00266                       iarr[j][i]=(buf[j] == floatNull) ? (int) *nodata : (int) buf[j];
00267                    }
00268                  }   
00269                      else
00270                     {
00271                    for(j=0; j < *nx; j++)
00272                    {
00273                       farr[j][i]= buf[j];
00274                    }
00275                 }
00276              }
00277        }
00278 
00279         /*
00280         Free row buffer                                         (13)
00281         */
00282         CFree1 ((char *)rowbuf);
00283         /*
00284         Close handles                                           (14)
00285         */
00286         CellLyrClose(channel1);  
00287         /*
00288         Done with the library                                   (15)
00289         */
00290         GridIOExit();
00291         return(0);
00292     }
00293 
00294 /*  Here assume file is ASCII  Close ESRI stuff. */
00295     CellLyrClose(channel1);
00296     GridIOExit();
00297 
00298     *filetype=0;  
00299     fp = fopen(file,"r");
00300     printf("%s\n",file);
00301     if(fp == NULL)
00302     {
00303         printf("\nERROR: Cannot open input file (%s).\n\n",file);
00304         return(1);
00305     }
00306     
00307     /* read ARC-Info header */
00308     while(1)
00309     {   
00310         readline(fp, fline);       
00311         if(!isalpha(*fline) || *fline == '-')
00312             break;       
00313         
00314         hdrlines++;
00315 
00316         sscanf(fline,"%s %f",keyword,&value);
00317         
00318         if(strcmp(keyword,"ncols") == 0 || strcmp(keyword,"NCOLS") == 0)
00319             *nx = (int)value;
00320         else if(strcmp(keyword,"nrows") == 0 || strcmp(keyword,"NROWS") == 0)
00321             *ny = (int)value;
00322         else if(strcmp(keyword,"xllcenter") == 0 || strcmp(keyword,"XLLCENTER") == 0)
00323         {
00324             utmetag = 'c';
00325             utme = value;
00326         }
00327         else if(strcmp(keyword,"xllcorner") == 0 || strcmp(keyword,"XLLCORNER") == 0)
00328         {
00329             utmetag = 'e';
00330             utme = value;
00331         }
00332         else if(strcmp(keyword,"yllcenter") == 0 || strcmp(keyword,"YLLCENTER") == 0)
00333         {
00334             utmntag = 'c';
00335             utmn = value;
00336         }
00337         else if(strcmp(keyword,"yllcorner") == 0 || strcmp(keyword,"YLLCORNER") == 0)
00338         {
00339             utmntag = 'e';
00340             utmn = value;
00341         }
00342         else if(strcmp(keyword,"cellsize") == 0 || strcmp(keyword,"CELLSIZE") == 0)
00343         {
00344             *dx = *dy = value;
00345             *csize = (double) value;
00346         }
00347         else if(strcmp(keyword,"nodata_value") == 0 || strcmp(keyword,"NODATA_VALUE") == 0 ||
00348                 strcmp(keyword,"NODATA_value") == 0)
00349             *nodata = value;
00350     }
00351     
00352     /* adjust utme and utmn if necessary (we store center of reference cell) */
00353     if(utmetag == 'e') utme = utme + *dx/2;
00354     if(utmntag == 'e') utmn = utmn + *dy/2;
00355      bndbox[0] = utme - *csize/2.;   
00356      bndbox[1] = utmn - *csize/2.;
00357      bndbox[2] = bndbox[0] + *csize * (*nx);
00358      bndbox[3] = bndbox[1] + *csize * (*ny);
00359     /* position file pointer for ARC-Info file to beginning of image data */
00360     rewind(fp);
00361     for(i=0; i<hdrlines; i++) readline(fp, fline);
00362     
00363     /* convert depending on datatype */
00364     if(datatype == RPSHRDTYPE)
00365     {   
00366         sarr = (short **) matalloc(*nx, *ny, datatype);
00367              
00368         /* read in the ARC-Info file */        
00369         for(i=0; i< *ny; i++)
00370         {
00371             for(j=0; j< *nx; j++)
00372                 fscanf(fp,"%hd",&sarr[j][i]);
00373         }
00374         *data = (void **) sarr;
00375     }
00376     else if(datatype == RPINTDTYPE)
00377     {
00378        iarr = (int **) matalloc(*nx, *ny, datatype);
00379         
00380         for(i=0; i< *ny; i++)
00381         {
00382             for(j=0; j< *nx; j++)
00383                 fscanf(fp,"%d",&iarr[j][i]);
00384         }
00385         *data = (void **) iarr;
00386     }
00387     else if(datatype == RPFLTDTYPE)
00388     {
00389        farr = (float **) matalloc(*nx, *ny, datatype);
00390 
00391         /* read in the ARC-Info file */
00392         for(i=0; i< *ny; i++)
00393         {
00394             for(j=0; j< *nx; j++)
00395                         {
00396 
00397                 fscanf(fp,"%f",&farr[j][i]);
00398                         }
00399         }
00400         *data = (void **) farr;   
00401     }
00402     else
00403     {
00404         printf("\nERROR: unknown datatype (%s).\n\n",datatype);
00405     }
00406     fclose(fp);
00407     return(0);
00408 }
00409 
00410 int gridwrite(char *file, void **data, int datatype, int nx, int ny, float dx, 
00411  float dy, double bndbox[4], double csize, float nodata, int filetype)
00412 {
00413 FILE *fp;
00414 
00415     int i, j;
00416     char fline[MAXLN];
00417     float **farr;
00418     int **iarr;
00419     short **sarr;
00420     double adjbndbox[4],utme,utmn;
00421     int channel1,type;
00422     CELLTYPE *rowbuf;
00423 
00424 /*  File types are
00425     0=ASCII   
00426     1= ARCVIEW grid via the ESRI Application Programmers Interface  */    
00427   if(filetype == 0)   /*  ASCII FILE  */
00428   {
00429     /* open ARC-Info file */
00430     fp = fopen(file,"w");
00431     if(fp == NULL)
00432     {
00433         printf("\nERROR: Cannot open output file (%s).\n\n",file);
00434         return(4);
00435     }
00436     
00437    
00438     /* write ARC-Info header */
00439     fprintf(fp,"ncols         %d\n",nx);
00440     fprintf(fp,"nrows         %d\n",ny);
00441      utme=bndbox[0]+dx*0.5;
00442      utmn=bndbox[1]+dy*0.5;
00443     fprintf(fp,"xllcenter     %f\n",utme);
00444     fprintf(fp,"yllcenter     %f\n",utmn);
00445     fprintf(fp,"cellsize      %f\n",csize);
00446     fprintf(fp,"nodata_value  %g\n",nodata);
00447     
00448     /* write raster data to ARC/INFO file */
00449     /* convert depending on datatype */
00450     if(datatype == RPSHRDTYPE)
00451     {   
00452         sarr = (short **) data;       
00453         for(i=0; i< ny; i++)
00454         {
00455             for(j=0; j< nx; j++)
00456             {
00457                 fprintf(fp,"%hd ",sarr[j][i]);
00458                 if((j+1) % LINELEN == 0)fprintf(fp,"\n");
00459             }
00460             fprintf(fp,"\n");
00461         }
00462     }
00463     else if(datatype == RPINTDTYPE)
00464     {
00465         iarr = (int **) data;
00466         for(i=0; i< ny; i++)
00467         {
00468             for(j=0; j< nx; j++)
00469             {
00470                 fprintf(fp,"%d ",iarr[j][i]);
00471                 if((j+1) % LINELEN == 0)fprintf(fp,"\n");
00472             }
00473             fprintf(fp,"\n");
00474         }
00475     }
00476     else if(datatype == RPFLTDTYPE)
00477     {
00478         farr = (float **) data;
00479         for(i=0; i< ny; i++)
00480         {
00481             for(j=0; j< nx; j++)
00482             {
00483                 fprintf(fp,"%g ",farr[j][i]);
00484                 if((j+1) % LINELEN == 0)fprintf(fp,"\n");
00485             }
00486             fprintf(fp,"\n");
00487         }   
00488     }
00489     else
00490     {
00491         printf("\nERROR: unknown datatype (%s).\n\n",datatype);
00492     }
00493     fclose(fp);
00494   }
00495   else
00496   {
00497 /*  ESRI grid file  */
00498      GridIOSetup();
00499          AccessWindowClear();  /*  Forget about any window it used to have  */
00500      if (CellLyrExists(file))
00501      {
00502 /*  Save old file as a backup and use new file name  */
00503         sprintf(fline,"%s%s",file,"_b");
00504         if (CellLyrExists(fline))GridDelete(fline);
00505         GridRename(file,fline);
00506         printf("Output grid %s exists and will be overwritten.\n",file);
00507         printf("The old grid is preserved as %s\n",fline);
00508         GridDelete(file);
00509      } 
00510      if(datatype == RPSHRDTYPE || datatype == RPINTDTYPE) 
00511      {
00512        type=CELLINT;
00513      }
00514      else type= CELLFLOAT;
00515 
00516      if((channel1 = CellLayerCreate(file,WRITEONLY,ROWIO,type,csize,bndbox)) < 0)
00517      {
00518         printf ("Could not cread output grid %s\n",file);
00519         CellLyrClose(channel1);
00520         GridIOExit();
00521         return(5);
00522       }
00523      if(AccessWindowSet(bndbox, csize, adjbndbox) < 0)
00524      {
00525         printf ("Could not set Window\n");
00526         CellLyrClose(channel1);
00527         CellLyrDelete (file);
00528         GridIOExit();
00529         return(5);
00530      }
00531 /*  Allocate row buffer  */
00532     if((rowbuf = (CELLTYPE *)CAllocate1(nx,sizeof(CELLTYPE))) == NULL)
00533     {
00534         printf("Could not allocate buffer memory\n");
00535         CellLyrClose(channel1);
00536         CellLyrDelete (file);
00537         GridIOExit();
00538         return(5);
00539      }
00540      if(type == CELLINT)
00541      {
00542           register int *buf = (int *)rowbuf;
00543           if(datatype == RPSHRDTYPE)
00544           {
00545              sarr = (short **)data;
00546             for(i=0; i < ny; i++)
00547             {
00548                    for(j=0; j < nx; j++)
00549                    {
00550                       buf[j] = (int) sarr[j][i];
00551                       if(buf[j] == (int) nodata)buf[j]=MISSINGINT;
00552                    }
00553                    PutWindowRow (channel1, i, rowbuf);
00554             }
00555           }
00556           else if(datatype == RPINTDTYPE)
00557           {
00558              iarr = (int **)data;
00559              for(i=0; i< ny; i++)
00560              {
00561                    for(j=0; j < nx; j++)
00562                    {
00563                       buf[j] = (int) iarr[j][i];
00564                       if(buf[j] == (int) nodata)buf[j]=MISSINGINT;
00565                    }
00566                    PutWindowRow (channel1, i, rowbuf);
00567              }
00568           }
00569        }
00570        else   /*  Here type is float   */
00571        {
00572           register float *buf = (float *)rowbuf;
00573           float floatNull;
00574 
00575           GetMissingFloat(&floatNull);
00576           farr = (float **)data;
00577           for(i=0; i < ny; i++)
00578           {
00579                    for(j=0; j < nx; j++)
00580                    {
00581                       buf[j] = farr[j][i];
00582                       if(buf[j] == nodata)buf[j]=floatNull;
00583                    }
00584              PutWindowRow (channel1, i, rowbuf);
00585           }
00586        }
00587        CFree1 ((char *)rowbuf);
00588        CellLyrClose(channel1);
00589        GridIOExit();
00590    }
00591    return(0);
00592 }
00593 
00594 void eol(FILE *fp)
00595 {
00596     char ch;
00597     
00598     while(1)
00599     {
00600       if((ch = getc(fp)) == '\n') return;
00601       
00602       if(ch == EOF) { fseek(fp, -1L, SEEK_CUR); return; }
00603     }
00604 }
00605 
00606 
00607 

Generated on Sun Aug 5 17:34:00 2007 for PIHMgis by  doxygen 1.5.2