]> git.mxchange.org Git - flightgear.git/blob - src/Airports/simple.cxx
David Luff writes:
[flightgear.git] / src / Airports / simple.cxx
1 //
2 // simple.cxx -- a really simplistic class to manage airport ID,
3 //                 lat, lon of the center of one of it's runways, and 
4 //                 elevation in feet.
5 //
6 // Written by Curtis Olson, started April 1998.
7 //
8 // Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
9 //
10 // This program is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU General Public License as
12 // published by the Free Software Foundation; either version 2 of the
13 // License, or (at your option) any later version.
14 //
15 // This program is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 // General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 //
24 // $Id$
25
26 #ifdef HAVE_CONFIG_H
27 #  include <config.h>
28 #endif
29
30 #include <simgear/compiler.h>
31
32 #include <simgear/debug/logstream.hxx>
33 #include <simgear/misc/sgstream.hxx>
34
35 #include STL_STRING
36 #include STL_FUNCTIONAL
37 #include STL_ALGORITHM
38
39 #include "simple.hxx"
40
41 SG_USING_NAMESPACE(std);
42
43 #ifndef _MSC_VER
44 #   define NDEBUG                       // she don't work without it.
45 #endif
46 #include <mk4.h>
47 #include <mk4str.h>
48 #ifndef _MSC_VER
49 #  undef NDEBUG
50 #endif
51
52 #ifdef SG_HAVE_STD_INCLUDES
53 #  include <istream>
54 #elif defined( __BORLANDC__ ) || defined (__APPLE__)
55 #  include <iostream>
56 #else
57 #  include <istream.h>
58 #endif
59 SG_USING_STD(istream);
60
61
62 inline istream&
63 operator >> ( istream& in, FGAirport& a )
64 {
65     return in >> a.id >> a.latitude >> a.longitude >> a.elevation;
66 }
67
68
69 FGAirports::FGAirports( const string& file ) {
70     // open the specified database readonly
71     storage = new c4_Storage( file.c_str(), false );
72
73     if ( !storage->Strategy().IsValid() ) {
74         SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
75         exit(-1);
76     }
77
78     vAirport = new c4_View;
79     *vAirport = 
80         storage->GetAs("airport[ID:S,Longitude:F,Latitude:F,Elevation:F]");
81 }
82
83
84 // search for the specified id
85 bool
86 FGAirports::search( const string& id, FGAirport* a ) const
87 {
88     c4_StringProp pID ("ID");
89     c4_FloatProp pLon ("Longitude");
90     c4_FloatProp pLat ("Latitude");
91     c4_FloatProp pElev ("Elevation");
92
93     int idx = vAirport->Find(pID[id.c_str()]);
94     cout << "idx = " << idx << endl;
95
96     if ( idx == -1 ) {
97         return false;
98     }
99
100     c4_RowRef r  = vAirport->GetAt(idx);
101     a->id        = (const char *) pID(r); /// NHV fix wrong case crash
102     a->longitude = (double) pLon(r);
103     a->latitude  =  (double) pLat(r);
104     a->elevation = (double) pElev(r);
105
106     return true;
107 }
108
109
110 FGAirport
111 FGAirports::search( const string& id ) const
112 {
113     FGAirport a;
114     search( id, &a );
115     return a;
116 }
117
118
119 // Destructor
120 FGAirports::~FGAirports( void ) {
121     delete storage;
122 }
123
124
125 // Constructor
126 FGAirportsUtil::FGAirportsUtil() {
127 }
128
129
130 // load the data
131 int FGAirportsUtil::load( const string& file ) {
132     FGAirport a;
133
134     airports.erase( airports.begin(), airports.end() );
135
136     sg_gzifstream in( file );
137     if ( !in.is_open() ) {
138         SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
139         exit(-1);
140     } else {
141         SG_LOG( SG_GENERAL, SG_ALERT, "opened: " << file );
142     }
143
144     // skip first line of file
145     char tmp[2048];
146     in.getline( tmp, 2048 );
147
148     // read in each line of the file
149
150 #ifdef __MWERKS__
151
152     in >> ::skipws;
153     char c = 0;
154     while ( in.get(c) && c != '\0' ) {
155         if ( c == 'A' ) {
156             in >> a;
157             SG_LOG( SG_GENERAL, SG_INFO, a.id );
158             in >> skipeol;
159             airports.insert(a);
160         } else if ( c == 'R' ) {
161             in >> skipeol;
162         } else {
163             in >> skipeol;
164         }
165         in >> ::skipws;
166     }
167
168 #else
169
170     in >> ::skipws;
171     string token;
172     while ( ! in.eof() ) {
173         in >> token;
174         if ( token == "A" ) {
175             in >> a;
176             SG_LOG( SG_GENERAL, SG_INFO, "in <- " << a.id );
177             in >> skipeol;
178             airports.insert(a);
179         } else if ( token == "R" ) {
180             in >> skipeol;
181         } else {
182             in >> skipeol;
183         }
184         in >> ::skipws;
185     }
186
187 #endif
188
189     return 1;
190 }
191
192
193 // save the data in gdbm format
194 bool FGAirportsUtil::dump_mk4( const string& file ) {
195
196     // open database for writing
197     c4_Storage storage( file.c_str(), true );
198
199     // need to do something about error handling here!
200
201     // define the properties
202     c4_StringProp pID ("ID");
203     c4_FloatProp pLon ("Longitude");
204     c4_FloatProp pLat ("Latitude");
205     c4_FloatProp pElev ("Elevation");
206
207     // Start with an empty view of the proper structure.
208     c4_View vAirport =
209         storage.GetAs("airport[ID:S,Longitude:F,Latitude:F,Elevation:F]");
210
211     c4_Row row;
212
213     const_iterator current = airports.begin();
214     const_iterator end = airports.end();
215     while ( current != end ) {
216         // add each airport record
217         cout << "out -> " << current->id << endl;
218         pID (row) = current->id.c_str();
219         pLon (row) = current->longitude;
220         pLat (row) = current->latitude;
221         pElev (row) = current->elevation;
222         vAirport.Add(row);
223
224         ++current;
225     }
226
227     // commit our changes
228     storage.Commit();
229
230     return true;
231 }
232
233
234 // search for the specified id
235 bool
236 FGAirportsUtil::search( const string& id, FGAirport* a ) const
237 {
238     const_iterator it = airports.find( FGAirport(id) );
239     if ( it != airports.end() )
240     {
241         *a = *it;
242         return true;
243     }
244     else
245     {
246         return false;
247     }
248 }
249
250
251 FGAirport
252 FGAirportsUtil::search( const string& id ) const
253 {
254     FGAirport a;
255     this->search( id, &a );
256     return a;
257 }
258
259
260 // Destructor
261 FGAirportsUtil::~FGAirportsUtil( void ) {
262 }
263
264