#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sgstream.hxx>
#include <simgear/misc/strutils.hxx>
+#include <simgear/structure/exception.hxx>
-#include STL_STRING
+#include <string>
#include "simple.hxx"
#include "runways.hxx"
#include "apt_loader.hxx"
-static void addAirport(FGAirportList *airports, const string& apt_id, const string& apt_name,
+static FGPositioned::Type fptypeFromRobinType(int aType)
+{
+ switch (aType) {
+ case 1: return FGPositioned::AIRPORT;
+ case 16: return FGPositioned::SEAPORT;
+ case 17: return FGPositioned::HELIPORT;
+ default:
+ SG_LOG(SG_GENERAL, SG_ALERT, "unsupported type:" << aType);
+ throw sg_range_exception("Unsupported airport type", "fptypeFromRobinType");
+ }
+}
+
+FGAirport* addAirport(FGAirportList *airports, const string& apt_id, const string& apt_name,
int rwy_count, double rwy_lat_accum, double rwy_lon_accum, double last_rwy_heading,
double apt_elev, SGGeod& tower, bool got_tower, int type)
{
if (apt_id.empty())
- return;
+ return NULL;
if (!rwy_count) {
SG_LOG(SG_GENERAL, SG_ALERT, "ERROR: No runways for " << apt_id
<< ", skipping." );
- return;
+ return NULL;
}
double lat = rwy_lat_accum / (double)rwy_count;
tower = SGGeod::fromDegFt(lon + fudge_lon, lat + fudge_lat, apt_elev + tower_height);
}
- airports->add(apt_id, SGGeod::fromDegFt(lon, lat, apt_elev), tower, apt_name, false,
- type == 1/*airport*/, type == 16/*seaport*/, type == 17/*heliport*/);
+
+
+ return airports->add(apt_id, SGGeod::fromDegFt(lon, lat, apt_elev), tower, apt_name, false,
+ fptypeFromRobinType(type));
}
// Load the airport data base from the specified aptdb file. The
// metar file is used to mark the airports as having metar available
// or not.
-bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways,
+bool fgAirportDBLoad( FGAirportList *airports,
const string &aptdb_file, const string &metar_file )
{
//
double last_apt_elev = 0.0;
string last_apt_name = "";
string last_apt_info = "";
- string last_apt_type = "";
+ int last_apt_type = 0;
SGGeod last_tower;
bool got_tower = false;
string line;
char tmp[2049];
tmp[2048] = 0;
-
+ vector<FGRunwayPtr> runways;
+
unsigned int line_id = 0;
unsigned int line_num = 0;
double rwy_lon_accum = 0.0;
SG_LOG( SG_GENERAL, SG_BULK, "Next airport = " << id << " "
<< elev );
- addAirport(airports, last_apt_id, last_apt_name, rwy_count, rwy_lat_accum, rwy_lon_accum,
- last_rwy_heading, last_apt_elev, last_tower, got_tower, line_id);
+ FGAirport* apt = addAirport(airports, last_apt_id, last_apt_name, rwy_count, rwy_lat_accum, rwy_lon_accum,
+ last_rwy_heading, last_apt_elev, last_tower, got_tower, last_apt_type);
+
+ for (unsigned int r=0; r< runways.size(); ++r) {
+ apt->addRunway(runways[r]);
+ }
+ runways.clear();
+
last_apt_id = id;
last_apt_elev = elev;
last_apt_name = "";
last_apt_name += token[token.size() - 1];
last_apt_info = line;
- last_apt_type = token[0];
+ last_apt_type = atoi( token[0].c_str() );
// clear runway list for start of next airport
rwy_lon_accum = 0.0;
double stopway1 = atof( stop[0].c_str() );
double stopway2 = atof( stop[1].c_str() );
- string lighting_flags = token[9];
int surface_code = atoi( token[10].c_str() );
- string shoulder_code = token[11];
- int marking_code = atoi( token[12].c_str() );
- double smoothness = atof( token[13].c_str() );
- bool dist_remaining = (atoi( token[14].c_str() ) == 1 );
-
- runways->add( last_apt_id, rwy_no, lon, lat, heading, length,
- width, displ_thresh1, displ_thresh2,
- stopway1, stopway2, lighting_flags, surface_code,
- shoulder_code, marking_code, smoothness,
- dist_remaining );
+ SGGeod pos(SGGeod::fromDegFt(lon, lat, 0.0));
+ FGRunway* rwy = new FGRunway(NULL, rwy_no, pos, heading, length,
+ width, displ_thresh1, stopway1, surface_code, false);
+ runways.push_back(rwy);
+
+ if (rwy_no[0] != 'x') {
+ // runways need a reciprocal, taxiways do not
+ FGRunway* reciprocal = new FGRunway(NULL, FGRunway::reverseIdent(rwy_no),
+ pos, heading + 180.0, length, width,
+ displ_thresh2, stopway2, surface_code, true);
+
+ runways.push_back(reciprocal);
+ }
} else if ( line_id == 18 ) {
// beacon entry (ignore)
} else if ( line_id == 14 ) {
double lat = atof( token[1].c_str() );
double lon = atof( token[2].c_str() );
double elev = atof( token[3].c_str() );
- last_tower = SGGeod::fromDegFt(lon, lat, elev);
+ last_tower = SGGeod::fromDegFt(lon, lat, elev + last_apt_elev);
got_tower = true;
} else if ( line_id == 19 ) {
// windsock entry (ignore)
// add the last airport being processed if any
addAirport(airports, last_apt_id, last_apt_name, rwy_count, rwy_lat_accum, rwy_lon_accum,
- last_rwy_heading, last_apt_elev, last_tower, got_tower, 0);
+ last_rwy_heading, last_apt_elev, last_tower, got_tower, last_apt_type);
//
if ( ident == "#" || ident == "//" ) {
metar_in >> skipeol;
} else {
- const FGAirport* a = airports->search( ident );
- if ( a ) airports->has_metar( ident );
+ FGAirport* apt = FGAirport::findByIdent(ident);
+ if (apt) {
+ apt->setMetar(true);
+ }
}
}