]> git.mxchange.org Git - flightgear.git/blob - src/ATC/atislist.cxx
Tweak #includes to use double quotes for local files not <>
[flightgear.git] / src / ATC / atislist.cxx
1 // atislist.cxx -- navaids management class
2 //
3 // Written by Curtis Olson, started April 2000.
4 //
5 // Copyright (C) 2000  Curtis L. Olson - curt@flightgear.org
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21
22 #ifdef HAVE_CONFIG_H
23 #  include <config.h>
24 #endif
25
26 #include <simgear/debug/logstream.hxx>
27 #include <simgear/misc/sgstream.hxx>
28 #include <simgear/math/sg_geodesy.hxx>
29 #include <simgear/math/sg_random.h>
30
31 #include "atislist.hxx"
32
33
34 FGATISList *current_atislist;
35
36
37 // Constructor
38 FGATISList::FGATISList( void ) {
39 }
40
41
42 // Destructor
43 FGATISList::~FGATISList( void ) {
44 }
45
46
47 // load the navaids and build the map
48 bool FGATISList::init( SGPath path ) {
49     FGATIS a;
50
51     atislist.erase( atislist.begin(), atislist.end() );
52
53     sg_gzifstream in( path.str() );
54     if ( !in.is_open() ) {
55         SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() );
56         exit(-1);
57     }
58
59     // read in each line of the file
60
61     in >> skipeol;
62     in >> skipcomment;
63
64 #ifdef __MWERKS__
65
66     char c = 0;
67     while ( in.get(c) && c != '\0' && a.get_type() != '[' ) {
68         in.putback(c);
69         in >> a;
70         if ( a.get_type() != '[' ) {
71             atislist[a.get_freq()].push_back(a);
72         }
73         in >> skipcomment;
74     }
75
76 #else
77
78     double min = 100000;
79     double max = 0;
80
81     while ( ! in.eof() && a.get_type() != '[' ) {
82         in >> a;
83         //cout << "id = " << a.get_ident() << endl;
84         //cout << " type = " << a.get_type() << endl;
85         //cout << " lon = " << a.get_lon() << endl;
86         //cout << " lat = " << a.get_lat() << endl;
87         //cout << " elev = " << a.get_elev() << endl;
88         //cout << " freq = " << a.get_freq() << endl;
89         //cout << " range = " << a.get_range() << endl;
90         if ( a.get_type() != '[' ) {
91             atislist[a.get_freq()].push_back(a);
92         }
93         in >> skipcomment;
94
95         if ( a.get_type() != 'N' ) {
96             if ( a.get_freq() < min ) {
97                 min = a.get_freq();
98             }
99             if ( a.get_freq() > max ) {
100                 max = a.get_freq();
101             }
102         }
103     }
104
105     // cout << "min freq = " << min << endl;
106     // cout << "max freq = " << max << endl;
107
108 #endif
109
110     return true;
111 }
112
113
114 // query the database for the specified frequency, lon and lat are in
115 // degrees, elev is in meters
116 bool FGATISList::query( double lon, double lat, double elev, double freq,
117                        FGATIS *a )
118 {
119     atis_list_type stations = atislist[(int)(freq*100.0 + 0.5)];
120
121     atis_list_iterator current = stations.begin();
122     atis_list_iterator last = stations.end();
123
124     // double az1, az2, s;
125     Point3D aircraft = sgGeodToCart( Point3D(lon, lat, elev) );
126     Point3D station;
127     double d;
128     for ( ; current != last ; ++current ) {
129         //cout << "testing " << current->get_ident() << endl;
130         station = Point3D(current->get_x(), current->get_y(), current->get_z());
131         //cout << "aircraft = " << aircraft << endl;
132         //cout << "station = " << station << endl;
133
134         d = aircraft.distance3Dsquared( station );
135
136         //cout << "  dist = " << sqrt(d)
137         //     << "  range = " << current->get_range() * SG_NM_TO_METER << endl;
138
139         // match up to twice the published range so we can model
140         // reduced signal strength
141         if ( d < (2 * current->get_range() * SG_NM_TO_METER 
142                   * 2 * current->get_range() * SG_NM_TO_METER ) ) {
143             //cout << "matched = " << current->get_ident() << endl;
144             *a = *current;
145             return true;
146         }
147     }
148
149     return false;
150 }
151
152
153 int FGATISList::GetCallSign( string apt_id, int hours, int mins )
154 {
155     atis_transmission_type tran;
156
157     if(atislog.find(apt_id) == atislog.end()) {
158         // This station has not transmitted yet - return a random identifier
159         // and add the transmission to the log
160         tran.hours = hours;
161         tran.mins = mins;
162         sg_srandom_time();
163         tran.callsign = int(sg_random() * 25) + 1;      // This *should* give a random int between 1 and 26
164         //atislog[apt_id].push_back(tran);
165         atislog[apt_id] = tran;
166     } else {
167         // This station has transmitted - calculate the appropriate identifier
168         // and add the transmission to the log if it has changed
169         tran = atislog[apt_id];
170         // This next bit assumes that no-one comes back to the same ATIS station
171         // after running FlightGear for more than 24 hours !!
172         if((tran.hours == hours) && (tran.mins == mins)) {
173             return(tran.callsign);
174         } else {
175             if(tran.hours == hours) {
176                 // The minutes must have changed
177                 tran.mins = mins;
178                 tran.callsign++;
179             } else {
180                 if(hours < tran.hours) {
181                     hours += 24;
182                 }
183                 tran.callsign += (hours - tran.hours);
184                 if(mins != 0) {
185                     // Assume transmissions were made on every hour
186                     tran.callsign++;
187                 }
188                 tran.hours = hours;
189                 tran.mins = mins;
190             }
191             // Wrap if we've exceeded Zulu
192             if(tran.callsign > 26) {
193                 tran.callsign -= 26;
194             }
195             // And write the new transmission to the log
196             atislog[apt_id] = tran;
197         }
198     }
199     return(tran.callsign);
200 }