]> git.mxchange.org Git - flightgear.git/blob - src/Navaids/fixlist.cxx
- remove the SG_GLxxxx_H #defines, since OSG provides its own versions
[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 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     while ( ! in.eof() ) {
62
63         FGFix fix;
64         in >> fix;
65         if ( fix.get_lat() > 95.0 ) {
66             break;
67         }
68
69         /* cout << "ident=" << fix.get_ident()
70              << ", lat=" << fix.get_lat()
71              << ", lon=" << fix.get_lon() << endl; */
72
73         fixlist.insert(pair<string, FGFix>(fix.get_ident(), fix));
74         in >> skipcomment;
75     }
76     return true;
77 }
78
79
80 // query the database for the specified fix, lon and lat are in
81 // degrees, elev is in meters
82 bool FGFixList::query( const string& ident, FGFix *fix ) {
83     fix_map_const_iterator it = fixlist.find(ident);
84     if ( it != fixlist.end() ) {
85         *fix = it->second;
86         return true;
87     } else {
88         return false;
89     }
90 }
91
92
93 // query the database for the specified fix, lon and lat are in
94 // degrees, elev is in meters
95 bool FGFixList::query_and_offset( const string& ident, double lon, double lat,
96                                   double elev, FGFix *fix, double *heading,
97                                   double *dist )
98 {
99     pair<fix_map_const_iterator, fix_map_const_iterator> range = fixlist.equal_range(ident);
100
101     if (range.first == range.second) {
102         return false;
103     }
104
105     double min_s = -1.0;
106     for (fix_map_const_iterator current = range.first; current != range.second; ++current) {
107         double az1, az2, s;
108         geo_inverse_wgs_84( elev, lat, lon,
109                         current->second.get_lat(), current->second.get_lon(),
110                         &az1, &az2, &s );
111         // cout << "  dist = " << s << endl;
112         if (min_s < 0 || s < min_s) {
113             *heading = az2;
114             *dist = s;
115             min_s = s;
116             *fix = current->second;
117         }
118     }
119
120     return true;
121 }
122
123 const FGFix* FGFixList::findFirstByIdent( const string& ident, bool exact)
124 {
125     fix_map_iterator itr;
126     if(exact) {
127         itr = fixlist.find(ident);
128     } else {
129         itr = fixlist.lower_bound(ident);
130     }
131     if(itr == fixlist.end()) {
132         return(NULL);
133     } else {
134         return(&(itr->second));
135     }
136 }