1
0
Fork 0
flightgear/src/Airports/simple.cxx
ehofman 31621f50af Olaf Flebbe:
This patch makes FlightGear at least compile on MSVC. I hope I have removed
reference of my other local changes. DSP and DSW files are included for
reference. They have been reconstructed with am2dsp.pl. I had to introduce a
change to am2dsp because of the need of filenames with embedded spaces. (Yuck)

The major direction is to remove clutter like the _USE_MATH_DEFINES and have it
on the compiler command line sice there is no central include file. You will
have to put it on the command line for your locale Project files, if it not
there, already. I added the _CRT_SECURE_NO_DEPRECATE define for 2005, since it
does no harm to other VC version.
2006-02-17 08:54:22 +00:00

331 lines
8.8 KiB
C++

//
// simple.cxx -- a really simplistic class to manage airport ID,
// lat, lon of the center of one of it's runways, and
// elevation in feet.
//
// Written by Curtis Olson, started April 1998.
// Updated by Durk Talsma, started December, 2004.
//
// Copyright (C) 1998 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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$
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <math.h>
#include <algorithm>
#include <simgear/compiler.h>
#include <plib/sg.h>
#include <plib/ul.h>
#include <Environment/environment_mgr.hxx>
#include <Environment/environment.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/props/props.hxx>
#include <simgear/structure/subsystem_mgr.hxx>
//#include <simgear/route/waypoint.hxx>
#include <simgear/debug/logstream.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <Airports/runways.hxx>
#include STL_STRING
#include "simple.hxx"
SG_USING_STD(sort);
SG_USING_STD(random_shuffle);
/***************************************************************************
* FGAirport
***************************************************************************/
FGAirport::FGAirport() : _longitude(0), _latitude(0), _elevation(0)
{
dynamics = 0;
}
FGAirport::FGAirport(const string &id, double lon, double lat, double elev, const string &name, bool has_metar)
{
_id = id;
_longitude = lon;
_latitude = lat;
_elevation = elev;
_name = name;
_has_metar = has_metar;
dynamics = 0;
}
FGAirport::~FGAirport()
{
delete dynamics;
}
FGAirportDynamics * FGAirport::getDynamics()
{
if (dynamics != 0)
return dynamics;
else
{
FGRunwayPreference rwyPrefs;
//cerr << "Trying to load dynamics for " << _id << endl;
dynamics = new FGAirportDynamics(_latitude, _longitude, _elevation, _id);
SGPath parkpath( globals->get_fg_root() );
parkpath.append( "/Airports/AI/" );
parkpath.append(_id);
parkpath.append("parking.xml");
SGPath rwyPrefPath( globals->get_fg_root() );
rwyPrefPath.append( "/Airports/AI/" );
rwyPrefPath.append(_id);
rwyPrefPath.append("rwyuse.xml");
//if (ai_dirs.find(id.c_str()) != ai_dirs.end()
// && parkpath.exists())
if (parkpath.exists())
{
try {
readXML(parkpath.str(),*dynamics);
dynamics->init();
}
catch (const sg_exception &e) {
//cerr << "unable to read " << parkpath.str() << endl;
}
}
//if (ai_dirs.find(id.c_str()) != ai_dirs.end()
// && rwyPrefPath.exists())
if (rwyPrefPath.exists())
{
try {
readXML(rwyPrefPath.str(), rwyPrefs);
dynamics->setRwyUse(rwyPrefs);
}
catch (const sg_exception &e) {
//cerr << "unable to read " << rwyPrefPath.str() << endl;
//exit(1);
}
}
//exit(1);
}
return dynamics;
}
/******************************************************************************
* FGAirportList
*****************************************************************************/
// Populates a list of subdirectories of $FG_ROOT/Airports/AI so that
// the add() method doesn't have to try opening 2 XML files in each of
// thousands of non-existent directories. FIXME: should probably add
// code to free this list after parsing of apt.dat is finished;
// non-issue at the moment, however, as there are no AI subdirectories
// in the base package.
//
// Note: 2005/12/23: This is probably not necessary anymore, because I'm
// Switching to runtime airport dynamics loading (DT).
FGAirportList::FGAirportList()
{
// ulDir* d;
// ulDirEnt* dent;
// SGPath aid( globals->get_fg_root() );
// aid.append( "/Airports/AI" );
// if((d = ulOpenDir(aid.c_str())) == NULL)
// return;
// while((dent = ulReadDir(d)) != NULL) {
// SG_LOG( SG_GENERAL, SG_DEBUG, "Dent: " << dent->d_name );
// ai_dirs.insert(dent->d_name);
// }
// ulCloseDir(d);
}
FGAirportList::~FGAirportList( void ) {
for(unsigned int i = 0; i < airports_array.size(); ++i) {
delete airports_array[i];
}
}
// add an entry to the list
void FGAirportList::add( const string &id, const double longitude,
const double latitude, const double elevation,
const string &name, const bool has_metar )
{
FGRunwayPreference rwyPrefs;
FGAirport* a = new FGAirport(id, longitude, latitude, elevation, name, has_metar);
airports_by_id[a->getId()] = a;
// try and read in an auxilary file
airports_array.push_back( a );
SG_LOG( SG_GENERAL, SG_BULK, "Adding " << id << " pos = " << longitude
<< ", " << latitude << " elev = " << elevation );
}
// search for the specified id
FGAirport* FGAirportList::search( const string& id) {
airport_map_iterator itr = airports_by_id.find(id);
return(itr == airports_by_id.end() ? NULL : itr->second);
}
// search for first subsequent alphabetically to supplied id
const FGAirport* FGAirportList::findFirstById( const string& id, bool exact ) {
airport_map_iterator itr;
if(exact) {
itr = airports_by_id.find(id);
} else {
itr = airports_by_id.lower_bound(id);
}
if(itr == airports_by_id.end()) {
return(NULL);
} else {
return(itr->second);
}
}
// search for the airport nearest the specified position
FGAirport* FGAirportList::search( double lon_deg, double lat_deg,
bool with_metar ) {
int closest = -1;
double min_dist = 360.0;
unsigned int i;
for ( i = 0; i < airports_array.size(); ++i ) {
// crude manhatten distance based on lat/lon difference
double d = fabs(lon_deg - airports_array[i]->getLongitude())
+ fabs(lat_deg - airports_array[i]->getLatitude());
if ( d < min_dist ) {
if ( !with_metar || (with_metar&&airports_array[i]->getMetar()) ) {
closest = i;
min_dist = d;
}
}
}
return ( closest > -1 ? airports_array[closest] : NULL );
}
int
FGAirportList::size () const
{
return airports_array.size();
}
const FGAirport *FGAirportList::getAirport( unsigned int index ) const
{
if(index < airports_array.size()) {
return(airports_array[index]);
} else {
return(NULL);
}
}
/**
* Mark the specified airport record as not having metar
*/
void FGAirportList::no_metar( const string &id ) {
if(airports_by_id.find(id) != airports_by_id.end()) {
airports_by_id[id]->setMetar(false);
}
}
/**
* Mark the specified airport record as (yes) having metar
*/
void FGAirportList::has_metar( const string &id ) {
if(airports_by_id.find(id) != airports_by_id.end()) {
airports_by_id[id]->setMetar(true);
}
}
// find basic airport location info from airport database
const FGAirport *fgFindAirportID( const string& id) {
const FGAirport* result = NULL;
if ( id.length() ) {
SG_LOG( SG_GENERAL, SG_INFO, "Searching for airport code = " << id );
result = globals->get_airports()->search( id );
if ( result == NULL ) {
SG_LOG( SG_GENERAL, SG_ALERT,
"Failed to find " << id << " in apt.dat.gz" );
return NULL;
}
} else {
return NULL;
}
SG_LOG( SG_GENERAL, SG_INFO,
"Position for " << id << " is ("
<< result->getLongitude() << ", "
<< result->getLatitude() << ")" );
return result;
}
// get airport elevation
double fgGetAirportElev( const string& id ) {
// double lon, lat;
SG_LOG( SG_GENERAL, SG_INFO,
"Finding elevation for airport: " << id );
const FGAirport *a=fgFindAirportID( id);
if (a) {
return a->getElevation();
} else {
return -9999.0;
}
}
// get airport position
Point3D fgGetAirportPos( const string& id ) {
// double lon, lat;
SG_LOG( SG_ATC, SG_INFO,
"Finding position for airport: " << id );
const FGAirport *a = fgFindAirportID( id);
if (a) {
return Point3D(a->getLongitude(), a->getLatitude(), a->getElevation());
} else {
return Point3D(0.0, 0.0, -9999.0);
}
}