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