Imported Upstream version 1.1.1
[debian/splat] / utils / usgs2sdf.c
1 /***************************************************************************\
2 *            USGS2SDF: USGS to SPLAT Data File Converter Utility            *
3 *               Copyright John A. Magliacane, KD2BD 1997-2001               *
4 *                         Last update: 05-Sep-2005                          *
5 *****************************************************************************
6 * Updated July 2005 by John Gabrysch (jgabby@gmail.com) to properly handle  *
7 *   the updated USGS DEM file format and to properly scale Alaska tiles.    *
8 *****************************************************************************
9 *                                                                           *
10 * This program reads files containing delimited US Geological Survey        *
11 * Digital Elevation Model Data files, and creates Splat Data Files          *
12 * containing ONLY the raw information needed by SPLAT!, thereby saving      *
13 * disk space, as well as read/write time.                                   *
14 *                                                                           *
15 * The format of .sdf files created by this utility is as follows:           *
16 *                                                                           *
17 *       maximum west longitude (degrees West)                               *
18 *       minimum north latitude (degrees North)                              *
19 *       minimum west longitude (degrees West)                               *
20 *       maximum north latitude (degrees North)                              *
21 *       ...1440000 elevation points... (1200x1200)                          *
22 *                                                                           *
23 * All data is represented as integers.  A single '\n' follows each value.   *
24 *                                                                           *
25 * SPLAT Data Files are named according to the geographical locations        *
26 * they represent (ie: min_north:max_north:min_west:max_west.sdf).           *
27 *                                                                           *
28 *****************************************************************************
29 *           To compile: gcc -Wall -O3 -s usgs2sdf.c -o usgs2sdf             *
30 *****************************************************************************
31 *                                                                           *
32 * This program is free software; you can redistribute it and/or modify it   *
33 * under the terms of the GNU General Public License as published by the     *
34 * Free Software Foundation; either version 2 of the License or any later    *
35 * version.                                                                  *
36 *                                                                           *
37 * This program is distributed in the hope that it will useful, but WITHOUT  *
38 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     *
39 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License     *
40 * for more details.                                                         *
41 *                                                                           *
42 \***************************************************************************/
43
44 #include <stdio.h>
45 #include <stdlib.h>
46
47 char *d2e(string)
48 char *string;
49 {
50         /* This function is used to replace 'D's with 'E's for proper
51            exponential notation of numeric strings read from delimited
52            USGS data files.  It returns a pointer to a string. */
53
54         unsigned char x;
55
56         for (x=0; string[x]!=0; x++)
57                 if (string[x]=='D')
58                         string[x]='E';
59         return (string);
60 }
61
62 int main(argc,argv)
63 int argc;
64 char *argv[];
65 {
66         unsigned char minimum[30], maximum[30], swlong[30], swlat[30],
67                       nwlong[30], nwlat[30], nelong[30], nelat[30],
68                       selong[30], selat[30];
69         char string[40];
70         double max_el, min_el, max_west, min_west, max_north, min_north;
71         int x, y, z, c, array[1202][1202];
72         int arc_mod=0;
73         char splatfile[25];
74         FILE *fd;
75
76         if (argc!=2)
77         {
78                 fprintf(stderr,"Usage: usgs2sdf uncompressed_delimited_usgs_datafile (ie: wilmington-e)\n");
79                 exit(0);
80         }
81
82         fd=fopen(argv[1],"rb");
83
84         if (fd!=NULL)
85         {
86                 fprintf(stdout,"Reading \"%s\"...",argv[1]);
87                 fflush(stdout);
88
89                 /* Skip first 548 bytes */
90
91                 for (x=0; x<548; x++)
92                         getc(fd);
93
94                 /* Read quadrangle corners */
95         
96                 /* Read southwest longitude */
97
98                 for (x=0; x<22; x++)
99                         swlong[x]=getc(fd);
100
101                 swlong[x]=0;
102
103                 /* Skip 2 bytes */
104
105                 for (x=0; x<2; x++)
106                         getc(fd);
107
108                 /* Read southwest latitude */
109
110                 for (x=0; x<22; x++)
111                         swlat[x]=getc(fd);
112
113                 swlat[x]=0;
114
115                 /* Skip 2 bytes */
116
117                 for (x=0; x<2; x++)
118                         getc(fd);
119
120                 /* Read northwest longitude */
121
122                 for (x=0; x<22; x++)
123                         nwlong[x]=getc(fd);
124
125                 nwlong[x]=0;
126
127                 /* Skip 2 bytes */
128
129                 for (x=0; x<2; x++)
130                         getc(fd);
131
132                 /* Read northwest latitude */
133
134                 for (x=0; x<22; x++)
135                         nwlat[x]=getc(fd);
136
137                 nwlat[x]=0;
138
139                 /* Skip 2 bytes */
140
141                 for (x=0; x<2; x++)
142                         getc(fd);
143
144                 /* Read northeast longitude */
145
146                 for (x=0; x<22; x++)
147                         nelong[x]=getc(fd);
148
149                 nelong[x]=0;
150
151                 /* Skip 2 bytes */
152
153                 for (x=0; x<2; x++)
154                         getc(fd);
155
156                 /* Read northeast latitude */
157
158                 for (x=0; x<22; x++)
159                         nelat[x]=getc(fd);
160
161                 nelat[x]=0;
162
163                 /* Skip 2 bytes */
164
165                 for (x=0; x<2; x++)
166                         getc(fd);
167
168                 /* Read southeast longitude */
169
170                 for (x=0; x<22; x++)
171                         selong[x]=getc(fd);
172
173                 selong[x]=0;
174
175                 /* Skip 2 bytes */
176
177                 for (x=0; x<2; x++)
178                         getc(fd);
179
180                 /* Read southeast latitude */
181
182                 for (x=0; x<22; x++)
183                         selat[x]=getc(fd);
184
185                 selat[x]=0;
186
187                 /* Skip 2 bytes */
188
189                 for (x=0; x<2; x++)
190                         getc(fd);
191
192                 /* Read minimum elevation */ 
193
194                 for (x=0; x<22; x++)
195                         minimum[x]=getc(fd);
196
197                 minimum[x]=0;
198
199                 /* Skip 2 bytes */
200
201                 for (x=0; x<2; x++)
202                         getc(fd);
203
204                 /* Read maximum elevation */
205
206                 for (x=0; x<22; x++)
207                         maximum[x]=getc(fd);
208
209                 maximum[x]=0;
210
211                 sscanf(d2e((char*)minimum),"%lG",&min_el);
212                 sscanf(d2e((char*)maximum),"%lf",&max_el);
213
214                 sscanf(d2e((char*)swlong),"%lf",&max_west);
215                 sscanf(d2e((char*)swlat),"%lf",&min_north);
216
217                 sscanf(d2e((char*)nelong),"%lf",&min_west);
218                 sscanf(d2e((char*)nelat),"%lf",&max_north);
219
220                 max_west/=-3600.0;
221                 min_north/=3600.0;
222                 max_north/=3600.0;
223                 min_west/=-3600.0;
224
225                 /* If the latitude is between 50 and 70, there are only 600 vertical lines of data.  
226                    If the latitude is greater than 70, there are only 400.  arc_mod is the flag for
227                    use later */
228
229                 if (min_north >= 50.0)
230                         arc_mod++;
231                 
232                 if (min_north >= 70.0)
233                         arc_mod++;
234
235
236                 /* Skip 84 Bytes  - Modified to 238 by jgabby 07/05 */
237
238                 for (x=0; x<238; x++)
239                         getc(fd);
240
241                 /* Read elevation data... */
242
243                 for (x=1200; x>=0; x--)
244                 {
245                         if (x==900)
246                         {
247                                 printf(" 25%c...",37);
248                                 fflush(stdout);
249                         }
250
251                         if (x==600)
252                         {
253                                 printf(" 50%c...",37);
254                                 fflush(stdout);
255                         }
256
257                         if (x==300)
258                         {
259                                 printf(" 75%c... ",37);
260                                 fflush(stdout);
261                         }
262
263                         /* Skip over 9 strings of data */
264
265                         for (y=0; y<9; y++)
266                         {
267                                 string[0]=0;
268
269                                 do
270                                 {
271                                         c=getc(fd);
272
273                                 } while (c==' ' || c=='\n');
274
275                                 for (z=0; c!=' ' && c!='\n' && z<28; z++)
276                                 {
277                                         string[z]=c;
278                                         c=getc(fd);
279                                 }
280
281                                 string[z]=0;    
282                         }
283
284                         /* Store elevation data in array */
285
286                         for (y=0; y<1201; y++)
287                         {
288                                 string[0]=0;
289
290                                 do
291                                 {
292                                         c=getc(fd);
293
294                                 } while (c==' ' || c=='\n');
295
296                                 for (z=0; c!=' ' && c!='\n' && z<28; z++)
297                                 {
298                                         string[z]=c;
299                                         c=getc(fd);
300                                 }
301
302                                 string[z]=0;
303
304                                 sscanf(string,"%d",&array[y][x]);
305
306                                 /* The next few lines either duplicate or triplicate the lines to
307                                    ensure a 1200x1200 result, depending on how arc_mod was set earlier */
308
309                                 if (arc_mod > 0)
310                                         sscanf(string,"%d",&array[y][x-1]);
311
312                                 if (arc_mod > 1)
313                                         sscanf(string,"%d",&array[y][x-2]);                             
314                         }
315                         
316                         if (arc_mod > 0)
317                                 x--;
318
319
320                         if (arc_mod > 1)
321                                 x--;
322                 }
323
324                 fclose(fd);
325
326                 /* Write splat data file to disk */
327
328                 sprintf(splatfile,"%.0f:%.0f:%.0f:%.0f.sdf",min_north,max_north,min_west,max_west);
329
330                 fprintf(stdout," Done!\nWriting \"%s\"... ",splatfile);
331                 fflush(stdout);
332
333                 fd=fopen(splatfile,"w");
334
335                 fprintf(fd,"%.0f\n%.0f\n%.0f\n%.0f\n", max_west, min_north, min_west, max_north);
336
337                 for (x=0; x<1200; x++)
338                         for (y=0; y<1200; y++)
339                                 fprintf(fd,"%d\n",array[x][y]);
340
341                 fclose(fd);
342                 fprintf(stdout,"Done!\n");
343                 fflush(stdout);
344         }
345
346         if (fd==NULL)
347         {
348                 fprintf(stderr,"*** %c%s%c: File Not Found!\n",34,argv[1],34);
349                 exit(-1);
350         }
351
352         else
353                 exit(0);
354 }
355