int vdn(int n) { int ip,k,imin; float ed; nis=n; do { n=nis; nis=0; for(ip=1; ip <=n; ip++)dn[ip]=0; for(k=1; k<=7; k=k+2) for(ip=1; ip<=n; ip++) { ed=elev[js[ip]][is[ip]]-elev[js[ip]+d2[k]][is[ip]+d1[k]]; if(ed >= 0. && dir[js[ip]+d2[k]][is[ip]+d1[k]] != 0 && dn[ip] == 0) dn[ip]=k; } for(k=2; k<=8; k=k+2) for(ip=1; ip<=n; ip++) { ed=elev[js[ip]][is[ip]]-elev[js[ip]+d2[k]][is[ip]+d1[k]]; if(ed >= 0. && dir[js[ip]+d2[k]][is[ip]+d1[k]] != 0 && dn[ip] == 0) dn[ip]=k; } imin=1; /* location of point on stack with lowest elevation */ for(ip=1; ip <= n; ip++) { if(dn[ip] > 0)dir[js[ip]][is[ip]]=dn[ip]; else { nis++; is[nis]=is[ip]; js[nis]=js[ip]; if(elev[js[nis]][is[nis]] < elev[js[imin]][is[imin]])imin=nis; } } SetWorkingStatus(); }while(nis < n); return(imin); }
int setdf(float mval) { int i,j,k,n,nflat,ni,ip,imin,err,jn,in,np1,nt; float fact[9],per=1.; /* Initialize boundaries */ for(i=i1; i< n1; i++) { dir[i][i2]= -1; dir[i][n2-1]= -1; } for(i=i2; i< n2; i++) { dir[i1][i]= -1; dir[n1-1][i]= -1; } /* initialize internal pointers */ for(i=i2+1; i< n2-1; i++)for(j=i1+1; j<n1-1; j++) { if(elev[j][i] <= mval)dir[j][i]= -1; else dir[j][i] = 0; } /* Direction factors */ for(k=1; k<= 8; k++) fact[k]=(float)(1./sqrt(d1[k]*dy*d1[k]*dy+d2[k]*d2[k]*dx*dx)); /* printf("Problem Pixels \n"); */ /* printf(" Flats Unresolved\n"); */ /* Set positive slope directions - store unresolved on stack */ /*ttt n=1; Avoid iterating - work with stack only while(n >= 1) { */ nis=0; for(i=i2+1; i< n2-1; i++)for(j=i1+1; j<n1-1; j++) { if(elev[j][i] > mval)set(i,j,fact,mval); /* Put unresolved pixels on stack */ if(dir[j][i] == 0) { err=addstack(i,j); } } nflat=nis; /* routine to drain flats to neighbors */ SetWorkingStatus(); imin=vdn(nflat); n=nis; printf("Number of pits to resolve: %d\n",n); np1=n; nt=np1*(1-per/100); /* initialize apool to zero */ for(i=i2; i< n2; i++)for(j=i1; j<n1; j++) apool[j][i]=0; /* store unresolved stack location in apool for easy deletion for(k=1; k<=nis; k++) apool[js[k]][is[k]]= - k; */ /* pooln=0; */ while(nis > 0) /* While AA */ { /* fp=fopen("temp.dat","w"); for(ip=1; ip <= nis; ip++) { i=is[ip]; j=js[ip]; fprintf(fp,"%d %d %f\n",i,j,elev[j][i]); } fclose(fp); */ i=is[imin]; j=js[imin]; /* if(i == 12 && j == 27) { printf("Here"); } */ /* pooln=pooln+1; */ pooln=1; npool=0; nf = 0; /* reset flag to that new min elev is found */ pool(i,j); /* Recursive call on unresolved point with lowest elevation */ /* Find the pour point of the pool */ /* err = gridwrite("pool.asc",(void **)apool,RPSHRDTYPE,nx,ny,dx,dy, bndbox,csize,-9999,0); */ for(ip=1; ip<=npool; ip++) { i=ipool[ip]; j=jpool[ip]; for(k=1; k <=8; k++) { jn=j+d2[k]; in=i+d1[k]; if(apool[jn][in] != pooln) /* neighbor not in pool */ { et=max2(elev[j][i],elev[jn][in]); if(nf == 0) /* this is the first edge found */ { emin=et; nf=1; /* ipour=i; jpour=j; */ } else { /* emin=min2(emin,et); */ if(emin > et) { emin = et; /* ipour=i; jpour=j; */ } } } } } /* Fill the pool */ for(k=1; k<=npool; k++) { i=ipool[k]; j=jpool[k]; if(elev[j][i] <= emin) { if(dir[j][i] > 0) /* Can be in pool, but not flat */ { dir[j][i]=0; /* Add to stack */ err=addstack(i,j); } for(ip=1; ip <=8; ip++) { jn=j+d2[ip]; in=i+d1[ip]; if(elev[jn][in] > elev[j][i] && dir[jn][in] > 0) /* Only zero direction of neighbors that are higher - because lower or equal may be a pour point in a pit that must not be disrupted */ { dir[jn][in] = 0; err=addstack(in,jn); } } elev[j][i] =emin; } apool[j][i]=0; /* Reinitialize for next time round */ } /* reset unresolved stack */ ni=0; for(ip=1; ip <= nis; ip++) { set(is[ip],js[ip],fact,mval); if(dir[js[ip]][is[ip]] == 0) /* still on stack */ { ni++; is[ni]=is[ip]; js[ni]=js[ip]; /* apool[js[ni]][is[ni]] = -ni; /* Need to resave stack locations since the stack is being shortened */ } /* else apool[js[ip]][is[ip]] = 0; /* Out of pool */ } /* fp=fopen("temp.dat","w"); for(ip=1; ip <= nis; ip++) { i=is[ip]; j=js[ip]; fprintf(fp,"%d %d %f\n",i,j,elev[j][i]); } fclose(fp); */ n=nis; imin=vdn(ni); if(nis < nt){ printf("Percentage done %f\n",per); per=per+1; nt=np1*(1-per/100); } /* Debug writes err = gridwrite("elev.asc",(void **)elev,RPFLTDTYPE,nx,ny,dx,dy, bndbox,csize,mval,0); err = gridwrite("pool.asc",(void **)apool,RPSHRDTYPE,nx,ny,dx,dy, bndbox,csize,-9999,0); */ } /* end of while AA */ return(err); }
/* Converted from FORTRAN July 05, 1997 K. Tarbet C C---SUBROUTINE TO SET VARIABLE DIRECTIONS. C DIRECTIONS MEASURED ANTICLOCKWISE FROM EAST IN RADIANS. C */ void setdf2(void ) { float FANG[9]; float dxx[3]; int i,j; float dd; /* INITIALISE ANGLES and slopes */ for (i=0; i<nx; i++) { ang[i][0]=-2; ang[i][ny-1]=-2; slope[i][0]=-1; slope[i][ny-1]=-1; } for(i=0; i<ny; i++) { ang[0][i]=-2; ang[nx-1][i]=-2; slope[0][i]=-1; slope[nx-1][i]=-1; } FANG[1]=0.; FANG[2]=(float)atan2(dy,dx); FANG[3]=(float) PI2; FANG[4]=2*FANG[3]-FANG[2]; FANG[5]=2*FANG[3]; FANG[6]=2*FANG[3]+FANG[2]; FANG[7]=3*FANG[3]; FANG[8]=4*FANG[3]-FANG[2]; /* --INITIALISE INTERNAL POINTERS (-VE POINTER INDICATES OUTSIDE DOMAIN) */ for(i=1; i<ny-1; i++) for(j=1; j<nx-1; j++) { if(dir[j][i] < 0) { ang[j][i]=-2.; slope[j][i]=-1.; /* ! -1 slope indicates no data */ } else if(dir[j][i] == 0) { ang[j][i]=-1.; /* DGT 9/2/97 since without */ slope[j][i]=0.; /* pit filling dir = 0 is possible */ /* ang = -1 designates unfilled pit, ang = -2 designates no data. */ } else ang[j][i]=0.; } /* TEST ALL INTERNAL ELEVATIONS AND SET SLOPE AND ANGLE */ dxx[1]=dx; dxx[2]=dy; dd=(float)sqrt(dx*dx+dy*dy); for(i=1; i<ny-1; i++) { SetWorkingStatus(); for(j=1; j<nx-1; j++) { if(dir[j][i]>0 ) { SET2(i,j,dxx,dd); if(ang[j][i] < -0.5) ang[j][i]=FANG[dir[j][i]]; } } } }