1 // approachlist.cxx -- Approach data management class
3 // Written by Alexander Kappes, started March 2002.
4 // Based on navlist.cxx by Curtis Olson, started April 2000.
6 // Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
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.
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.
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.
29 #include <simgear/debug/logstream.hxx>
30 #include <simgear/misc/sgstream.hxx>
31 #include <simgear/math/sg_geodesy.hxx>
33 #include "approachlist.hxx"
36 FGApproachList *current_approachlist;
40 FGApproachList::FGApproachList( void ) {
45 FGApproachList::~FGApproachList( void ) {
49 // load the approach data and build the map
50 bool FGApproachList::init( SGPath path ) {
52 approachlist_freq.erase( approachlist_freq.begin(), approachlist_freq.end() );
53 approachlist_bck.erase( approachlist_bck.begin(), approachlist_bck.end() );
55 sg_gzifstream in( path.str() );
56 if ( !in.is_open() ) {
57 SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() );
61 // read in each line of the file
66 cout << " APPROACH " << endl;
69 while ( in.get(c) && c != '\0' ) {
77 if ( a.get_type() == '[' ) {
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;
88 approachlist_freq[a.get_freq()].push_back(a);
89 approachlist_bck[int(a.get_bucket())].push_back(a);
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,
103 lon *= SGD_DEGREES_TO_RADIANS;
104 lat *= SGD_DEGREES_TO_RADIANS;
106 approach_list_type stations = approachlist_freq[(int)(freq*100.0 + 0.5)];
108 approach_list_iterator current = stations.begin();
109 approach_list_iterator last = stations.end();
111 // double az1, az2, s;
112 Point3D aircraft = sgGeodToCart( Point3D(lon, lat, elev) );
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;
121 d = aircraft.distance3Dsquared( station );
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;
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;
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)
150 // get bucket number for plane position
151 SGBucket buck(lon, lat);
153 //cout << "plane bucket" << bucket << endl;
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 );
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();
170 double rlon = lon * SGD_DEGREES_TO_RADIANS;
171 double rlat = lat * SGD_DEGREES_TO_RADIANS;
173 // double az1, az2, s;
174 Point3D aircraft = sgGeodToCart( Point3D(rlon, rlat, elev) );
177 for ( ; current != last ; ++current ) {
178 station = Point3D(current->get_x(), current->get_y(), current->get_z());
179 d = aircraft.distance3Dsquared( station );
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;
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;
204 cout << "Approachlist error: Too many stations in range" << endl;
212 return true; //DCL - added this to prevent a compiler warning
216 bool FGApproachList::get_name( string apt_id )
219 double freq = 125.22;
221 approach_list_type stations = approachlist_freq[(int)(freq*100.0 + 0.5)];
223 approach_list_iterator current = stations.begin();
224 approach_list_iterator last = stations.end();
226 if(current != last) {
227 cout << "ApproachList" << endl;
228 cout << "name" << current->get_name() << endl;
229 cout << "bucket" << current->get_bucket() << endl;