static inline double Terrain_Slope_RiseRun(const Array2D<T> &elevations, const int x, const int y, const float zscale){ const auto tsv = TerrainSetup(elevations,x,y,zscale); //See p. 18 of Horn (1981) double dzdx = ( (tsv.c+2*tsv.f+tsv.i) - (tsv.a+2*tsv.d+tsv.g) ) / 8 / elevations.getCellLengthX(); double dzdy = ( (tsv.g+2*tsv.h+tsv.i) - (tsv.a+2*tsv.b+tsv.c) ) / 8 / elevations.getCellLengthY(); //The above fits are surface to a 3x3 neighbour hood. This returns the slope //along the direction of maximum gradient. return sqrt(dzdx*dzdx+dzdy*dzdy); }
static inline double Terrain_Aspect(const Array2D<T> &elevations, const int x, const int y, const float zscale){ const auto tsv = TerrainSetup(elevations,x,y,zscale); //See p. 18 of Horn (1981) double dzdx = ( (tsv.c+2*tsv.f+tsv.i) - (tsv.a+2*tsv.d+tsv.g) ) / 8 / elevations.getCellLengthX(); double dzdy = ( (tsv.g+2*tsv.h+tsv.i) - (tsv.a+2*tsv.b+tsv.c) ) / 8 / elevations.getCellLengthY(); double the_aspect = 180.0/M_PI*atan2(dzdy,-dzdx); if(the_aspect<0) return 90-the_aspect; else if(the_aspect>90.0) return 360.0-the_aspect+90.0; else return 90.0-the_aspect; }
static inline void TerrainProcessor(F func, const Array2D<T> &elevations, const float zscale, Array2D<float> &output){ if(elevations.getCellLengthX()!=elevations.getCellLengthY()) RDLOG_WARN<<"Cell X and Y dimensions are not equal!"; output.resize(elevations); ProgressBar progress; progress.start(elevations.size()); #pragma omp parallel for for(int y=0;y<elevations.height();y++){ progress.update(y*elevations.width()); for(int x=0;x<elevations.width();x++) if(elevations.isNoData(x,y)) output(x,y) = output.noData(); else output(x,y) = func(elevations,x,y,zscale); } RDLOG_TIME_USE<<"Wall-time = "<<progress.stop(); }