00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include "lsm.h"
00010 #include "gridio.h"
00011 
00012 
00013 int addstack(int i, int j);
00014 
00015 
00016 int flood(char *demfile, char *pointfile, char *newfile)
00017 {
00018   int err;
00019 
00020    
00021 
00022 
00023    d1[1]=0; d1[2]= -1; d1[3]= -1; d1[4]= -1; d1[5]=0; d1[6]=1; d1[7]=1; d1[8]=1;
00024    d2[1]=1; d2[2]=1; d2[3]=0; d2[4]= -1; d2[5]= -1; d2[6]= -1; d2[7]=0; d2[8]=1;
00025 
00026   err=gridread(demfile,(void ***)&elev,RPFLTDTYPE,&nx,&ny,&dx,&dy,bndbox,&csize,&mval,&filetype);
00027              
00028   if(err != 0)return(err);
00029 
00030   dir = (short **) matalloc(nx, ny, RPSHRDTYPE);
00031   apool = (short **) matalloc(nx, ny, RPSHRDTYPE);
00032   istack = (int) (nx * ny * 0.1);
00033   pstack=istack;
00034   dn = (short *)malloc(sizeof(short) * istack);
00035   is = (short *)malloc(sizeof(short) * istack);
00036   js = (short *)malloc(sizeof(short) * istack);
00037   ipool = (short *)malloc(sizeof(short) * pstack);
00038   jpool = (short *)malloc(sizeof(short) * pstack);
00039   if(dn == NULL || is == NULL || js == NULL || ipool == NULL || jpool == NULL)
00040   {
00041      printf("\nError:  Cannot allocate memory for stacks\n");
00042      return(11);
00043   }
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074   i1=0; i2=0; n1=nx; n2=ny;   
00075   printf("Grid size: %d x %d\n",n1,n2);
00076   setdf(mval);
00077 
00078   free(dn); free(is); free(js); free(ipool); free(jpool); 
00079   free(apool[0]); free(apool);
00080 
00081   printf("Writing output ...");
00082   err = gridwrite(newfile,(void **)elev,RPFLTDTYPE,nx,ny,dx,dy,
00083              bndbox,csize,mval,filetype);
00084   if(err != 0)return(err);
00085 
00086 
00087  
00088   return(0);  
00089 }
00090 
00091 int setdf(float mval)
00092 {
00093   int i,j,k,n,nflat,ni,ip,imin,err,jn,in,np1,nt;
00094   float fact[9],per=1.;
00095 
00096 
00097   for(i=i1; i< n1; i++)
00098   {
00099      dir[i][i2]= -1;
00100      dir[i][n2-1]= -1;
00101   }
00102   for(i=i2; i< n2; i++)
00103   {
00104      dir[i1][i]= -1;
00105      dir[n1-1][i]= -1;
00106   }
00107 
00108   for(i=i2+1; i< n2-1; i++)for(j=i1+1; j<n1-1; j++)
00109   {
00110     if(elev[j][i] <= mval)dir[j][i]= -1;
00111     else dir[j][i] = 0;
00112   }
00113 
00114   for(k=1; k<= 8; k++)
00115     fact[k]=(float)(1./sqrt(d1[k]*dy*d1[k]*dy+d2[k]*d2[k]*dx*dx));
00116 
00117    
00118 
00119 
00120 
00121 
00122   nis=0;
00123   for(i=i2+1; i< n2-1; i++)for(j=i1+1; j<n1-1; j++)
00124   {
00125     if(elev[j][i] > mval)set(i,j,fact,mval);
00126 
00127     if(dir[j][i] == 0)
00128     {
00129                 err=addstack(i,j);
00130     }
00131    }
00132    nflat=nis;
00133 
00134    SetWorkingStatus();  
00135    imin=vdn(nflat);
00136    n=nis;
00137  
00138    printf("Number of pits to resolve: %d\n",n);  
00139    np1=n;
00140    nt=np1*(1-per/100);
00141 
00142 
00143    for(i=i2; i< n2; i++)for(j=i1; j<n1; j++)
00144     apool[j][i]=0;
00145 
00146 
00147 
00148 
00149   while(nis > 0)   
00150   {
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160     i=is[imin];
00161     j=js[imin];
00162 
00163 
00164 
00165 
00166 
00167         pooln=1;
00168     npool=0;
00169     nf = 0;  
00170     pool(i,j);  
00171 
00172 
00173  
00174  
00175         for(ip=1; ip<=npool; ip++)
00176         {
00177                 i=ipool[ip];
00178                 j=jpool[ip];
00179                 for(k=1; k <=8; k++)    
00180         {
00181                          jn=j+d2[k];
00182                          in=i+d1[k];
00183                          if(apool[jn][in] != pooln)  
00184                          {
00185                 et=max2(elev[j][i],elev[jn][in]);
00186                 if(nf == 0)  
00187                 {
00188                   emin=et;
00189                   nf=1;
00190 
00191 
00192                 }
00193                 else
00194                 {
00195                   
00196                                         if(emin > et)
00197                                         {
00198                                                 emin = et;
00199 
00200 
00201                                         }
00202                 }
00203                          }
00204                 }
00205         }
00206 
00207     for(k=1; k<=npool; k++)
00208         {
00209                 i=ipool[k];
00210                 j=jpool[k];
00211       if(elev[j][i] <= emin)
00212           {
00213                   if(dir[j][i] > 0)   
00214                   {
00215                           dir[j][i]=0;
00216                           
00217                           err=addstack(i,j);
00218                   }
00219                   for(ip=1; ip <=8; ip++)
00220                   {
00221                           jn=j+d2[ip];
00222                           in=i+d1[ip];
00223                           if(elev[jn][in] > elev[j][i] && dir[jn][in] > 0)
00224 
00225 
00226                           {
00227                                   dir[jn][in] = 0;
00228                                   err=addstack(in,jn);
00229                           }
00230                   }
00231                   elev[j][i] =emin;
00232 
00233           }
00234           apool[j][i]=0;  
00235         }
00236 
00237 
00238     ni=0;
00239     for(ip=1; ip <= nis; ip++)
00240     {
00241        set(is[ip],js[ip],fact,mval);  
00242            if(dir[js[ip]][is[ip]] == 0)  
00243        {
00244           ni++;
00245           is[ni]=is[ip];
00246           js[ni]=js[ip];
00247 
00248 
00249        }
00250 
00251 
00252      }
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262          n=nis;
00263          imin=vdn(ni);
00264          if(nis < nt){
00265                  printf("Percentage done %f\n",per);
00266                  per=per+1;
00267                  nt=np1*(1-per/100);
00268          }
00269          
00270 
00271 
00272 
00273   
00274   }  
00275 
00276   return(err);
00277 }
00278 int vdn(int n)
00279 {
00280   int ip,k,imin;
00281   float ed;
00282   nis=n;
00283   do
00284   {
00285   n=nis;
00286   nis=0;
00287   for(ip=1; ip <=n; ip++)dn[ip]=0;
00288   for(k=1; k<=7; k=k+2)
00289     for(ip=1; ip<=n; ip++)
00290     {
00291        ed=elev[js[ip]][is[ip]]-elev[js[ip]+d2[k]][is[ip]+d1[k]];
00292        if(ed >= 0. && dir[js[ip]+d2[k]][is[ip]+d1[k]] != 0 && dn[ip] == 0)
00293          dn[ip]=k;
00294     }
00295   for(k=2; k<=8; k=k+2)
00296     for(ip=1; ip<=n; ip++)
00297     {
00298        ed=elev[js[ip]][is[ip]]-elev[js[ip]+d2[k]][is[ip]+d1[k]];
00299        if(ed >= 0. && dir[js[ip]+d2[k]][is[ip]+d1[k]] != 0 && dn[ip] == 0)
00300          dn[ip]=k;
00301     }
00302   imin=1;  
00303   for(ip=1; ip <= n; ip++)
00304   {
00305      if(dn[ip] > 0)dir[js[ip]][is[ip]]=dn[ip];
00306      else
00307      {
00308         nis++;
00309         is[nis]=is[ip];
00310         js[nis]=js[ip];
00311         if(elev[js[nis]][is[nis]] < elev[js[imin]][is[imin]])imin=nis;
00312      }
00313   }
00314   SetWorkingStatus(); 
00315   }while(nis < n);
00316   return(imin);
00317 }   
00318 
00319 void set(int i,int j,float *fact,float mval)
00320 {
00321   float slope,smax;
00322   int k;
00323   dir[j][i]=0;  
00324   smax=0.;
00325   for(k=1; k<=8; k++)
00326   {
00327     if(elev[j+d2[k]][i+d1[k]] <= mval) dir[j][i] = -1;
00328     slope=fact[k]*(elev[j][i]-elev[j+d2[k]][i+d1[k]]);
00329     if(slope > smax && dir[j][i] != -1)
00330     {
00331        smax=slope;
00332        dir[j][i]=k;
00333     }
00334   }
00335 }
00336 
00337 
00338 int pool(int i,int j)
00339 
00340   {
00341     int in,jn,k;
00342     if(apool[j][i]<=0)   
00343     {
00344 
00345         if(dir[j][i]!= -1)  
00346                  
00347       {
00348         apool[j][i]=pooln;  
00349         npool=npool+1;
00350         if(npool >= pstack)
00351         {
00352           if(pstack < (nx*ny))
00353           {
00354 
00355             printf("\n Enlarging pool stack\n");
00356             pstack=(int) (pstack + nx*ny*.1);
00357             if(pstack > nx*ny)
00358             {
00359               printf("\n Pool stack too large, exiting ...\n");
00360               return(14);
00361             }
00362             ipool = (short *)realloc(ipool, sizeof(short) * pstack);
00363             jpool = (short *)realloc(jpool, sizeof(short) * pstack);
00364             if(ipool == NULL || jpool == NULL)
00365             {
00366               printf("\n Cannot reallocate pool stack, exiting ...\n");
00367               return(15);
00368             }
00369           }
00370           else
00371           {
00372             printf("\n Could not enlarge Pool stack\n");
00373             return(16);
00374           }
00375         }
00376         ipool[npool]=i;
00377         jpool[npool]=j;
00378 
00379         for(k=1; k<=8; k++)
00380         {  
00381            in=i+d1[k];
00382            jn=j+d2[k];
00383 
00384            if((dir[jn][in]>0 && (dir[jn][in]-k==4||dir[jn][in]-k==-4))
00385               || (dir[jn][in] == 0 && elev[jn][in] >= elev[j][i]))  
00386                
00387              {
00388 
00389 
00390 
00391                                    pool(in,jn);
00392              }
00393  
00394 
00395 
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406         }
00407       }
00408     }
00409   }
00410 
00411      
00412 
00413 float min2(float e1,float e2)
00414 { 
00415   float em; 
00416   em=e1;
00417   if(e2 < em)em=e2;
00418   return(em);
00419 }
00420 
00421 float max2(float e1,float e2)
00422 { 
00423   float em; 
00424   em=e1;
00425   if(e2 > em)em=e2;
00426   return(em);
00427 }
00428 
00429 int addstack(int i, int j)
00430 {
00431         
00432         nis=nis+1;
00433         if(nis >= istack )
00434       {
00435         
00436          istack=(int) (istack + nx*ny*.1);
00437          if(istack > nx*ny)
00438          {
00439            printf("\n is,js stack too large, exiting ...\n");
00440            return(12);
00441          }
00442          printf("\n Enlarging is,js stack\n");
00443          is = (short *)realloc(is, sizeof(short) * istack);
00444          js = (short *)realloc(js, sizeof(short) * istack);
00445          dn = (short *)realloc(dn, sizeof(short) * istack);
00446          if(is == NULL || js == NULL || dn == NULL)
00447         {
00448          printf("\n Could not enlarge stack\n");
00449          return(13);
00450         }
00451       }
00452         is[nis]=i;
00453         js[nis]=j;
00454         return(0);
00455 }
00456 
00457 
00458 
00459 
00460