X-Git-Url: https://git.gag.com/?p=debian%2Fsplat;a=blobdiff_plain;f=utils%2Fsrtm2sdf.c;fp=utils%2Fsrtm2sdf.c;h=a12ee35534ccfdcdf3f3b3ec18b30272ef6a3816;hp=0000000000000000000000000000000000000000;hb=63fe09e1131ae8f451b4a5af9dbae05cb07d529e;hpb=8c97af274a0a0c0f6c949aab5b35731f7b187873 diff --git a/utils/srtm2sdf.c b/utils/srtm2sdf.c new file mode 100644 index 0000000..a12ee35 --- /dev/null +++ b/utils/srtm2sdf.c @@ -0,0 +1,586 @@ +/************************************************************\ + ** Created originally by Jonathan Naylor, G4KLX ** + ** Later embellished by John Magliacane, KD2BD to ** + ** detect and handle voids found in the SRTM data ** + ************************************************************ + ** Compile like this: ** + ** cc -Wall -O3 -s -lbz2 srtm2sdf.c -o srtm2sdf ** + ** Last modification: 18-Mar-2006 ** +\************************************************************/ + +#include +#include +#include +#include +#include +#include + +#define BZBUFFER 65536 + +char sdf_filename[25], sdf_path[255], replacement_flag, opened=0; +int srtm[1201][1201], usgs[1200][1200], max_north, max_west, + min_north, min_west, merge=0, min_elevation, bzerror; + +int ReadSRTM(char *filename) +{ + int x, y, infile, byte, bytes_read; + unsigned char error, buffer[2]; + char north[3], west[4], *base=NULL; + + if (strstr(filename, ".zip")!=NULL) + { + fprintf(stderr, "*** Error: \"%s\" must be uncompressed\n",filename); + return -1; + + } + + if (strstr(filename, ".hgt")==NULL) + { + fprintf(stderr, "*** Error: \"%s\" does not have the correct extension (.hgt)\n",filename); + return -1; + } + + base=strrchr(filename, '/'); + + if (base==NULL) + base=filename; + else + base+=1; + + north[0]=base[1]; + north[1]=base[2]; + north[2]=0; + + west[0]=base[4]; + west[1]=base[5]; + west[2]=base[6]; + west[3]=0; + + if ((base[0]!='N' && base[0]!='S') || (base[3]!='W' && base[3]!='E')) + { + fprintf(stderr, "*** Error: \"%s\" doesn't look like a valid SRTM filename.\n", filename); + return -1; + } + + max_west=atoi(west); + + if (base[3]=='E') + max_west=360-max_west; + + min_west=max_west-1; + + if (max_west==360) + max_west=0; + + if (base[0]=='N') + min_north=atoi(north); + else + min_north=-atoi(north); + + max_north=min_north+1; + + infile=open(filename, O_RDONLY); + + if (infile==0) + { + fprintf(stderr, "*** Error: Cannot open \"%s\"\n", filename); + return -1; + } + + read(infile,&buffer,2); + + if ((buffer[0]=='P') && (buffer[1]=='K')) + { + fprintf(stderr, "*** Error: \"%s\" still appears to be compressed!\n",filename); + close(infile); + return -1; + } + + lseek(infile,0L,SEEK_SET); + + sprintf(sdf_filename, "%d:%d:%d:%d.sdf", min_north, max_north, min_west, max_west); + + error=0; + replacement_flag=0; + + printf("Reading %s... ", filename); + fflush(stdout); + + for (x=0; (x<1201 && error==0); x++) + for (y=0; (y<1201 && error==0); y++) + { + bytes_read=read(infile,&buffer,2); + + if (bytes_read==2) + { + byte=buffer[1]+(buffer[0]<<8); + + if (buffer[0]&128) + byte-=0x10000; + + /* Flag problem elevations here */ + + if (byte<=min_elevation) + replacement_flag=1; + + srtm[x][y]=byte; + } + + else + error=1; + } + + if (error) + { + fprintf(stderr,"\n*** Error: Premature EOF detected while reading \"%s\"! :-(\n",filename); + return -1; + } + + close(infile); + + return 0; +} + +int LoadSDF_SDF(char *name) +{ + /* This function reads uncompressed + SPLAT Data Files (.sdf) into memory. */ + + int x, y, dummy; + char sdf_file[255], path_plus_name[255]; + FILE *infile; + + for (x=0; name[x]!='.' && name[x]!=0 && x<250; x++) + sdf_file[x]=name[x]; + + sdf_file[x]='.'; + sdf_file[x+1]='s'; + sdf_file[x+2]='d'; + sdf_file[x+3]='f'; + sdf_file[x+4]=0; + + strncpy(path_plus_name,sdf_path,255); + strncat(path_plus_name,sdf_file,255); + + infile=fopen(path_plus_name,"rb"); + + if (infile==NULL) + return 0; + + fscanf(infile,"%d", &dummy); + fscanf(infile,"%d", &dummy); + fscanf(infile,"%d", &dummy); + fscanf(infile,"%d", &dummy); + + printf("\nReading %s... ",path_plus_name); + fflush(stdout); + + for (x=0; x<1200; x++) + for (y=0; y<1200; y++) + fscanf(infile,"%d",&usgs[x][y]); + + fclose(infile); + + return 1; +} + +char *BZfgets(BZFILE *bzfd, unsigned length) +{ + /* This function returns at most one less than 'length' number + of characters from a bz2 compressed file whose file descriptor + is pointed to by *bzfd. In operation, a buffer is filled with + uncompressed data (size = BZBUFFER), which is then parsed + and doled out as NULL terminated character strings every time + this function is invoked. A NULL string indicates an EOF + or error condition. */ + + static int x, y, nBuf; + static char buffer[BZBUFFER+1], output[BZBUFFER+1]; + char done=0; + + if (opened!=1 && bzerror==BZ_OK) + { + /* First time through. Initialize everything! */ + + x=0; + y=0; + nBuf=0; + opened=1; + output[0]=0; + } + + do + { + if (x==nBuf && bzerror!=BZ_STREAM_END && bzerror==BZ_OK && opened) + { + /* Uncompress data into a static buffer */ + + nBuf=BZ2_bzRead(&bzerror, bzfd, buffer, BZBUFFER); + buffer[nBuf]=0; + x=0; + } + + /* Build a string from buffer contents */ + + output[y]=buffer[x]; + + if (output[y]=='\n' || output[y]==0 || y==(int)length-1) + { + output[y+1]=0; + done=1; + y=0; + } + + else + y++; + x++; + + } while (done==0); + + if (output[0]==0) + opened=0; + + return (output); +} + +int LoadSDF_BZ(char *name) +{ + /* This function reads .bz2 compressed + SPLAT Data Files into memory. */ + + int x, y, dummy; + char sdf_file[255], path_plus_name[255]; + FILE *fd; + BZFILE *bzfd; + + for (x=0; name[x]!='.' && name[x]!=0 && x<247; x++) + sdf_file[x]=name[x]; + + sdf_file[x]='.'; + sdf_file[x+1]='s'; + sdf_file[x+2]='d'; + sdf_file[x+3]='f'; + sdf_file[x+4]='.'; + sdf_file[x+5]='b'; + sdf_file[x+6]='z'; + sdf_file[x+7]='2'; + sdf_file[x+8]=0; + + strncpy(path_plus_name,sdf_path,255); + strncat(path_plus_name,sdf_file,255); + + fd=fopen(path_plus_name,"rb"); + bzfd=BZ2_bzReadOpen(&bzerror,fd,0,0,NULL,0); + + if (fd!=NULL && bzerror==BZ_OK) + { + printf("\nReading %s... ",path_plus_name); + fflush(stdout); + + sscanf(BZfgets(bzfd,255),"%d",&dummy); + sscanf(BZfgets(bzfd,255),"%d",&dummy); + sscanf(BZfgets(bzfd,255),"%d",&dummy); + sscanf(BZfgets(bzfd,255),"%d",&dummy); + + for (x=0; x<1200; x++) + for (y=0; y<1200; y++) + sscanf(BZfgets(bzfd,20),"%d",&usgs[x][y]); + + fclose(fd); + + BZ2_bzReadClose(&bzerror,bzfd); + + return 1; + } + + else + return 0; +} + +char LoadSDF(char *name) +{ + /* This function loads the requested SDF file from the filesystem. + First, it tries to invoke the LoadSDF_SDF() function to load an + uncompressed SDF file (since uncompressed files load slightly + faster). Failing that, it tries to load a compressed SDF file + by invoking the LoadSDF_BZ() function. */ + + int return_value=-1; + + /* Try to load an uncompressed SDF first. */ + + return_value=LoadSDF_SDF(name); + + /* If that fails, try loading a compressed SDF. */ + + if (return_value==0 || return_value==-1) + return_value=LoadSDF_BZ(name); + + return return_value; +} + +int ReadUSGS() +{ + char usgs_filename[15]; + + /* usgs_filename is a minimal filename ("40:41:74:75"). + Full path and extentions are added later though + subsequent function calls. */ + + sprintf(usgs_filename, "%d:%d:%d:%d", min_north, max_north, min_west, max_west); + + return (LoadSDF(usgs_filename)); +} + +void average_terrain(x,y,z) +int x, y, z; +{ + long accum; + int temp=0, count, bad_value; + double average; + + bad_value=srtm[x][y]; + + accum=0L; + count=0; + + if (x!=0) + { + temp=srtm[x-1][y]; + + if (temp>bad_value) + { + accum+=temp; + count++; + } + } + + if (x!=1201) + { + temp=srtm[x+1][y]; + + if (temp>bad_value) + { + accum+=temp; + count++; + } + } + + if ((x!=0) && (y!=1201)) + { + temp=srtm[x-1][y+1]; + + if (temp>bad_value) + { + accum+=temp; + count++; + } + } + + if (y!=1201) + { + temp=srtm[x][y+1]; + + if (temp>bad_value) + { + accum+=temp; + count++; + } + } + + if ((x!=1201) && (y!=1201)) + { + temp=srtm[x+1][y+1]; + + if (temp>bad_value) + { + accum+=temp; + count++; + } + } + + if ((x!=0) && (y!=0)) + { + temp=srtm[x-1][y-1]; + + if (temp>bad_value) + { + accum+=temp; + count++; + } + } + + if (y!=0) + { + temp=srtm[x][y-1]; + + if (temp>bad_value) + { + accum+=temp; + count++; + } + } + + if ((x!=1201) && (y!=0)) + { + temp=srtm[x+1][y-1]; + + if (temp>bad_value) + { + accum+=temp; + count++; + } + } + + if (count!=0) + { + average=(((double)accum)/((double)count)); + temp=(int)(average+0.5); + } + + if (temp>min_elevation) + srtm[x][y]=temp; + else + srtm[x][y]=min_elevation; +} + +void WriteSDF(char *filename) +{ + int x, y, byte, last_good_byte=0; + FILE *outfile; + + printf("\nWriting %s... ", filename); + fflush(stdout); + + outfile=fopen(filename,"wb"); + + fprintf(outfile, "%d\n%d\n%d\n%d\n", max_west, min_north, min_west, max_north); + + for (x=1200; x>0; x--) + for (y=1200; y>0; y--) + { + byte=srtm[x][y]; + + if (byte>min_elevation) + last_good_byte=byte; + + if (byte and/or from string */ + + for (x=0; string[x]!=13 && string[x]!=10 && string[x]!=0 && x<253; x++); + string[x]=0; + + strncpy(sdf_path,string,253); + + fclose(fd); + } + } + + /* Ensure a trailing '/' is present in sdf_path */ + + if (sdf_path[0]) + { + x=strlen(sdf_path); + + if (sdf_path[x-1]!='/' && x!=0) + { + sdf_path[x]='/'; + sdf_path[x+1]=0; + } + } + + if (ReadSRTM(argv[z+1])==0) + { + if (replacement_flag && sdf_path[0]) + merge=ReadUSGS(); + + WriteSDF(sdf_filename); + } + + return 0; +} +