/** @brief Reads an ArcGrid ASCII file @author Richard Barnes @param[in] &filename Name of ArcGrid ASCII file to read @param[out] &elevations DEM object containing contents of file @returns 0 upon success */ int load_ascii_data(const char filename[], float_2d &elevations){ FILE *fin; long long file_size; int rows,columns; Timer load_time; ProgressBar progress; load_time.start(); errno=0; diagnostic_arg("Opening input ASCII-DEM file \"%s\"...",filename); fin=fopen(filename,"r"); if(fin==NULL){ diagnostic_arg("failed with error %d: \"%s\"!\n",errno,strerror(errno)); exit(-1); } diagnostic("succeeded.\n"); diagnostic("Calculating file size..."); if(fseek(fin,-1,SEEK_END)!=0){ diagnostic("failed! (Couldn't jump to end of file.)\n"); exit(-1); } if((file_size=ftell(fin))==-1){ diagnostic("failed! (Couldn't determine file size.)\n"); exit(-1); } if(fseek(fin,0,SEEK_SET)!=0){ diagnostic("failed! (Couldn't jump back to beginning of file.)\n"); exit(-1); } diagnostic("succeeded.\n"); // posix_fadvise(fileno(fin),0,0,POSIX_FADV_SEQUENTIAL); diagnostic("Reading DEM header..."); if(fscanf(fin,"ncols %d nrows %d xllcorner %lf yllcorner %lf cellsize %lf NODATA_value %f",&columns, &rows, &elevations.xllcorner, &elevations.yllcorner, &elevations.cellsize, &elevations.no_data)!=6){ diagnostic("failed!\n"); exit(-1); } diagnostic("succeeded.\n"); diagnostic_arg("The loaded DEM will require approximately %ldMB of RAM.\n",columns*rows*((long)sizeof(float))/1024/1024); diagnostic("Resizing elevation matrix..."); //TODO: Consider abstracting this block elevations.resize(columns,rows); diagnostic("succeeded.\n"); diagnostic("%%Reading elevation matrix...\n"); progress.start(file_size); float temp; elevations.data_cells=0; for(int y=0;y<rows;y++){ progress.update(ftell(fin)); //Todo: Check to see if ftell fails here? for(int x=0;x<columns;x++){ if (fscanf(fin,"%f", &temp)!=1){ diagnostic("\n\tFailed! (Couldn't read or convert a value!)\n"); exit(-1); } elevations(x,y)=temp; if(temp!=elevations.no_data) elevations.data_cells++; } } diagnostic_arg(SUCCEEDED_IN,progress.stop()); fclose(fin); diagnostic_arg( "Read %ld cells, of which %ld contained data (%ld%%).\n", elevations.width()*elevations.height(), elevations.data_cells, elevations.data_cells*100/elevations.width()/elevations.height() ); load_time.stop(); diagnostic_arg("Read time was: %lfs\n", load_time.accumulated()); return 0; }
void dinf_upslope_area_interval(const float_2d &flowdirs, grid_engine< boost::numeric::interval<T> > &area){ char_2d dependency; std::queue<grid_cell> sources; ProgressBar progress; diagnostic_arg("The sources queue will require at most approximately %ldMB of RAM.\n",flowdirs.width()*flowdirs.height()*((long)sizeof(grid_cell))/1024/1024); diagnostic("Setting up the dependency matrix..."); dependency.copyprops(flowdirs); dependency.init(0); diagnostic("succeeded.\n"); diagnostic("Setting up the area matrix..."); area.copyprops(flowdirs); area.init((float)0); area.no_data=dinf_NO_DATA; diagnostic("succeeded.\n"); bool has_cells_without_flow_directions=false; diagnostic("%%Calculating dependency matrix & setting no_data cells...\n"); progress.start( flowdirs.width()*flowdirs.height() ); #pragma omp parallel for reduction(|:has_cells_without_flow_directions) for(int x=0;x<flowdirs.width();x++){ progress.update( x*flowdirs.height() ); for(int y=0;y<flowdirs.height();y++){ if(flowdirs(x,y)==flowdirs.no_data){ area(x,y)=area.no_data; dependency(x,y)=9; //Note: This is an unnecessary safety precaution continue; } if(flowdirs(x,y)==NO_FLOW){ has_cells_without_flow_directions=true; continue; } int n_high,n_low; int nhx,nhy,nlx,nly; where_do_i_flow(flowdirs(x,y),n_high,n_low); nhx=x+dinf_dx[n_high],nhy=y+dinf_dy[n_high]; if(n_low!=-1){ nlx=x+dinf_dx[n_low]; nly=y+dinf_dy[n_low]; } if( n_low!=-1 && flowdirs.in_grid(nlx,nly) && flowdirs(nlx,nly)!=flowdirs.no_data ) dependency(nlx,nly)++; if( flowdirs.in_grid(nhx,nhy) && flowdirs(nhx,nhy)!=flowdirs.no_data ) dependency(nhx,nhy)++; } } diagnostic_arg(SUCCEEDED_IN,progress.stop()); if(has_cells_without_flow_directions) diagnostic("\033[91mNot all cells had defined flow directions! This implies that there will be digital dams!\033[39m\n"); diagnostic("%%Locating source cells...\n"); progress.start( flowdirs.width()*flowdirs.height() ); for(int x=0;x<flowdirs.width();x++){ progress.update( x*flowdirs.height() ); for(int y=0;y<flowdirs.height();y++) if(flowdirs(x,y)==flowdirs.no_data) continue; else if(flowdirs(x,y)==NO_FLOW) continue; else if(dependency(x,y)==0) sources.push(grid_cell(x,y)); } diagnostic_arg(SUCCEEDED_IN,progress.stop()); diagnostic("%%Calculating up-slope areas...\n"); progress.start( flowdirs.data_cells ); long int ccount=0; while(sources.size()>0){ grid_cell c=sources.front(); sources.pop(); ccount++; progress.update(ccount); if(flowdirs(c.x,c.y)==flowdirs.no_data) //TODO: This line shouldn't be necessary since NoData's do not get added below continue; area(c.x,c.y)+=1; if(flowdirs(c.x,c.y)==NO_FLOW) continue; int n_high,n_low,nhx,nhy,nlx,nly; where_do_i_flow(flowdirs(c.x,c.y),n_high,n_low); nhx=c.x+dinf_dx[n_high],nhy=c.y+dinf_dy[n_high]; float phigh,plow; area_proportion(flowdirs(c.x,c.y), n_high, n_low, phigh, plow); if(flowdirs.in_grid(nhx,nhy) && flowdirs(nhx,nhy)!=flowdirs.no_data) area(nhx,nhy)+=area(c.x,c.y)*(T)phigh; if(n_low!=-1){ nlx=c.x+dinf_dx[n_low]; nly=c.y+dinf_dy[n_low]; if(flowdirs.in_grid(nlx,nly) && flowdirs(nlx,nly)!=flowdirs.no_data){ area(nlx,nly)+=area(c.x,c.y)*(T)plow; if((--dependency(nlx,nly))==0) sources.push(grid_cell(nlx,nly)); } } if( flowdirs.in_grid(nhx,nhy) && flowdirs(nhx,nhy)!=flowdirs.no_data && (--dependency(nhx,nhy))==0) sources.push(grid_cell(nhx,nhy)); } diagnostic_arg(SUCCEEDED_IN,progress.stop()); }