void d8_flow_directions( const array2d<T> &elevations, array2d<U> &flowdirs ){ ProgressBar progress; diagnostic("Setting up the flow directions matrix..."); flowdirs.copyprops(elevations); flowdirs.init(NO_FLOW); flowdirs.no_data=d8_NO_DATA; diagnostic("succeeded.\n"); diagnostic("%%Calculating D8 flow directions...\n"); progress.start( elevations.width()*elevations.height() ); #pragma omp parallel for for(int x=0;x<elevations.width();x++){ progress.update( x*elevations.height() ); for(int y=0;y<elevations.height();y++) if(elevations(x,y)==elevations.no_data) flowdirs(x,y)=flowdirs.no_data; else flowdirs(x,y)=d8_FlowDir(elevations,x,y); } diagnostic_arg(SUCCEEDED_IN,progress.stop()); }
/** @brief Writes an arrow representation of a 2D D8 flow direction array @author Richard Barnes @param[in] &filename Name of file to write to @param[in] &elevations 2D array of D8 flow directions @returns 0 upon success */ int write_arrows(const char filename[], const char_2d &flowdirs){ std::locale::global(std::locale("")); std::wofstream fout; Timer write_time; ProgressBar progress; write_time.start(); diagnostic_arg("Opening arrow output file \"%s\"...",filename); fout.open(filename); if(!fout.is_open()){ diagnostic("failed!\n"); exit(-1); //TODO: Need to make this safer! Don't just close after all that work! } diagnostic("succeeded.\n"); diagnostic("%%Writing arrows...\n"); progress.start( flowdirs.width()*flowdirs.height() ); for(int y=0;y<flowdirs.height();++y){ progress.update( y*flowdirs.width() ); for(int x=0;x<flowdirs.width();++x){ if(flowdirs(x,y)==flowdirs.no_data) //TODO: Crude way of detecting chars and bools fout<<L" "; else if (flowdirs(x,y)==NO_FLOW) fout<<fd[0]; else fout<<fd[flowdirs(x,y)]; fout<<L" "; } fout<<std::endl; } diagnostic_arg(SUCCEEDED_IN,progress.stop()); fout.close(); write_time.stop(); diagnostic_arg("Write time was: %lf\n", write_time.accumulated()); return 0; }
void d8_flats_alter_dem( const int_2d &flat_mask, const int_2d &labels, array2d<U> &elevations ){ ProgressBar progress; diagnostic("%%Calculating D8 flow directions using flat mask...\n"); progress.start( flat_mask.width()*flat_mask.height() ); #pragma omp parallel for for(int x=1;x<flat_mask.width()-1;x++){ progress.update( x*flat_mask.height() ); for(int y=1;y<flat_mask.height()-1;y++){ if(labels(x,y)==0) continue; bool higher[9]; for(int n=1;n<=8;++n) higher[n]=elevations(x,y)>elevations(x+dx[n],y+dy[n]); //TODO: nextafterf is the floating point version; should use an //overloaded version instead to be able to handle both double and float for(int i=0;i<flat_mask(x,y);++i) elevations(x,y)=nextafterf(elevations(x,y),std::numeric_limits<U>::infinity()); for(int n=1;n<=8;++n){ int nx=x+dx[n]; int ny=y+dy[n]; if(labels(nx,ny)==labels(x,y)) continue; if(elevations(x,y)<elevations(nx,ny)) continue; if(!higher[n]) diagnostic_arg("Attempting to raise (%d,%d) resulted in an invalid alteration of the DEM!\n",x,y); } } } diagnostic_arg(SUCCEEDED_IN,progress.stop()); }
void d8_flow_flats( const int_2d &flat_mask, const int_2d &groups, array2d<U> &flowdirs ){ ProgressBar progress; diagnostic("%%Calculating D8 flow directions using flat mask...\n"); progress.start( flat_mask.width()*flat_mask.height() ); #pragma omp parallel for for(int x=1;x<flat_mask.width()-1;x++){ progress.update( x*flat_mask.height() ); for(int y=1;y<flat_mask.height()-1;y++) if(flat_mask(x,y)==flat_mask.no_data) continue; else if (flowdirs(x,y)==NO_FLOW) flowdirs(x,y)=d8_masked_FlowDir(flat_mask,groups,x,y); } diagnostic_arg(SUCCEEDED_IN,progress.stop()); }
/** @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 d8_upslope_cells( int x0, int y0, int x1, int y1, const array2d<T> &flowdirs,array2d<U> &upslope_cells ){ diagnostic("Setting up the upslope_cells matrix..."); upslope_cells.copyprops(flowdirs); upslope_cells.init(d8_NO_DATA); upslope_cells.no_data=d8_NO_DATA; diagnostic("succeeded.\n"); ProgressBar progress; std::queue<grid_cell> expansion; if(x0>x1){ std::swap(x0,x1); std::swap(y0,y1); } //Modified Bresenham Line-Drawing Algorithm int deltax=x1-x0; int deltay=y1-y0; float error=0; float deltaerr=(float)deltay/(float)deltax; if (deltaerr<0) deltaerr=-deltaerr; diagnostic_arg("Line slope is %f\n",deltaerr); int y=y0; for(int x=x0;x<=x1;x++){ expansion.push(grid_cell(x,y)); upslope_cells(x,y)=2; error+=deltaerr; if (error>=0.5) { expansion.push(grid_cell(x+1,y)); upslope_cells(x+1,y)=2; y+=sgn(deltay); error-=1; } } progress.start(flowdirs.data_cells); long int ccount=0; while(expansion.size()>0){ grid_cell c=expansion.front(); expansion.pop(); progress.update(ccount++); for(int n=1;n<=8;n++) if(!flowdirs.in_grid(c.x+dx[n],c.y+dy[n])) continue; else if(flowdirs(c.x+dx[n],c.y+dy[n])==NO_FLOW) continue; else if(flowdirs(c.x+dx[n],c.y+dy[n])==flowdirs.no_data) continue; else if(upslope_cells(c.x+dx[n],c.y+dy[n])==upslope_cells.no_data && n==inverse_flow[flowdirs(c.x+dx[n],c.y+dy[n])]){ expansion.push(grid_cell(c.x+dx[n],c.y+dy[n])); upslope_cells(c.x+dx[n],c.y+dy[n])=1; } } diagnostic_arg(SUCCEEDED_IN,progress.stop()); diagnostic_arg("Found %ld up-slope cells.\n",ccount); }
void d8_upslope_area(const array2d<T> &flowdirs, array2d<U> &area){ char_2d dependency; std::queue<grid_cell> sources; ProgressBar progress; diagnostic("\n###D8 Upslope Area\n"); 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("Resizing dependency matrix..."); dependency.copyprops(flowdirs); diagnostic("succeeded.\n"); diagnostic("Setting up the area matrix..."); area.copyprops(flowdirs); area.init(0); area.no_data=d8_NO_DATA; diagnostic("succeeded.\n"); diagnostic("%%Calculating dependency matrix & setting no_data cells...\n"); progress.start( flowdirs.width()*flowdirs.height() ); #pragma omp parallel for for(int x=0;x<flowdirs.width();x++){ progress.update( x*flowdirs.height() ); for(int y=0;y<flowdirs.height();y++){ dependency(x,y)=0; if(flowdirs(x,y)==flowdirs.no_data){ area(x,y)=area.no_data; continue; } for(int n=1;n<=8;n++) if(!flowdirs.in_grid(x+dx[n],y+dy[n])) continue; else if(flowdirs(x+dx[n],y+dy[n])==NO_FLOW) continue; else if(flowdirs(x+dx[n],y+dy[n])==flowdirs.no_data) continue; else if(n==inverse_flow[(int)flowdirs(x+dx[n],y+dy[n])]) ++dependency(x,y); } } diagnostic_arg(SUCCEEDED_IN,progress.stop()); 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(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); area(c.x,c.y)+=1; if(flowdirs(c.x,c.y)==NO_FLOW) continue; int nx=c.x+dx[(int)flowdirs(c.x,c.y)]; int ny=c.y+dy[(int)flowdirs(c.x,c.y)]; if(flowdirs.in_grid(nx,ny) && area(nx,ny)!=area.no_data){ area(nx,ny)+=area(c.x,c.y); if((--dependency(nx,ny))==0) sources.push(grid_cell(nx,ny)); } } diagnostic_arg(SUCCEEDED_IN,progress.stop()); }
int load_ascii_data(std::string filename, array2d<T> &elevations){ std::ifstream fin; size_t file_size; int rows,columns; Timer load_time; ProgressBar progress; load_time.start(); diagnostic_arg("Opening input ASCII-DEM file \"%s\"...",filename.c_str()); fin.open(filename.c_str()); if(!fin.good()){ diagnostic("failed!\n"); exit(-1); } diagnostic("succeeded.\n"); diagnostic("Calculating file size..."); fin.seekg(0, fin.end); file_size=fin.tellg(); fin.seekg(0, fin.beg); diagnostic("succeeded.\n"); // posix_fadvise(fileno(fin),0,0,POSIX_FADV_SEQUENTIAL); diagnostic("Reading DEM header..."); fin>>must_be("ncols") >>columns; fin>>must_be("nrows") >>rows; fin>>must_be("xllcorner") >>elevations.xllcorner; fin>>must_be("yllcorner") >>elevations.yllcorner; fin>>must_be("cellsize") >>elevations.cellsize; try { fin>>must_be("NODATA_value") >>elevations.no_data; } catch (std::string e) { std::cerr<<e<<std::endl; std::cerr<<"Continuing without a NoData value!"<<std::endl; } 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); elevations.data_cells=0; for(int y=0;y<rows;y++){ progress.update(fin.tellg()); //Todo: Check to see if ftell fails here? for(int x=0;x<columns;x++){ fin>>elevations(x,y); if(elevations(x,y)!=elevations.no_data) elevations.data_cells++; } } diagnostic_arg(SUCCEEDED_IN,progress.stop()); fin.close(); 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; }
int read_floating_data( const std::string basename, array2d<T> &grid ){ Timer io_time; ProgressBar progress; std::string fn_header(basename), fn_data(basename); //TODO: The section below should work, but is something of an abomination if(typeid(T)==typeid(float)){ fn_header+=".hdr"; fn_data+=".flt"; } else if (typeid(T)==typeid(double)){ fn_header+=".hdr"; fn_data+=".dflt"; } else { std::cerr<<"Cannot read floating type data into this format!"<<std::endl; exit(-1); } int columns, rows; std::string byteorder; io_time.start(); { std::ifstream fin; diagnostic_arg("Opening floating-point header file \"%s\" for reading...",fn_header.c_str()); fin.open(fn_header.c_str()); if(fin==NULL){ diagnostic("failed!\n"); exit(-1); } diagnostic("succeeded.\n"); diagnostic("Reading DEM header..."); fin>>must_be("ncols") >>columns; fin>>must_be("nrows") >>rows; fin>>must_be("xllcorner") >>grid.xllcorner; fin>>must_be("yllcorner") >>grid.yllcorner; fin>>must_be("cellsize") >>grid.cellsize; fin>>must_be("NODATA_value") >>grid.no_data; fin>>must_be("BYTEORDER") >>byteorder; diagnostic("succeeded.\n"); fin.close(); } diagnostic_arg("The loaded DEM will require approximately %ldMB of RAM.\n",columns*rows*((long)sizeof(float))/1024/1024); diagnostic("Resizing grid..."); //TODO: Consider abstracting this block grid.resize(columns,rows); diagnostic("succeeded.\n"); diagnostic_arg("Opening floating-point data file \"%s\" for reading...",fn_data.c_str()); { std::ifstream fin(fn_data.c_str(), std::ios::binary | std::ios::in); if(!fin.is_open()){ diagnostic("failed!\n"); exit(-1); //TODO: Need to make this safer! Don't just close after all that work! } diagnostic("succeeded.\n"); diagnostic("%%Reading data...\n"); progress.start(columns*rows); grid.data_cells=0; for(int y=0;y<rows;++y){ progress.update(y*columns); //Todo: Check to see if ftell fails here? for(int x=0;x<columns;++x){ fin.read(reinterpret_cast<char*>(&grid(x,y)), std::streamsize(sizeof(T))); if(grid(x,y)!=grid.no_data) grid.data_cells++; } } io_time.stop(); diagnostic_arg(SUCCEEDED_IN,progress.stop()); } diagnostic_arg( "Read %ld cells, of which %ld contained data (%ld%%).\n", grid.width()*grid.height(), grid.data_cells, grid.data_cells*100/grid.width()/grid.height() ); diagnostic_arg("Read time was: %lf\n", io_time.accumulated()); return 0; }
int write_floating_data( const std::string basename, const array2d<T> &output_grid ){ Timer write_time; ProgressBar progress; std::string fn_header(basename), fn_data(basename); //TODO: The section below should work, but is something of an abomination if(typeid(T)==typeid(float)){ fn_header+=".hdr"; fn_data+=".flt"; } else if (typeid(T)==typeid(double)){ fn_header+=".hdr"; fn_data+=".dflt"; } else { std::cerr<<"Cannot write floating type data into this format!"<<std::endl; exit(-1); } write_time.start(); { diagnostic_arg("Opening floating-point header file \"%s\" for writing...",fn_header.c_str()); std::ofstream fout; fout.open(fn_header.c_str()); if(!fout.is_open()){ diagnostic("failed!\n"); exit(-1); //TODO: Need to make this safer! Don't just close after all that work! } diagnostic("succeeded.\n"); diagnostic("Writing floating-point header file..."); fout<<"ncols\t\t"<<output_grid.width()<<std::endl; fout<<"nrows\t\t"<<output_grid.height()<<std::endl; fout<<"xllcorner\t"<<std::fixed<<std::setprecision(10)<<output_grid.xllcorner<<std::endl; fout<<"yllcorner\t"<<std::fixed<<std::setprecision(10)<<output_grid.yllcorner<<std::endl; fout<<"cellsize\t"<<std::fixed<<std::setprecision(10)<<output_grid.cellsize<<std::endl; fout<<"NODATA_value\t"<<std::fixed<<std::setprecision(10)<<output_grid.no_data<<std::endl; fout<<"BYTEORDER\tLSBFIRST"<<std::endl; //TODO fout.close(); diagnostic("succeeded.\n"); } diagnostic_arg("Opening floating-point data file \"%s\" for writing...",fn_data.c_str()); { std::ofstream fout(fn_data.c_str(), std::ios::binary | std::ios::out); if(!fout.is_open()){ diagnostic("failed!\n"); exit(-1); //TODO: Need to make this safer! Don't just close after all that work! } diagnostic("succeeded.\n"); diagnostic("%%Writing floating-point data file...\n"); progress.start( output_grid.width()*output_grid.height() ); for(int y=0;y<output_grid.height();++y){ progress.update( y*output_grid.width() ); for(int x=0;x<output_grid.width();++x) fout.write(reinterpret_cast<const char*>(&output_grid(x,y)), std::streamsize(sizeof(T))); } fout.close(); write_time.stop(); diagnostic_arg(SUCCEEDED_IN,progress.stop()); } diagnostic_arg("Write time was: %lf\n", write_time.accumulated()); return 0; }
int output_ascii_data( const std::string filename, const array2d<T> &output_grid, int precision=8 ){ std::ofstream fout; std::string outputsep=" "; int output_type=OUTPUT_DEM; Timer write_time; ProgressBar progress; write_time.start(); diagnostic_arg("Opening ASCII output file \"%s\"...",filename.c_str()); fout.open(filename.c_str()); if(!fout.is_open()){ diagnostic("failed!\n"); exit(-1); //TODO: Need to make this safer! Don't just close after all that work! } diagnostic("succeeded.\n"); //OmniGlyph output if(filename.substr(filename.length()-4)==".omg"){ outputsep="|"; output_type=OUTPUT_OMG; diagnostic("Writing OmniGlyph file header..."); fout<<"Contents: Pixel array"<<std::endl; fout<<std::endl; fout<<"Width: "<<output_grid.width()<<std::endl; fout<<"Height: "<<output_grid.height()<<std::endl; fout<<std::endl; fout<<"Spectral bands: 1"<<std::endl; fout<<"Bits per band: 32"<<std::endl; fout<<"Range of values: "<<output_grid.min()<<","<<output_grid.max()<<std::endl; fout<<"Actual range: "<<output_grid.no_data<<","<<output_grid.max()<<std::endl; //TODO: Assumes no_data is a small negative value fout<<"Gamma exponent: 0."<<std::endl; fout<<"Resolution: 100 pixels per inch"<<std::endl; fout<<std::endl; fout<<"|"<<std::endl; } else { diagnostic("Writing ArcGrid ASCII file header..."); fout<<"ncols\t\t"<<output_grid.width()<<std::endl; fout<<"nrows\t\t"<<output_grid.height()<<std::endl; fout<<"xllcorner\t"<<std::fixed<<std::setprecision(precision)<<output_grid.xllcorner<<std::endl; fout<<"yllcorner\t"<<std::fixed<<std::setprecision(precision)<<output_grid.yllcorner<<std::endl; fout<<"cellsize\t"<<std::fixed<<std::setprecision(precision)<<output_grid.cellsize<<std::endl; fout<<"NODATA_value\t"<<std::fixed<<std::setprecision(precision); if(sizeof(T)==1) //TODO: Crude way of detecting chars and bools fout<<(int)output_grid.no_data<<std::endl; else fout<<output_grid.no_data<<std::endl; } diagnostic("succeeded.\n"); diagnostic("%%Writing ArcGrid ASCII file data...\n"); progress.start( output_grid.width()*output_grid.height() ); fout.precision(precision); fout.setf(std::ios::fixed); for(int y=0;y<output_grid.height();y++){ progress.update( y*output_grid.width() ); if(output_type==OUTPUT_OMG) fout<<"|"; for(int x=0;x<output_grid.width();x++) if(sizeof(T)==1) //TODO: Crude way of detecting chars and bools fout<<(int)output_grid(x,y)<<outputsep; else fout<<output_grid(x,y)<<outputsep; fout<<std::endl; } diagnostic_arg(SUCCEEDED_IN,progress.stop()); fout.close(); write_time.stop(); diagnostic_arg("Write time was: %lf\n", write_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()); }