]> git.mxchange.org Git - flightgear.git/blob - src/ATC/towerlist.cxx
Patch from Melchior Franz:
[flightgear.git] / src / ATC / towerlist.cxx
1 // towerlist.cxx -- ATC Tower data management class
2 //
3 // Written by David Luff, started March 2002.
4 // Based on navlist.cxx by Curtis Olson, started April 2000.
5 //
6 // Copyright (C) 2000  Curtis L. Olson - curt@flightgear.org
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22
23 #ifdef HAVE_CONFIG_H
24 #  include <config.h>
25 #endif
26
27 #include <simgear/debug/logstream.hxx>
28 #include <simgear/misc/sgstream.hxx>
29 #include <simgear/math/sg_geodesy.hxx>
30 #include <simgear/math/sg_random.h>
31
32 #include "towerlist.hxx"
33
34 FGTowerList *current_towerlist;
35
36 // Constructor
37 FGTowerList::FGTowerList( void ) {
38 }
39
40
41 // Destructor
42 FGTowerList::~FGTowerList( void ) {
43 }
44
45
46 // load the navaids and build the map
47 bool FGTowerList::init( SGPath path ) {
48
49     towerlist.erase( towerlist.begin(), towerlist.end() );
50
51     sg_gzifstream in( path.str() );
52     if ( !in.is_open() ) {
53         SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() );
54         exit(-1);
55     }
56
57     // read in each line of the file
58
59     in >> skipcomment;
60
61 #ifdef __MWERKS__
62     char c = 0;
63     while ( in.get(c) && c != '\0' ) {
64         in.putback(c);
65 #else
66     while ( !in.eof() ) {
67 #endif
68
69         FGTower t;
70         in >> t;
71         if ( t.get_type() == '[' ) {
72             break;
73         }
74
75         //cout << "id = " << t.GetIdent() << endl;
76         //cout << " type = " << t.get_type() << endl;
77         //cout << " lon = " << t.get_lon() << endl;
78         //cout << " lat = " << t.get_lat() << endl;
79         //cout << " elev = " << t.get_elev() << endl;
80         //cout << " freq = " << t.get_freq() << endl;
81         //cout << " range = " << t.get_range() << endl;
82
83         towerlist[t.get_freq()].push_back(t);
84         in >> skipcomment;
85     }
86
87     return true;
88 }
89
90
91 // query the database for the specified frequency, lon and lat are in
92 // degrees, elev is in meters
93 bool FGTowerList::query( double lon, double lat, double elev, double freq,
94                        FGTower *t )
95 {
96     lon *= SGD_DEGREES_TO_RADIANS;
97     lat *= SGD_DEGREES_TO_RADIANS;
98     //cout << "lon = " << lon << '\n';
99     //cout << "lat = " << lat << '\n';
100     //cout << "elev = " << elev << '\n';
101     //cout << "freq = " << freq << '\n';
102
103     tower_list_type stations = towerlist[(int)(freq*100.0 + 0.5)];
104
105     tower_list_iterator current = stations.begin();
106     tower_list_iterator last = stations.end();
107
108     // double az1, az2, s;
109     Point3D aircraft = sgGeodToCart( Point3D(lon, lat, elev) );
110     Point3D station;
111     double d;
112     for ( ; current != last ; ++current ) {
113         //cout << "testing " << current->GetIdent() << endl;
114         station = Point3D(current->get_x(), current->get_y(), current->get_z());
115         //cout << "aircraft = " << aircraft << endl;
116         //cout << "station = " << station << endl;
117
118         d = aircraft.distance3Dsquared( station );
119
120         //cout << "  dist = " << sqrt(d)
121         //     << "  range = " << current->get_range() * SG_NM_TO_METER << endl;
122
123         // match up to twice the published range so we can model
124         // reduced signal strength
125         if ( d < (2 * current->get_range() * SG_NM_TO_METER 
126                   * 2 * current->get_range() * SG_NM_TO_METER ) ) {
127             //cout << "matched = " << current->GetIdent() << endl;
128             *t = *current;
129             return true;
130         }
131     }
132
133     return false;
134 }