]> git.mxchange.org Git - flightgear.git/blob - src/Navaids/fixlist.cxx
return attribute mask as unsigned
[flightgear.git] / src / Navaids / fixlist.cxx
1 // fixlist.cxx -- fix list management class
2 //
3 // Written by Curtis Olson, started April 2000.
4 //
5 // Copyright (C) 2000  Curtis L. Olson - http://www.flightgear.org/~curt
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #include <simgear/debug/logstream.hxx>
29 #include <simgear/misc/sgstream.hxx>
30 #include <simgear/math/sg_geodesy.hxx>
31
32 #include "fixlist.hxx"
33 SG_USING_STD(pair);
34
35
36 // Constructor
37 FGFixList::FGFixList( void ) {
38 }
39
40
41 // Destructor
42 FGFixList::~FGFixList( void ) {
43 }
44
45
46 // load the navaids and build the map
47 bool FGFixList::init( SGPath path ) {
48     fixlist.erase( fixlist.begin(), fixlist.end() );
49
50     sg_gzifstream in( path.str() );
51     if ( !in.is_open() ) {
52         SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() );
53         exit(-1);
54     }
55
56     // toss the first two lines of the file
57     in >> skipeol;
58     in >> skipeol;
59
60     // read in each remaining line of the file
61
62 #ifdef __MWERKS__
63     char c = 0;
64     while ( in.get(c) && c != '\0' ) {
65         in.putback(c);
66 #else   
67     while ( ! in.eof() ) {
68 #endif
69
70         FGFix fix;
71         in >> fix;
72         if ( fix.get_lat() > 95.0 ) {
73             break;
74         }
75
76         /* cout << "ident=" << fix.get_ident()
77              << ", lat=" << fix.get_lat()
78              << ", lon=" << fix.get_lon() << endl; */
79
80         fixlist.insert(pair<string, FGFix>(fix.get_ident(), fix));
81         in >> skipcomment;
82     }
83     return true;
84 }
85
86
87 // query the database for the specified fix, lon and lat are in
88 // degrees, elev is in meters
89 bool FGFixList::query( const string& ident, FGFix *fix ) {
90     fix_map_const_iterator it = fixlist.find(ident);
91     if ( it != fixlist.end() ) {
92         *fix = it->second;
93         return true;
94     } else {
95         return false;
96     }
97 }
98
99
100 // query the database for the specified fix, lon and lat are in
101 // degrees, elev is in meters
102 bool FGFixList::query_and_offset( const string& ident, double lon, double lat,
103                                   double elev, FGFix *fix, double *heading,
104                                   double *dist )
105 {
106     pair<fix_map_const_iterator, fix_map_const_iterator> range = fixlist.equal_range(ident);
107
108     if (range.first == range.second) {
109         return false;
110     }
111
112     double min_s = -1.0;
113     for (fix_map_const_iterator current = range.first; current != range.second; ++current) {
114         double az1, az2, s;
115         geo_inverse_wgs_84( elev, lat, lon,
116                         current->second.get_lat(), current->second.get_lon(),
117                         &az1, &az2, &s );
118         // cout << "  dist = " << s << endl;
119         if (min_s < 0 || s < min_s) {
120             *heading = az2;
121             *dist = s;
122             min_s = s;
123             *fix = current->second;
124         }
125     }
126
127     return true;
128 }
129
130 const FGFix* FGFixList::findFirstByIdent( const string& ident, bool exact)
131 {
132     fix_map_iterator itr;
133     if(exact) {
134         itr = fixlist.find(ident);
135     } else {
136         itr = fixlist.lower_bound(ident);
137     }
138     if(itr == fixlist.end()) {
139         return(NULL);
140     } else {
141         return(&(itr->second));
142     }
143 }