// runways.cpp -- FGFS runway list // // Written by Frederic Bouvier, started May 2002. // // Copyright (C) 2002 Frederic Bouvier - fredb@users.sourceforge.net // Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // // $Id: runways.cpp,v 1.10 2005/05/09 07:02:13 fredb Exp $ #include "runways.hpp" #include #include #include FGSD_Runways::~FGSD_Runways() { for ( RunwayMap::iterator it = _runwayMap.begin(); it != _runwayMap.end(); ++it ) { delete it->second; } _runwayMap.clear(); } bool FGSD_Runways::search( const char *__aptid, RunwayList &__rwyLst ) const { bool ret = false; FGSD_RunwayKey key; key.id = __aptid; key.rwy_no = ""; RunwayMap::const_iterator it = _runwayMap.upper_bound( key ); while ( it != _runwayMap.end() && it->first.id == __aptid ) { __rwyLst.push_back( *it->second ); ret = true; ++it; } return ret; } bool FGSD_Runways::search( const char *__aptid, const char *__rwy_no, FGSD_Runway &__runway ) const { bool ret = false; FGSD_RunwayKey key; key.id = __aptid; key.rwy_no = __rwy_no; RunwayMap::const_iterator it = _runwayMap.find( key ); if ( it != _runwayMap.end() ) { __runway = *it->second; ret = true; } return ret; } void FGSD_Runways::insertRunway( FGSD_Runway *__rwy ) { FGSD_RunwayKey key; key.id = __rwy->id; key.rwy_no = __rwy->rwy_no; _runwayMap[ key ] = __rwy; } FGSD_Taxiways::~FGSD_Taxiways() { for ( TaxiwayMap::iterator it = _taxiwayMap.begin(); it != _taxiwayMap.end(); ++it ) { delete it->second; } _taxiwayMap.clear(); } bool FGSD_Taxiways::search( const char *__aptid, TaxiwayList &__twyLst ) const { bool ret = false; FGSD_TaxiwayKey key; key.id = __aptid; key.twy_no = ""; TaxiwayMap::const_iterator it = _taxiwayMap.upper_bound( key ); while ( it != _taxiwayMap.end() && it->first.id == __aptid ) { __twyLst.push_back( *it->second ); ret = true; ++it; } return ret; } bool FGSD_Taxiways::search( const char *__aptid, const char *__twy_no, TaxiwayList &__twyLst ) const { bool ret = false; FGSD_TaxiwayKey key; key.id = __aptid; key.twy_no = ""; TaxiwayMap::const_iterator it = _taxiwayMap.upper_bound( key ); while ( it != _taxiwayMap.end() && it->first.id == __aptid && it->first.twy_no == __twy_no ) { __twyLst.push_back( *it->second ); ret = true; ++it; } return ret; } void FGSD_Taxiways::insertTaxiway( FGSD_Taxiway *__twy ) { FGSD_TaxiwayKey key; key.id = __twy->id; key.twy_no = __twy->twy_no; _taxiwayMap.insert( TaxiwayMap::value_type( key, __twy ) ); } FGSD_Airports::~FGSD_Airports() { for ( AirportMap::iterator it = _airportMap.begin(); it != _airportMap.end(); ++it ) delete it->second; _airportMap.clear(); _aptNameMap.clear(); } bool FGSD_Airports::search( const AirportMap &__map, const char *__aptid, FGSD_Airport &__airport ) const { bool ret = false; std::string id( __aptid ); AirportMap::const_iterator it = __map.find( id ); if ( it != __map.end() ) { __airport = *it->second; ret = true; } return ret; } bool FGSD_Airports::previous( const AirportMap &__map, const char *__aptid, size_t pos, FGSD_Airport &__airport ) const { bool ret = false; size_t nb = strlen( __aptid ); nb = pos < nb ? pos + 1 : nb; std::string key( __aptid, nb ); if ( nb > 0 ) key[ nb - 1 ] -= 1; else key = ""; AirportMap::const_iterator it = __map.lower_bound( key ); if ( it != __map.end() && it->first == __aptid ) --it; if ( it != __map.end() ) { __airport = *it->second; ret = true; } return ret; } bool FGSD_Airports::next( const AirportMap &__map, const char *__aptid, size_t pos, FGSD_Airport &__airport ) const { bool ret = false; size_t nb = strlen( __aptid ); nb = pos < nb ? pos + 1 : nb; std::string key( __aptid, nb ); if ( nb > 0 ) key[ nb - 1 ] += 1; else key = ""; AirportMap::const_iterator it = __map.upper_bound( key ); if ( it != __map.end() ) { __airport = *it->second; ret = true; } return ret; } void FGSD_Airports::insertAirport( FGSD_Airport *__apt ) { _airportMap[ __apt->id ] = __apt; _aptNameMap[ __apt->name ] = __apt; } bool FGSD_AirportUtil::loadDatabase( const char *__fgRoot, FGSD_Airports &__airports, FGSD_Runways &__runways, FGSD_Taxiways &__taxiways, size_t &nbApt, void (*__step)( size_t, void * ), void *data ) { nbApt = 0; SGPath path; path = __fgRoot; path.append( "Airports/apt.dat" ); sg_gzifstream in( path.str() ); if ( in.is_open() ) { FGSD_Airport *current_apt = 0; std::string token, id; while ( !in.eof() ) { char buffer[ 2048 ]; in.getline( buffer, sizeof buffer ); if ( in.gcount() == 0 || buffer[0] == 0 ) continue; std::istringstream str( buffer ); str >> token; if ( token == "1" || token == "17" ) { std::string code; int tower, dummy; double length; str >> length >> tower >> dummy >> code >> ::skipws; char name_[ 1024 ]; str.getline( name_, sizeof name_ ); id = code; current_apt = new FGSD_Airport; current_apt->id = id; current_apt->name = name_; current_apt->height = 0; __airports.insertAirport( current_apt ); } else if ( token == "10" ) { std::string id, rwy_no, surface_flags, end1_flags, end2_flags; double lat, lon, heading, length, width, threshold1, stop1, threshold2, stop2; str >> lat >> lon >> rwy_no >> heading >> length >> threshold1 >> stop1 >> width >> end1_flags >> surface_flags; threshold2 = ( threshold1 - floor( threshold1 ) ) * 10000.0; threshold1 = floor( threshold1 ); stop2 = ( stop1 - floor( stop1 ) ) * 10000.0; stop1 = floor( stop1 ); end2_flags = end1_flags.substr( 3 ); end1_flags.erase( 3 ); id = rwy_no; current_apt->lon = lon; current_apt->lat = lat; FGSD_Runway *rwy = new FGSD_Runway; rwy->id = id; rwy->rwy_no = rwy_no; rwy->lat = lat; rwy->lon = lon; rwy->heading = heading; rwy->length = length; rwy->width = width; rwy->surface_flags = surface_flags; rwy->end1_flags = end1_flags; rwy->threshold1 = threshold1; rwy->stop1 = stop1; rwy->end2_flags = end2_flags; rwy->threshold2 = threshold2; rwy->stop2 = stop2; __runways.insertRunway( rwy ); } else if ( token == "99" ) break; __step( 1, data ); nbApt++; } } else { path = __fgRoot; path.append( "Airports/default.apt" ); in.open( path.str() ); if ( in.is_open() ) { std::string token, id; while ( !in.eof() ) { char buffer[ 1024 ]; in.getline( buffer, sizeof buffer ); std::istringstream str( buffer ); str >> token; if ( token == "A" ) { std::string code; double lat, lon, height; str >> id >> lat >> lon >> height >> code >> ::skipws; char name_[ 1024 ]; str.getline( name_, sizeof name_ ); FGSD_Airport *apt = new FGSD_Airport; apt->id = id; apt->name = name_; apt->lon = lon; apt->lat = lat; apt->height = height; __airports.insertAirport( apt ); } else if ( token == "R" ) { std::string rwy_no, surface_flags, end1_flags, end2_flags; double lat, lon, heading, length, width, threshold1, stop1, threshold2, stop2; str >> rwy_no >> lat >> lon >> heading >> length >> width >> surface_flags >> end1_flags >> threshold1 >> stop1 >> end2_flags >> threshold2 >> stop2; FGSD_Runway *rwy = new FGSD_Runway; rwy->id = id; rwy->rwy_no = rwy_no; rwy->lat = lat; rwy->lon = lon; rwy->heading = heading; rwy->length = length; rwy->width = width; rwy->surface_flags = surface_flags; rwy->end1_flags = end1_flags; rwy->threshold1 = threshold1; rwy->stop1 = stop1; rwy->end2_flags = end2_flags; rwy->threshold2 = threshold2; rwy->stop2 = stop2; __runways.insertRunway( rwy ); } else if ( token == "T" ) { std::string twy_no; char center, surface, edge; double lat, lon, heading, length, width; str >> twy_no >> lat >> lon >> heading >> length >> width >> center >> surface >> edge; FGSD_Taxiway *twy = new FGSD_Taxiway; twy->id = id; twy->twy_no = twy_no; twy->lat = lat; twy->lon = lon; twy->heading = heading; twy->length = length; twy->width = width; twy->center = center; twy->surface = surface; twy->edge = edge; __taxiways.insertTaxiway( twy ); } __step( 1, data ); nbApt++; } } } return false; }