]> git.mxchange.org Git - flightgear.git/blob - src/ATC/approachlist.cxx
A bunch of reorg and clean up of the KR 87 (adf) code including some
[flightgear.git] / src / ATC / approachlist.cxx
1 // approachlist.cxx -- Approach data management class
2 //
3 // Written by Alexander Kappes, 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 // $Id$
23
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #include <simgear/debug/logstream.hxx>
30 #include <simgear/misc/sgstream.hxx>
31 #include <simgear/math/sg_geodesy.hxx>
32
33 #include "approachlist.hxx"
34
35
36 FGApproachList *current_approachlist;
37
38
39 // Constructor
40 FGApproachList::FGApproachList( void ) {
41 }
42
43
44 // Destructor
45 FGApproachList::~FGApproachList( void ) {
46 }
47
48
49 // load the approach data and build the map
50 bool FGApproachList::init( SGPath path ) {
51
52     approachlist_freq.erase( approachlist_freq.begin(), approachlist_freq.end() );
53     approachlist_bck.erase( approachlist_bck.begin(), approachlist_bck.end() );
54
55     sg_gzifstream in( path.str() );
56     if ( !in.is_open() ) {
57         SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() );
58         exit(-1);
59     }
60
61     // read in each line of the file
62
63     // in >> skipeol;
64     in >> skipcomment;
65
66     cout << " APPROACH " << endl;
67 #ifdef __MWERKS__
68     char c = 0;
69     while ( in.get(c) && c != '\0' ) {
70         in.putback(c);
71 #else
72     while ( !in.eof() ) {
73 #endif
74
75         FGApproach a;
76         in >> a;
77         if ( a.get_type() == '[' ) {
78             break;
79         }
80         //cout << " type = " << a.get_type() << endl;
81         //cout << " lon = " << a.get_lon() << endl;
82         //cout << " lat = " << a.get_lat() << endl;
83         //cout << " elev = " << a.get_elev() << endl;
84         //cout << " freq = " << a.get_freq() << endl;
85         //cout << " Airport Code = " << a.GetIdent() << endl; 
86         //cout << " Name = " << a.get_name() << endl; 
87
88         approachlist_freq[a.get_freq()].push_back(a);
89         approachlist_bck[a.get_bucket()].push_back(a);
90         in >> skipcomment;
91
92     }
93
94     return true;
95 }
96
97
98 // query the database for the specified frequency, lon and lat are in
99 // degrees, elev is in meters
100 bool FGApproachList::query_freq( double lon, double lat, double elev, double freq,
101                             FGApproach *a )
102 {
103   lon *= SGD_DEGREES_TO_RADIANS;
104   lat *= SGD_DEGREES_TO_RADIANS;
105
106   approach_list_type stations = approachlist_freq[(int)(freq*100.0 + 0.5)];
107   
108   approach_list_iterator current = stations.begin();
109   approach_list_iterator last = stations.end();
110   
111   // double az1, az2, s;
112   Point3D aircraft = sgGeodToCart( Point3D(lon, lat, elev) );
113   Point3D station;
114   double d;
115   for ( ; current != last ; ++current ) {
116     //cout << "testing " << current->GetIdent() << endl;
117     station = Point3D(current->get_x(), current->get_y(), current->get_z());
118     //cout << "aircraft = " << aircraft << endl;
119     //cout << "station = " << station << endl;
120     
121     d = aircraft.distance3Dsquared( station );
122     
123     //cout << "  dist = " << sqrt(d)
124     //     << "  range = " << current->get_range() * SG_NM_TO_METER << endl;
125     //cout << "  Aircraft: lon = " << lon << "  lat = " << lat 
126     //     << "  elev = " << elev << endl;
127     //cout << "  Airport:  lon = " << current->get_lon() 
128     //     << "  lat = " << current->get_lat() 
129     //     << "  elev = " << current->get_elev() 
130     //     << "  z = " << current->get_z() << endl;
131     
132     // match up to twice the published range so we can model
133     // reduced signal strength
134     if ( d < (2 * current->get_range() * SG_NM_TO_METER 
135               * 2 * current->get_range() * SG_NM_TO_METER ) ) {
136       //cout << "matched = " << current->GetIdent() << endl;
137       *a = *current;
138       return true;
139     }
140   }
141   return false;
142 }
143
144 // query the database for the specified frequency, lon and lat are in
145 // degrees, elev is in meters
146 bool FGApproachList::query_bck( double lon, double lat, double elev, FGApproach *a, 
147                                 int max_app, int &num_app)
148 {
149
150   // get bucket number for plane position
151   SGBucket buck(lon, lat);
152
153   //cout << "plane bucket" << bucket << endl;
154
155   // get neigboring buckets
156   double max_range = 100;
157   int bx = int ( max_range*SG_NM_TO_METER / buck.get_width_m() / 2);
158   int by = int ( max_range*SG_NM_TO_METER / buck.get_height_m() / 2 );
159
160   // loop over bucket range 
161   for ( int i=-bx; i<bx; i++) {
162     for ( int j=-by; j<by; j++) {
163       buck = sgBucketOffset(lon, lat, i, j);
164       long int bucket = buck.gen_index();
165       //cout << "bucket number = " << bucket << endl;
166       approach_list_type stations = approachlist_bck[bucket];
167       approach_list_iterator current = stations.begin();
168       approach_list_iterator last = stations.end();
169  
170       double rlon = lon * SGD_DEGREES_TO_RADIANS;
171       double rlat = lat * SGD_DEGREES_TO_RADIANS;
172  
173       // double az1, az2, s;
174       Point3D aircraft = sgGeodToCart( Point3D(rlon, rlat, elev) );
175       Point3D station;
176       double d;
177       for ( ; current != last ; ++current ) {
178         station = Point3D(current->get_x(), current->get_y(), current->get_z());
179         d = aircraft.distance3Dsquared( station );
180         /*
181           cout << "  dist = " << sqrt(d)
182           << "  range = " << current->get_range() * SG_NM_TO_METER << endl;
183           cout << "  Aircraft: lon = " << lon
184           << "  lat = " << lat/SGD_DEGREES_TO_RADIANS 
185           << "  bucket = " << bucket
186           << "  elev = " << elev << endl;
187           cout << "  Airport:  Id = " << current->GetIdent() 
188           << "  lon = " << current->get_lon() 
189           << "  lat = " << current->get_lat() 
190           << "  elev = " << current->get_elev() 
191           << "  bucket = " << current->get_bucket() 
192           << "  z = " << current->get_z() << endl;
193         */
194         // match up to twice the published range so we can model
195         // reduced signal strength
196         if ( d < (current->get_range() * SG_NM_TO_METER 
197                   * current->get_range() * SG_NM_TO_METER ) ) {
198           //cout << "matched = " << current->GetIdent() << endl;
199           if (num_app < max_app) {
200             a[num_app] = *current;
201             num_app += 1;
202           }
203           else {
204             cout << "Approachlist error: Too many stations in range" << endl; 
205           }
206           
207           //return true;
208         }
209       }
210     }
211   }
212   return true;  //DCL - added this to prevent a compiler warning
213 }
214
215
216 bool FGApproachList::get_name( string apt_id )
217 {
218   string name;
219   double freq = 125.22;
220
221   approach_list_type stations = approachlist_freq[(int)(freq*100.0 + 0.5)];
222   
223   approach_list_iterator current = stations.begin();
224   approach_list_iterator last    = stations.end();
225
226   if(current != last) {  
227     cout << "ApproachList" << endl;
228     cout << "name" << current->get_name() << endl;
229     cout << "bucket" << current->get_bucket() << endl;
230   }
231
232   return 0;
233
234 }