]> git.mxchange.org Git - flightgear.git/blob - src/Navaids/fixlist.cxx
Fix a compile problem for lower_bound()
[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 <algorithm>
29
30 #include <simgear/debug/logstream.hxx>
31 #include <simgear/misc/sgstream.hxx>
32 #include <simgear/math/sg_geodesy.hxx>
33
34 #include "fixlist.hxx"
35 #include "Airports/simple.hxx";
36
37 using std::pair;
38
39
40 // Constructor
41 FGFixList::FGFixList( void ) {
42 }
43
44
45 // Destructor
46 FGFixList::~FGFixList( void ) {
47 }
48
49
50 // load the navaids and build the map
51 bool FGFixList::init( SGPath path ) {
52     fixlist.erase( fixlist.begin(), fixlist.end() );
53
54     sg_gzifstream in( path.str() );
55     if ( !in.is_open() ) {
56         SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() );
57         exit(-1);
58     }
59
60     // toss the first two lines of the file
61     in >> skipeol;
62     in >> skipeol;
63
64     // read in each remaining line of the file
65     while ( ! in.eof() ) {
66
67         FGFix fix;
68         in >> fix;
69         if ( fix.get_lat() > 95.0 ) {
70             break;
71         }
72
73         /* cout << "ident=" << fix.get_ident()
74              << ", lat=" << fix.get_lat()
75              << ", lon=" << fix.get_lon() << endl; */
76
77         fixlist.insert(pair<string, FGFix>(fix.get_ident(), fix));
78         in >> skipcomment;
79     }
80     return true;
81 }
82
83
84 // query the database for the specified fix, lon and lat are in
85 // degrees, elev is in meters
86 bool FGFixList::query( const string& ident, FGFix *fix ) {
87     fix_map_const_iterator it = fixlist.find(ident);
88     if ( it != fixlist.end() ) {
89         *fix = it->second;
90         return true;
91     } else {
92         return false;
93     }
94 }
95
96
97 // query the database for the specified fix, lon and lat are in
98 // degrees, elev is in meters
99 bool FGFixList::query_and_offset( const string& ident, double lon, double lat,
100                                   double elev, FGFix *fix, double *heading,
101                                   double *dist )
102 {
103     pair<fix_map_const_iterator, fix_map_const_iterator> range = fixlist.equal_range(ident);
104
105     if (range.first == range.second) {
106         return false;
107     }
108
109     double min_s = -1.0;
110     for (fix_map_const_iterator current = range.first; current != range.second; ++current) {
111         double az1, az2, s;
112         geo_inverse_wgs_84( elev, lat, lon,
113                         current->second.get_lat(), current->second.get_lon(),
114                         &az1, &az2, &s );
115         // cout << "  dist = " << s << endl;
116         if (min_s < 0 || s < min_s) {
117             *heading = az2;
118             *dist = s;
119             min_s = s;
120             *fix = current->second;
121         }
122     }
123
124     return true;
125 }
126
127 const FGFix* FGFixList::search(const string& ident)
128 {
129   fix_map_iterator itr = fixlist.find(ident);
130   if (itr == fixlist.end()) {
131     return NULL;
132   }
133   
134   return &itr->second;
135 }
136
137 class orderingFunctor
138 {
139 public:
140   orderingFunctor(FGIdentOrdering* aOrder) :
141     mOrdering(aOrder)
142   { assert(aOrder); }
143   
144   bool operator()(const fix_map_type::value_type& aA, const std::string& aB) const
145   {
146     return mOrdering->compare(aA.first,aB);
147   }
148   
149 private:
150   FGIdentOrdering* mOrdering;
151 };
152
153 const FGFix* FGFixList::findFirstByIdent( const string& ident, FGIdentOrdering* aOrder)
154 {
155   fix_map_iterator itr;
156   if (aOrder) {
157     orderingFunctor func(aOrder);
158     itr = std::lower_bound(fixlist.begin(),fixlist.end(), ident, func);
159   } else {
160     itr = fixlist.lower_bound(ident);
161   }
162   
163   if (itr == fixlist.end()) {
164     return NULL;
165   }
166   
167   return &itr->second;
168 }