pihmRasterLIBS/setdir.cpp

Go to the documentation of this file.
00001 /*  C version of setdir.c. This does not fill pits, it is intended for use AFTER
00002     d8.c which fills pits.  Input is a dem file name.  Output is
00003     slope and dinf angle files.   This version implements Garbrecht flow directions
00004         for flats.
00005      
00006   David G Tarboton
00007   Utah State University   
00008      */
00009 
00010 /*
00011 This roughly follows the following pseudocode from my review of Garbrecht's paper
00012 
00013 Pseudocode to iteratively resolve flow directions
00014 
00015 Define arrays E(x), D(x), S1(x), S2(x), I(x) where x refers to grid location.
00016  where E is original elevation, D is total increment, S1 step 1 increment, 
00017  S2 step 2 increment, I a flag to indicate whether flow direction has been set.  
00018 
00019 Initialize  
00020 do for each x
00021         read in E(x)
00022         I(x) = 1
00023 enddo
00024 unresolved = 1
00025 while(unresolved > 0)
00026         unresolved = 0
00027         do for each x
00028                 if(I(x) > 0)then      /*  only apply to unresolved pixels  
00029                         calculate slope to each neighbor using E(x) 
00030                         if(max slope > 0)then
00031                                 assign flow direction to appropriate neighbor
00032                                 I(x) = 0   /*  flag it as resolved   
00033                         else
00034                                 unresolved=unresolved + 1
00035                                 I(x) = 1   /* this flags the pixel as unresolved  
00036                         endif
00037                 endif
00038         enddo
00039         if(unresolved > 0)then
00040                 for each x
00041                         D(x) = S2(x) = S2(x)= 0      /*  reset arrays for iteration  
00042                 for each x with I(x) > 0
00043                         Calculate step 1 increment towards falling terrain, S1(x) 
00044                 for each x with I(x) > 0
00045                         Calculate step 2 increment away from rising terrain, S2(x)
00046                 for each x with I(x) > 0
00047                         D(x) = S1(x) + S2(x)
00048                 for each x
00049                         E(x) = D(x)   
00050 /*  overwrite original elevations since they are no longer needed from now 
00051 on slopes are based on D(x)  
00052         endif
00053 endwhile
00054 output results
00055 end
00056 
00057   */
00058 
00059 
00060 
00061 
00062 
00063 #include "lsm.h"
00064 /* This include declares all necessary global variables  */
00065 void incfall(int n, float *elev1, short *s1,int **spos,  
00066                          int iter, int *sloc);
00067 void incrise(int n, float *elev1, short *s2,int **spos, int iter, int *sloc);
00068 
00069 void set2(int i,int j,float *fact,float *elev1, float *elev2, int iter, 
00070                   int **spos, short *s);
00071 void flatrout(int n,int *sloc, short *s,
00072                           int **spos,int iter,float *elev1,float *elev2, float *fact, int ns);
00073 void sloped8(void);
00074 
00075 int setdir(char *demfile, char *angfile, char *slopefile, char *pfile)
00076 { 
00077   int err,filetype;
00078   float mval;
00079   double bndbox[4],csize;
00080   
00081 /* define directions */
00082    d1[1]=0; d1[2]= -1; d1[3]= -1; d1[4]= -1; d1[5]=0; d1[6]=1; d1[7]=1; d1[8]=1;
00083    d2[1]=1; d2[2]=1; d2[3]=0; d2[4]= -1; d2[5]= -1; d2[6]= -1; d2[7]=0; d2[8]=1;
00084 
00085 
00086   err=gridread(demfile,(void ***)&elev,RPFLTDTYPE,&nx,&ny,&dx,&dy,
00087              bndbox,&csize,&mval,&filetype);
00088   if(err != 0)goto ERROR2;          
00089 
00090 /*  allocate  dir and stack arrays  */
00091   dir = (short **) matalloc(nx, ny, RPSHRDTYPE);
00092 
00093   i1=0; i2=0; n1=nx; n2=ny;  /*  full grid  */ 
00094   err=setdfnoflood(mval);
00095    if(err != 0)goto ERROR1;
00096 /*  err = gridwrite(pfile,(void **)dir,RPSHRDTYPE,nx,ny,dx,dy,
00097           bndbox,csize,-1,filetype);   */
00098 
00099 /*  allocate memory for slope and angle  */
00100   slope = (float **) matalloc(nx, ny, RPFLTDTYPE);
00101   ang = (float **) matalloc(nx, ny, RPFLTDTYPE);
00102   setdf2();
00103   err = gridwrite(slopefile,(void **)slope,RPFLTDTYPE,nx,ny,dx,dy,
00104              bndbox,csize,-1.,filetype);
00105   if (err != 0)goto ERROR3;
00106   err = gridwrite(angfile,(void **)ang,RPFLTDTYPE,nx,ny,dx,dy,
00107              bndbox,csize,-2.,filetype);
00108   if (err != 0)goto ERROR3;
00109 
00110 /*  Wrapping up  */
00111   err=0;
00112 ERROR3:
00113   free(slope[0]);
00114   free(slope);
00115   free(ang[0]);
00116   free(ang);
00117 ERROR1:
00118   free(dir[0]);
00119   free(dir);
00120 ERROR2:
00121   free(elev[0]);
00122   free(elev);
00123   return(err);
00124 }
00125 
00126 int setdird8(char *demfile, char *pfile, char *slopefile)
00127 { 
00128   int err,filetype;
00129   float mval;
00130   double bndbox[4],csize;
00131   
00132 /* define directions */
00133    d1[1]=0; d1[2]= -1; d1[3]= -1; d1[4]= -1; d1[5]=0; d1[6]=1; d1[7]=1; d1[8]=1;
00134    d2[1]=1; d2[2]=1; d2[3]=0; d2[4]= -1; d2[5]= -1; d2[6]= -1; d2[7]=0; d2[8]=1;
00135 
00136 
00137   err=gridread(demfile,(void ***)&elev,RPFLTDTYPE,&nx,&ny,&dx,&dy,
00138              bndbox,&csize,&mval,&filetype);
00139   
00140   if(err != 0)goto ERROR2;          
00141 printf("test1");
00142 /*  allocate  dir and stack arrays  */
00143   dir = (short **) matalloc(nx, ny, RPSHRDTYPE);
00144 
00145   i1=0; i2=0; n1=nx; n2=ny;  /*  full grid  */ 
00146   err=setdfnoflood(mval);
00147    if(err != 0)goto ERROR1;
00148   err = gridwrite(pfile,(void **)dir,RPSHRDTYPE,nx,ny,dx,dy,
00149           bndbox,csize,-1,filetype);
00150 
00151 /*  allocate memory for slope   */
00152   slope = (float **) matalloc(nx, ny, RPFLTDTYPE);
00153   sloped8();
00154   err = gridwrite(slopefile,(void **)slope,RPFLTDTYPE,nx,ny,dx,dy,
00155              bndbox,csize,-1.,filetype);
00156   if (err != 0)goto ERROR3;
00157 
00158 /*  Wrapping up  */
00159   err=0;
00160 ERROR3:
00161   free(slope[0]);
00162   free(slope);
00163 ERROR1:
00164   free(dir[0]);
00165   free(dir);
00166 ERROR2:
00167   free(elev[0]);
00168   free(elev);
00169   return(err);
00170 }
00171 
00172 int setdfnoflood(float mval)
00173 /*  This version is stripped of pit filling  */
00174 {
00175   int i,j,k,ip, n, iter;
00176   float fact[9];
00177   short *s;  /*  variables for flat draining   */
00178   int **spos, *sloc;
00179   float *elev2;
00180 
00181 
00182 /*  Initialize boundaries  */
00183   for(i=i1; i< n1; i++)
00184   {
00185      dir[i][0]= -1;
00186      dir[i][n2-1]= -1;
00187   }
00188   for(i=i2; i< n2; i++)
00189   {
00190      dir[0][i]= -1;
00191      dir[n1-1][i]= -1;
00192   }
00193 /*  iup=0; */
00194 /*  initialize internal pointers */
00195   for(i=i2+1; i< n2-1; i++)for(j=i1+1; j<n1-1; j++)
00196   {
00197     if(elev[j][i] <= mval)dir[j][i]= -1;
00198     else dir[j][i] = 0;
00199   }
00200 /*  Direction factors  */
00201   for(k=1; k<= 8; k++)
00202     fact[k]= (float) (1./sqrt(d1[k]*dy*d1[k]*dy+d2[k]*d2[k]*dx*dx));
00203 /*  Set positive slope directions   */
00204    n=0;
00205    for(i=i2+1; i< n2-1; i++)
00206           for(j=i1+1; j<n1-1; j++)
00207                   if(elev[j][i] > mval)
00208                   {
00209                           set(i,j,fact,mval);
00210                           if(dir[j][i] == 0)n++;
00211                   }
00212   if(n > 0)
00213   { 
00214 /*  Now resolve flats following the Procedure of Garbrecht and Martz, Journal
00215    of Hydrology, 1997.  */
00216 
00217 /*  Memory is utilized as follows
00218 is, js, dn, s and elev2 are unidimensional arrays storing information for flats.
00219 sloc is a indirect addressing array for accessing these - used during
00220 recursive iteration
00221 spos is a grid of pointers for accessing these to facilitate finding neighbors
00222 
00223 The routine flatrout is recursive and at each recursion allocates a new sloc for
00224 addressing these arrays and a new elev for keeping track of the elevations
00225 for that recursion level.  
00226   */
00227           iter=1;
00228           printf("Resolving %d Flats, Iteration: %d \n",n,iter);
00229       spos = (int **) matalloc(nx, ny, RPINTDTYPE);
00230       dn = (short *)malloc(sizeof(short) * n);
00231       is = (short *)malloc(sizeof(short) * n);
00232       js = (short *)malloc(sizeof(short) * n);
00233       s = (short *)malloc(sizeof(short) * n);
00234           sloc = (int *)malloc(sizeof(int) * n);
00235       elev2 = (float *)malloc(sizeof(float) *n);
00236 
00237   if(dn == NULL || is == NULL || js == NULL || s == NULL || 
00238           spos == NULL || elev2 == NULL || sloc == NULL)
00239   {
00240      printf("Unable to allocate at iteration %d\n",iter);
00241   }
00242 /*  Put unresolved pixels on stack  */
00243    ip=0;
00244    for(i=i2; i< n2; i++)
00245           for(j=i1; j<n1; j++)
00246   {
00247     spos[j][i]=-1;   /*  Initialize stack position  */
00248     if(dir[j][i] == 0)
00249     {
00250       is[ip]=i;
00251       js[ip]=j;
00252           dn[ip]=0;
00253           sloc[ip]=ip;
00254           /*   Initialize the stage 1 array for flat routing   */
00255           s[ip] = 1;
00256           spos[j][i]=ip;  /*  pointer for back tracking  */
00257           ip++;
00258           if(ip > n)printf("PROBLEM - Stack logic\n");
00259     }
00260   }
00261   flatrout(n,sloc,s,spos,iter,elev2,elev2,fact,n);
00262 /*  The direction 9 was used to flag pits.  Set these to 0  */
00263   for(i=i2; i< n2; i++)
00264           for(j=i1; j<n1; j++)
00265                   if(dir[j][i] == 9)dir[j][i]=0;
00266   free(spos[0]); free(spos);
00267   free(elev2);
00268   free(dn);
00269   free(is);
00270   free(js);
00271   free(s);
00272   free(sloc);
00273   printf("Done iteration %d\nFlats resolved %d\n",iter,n);
00274   } /*  End if n > 0  */
00275    return(0);   /*  OK exit from setdir  */
00276 }  /*  End setdfnoflood  */
00277 
00278 void flatrout(int n,int *sloc, short *s,
00279                           int **spos,int iter,float *elev1,float *elev2, float *fact, int ns)
00280 {
00281   int ip,nu, *sloc2,ipp;
00282   float *elev3;
00283 
00284   incfall(n,elev1,s,spos,iter,sloc);
00285   for(ip=0; ip < n; ip++)
00286   {
00287           elev2[sloc[ip]]=(float)(s[sloc[ip]]);
00288           s[sloc[ip]]=0;   /*  Initialize for pass 2  */
00289   }
00290 /*  Debug writes  
00291                 {
00292                         int err,i,j;
00293                         double bndbox[4],csize;
00294                         short ** sp;
00295                         float ** elevp;
00296                         elevp= (float **)matalloc(nx,ny,RPFLTDTYPE);
00297                         sp= (short **)matalloc(nx,ny,RPSHRDTYPE);
00298 
00299                         for(i=0; i<ny; i++)for(j=0;j<nx;j++)
00300                         {
00301                                 elevp[j][i]=0.;
00302                                 sp[j][i]=0;
00303                         }
00304 
00305                         for(ip=0; ip<n; ip++)
00306                                 elevp[js[sloc[ip]]][is[sloc[ip]]]=elev2[sloc[ip]];
00307                         err=gridwrite("elev.asc",(void **)elevp, RPFLTDTYPE,nx,ny,dx,dy,bndbox,
00308                                 csize,-2.,0);
00309                         for(ip=0; ip<n; ip++)
00310                                 sp[js[sloc[ip]]][is[sloc[ip]]]=s[sloc[ip]];
00311                         err=gridwrite("s.asc",(void **)sp, RPSHRDTYPE,nx,ny,dx,dy,bndbox,
00312                                 csize,-2.,0);
00313                         free(sp[0]); free(sp);
00314                         free(elevp[0]); free(elevp);
00315                 }    */
00316 
00317   incrise(n,elev1,s,spos,iter,sloc);
00318   for(ip=0; ip < n; ip++)
00319   {
00320           elev2[sloc[ip]] += (float)(s[sloc[ip]]);
00321   }
00322 /*  Debug writes  
00323                 {
00324                         int err,i,j;
00325                         double bndbox[4],csize;
00326                         short ** sp;
00327                         float ** elevp;
00328                         elevp= (float **)matalloc(nx,ny,RPFLTDTYPE);
00329                         sp= (short **)matalloc(nx,ny,RPSHRDTYPE);
00330 
00331                         for(i=0; i<ny; i++)for(j=0;j<nx;j++)
00332                         {
00333                                 elevp[j][i]=0.;
00334                                 sp[j][i]=0;
00335                         }
00336 
00337                         for(ip=0; ip<n; ip++)
00338                                 elevp[js[sloc[ip]]][is[sloc[ip]]]=elev2[sloc[ip]];
00339                         err=gridwrite("elev.asc",(void **)elevp, RPFLTDTYPE,nx,ny,dx,dy,bndbox,
00340                                 csize,-2.,0);
00341                         for(ip=0; ip<n; ip++)
00342                                 sp[js[sloc[ip]]][is[sloc[ip]]]=s[sloc[ip]];
00343                         err=gridwrite("s.asc",(void **)sp, RPSHRDTYPE,nx,ny,dx,dy,bndbox,
00344                                 csize,-2.,0);
00345                         free(sp[0]); free(sp);
00346                         free(elevp[0]); free(elevp);
00347                 }   */
00348   nu=0;
00349   for(ip=0; ip < n; ip++)
00350   {
00351           set2(is[sloc[ip]],js[sloc[ip]],fact,elev1,elev2,iter,spos,s);
00352           if(dir[js[sloc[ip]]][is[sloc[ip]]] == 0)nu++;
00353   }
00354   if(nu > 0)
00355   { 
00356 /*  Iterate Recursively   */
00357 /*  Now resolve flats following the Procedure of Garbrecht and Martz, Journal
00358    of Hydrology, 1997.  */
00359           iter=iter+1;
00360           printf("Resolving %d Flats, Iteration: %d \n",nu,iter);
00361       sloc2 = (int *)malloc(sizeof(int) * nu);
00362       elev3 = (float *)malloc(sizeof(float) *ns);
00363 
00364   if(sloc2 == NULL || elev3 == NULL)
00365   {
00366      printf("Unable to allocate at iteration %d\n",iter);
00367   }
00368   /*  Initialize elev3  */
00369   for(ip=0; ip < ns; ip++)elev3[ip]=0.;
00370 /*  Put unresolved pixels on new stacks - keeping in same positions  */
00371     ipp=0;
00372         for(ip=0; ip<n; ip++)
00373         {
00374     if(dir[js[sloc[ip]]][is[sloc[ip]]] == 0)
00375     {
00376                 sloc2[ipp]=sloc[ip];
00377           /*   Initialize the stage 1 array for flat routing   */
00378                 s[sloc[ip]] = 1;
00379           ipp++;
00380           if(ipp > nu)printf("PROBLEM - Stack logic\n");
00381         }
00382         else
00383         {
00384                 s[sloc[ip]] = -1;  /*  Used to designate out of remaining flat on 
00385                                                    higher iterations   */ 
00386         }
00387         dn[sloc[ip]]=0;  /*  Reinitialize for next time round.  */
00388   }
00389   flatrout(nu,sloc2,s,spos,iter,elev2,elev3,fact,ns);
00390   free(sloc2);
00391   free(elev3);
00392   printf("Done iteration %d\nFlats resolved %d\n",iter,n);
00393   } /*  end if nu > 0  */
00394 }   /*  End flatrout  */
00395 
00396 
00397 void incfall(int n, float *elev1, short *s1,int **spos,  
00398                          int iter, int *sloc)
00399 {
00400         /* This routine implements drainage towards lower areas - stage 1 */
00401         int done=0,donothing,k,ip,ninc,nincold,spn;
00402         short st=1,i,j,in,jn;
00403         float ed;
00404         nincold= -1;
00405         while(done < 1)
00406         {
00407                 done=1;
00408                 ninc=0;
00409                 for(ip=0; ip<n; ip++)
00410                 {
00411 /*                      if      adjacent to same level or lower that drains or 
00412                                 adjacent to pixel with s1 < st and dir not set
00413                                 do nothing  */
00414                         donothing=0;
00415                         j=js[sloc[ip]];
00416                         i=is[sloc[ip]];
00417                         for(k=1; k<=8; k++)
00418                         {
00419                                 jn=j+d2[k];
00420                                 in=i+d1[k];
00421                                 spn=spos[jn][in];
00422                                 if(iter <= 1)
00423                                 {
00424                                         ed=elev[j][i]-elev[jn][in];
00425                                 }
00426                                 else
00427                                 {
00428                                         ed=elev1[sloc[ip]]-
00429                                                 elev1[spn];
00430                                 }
00431                                 if(ed >= 0. && dir[jn][in] != 0)donothing = 1;  /* If neighbor drains */
00432                                 if(spn >= 0)     /* if neighbor is in flat   */
00433                                         if(s1[spn] >= 0 && s1[spn] < st   /*  If neighbor is not being  */
00434                                                 && dir[jn][in]  == 0)donothing = 1;   /*  Incremented  */
00435                         }
00436                         if(donothing == 0)
00437                         {
00438                                 s1[sloc[ip]]++;
00439                                 ninc++;
00440                                 done=0;
00441                         }
00442                 }   /*  End of loop over all flats  */
00443                 st=st+1;
00444                 printf("Incfall %d %d \n",ninc,n);
00445                 if(ninc == nincold)
00446                 {
00447                         done = 1;
00448                         printf("There are pits remaining, direction will not be set\n");
00449 /*  Set the direction of these pits to 9 to flag them   */
00450                         for(ip=0; ip<n; ip++)  /*  loop 2 over all flats  */
00451                         {
00452 /*                      if      adjacent to same level or lower that drains or 
00453                                 adjacent to pixel with s1 < st and dir not set
00454                                 do nothing  */
00455                                 donothing=0;
00456                                 j=js[sloc[ip]];
00457                                 i=is[sloc[ip]];
00458                                 for(k=1; k<=8; k++)
00459                                 {
00460                                         jn=j+d2[k];
00461                                         in=i+d1[k];
00462                                         spn=spos[jn][in];
00463                                         if(iter <= 1)
00464                                         {
00465                                                 ed=elev[j][i]-elev[jn][in];
00466                                         }
00467                                         else
00468                                         {
00469                                                 ed=elev1[sloc[ip]]-
00470                                                         elev1[spn];
00471                                         }
00472                                         if(ed >= 0. && dir[jn][in] != 0)donothing = 1;  /* If neighbor drains */
00473                                         if(spn >= 0)     /* if neighbor is in flat   */
00474                                         if(s1[spn] >= 0 && s1[spn] < st   /*  If neighbor is not being  */
00475                                                 && dir[jn][in]  == 0)donothing = 1;   /*  Incremented  */
00476                                 }
00477                                 if(donothing == 0)
00478                                 {
00479                                    dir[j][i] = 9;
00480 /*                                 printf("%d %d\n",i,j);    */
00481                                 }
00482                         }   /*  End of loop 2 over all flats  */
00483                 }
00484                 nincold=ninc;
00485         }  /*  End of while done loop  */
00486 }
00487 
00488 
00489 void incrise(int n, float *elev1, short *s2,int **spos, int iter, int *sloc)
00490 {
00491         /*  This routine implements stage 2 drainage away from higher ground 
00492         dn is used to flag pixels still being incremented */
00493         int done=0,ip,k,ninc,nincold,spn;
00494         float ed;
00495         short i,j,in,jn;
00496         nincold=0;
00497         while(done < 1)
00498         {
00499                 done=1;
00500                 ninc=0; 
00501                 for(ip=0; ip<n; ip++)
00502                 {
00503                         for(k=1; k<=8; k++)
00504                         {
00505                                 j=js[sloc[ip]];
00506                                 i=is[sloc[ip]];
00507                                 jn=j+d2[k];
00508                                 in=i+d1[k];
00509                                 spn=spos[jn][in];
00510 
00511                                 if(iter <= 1)
00512                                 {
00513                                         ed=elev[j][i]-elev[jn][in];
00514                                 }
00515                                 else
00516                                 {
00517                                         ed=elev1[sloc[ip]]-
00518                                                 elev1[spn];
00519                                 }
00520                                 if(ed < 0.)dn[sloc[ip]]=1;
00521                                 if(spn >=0)
00522                                         if(s2[spn] > 0)dn[sloc[ip]] = 1;
00523                         }
00524                 }
00525                 for(ip=0; ip<n; ip++)
00526                 {
00527                         s2[sloc[ip]]=s2[sloc[ip]]+dn[sloc[ip]];
00528                         ninc=ninc+dn[sloc[ip]];
00529                         if(dn[sloc[ip]] == 0)done=0;  /*  if still some not being incremented continue 
00530                                                                         looping  */
00531                 }
00532                 printf("incrise %d %d\n",ninc,n);   
00533                 if(ninc == nincold)done=1;   /*  If there are no new cells incremented  
00534                                                                          stop - this is the case when a flat has
00535                                                                          no higher ground around it.  */
00536                 nincold=ninc;
00537         }
00538 }
00539 
00540 void set2(int i,int j,float *fact,float *elev1, float *elev2, int iter, 
00541                   int **spos, short *s)
00542 {
00543 /*  This function sets directions based upon secondary elevations for
00544   assignment of flow directions across flats according to Garbrecht and Martz
00545   scheme.  There are two possibilities: 
00546         A.  The neighbor is outside the flat set
00547         B.  The neighbor is in the flat set.
00548         In the case of A the elevation of the neighbor is set to 0 for the purposes
00549         of computing slope.  Since the incremental elevations are all positive there is 
00550         always a downwards slope to such neighbors, and if the previous elevation 
00551         increment had 0 slope then a flow direction can be assigned.*/
00552   float slope,slope2,smax,ed;
00553   int k,spn,sp,kflat=0;
00554   short in,jn;
00555   smax=0.;
00556   sp=spos[j][i];
00557   for(k=1; k<=8; k++)
00558   {
00559                 jn=j+d2[k];
00560                 in=i+d1[k];
00561                 spn=spos[jn][in];
00562                 if(iter <= 1)
00563                 {
00564                         ed=elev[j][i]-elev[jn][in];
00565                 }
00566                 else
00567                 {
00568                         ed=elev1[sp]-elev1[spn];
00569                 }
00570                 slope=fact[k]* ed;
00571         if(spn < 0 || s[spn] < 0)
00572         {
00573                 /*  The neighbor is outside the flat set.  */
00574                 ed=0.;
00575         }
00576         else
00577         {
00578                 ed=elev2[spn];
00579         }
00580         slope2 =fact[k]*(elev2[sp]-ed);
00581         if(slope2 > smax && slope >= 0.)  /*  Only if latest iteration slope is 
00582                                                                           positive and previous iteration slope flat  */                
00583                 {
00584                         smax=slope2;
00585                         dir[j][i]=k;
00586                 }
00587   }  /*  End of for  */
00588 }
00589 
00590 
00591 /*
00592 
00593 Converted from FORTRAN July 05, 1997  K. Tarbet
00594 
00595 C
00596 C---SUBROUTINE TO SET VARIABLE DIRECTIONS.
00597 C    DIRECTIONS MEASURED ANTICLOCKWISE FROM EAST IN RADIANS.
00598 C
00599 */
00600 void setdf2(void )
00601 {
00602 float FANG[9];
00603 float dxx[3];
00604 int i,j;
00605 float dd;
00606 
00607 /*       INITIALISE ANGLES and slopes */
00608 
00609         for (i=0; i<nx; i++)
00610         {
00611          ang[i][0]=-2;
00612          ang[i][ny-1]=-2;
00613          slope[i][0]=-1;
00614          slope[i][ny-1]=-1;
00615          }
00616 
00617        for(i=0; i<ny; i++)
00618         {
00619          ang[0][i]=-2;
00620          ang[nx-1][i]=-2;
00621          slope[0][i]=-1;
00622          slope[nx-1][i]=-1;
00623         }
00624 
00625          FANG[1]=0.;
00626          FANG[2]=(float)atan2(dy,dx);
00627          FANG[3]=(float) PI2; 
00628          FANG[4]=2*FANG[3]-FANG[2];
00629          FANG[5]=2*FANG[3];
00630          FANG[6]=2*FANG[3]+FANG[2];
00631          FANG[7]=3*FANG[3];
00632          FANG[8]=4*FANG[3]-FANG[2];
00633 
00634 /* --INITIALISE INTERNAL POINTERS (-VE POINTER INDICATES OUTSIDE DOMAIN) */
00635 
00636         for(i=1; i<ny-1; i++)
00637            for(j=1; j<nx-1; j++)
00638               {
00639                 if(dir[j][i] <  0)   
00640                                          
00641                  {
00642                   ang[j][i]=-2.;
00643                   slope[j][i]=-1.; /*  !  -1 slope indicates no data */
00644                  }
00645                 else if(dir[j][i] == 0)
00646                  {
00647                   ang[j][i]=-1.;  /*  DGT 9/2/97 since without   */
00648                   slope[j][i]=0.;  /*  pit filling dir = 0 is possible  */
00649 /*  ang = -1 designates unfilled pit, ang = -2 designates no data.  */                  
00650                  }
00651                 else
00652                  ang[j][i]=0.;
00653                }
00654 
00655 
00656 
00657 /*    TEST ALL INTERNAL ELEVATIONS AND SET SLOPE AND ANGLE */
00658 
00659        dxx[1]=dx;
00660        dxx[2]=dy;
00661        dd=(float)sqrt(dx*dx+dy*dy);
00662         for(i=1; i<ny-1; i++)
00663     {
00664     SetWorkingStatus(); 
00665     for(j=1; j<nx-1; j++)
00666               {
00667                if(dir[j][i]>0 )
00668                    {
00669                    SET2(i,j,dxx,dd);
00670                    if(ang[j][i] < -0.5)
00671                         ang[j][i]=FANG[dir[j][i]];
00672                    }
00673               }
00674     }
00675  }
00676 
00677 /*     SUBROUTINE TO RETURN SLOPE AND ANGLE OF STEEPEST DECENT IF POSITIVE */
00678 
00679 void   SET2(int I, int J,float *DXX,float DD)
00680 {
00681 
00682 float SK[9];
00683 float ANGLE[9];
00684 float SMAX;
00685 int K;
00686 int KD;
00687 
00688 /*    int ID1[]= {NULL,1,2,2,1,1,2,2,1 };
00689       int ID2[]= {NULL,2,1,1,2,2,1,1,2};
00690       int I1[] = {NULL,0,-1,-1,0,0,1,1,0 };
00691       int I2[] = {NULL,-1,-1,-1,-1,1,1,1,1};
00692       int J1[] = {NULL,1,0,0,-1,-1,0,0,1};
00693       int J2[] = {NULL,1,1,-1,-1,-1,-1,1,1};
00694    float  ANGC[]={NULL,0.,1.,1.,2.,2.,3.,3.,4.};
00695    float  ANGF[]={NULL,1.,-1.,1.,-1.,1.,-1.,1.,-1.}; */
00696       int ID1[]= {0,1,2,2,1,1,2,2,1 };
00697 /*              int *ID1;  */
00698       int ID2[]= {0,2,1,1,2,2,1,1,2};
00699       int I1[] = {0,0,-1,-1,0,0,1,1,0 };
00700       int I2[] = {0,-1,-1,-1,-1,1,1,1,1};
00701       int J1[] = {0,1,0,0,-1,-1,0,0,1};
00702       int J2[] = {0,1,1,-1,-1,-1,-1,1,1};
00703    float  ANGC[]={0,0.,1.,1.,2.,2.,3.,3.,4.};
00704    float  ANGF[]={0,1.,-1.,1.,-1.,1.,-1.,1.,-1.};
00705  /*  ID1=ID1m-1;  */
00706 
00707        for(K=1; K<=8; K++)
00708        VSLOPE(elev[J][I],
00709               elev[J+J1[K]][I+I1[K]],
00710               elev[J+J2[K]][I+I2[K]],
00711               DXX[ID1[K]],DXX[ID2[K]],DD,&SK[K],&ANGLE[K]);
00712 
00713 SMAX=0.;
00714 KD=0;
00715       ang[J][I]=-1.;  /* USE -1 TO INDICATE DIRECTION NOT YET SET */
00716       for(K=1; K<=8; K++)
00717         {
00718         if(SK[K] >  SMAX)
00719            {
00720             SMAX=SK[K];
00721             KD=K;
00722            }
00723          }
00724 
00725       if(KD  > 0)
00726          ang[J][I]= (float) (ANGC[KD]*PI2+ANGF[KD]*ANGLE[KD]);
00727       slope[J][I]=SMAX;
00728 }
00729 
00730 
00731 
00732 void   VSLOPE(float E0,float E1, float E2,
00733               float D1,float D2,float DD,
00734               float *S,float *A)
00735 {
00736 /*    SUBROUTINE TO RETURN THE SLOPE AND ANGLE ASSOCIATED WITH A DEM PANEL */
00737 float S1,S2,AD;
00738 
00739 
00740 if(D1!=0)
00741       S1=(E0-E1)/D1;
00742 if(D2!=0)
00743       S2=(E1-E2)/D2;
00744 
00745 if(S2==0 && S1==0) *A=0;
00746       else
00747       *A= (float) atan2(S2,S1);
00748       AD= (float) atan2(D2,D1);
00749       if(*A  <   0.)
00750        {
00751        *A=0.;
00752        *S=S1;
00753        }
00754       else if(*A > AD)
00755        {
00756         *A=AD;
00757         *S=(E0-E2)/DD;
00758        }
00759       else
00760         *S= (float) sqrt(S1*S1+S2*S2);
00761  }
00762 
00763 void sloped8(void )
00764 {
00765         int k,i,j,in,jn;
00766         float fact[9],ed;
00767         /*  Direction factors  */
00768   for(k=1; k<= 8; k++)
00769     fact[k]= (float) (1./sqrt(d1[k]*dy*d1[k]*dy+d2[k]*d2[k]*dx*dx));
00770 
00771   for(i=i2; i< n2; i++)for(j=i1; j<n1; j++)
00772   {
00773     if(dir[j][i] > 0)
00774         {
00775                 jn=j+d2[dir[j][i]];
00776                 in=i+d1[dir[j][i]];
00777                 ed=elev[j][i]-elev[jn][in];
00778             slope[j][i]= ed*fact[dir[j][i]] ;   
00779         }
00780         else
00781                 slope[j][i]= -1.;
00782   }
00783 }

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