1 /* rawdem.c -- library of routines for processing raw dem files (30 arcsec)
3 * Written by Curtis Olson, started February 1998.
5 * Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * (Log is kept at end of this file)
26 #include <math.h> /* rint() */
28 #include <stdlib.h> /* atoi() atof() */
29 #include <string.h> /* swab() */
31 #include <sys/types.h> /* open() */
34 #include <unistd.h> /* close() */
39 /* Read the DEM header to determine various key parameters for this
41 void rawReadDemHdr( fgRAWDEM *raw, char *hdr_file ) {
43 char line[256], key[256], value[256];
47 if ( (hdr = fopen(hdr_file, "r")) == NULL ) {
48 printf("Error opening DEM header file: %s\n", hdr_file);
52 /* process each line */
53 while ( (fgets(line, 256, hdr) != NULL) ) {
54 /* printf("%s", line); */
59 while ( (line[i] != ' ') && (i < len) ) {
65 /* skip middle space */
66 while ( (line[i] == ' ') && (i < len) ) {
72 while ( (line[i] != '\n') && (i < len) ) {
73 value[i-offset] = line[i];
76 value[i-offset] = '\0';
77 /* printf("key='%s' value='%s'\n", key, value); */
79 if ( strcmp(key, "NROWS") == 0 ) {
80 raw->nrows = atoi(value);
81 } else if ( strcmp(key, "NCOLS") == 0 ) {
82 raw->ncols = atoi(value);
83 } else if ( strcmp(key, "ULXMAP") == 0 ) {
85 raw->ulxmap = (int)rint(tmp * 3600.0); /* convert to arcsec */
86 } else if ( strcmp(key, "ULYMAP") == 0 ) {
88 raw->ulymap = (int)rint(tmp * 3600.0); /* convert to arcsec */
89 } else if ( strcmp(key, "XDIM") == 0 ) {
91 raw->xdim = (int)rint(tmp * 3600.0); /* convert to arcsec */
92 } else if ( strcmp(key, "YDIM") == 0 ) {
94 raw->ydim = (int)rint(tmp * 3600.0); /* convert to arcsec */
100 raw->rootx = raw->ulxmap - (raw->xdim / 2);
101 raw->rooty = raw->ulymap + (raw->ydim / 2);
103 printf("%d %d %d %d %d %d %d %d\n", raw->nrows, raw->ncols,
104 raw->ulxmap, raw->ulymap, raw->rootx, raw->rooty, raw->xdim,
109 /* Open a raw DEM file. */
110 void rawOpenDemFile( fgRAWDEM *raw, char *raw_dem_file ) {
111 printf("Opening Raw DEM file: %s\n", raw_dem_file);
112 if ( (raw->fd = open(raw_dem_file ,O_RDONLY)) == -1 ) {
113 printf("Error opening Raw DEM file: %s\n", raw_dem_file);
119 /* Close a raw DEM file. */
120 void rawCloseDemFile( fgRAWDEM *raw ) {
125 /* Advance file pointer position to correct latitude (row) */
126 void rawAdvancePosition( fgRAWDEM *raw, int arcsec ) {
129 offset = 2 * raw->ncols * ( arcsec / raw->ydim );
131 if ( (result = lseek(raw->fd, offset, SEEK_SET)) == -1 ) {
132 printf("Error lseek filed trying to offset by %ld\n", offset);
136 printf("Successful seek ahead of %ld bytes\n", result);
140 /* Read the next row of data */
141 void rawReadNextRow( fgRAWDEM *raw, int index ) {
142 char buf[MAX_COLS_X_2];
145 if ( raw->ncols > MAX_ROWS ) {
146 printf("Error, buf needs to be bigger in rawReadNextRow()\n");
150 /* printf("Attempting to read %d bytes\n", 2 * raw->ncols); */
151 result = read(raw->fd, buf, 2 * raw->ncols);
152 /* printf("Read %d bytes\n", result); */
154 /* reverse byte order */
155 /* it would be nice to test in advance some how if we need to do
157 /* swab(frombuf, tobuf, 2 * raw->ncols); */
159 for ( i = 0; i < raw->ncols; i++ ) {
160 /* printf("hi = %d lo = %d\n", buf[2*i], buf[2*i + 1]); */
161 raw->strip[index][i] = ( (buf[2*i] + 1) << 8 ) + buf[2*i + 1];
166 /* Convert from pixel centered values to pixel corner values. This is
167 accomplished by taking the average of the closes center nodes. In
168 the following diagram "x" marks the data point location:
177 void rawConvertCenter2Edge( fgRAWDEM *raw ) {
180 /* derive corner nodes */
181 raw->edge[0][0] = raw->center[0][0];
182 raw->edge[120][0] = raw->center[119][0];
183 raw->edge[120][120] = raw->center[119][119];
184 raw->edge[0][120] = raw->center[0][119];
186 /* derive edge nodes */
187 for ( i = 1; i < 120; i++ ) {
188 raw->edge[i][0] = (raw->center[i-1][0] + raw->center[i][0]) / 2.0;
189 raw->edge[i][120] = (raw->center[i-1][119] + raw->center[i][119]) / 2.0;
190 raw->edge[0][i] = (raw->center[0][i-1] + raw->center[0][i]) / 2.0;
191 raw->edge[120][i] = (raw->center[119][i-1] + raw->center[119][i]) / 2.0;
194 /* derive internal nodes */
195 for ( j = 1; j < 120; j++ ) {
196 for ( i = 1; i < 120; i++ ) {
197 raw->edge[i][j] = ( raw->center[i-1][j-1] +
198 raw->center[i] [j-1] +
200 raw->center[i-1][j] ) / 4;
206 /* Dump out the ascii format DEM file */
207 void rawDumpAsciiDEM( fgRAWDEM *raw ) {
211 /* Read a horizontal strip of (1 vertical degree) from the raw DEM
212 * file specified by the upper latitude of the stripe specified in
214 void rawReadStrip( fgRAWDEM *raw, int lat_degrees ) {
216 int i, j, index, row, col;
217 int min = 0, max = 0;
218 int span, num_degrees, tile_width;
221 /* convert to arcsec */
222 lat = lat_degrees * 3600;
224 printf("Max Latitude = %d arcsec\n", lat);
226 /* validity check ... */
227 if ( (lat > raw->rooty) ||
228 (lat < (raw->rooty - raw->nrows * raw->ydim + 1)) ) {
229 printf("Latitude out of range for this DEM file\n");
233 printf ("Reading strip starting at %d (top and working down)\n", lat);
235 /* advance to the correct latitude */
236 rawAdvancePosition(raw, (raw->rooty - lat));
238 /* printf("short = %d\n", sizeof(short)); */
240 yrange = 3600 / raw->ydim;
242 for ( i = 0; i < yrange; i++ ) {
243 index = yrange - i - 1;
244 /* printf("About to read into row %d\n", index); */
245 rawReadNextRow(raw, index);
247 for ( j = 0; j < raw->ncols; j++ ) {
248 if ( raw->strip[index][j] == -9999 ) {
249 /* map ocean to 0 for now */
250 raw->strip[index][j] = 0;
253 if ( raw->strip[index][j] < min) {
254 min = raw->strip[index][j];
257 if ( raw->strip[index][j] > max) {
258 max = raw->strip[index][j];
262 printf("min = %d max = %d\n", min, max);
264 /* extract individual tiles from the strip */
265 span = raw->ncols * raw->xdim;
266 num_degrees = span / 3600;
267 tile_width = raw->ncols / num_degrees;
268 printf("span = %d num_degrees = %d width = %d\n",
269 span, num_degrees, tile_width);
271 for ( i = 0; i < num_degrees; i++ ) {
272 xstart = i * tile_width;
275 for ( row = 0; row < yrange; row++ ) {
276 for ( col = xstart; col < xend; col++ ) {
277 /* Copy from strip to pixel centered tile. Yep,
278 * row/col are reversed here. raw->strip is backwards
279 * for convenience. I am converting to [x,y] now. */
280 raw->center[col-xstart][row] = raw->strip[row][col];
284 /* Convert from pixel centered to pixel edge values */
285 rawConvertCenter2Edge(raw);
287 /* Dump out the ascii format DEM file */
288 rawDumpAsciiDEM(raw);
294 /* Revision 1.1 1998/03/02 23:31:01 curt