]> git.mxchange.org Git - flightgear.git/blob - Scenery/dem2scene.pl
97af872fa4a08ba446e3491e7b90f579d9f56d9e
[flightgear.git] / Scenery / dem2scene.pl
1 #!/usr/local/bin/perl
2 #
3 # dem2scene.pl -- Read in a dem data file, and output a more usable format.
4 #
5 # Written by Curtis Olson, started May 1997.
6 #
7 # Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
8 #
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write to the Free Software
21 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #
23 # $Id$
24 # (Log is kept at end of this file)
25 #---------------------------------------------------------------------------
26
27
28 use strict;
29
30
31 # declare variables
32 my($token);
33 my($i, $j);
34 my($arg);
35 my($res) = 1;
36
37 # "A" Record Information
38 my($dem_description, $dem_quadrangle);
39 my($dem_x1, $dem_y1, $dem_x2, $dem_y2, $dem_x3, $dem_y3, $dem_x4, $dem_y4);
40 my($dem_z1, $dem_z2); 
41 my($dem_resolution, $dem_num_profiles);
42
43 # "B" Record Information
44 my($prof_row, $prof_col);
45 my($prof_num_rows, $prof_num_cols);
46 my($prof_x1, $prof_y1);
47 my($prof_data);
48
49 # set input record separator to be a space
50 $/ = " ";
51
52 # parse command line arguments
53 while ( $arg = shift(@ARGV) ) {
54     if ( $arg eq "-r" ) {
55         $res = shift(@ARGV);
56         if ( $res < 1 ) {
57             &usage();
58         }
59     } else {
60         &usage();
61     }
62 }
63
64 # print usage and die
65 sub usage {
66     die "Usage: $0 [ -r resval ]\n";
67 }
68
69
70 &read_a_record();
71 &output_scene_hdr();
72
73 $i = 0;
74 while ( $i < $dem_num_profiles ) {
75     &read_b_record();
76     &output_row();
77
78     $i++;
79
80     if ( $i < $dem_num_profiles ) {
81         # not on last record
82         for ( $j = 1; $j < $res; $j++ ) {
83             # print "skipping row\n";
84             &read_b_record();
85         }
86     }
87 }
88
89 &output_scene_close();
90
91 # read and parse DEM "A" record
92 sub read_a_record {
93     my($i);
94
95     # read initial descriptive header
96     while ( ($token = &next_token()) ne "_END_OF_FILE_" ) {
97         if ( $token !~ m/^NJ/ && $token !~ m/^NI/ ) {
98             $dem_description .= "$token ";
99         } else {
100             chop($dem_description);
101             $dem_quadrangle = $token;
102             last;
103         }
104     }
105     # print "'$dem_description' '$dem_quadrangle'\n";
106
107     # DEM level code, 3 reflects processing by DMA
108     &next_token();
109
110     # Pattern code, 1 indicates a regular elevation pattern
111     &next_token();
112
113     # Planimetric reference system code, 0 indicates geographic
114     # coordinate system.
115     &next_token();
116
117     # Zone code
118     &next_token();
119
120     # Map projection parameters (ignored)
121     for ($i = 0; $i < 15; $i++) {
122         &next_token();
123     }
124
125     # Units code, 3 represents arc-seconds as the unit of measure for
126     # ground planimetric coordinates throughout the file.
127     die "Unknown units code!\n" if ( &next_token() ne "3" );
128
129     # Units code; 2 represents meters as the unit of measure for
130     # elevation coordinates throughout the file.  
131     die "Unknown units code!\n" if ( &next_token() ne "2" );
132
133     # Number (n) of sides in the polygon which defines the coverage of
134     # the DEM file (usually equal to 4).
135     die "Unknown polygon dimension!\n" if ( &next_token() ne "4" );
136
137     # Ground coordinates of bounding box in arc-seconds
138     $dem_x1 = &next_token();
139     $dem_y1 = &next_token();
140
141     $dem_x2 = &next_token();
142     $dem_y2 = &next_token();
143
144     $dem_x3 = &next_token();
145     $dem_y3 = &next_token();
146
147     $dem_x4 = &next_token();
148     $dem_y4 = &next_token();
149
150     # Minimum/maximum elevations in meters
151     $dem_z1 = &next_token();
152     $dem_z2 = &next_token();
153
154     # Counterclockwise angle from the primary axis of ground
155     # planimetric referenced to the primary axis of the DEM local
156     # reference system.
157     &next_token();
158
159     # Accuracy code; 0 indicates that a record of accuracy does not
160     # exist and that no record type C will follow.
161     # &next_token();
162
163     # DEM spacial resolution.  Usually (3,3,1) (3,6,1) or (3,9,1)
164     # depending on latitude
165     $dem_resolution = &next_token();
166
167     # one dimensional arrays
168     &next_token();
169
170     # number of profiles
171     $dem_num_profiles = &next_token();
172     $dem_num_profiles = (($dem_num_profiles - 1) / $res) + 1;
173 }
174
175
176 # output the scene headers
177 sub output_scene_hdr {
178     my($dx, $dy, $dz);
179
180     printf("mesh %s_terrain {\n", $dem_quadrangle);
181
182     $dem_x1 =~ s/D/E/; $dem_x1 += 0.0;
183     $dem_y1 =~ s/D/E/; $dem_y1 += 0.0;
184     print "    // This mesh is rooted at the following coordinates (in arc seconds)\n";
185     print "    origin_lon = $dem_x1\n";
186     print "    origin_lat = $dem_y1\n";
187     print "\n";
188
189     print "    // Number of rows and columns (needed by the parser so it can create\n";
190     print "    //the proper size structure\n";
191     print "    rows = $dem_num_profiles\n";
192     print "    cols = $dem_num_profiles\n";  # This isn't necessarily guaranteed
193     print "\n";
194
195     ($dx, $dy, $dz) = $dem_resolution =~ 
196         m/(.............)(............)(............)/;
197     $dx *= $res;
198     $dy *= $res;
199     print "    // Distance between x and y data points (in arc seconds)\n";
200     print "    row_step = $dx\n";
201     print "    col_step = $dy\n";
202     print "\n";
203 }
204
205
206 # output the scene close
207 sub output_scene_close {
208     print "\n";
209     print "}\n";
210 }
211
212
213 # read and parse DEM "B" record
214 sub read_b_record {
215     my($i, $j);
216
217     # row / column id of this profile
218     $prof_row = &next_token();
219     $prof_col = &next_token();
220
221     # Number of rows (elevations) and columns in this profile;
222     $prof_num_rows = &next_token();
223     $prof_num_cols = &next_token();
224
225     $prof_num_rows = (($prof_num_rows - 1) / $res) + 1;
226     # print "profile num rows = $prof_num_rows\n";
227
228     # Ground planimetric coordinates (arc-seconds) of the first
229     # elevation in the profile
230     $prof_x1 = &next_token();
231     $prof_y1 = &next_token();
232
233     # Elevation of local datum for the profile.  Always zero for
234     # 1-degree DEM, the reference is mean sea level.
235     &next_token();
236
237     # Minimum and maximum elevations for the profile.
238     &next_token();
239     &next_token();
240
241     # One (usually) dimensional array ($prof_num_rows,1) of elevations
242     $prof_data = "";
243     $i = 0;
244     while ( $i < $prof_num_rows ) {
245         $prof_data .= &next_token();
246         $prof_data .= " ";
247
248         $i++;
249
250         if ( $i < $prof_num_rows ) {
251             # not on last data point
252             # skip the tokens to get requested resolution
253             for ($j = 1; $j < $res; $j++) {
254                 # print "skipping ...\n";
255                 &next_token();
256             }
257         }
258     }
259     chop($prof_data);
260
261     # print "$prof_data\n\n";
262 }
263
264
265 # output a row of data
266 sub output_row {
267     print "    row = ($prof_data)\n";
268 }
269
270
271 # return next token from input stream
272 sub next_token {
273     my($token);
274
275     # print "in next token\n";
276
277     do {
278         $token = <>; chop($token);
279         if ( eof() ) {
280             $token = "_END_OF_FILE_";
281         }
282     } while ( $token eq "" );
283
284     # print "returning $token\n";
285
286     return $token;
287 }
288
289 while ( ($token = &next_token()) ne "_END_OF_FILE_" ) {
290     # print "'$token'\n";
291 }
292
293
294 #---------------------------------------------------------------------------
295 # $Log$
296 # Revision 1.2  1997/05/30 19:30:16  curt
297 # The LaRCsim flight model is starting to look like it is working.
298 #
299 # Revision 1.1  1997/05/27 21:56:02  curt
300 # Initial revision (with data skipping support)
301 #