]> git.mxchange.org Git - flightgear.git/blob - src/Airports/simple.cxx
4d74af4b4099926cab89d36b2f19c5a99bc45148
[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( SG_HAVE_NATIVE_SGI_COMPILERS )
55 #  include <iostream.h>
56 #elif defined( __BORLANDC__ ) || defined (__APPLE__)
57 #  include <iostream>
58 #else
59 #  include <istream.h>
60 #endif
61 #if ! defined( SG_HAVE_NATIVE_SGI_COMPILERS )
62 SG_USING_STD(istream);
63 #endif
64
65
66 inline istream&
67 operator >> ( istream& in, FGAirport& a )
68 {
69     return in >> a.id >> a.latitude >> a.longitude >> a.elevation;
70 }
71
72
73 FGAirports::FGAirports( const string& file ) {
74     // open the specified database readonly
75     storage = new c4_Storage( file.c_str(), false );
76
77     if ( !storage->Strategy().IsValid() ) {
78         SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
79         exit(-1);
80     }
81
82     vAirport = new c4_View;
83     *vAirport = 
84         storage->GetAs("airport[ID:S,Longitude:F,Latitude:F,Elevation:F]");
85 }
86
87
88 // search for the specified id
89 bool
90 FGAirports::search( const string& id, FGAirport* a ) const
91 {
92     c4_StringProp pID ("ID");
93     c4_FloatProp pLon ("Longitude");
94     c4_FloatProp pLat ("Latitude");
95     c4_FloatProp pElev ("Elevation");
96
97     int idx = vAirport->Find(pID[id.c_str()]);
98     cout << "idx = " << idx << endl;
99
100     if ( idx == -1 ) {
101         return false;
102     }
103
104     c4_RowRef r  = vAirport->GetAt(idx);
105     a->id        = (const char *) pID(r); /// NHV fix wrong case crash
106     a->longitude = (double) pLon(r);
107     a->latitude  =  (double) pLat(r);
108     a->elevation = (double) pElev(r);
109
110     return true;
111 }
112
113
114 FGAirport
115 FGAirports::search( const string& id ) const
116 {
117     FGAirport a;
118     search( id, &a );
119     return a;
120 }
121
122
123 // Destructor
124 FGAirports::~FGAirports( void ) {
125     delete storage;
126 }
127
128
129 // Constructor
130 FGAirportsUtil::FGAirportsUtil() {
131 }
132
133
134 // load the data
135 int FGAirportsUtil::load( const string& file ) {
136     FGAirport a;
137
138     airports.erase( airports.begin(), airports.end() );
139
140     sg_gzifstream in( file );
141     if ( !in.is_open() ) {
142         SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
143         exit(-1);
144     } else {
145         SG_LOG( SG_GENERAL, SG_ALERT, "opened: " << file );
146     }
147
148     // skip first line of file
149     char tmp[2048];
150     in.getline( tmp, 2048 );
151
152     // read in each line of the file
153
154 #ifdef __MWERKS__
155
156     in >> ::skipws;
157     char c = 0;
158     while ( in.get(c) && c != '\0' ) {
159         if ( c == 'A' ) {
160             in >> a;
161             SG_LOG( SG_GENERAL, SG_INFO, a.id );
162             in >> skipeol;
163             airports.insert(a);
164         } else if ( c == 'R' ) {
165             in >> skipeol;
166         } else {
167             in >> skipeol;
168         }
169         in >> ::skipws;
170     }
171
172 #else
173
174     in >> ::skipws;
175     string token;
176     while ( ! in.eof() ) {
177         in >> token;
178         if ( token == "A" ) {
179             in >> a;
180             SG_LOG( SG_GENERAL, SG_INFO, "in <- " << a.id );
181             in >> skipeol;
182             airports.insert(a);
183         } else if ( token == "R" ) {
184             in >> skipeol;
185         } else {
186             in >> skipeol;
187         }
188         in >> ::skipws;
189     }
190
191 #endif
192
193     return 1;
194 }
195
196
197 // save the data in gdbm format
198 bool FGAirportsUtil::dump_mk4( const string& file ) {
199
200     // open database for writing
201     c4_Storage storage( file.c_str(), true );
202
203     // need to do something about error handling here!
204
205     // define the properties
206     c4_StringProp pID ("ID");
207     c4_FloatProp pLon ("Longitude");
208     c4_FloatProp pLat ("Latitude");
209     c4_FloatProp pElev ("Elevation");
210
211     // Start with an empty view of the proper structure.
212     c4_View vAirport =
213         storage.GetAs("airport[ID:S,Longitude:F,Latitude:F,Elevation:F]");
214
215     c4_Row row;
216
217     const_iterator current = airports.begin();
218     const_iterator end = airports.end();
219     while ( current != end ) {
220         // add each airport record
221         cout << "out -> " << current->id << endl;
222         pID (row) = current->id.c_str();
223         pLon (row) = current->longitude;
224         pLat (row) = current->latitude;
225         pElev (row) = current->elevation;
226         vAirport.Add(row);
227
228         ++current;
229     }
230
231     // commit our changes
232     storage.Commit();
233
234     return true;
235 }
236
237
238 // search for the specified id
239 bool
240 FGAirportsUtil::search( const string& id, FGAirport* a ) const
241 {
242     const_iterator it = airports.find( FGAirport(id) );
243     if ( it != airports.end() )
244     {
245         *a = *it;
246         return true;
247     }
248     else
249     {
250         return false;
251     }
252 }
253
254
255 FGAirport
256 FGAirportsUtil::search( const string& id ) const
257 {
258     FGAirport a;
259     this->search( id, &a );
260     return a;
261 }
262
263
264 // Destructor
265 FGAirportsUtil::~FGAirportsUtil( void ) {
266 }
267
268