]> git.mxchange.org Git - flightgear.git/blob - src/ATC/groundlist.cxx
Changes towards tower control - work in progress with no end-user benefit yet
[flightgear.git] / src / ATC / groundlist.cxx
1 // groundlist.cxx -- ATC Ground data management class
2 //
3 // Written by David Luff, started November 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 "groundlist.hxx"
33
34 FGGroundList *current_groundlist;
35
36 // Constructor
37 FGGroundList::FGGroundList( void ) {
38 }
39
40
41 // Destructor
42 FGGroundList::~FGGroundList( void ) {
43 }
44
45
46 // load the navaids and build the map
47 bool FGGroundList::init( SGPath path ) {
48         
49         groundlist.erase( groundlist.begin(), groundlist.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                         FGGround g;
70                         in >> g;
71                         if ( g.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                         groundlist[g.get_freq()].push_back(g);
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 FGGroundList::query( double lon, double lat, double elev, double freq,
94         FGGround *g )
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                 ground_list_type stations = groundlist[(int)(freq*100.0 + 0.5)];
104                 
105                 ground_list_iterator current = stations.begin();
106                 ground_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                                         *g = *current;
129                                         return true;
130                                 }
131                 }
132                 
133                 return false;
134         }