]> git.mxchange.org Git - flightgear.git/blobdiff - src/Airports/simple.cxx
Set the format default to float instead of int.
[flightgear.git] / src / Airports / simple.cxx
index cad2e4671d7197eea1d0fb9f6ae39f2ce394ede1..cfbb61ac24092b841883d75331581a575aa9d343 100644 (file)
@@ -1,7 +1,7 @@
 //
 // 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.
+//               lat, lon of the center of one of it's runways, and 
+//               elevation in feet.
 //
 // Written by Curtis Olson, started April 1998.
 //
 //
 // $Id$
 
-
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
 
-#include <sys/types.h>         // for gdbm open flags
-#include <sys/stat.h>          // for gdbm open flags
-
-#ifdef HAVE_GDBM
-#  include <gdbm.h>
-#else
-#  include <simgear/gdbm/gdbm.h>
-#endif
+#include <math.h>
 
 #include <simgear/compiler.h>
 
 #include <simgear/debug/logstream.hxx>
-#include <simgear/misc/fgstream.hxx>
-
-#include <Main/options.hxx>
+#include <simgear/misc/sgstream.hxx>
 
 #include STL_STRING
-#include STL_FUNCTIONAL
-#include STL_ALGORITHM
+#include STL_IOSTREAM
 
 #include "simple.hxx"
 
-
-FGAirports::FGAirports( const string& file ) {
-    dbf = gdbm_open( (char *)file.c_str(), 0, GDBM_READER, 0, NULL );
-    if ( dbf == NULL ) {
-       cout << "Error opening " << file << endl;
-       exit(-1);
-    } else {
-       cout << "successfully opened " << file << endl;
-    }
-}
+SG_USING_NAMESPACE(std);
+SG_USING_STD(istream);
 
 
-// search for the specified id
-bool
-FGAirports::search( const string& id, FGAirport* a ) const
+inline istream&
+operator >> ( istream& in, FGAirport& a )
 {
-    FGAirport *tmp;
-    datum content;
-    datum key;
-
-    key.dptr = (char *)id.c_str();
-    key.dsize = id.length();
-
-    content = gdbm_fetch( dbf, key );
-
-    cout << "gdbm_fetch() finished" << endl;
-
-    if ( content.dptr != NULL ) {
-       tmp = (FGAirport *)content.dptr;
-
-       // a->id = tmp->id;
-       a->longitude = tmp->longitude;
-       a->latitude = tmp->latitude;
-       a->elevation = tmp->elevation;
+    string junk;
+    in >> junk >> a.id >> a.latitude >> a.longitude >> a.elevation
+       >> a.code;
 
-       free( content.dptr );
+    getline( in,a.name );
 
-    } else {
-       return false;
+    // Remove the space before the name
+    if ( a.name.substr(0,1) == " " ) {
+        a.name = a.name.erase(0,1);
     }
 
-    return true;
-}
-
-
-FGAirport
-FGAirports::search( const string& id ) const
-{
-    FGAirport a, *tmp;
-    datum content;
-    datum key;
+    a.has_metar = false;
 
-    key.dptr = (char *)id.c_str();
-    key.dsize = id.length();
-
-    content = gdbm_fetch( dbf, key );
-
-    if ( content.dptr != NULL ) {
-       tmp = (FGAirport *)content.dptr;
-       a = *tmp;
-    }
+#if 0
+    // As a quick seed for the has_metar value, only airports with
+    // four-letter codes can have metar stations
+    a.has_metar = (isalpha(a.id[0]) && isalpha(a.id[1]) && isalpha(a.id[2])
+        && isalpha(a.id[3]) && !a.id[4]);
+#endif
 
-    return a;
+    return in;
 }
 
 
-// Destructor
-FGAirports::~FGAirports( void ) {
-    gdbm_close( dbf );
-}
-
+FGAirportList::FGAirportList( const string &airport_file,
+                              const string &metar_file ) {
+    SG_LOG( SG_GENERAL, SG_INFO, "Reading simple airport list: "
+            << airport_file );
 
-// Constructor
-FGAirportsUtil::FGAirportsUtil() {
-}
+    // open the specified file for reading
+    sg_gzifstream apt_in( airport_file );
+    if ( !apt_in.is_open() ) {
+        SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << airport_file );
+       exit(-1);
+    }
 
+    // skip header line
+    apt_in >> skipeol;
 
-// load the data
-int FGAirportsUtil::load( const string& file ) {
     FGAirport a;
-
-    airports.erase( airports.begin(), airports.end() );
-
-    fg_gzifstream in( file );
-    if ( !in.is_open() ) {
-       FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << file );
-       exit(-1);
+    while ( apt_in ) {
+        apt_in >> a;
+        airports_by_id[a.id] = a;
+        airports_array.push_back( &airports_by_id[a.id] );
     }
 
-    /*
-    // We can use the STL copy algorithm because the input
-    // file doesn't contain and comments or blank lines.
-    copy( istream_iterator<FGAirport,ptrdiff_t>(in.stream()),
-         istream_iterator<FGAirport,ptrdiff_t>(),
-         inserter( airports, airports.begin() ) );
-    */
-
-    // read in each line of the file
-
-#ifdef __MWERKS__
-
-    in >> skipcomment;
-    char c = 0;
-    while ( in.get(c) && c != '\0' ) {
-       in.putback(c);
-       in >> a;
-       airports.insert(a);
-       in >> skipcomment;
-    }
 
-#else
+    SG_LOG( SG_GENERAL, SG_INFO, "Reading simple metar station list: "
+            << metar_file );
 
-    in >> skipcomment;
-    while ( ! in.eof() ) {
-       in >> a;
-       airports.insert(a);
-       in >> skipcomment;
+    // open the specified file for reading
+    sg_gzifstream metar_in( metar_file );
+    if ( !metar_in.is_open() ) {
+        SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << metar_file );
     }
 
-#endif
-
-    return 1;
+    string ident;
+    while ( metar_in ) {
+        metar_in >> ident;
+        if ( ident == "#" || ident == "//" ) {
+            metar_in >> skipeol;
+        } else {
+            airport_map_iterator apt = airports_by_id.find( ident );
+            if ( apt == airports_by_id.end() ) {
+                SG_LOG( SG_GENERAL, SG_DEBUG, "no apt = " << ident );
+            } else {
+                SG_LOG( SG_GENERAL, SG_DEBUG, "metar = " << ident );
+                airports_by_id[ident].has_metar = true;
+            }
+        }
+    }
 }
 
 
-// save the data in gdbm format
-bool FGAirportsUtil::dump_gdbm( const string& file ) {
-
-    GDBM_FILE dbf;
+// search for the specified id
+FGAirport FGAirportList::search( const string& id) {
+    return airports_by_id[id];
+}
 
-#if !defined( MACOS )
-    dbf = gdbm_open( (char *)file.c_str(), 0, GDBM_NEWDB | GDBM_FAST, 
-                    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH,
-                    NULL );
-#else
-    dbf = gdbm_open( (char *)file.c_str(), 0, GDBM_NEWDB | GDBM_FAST,
-                    NULL, NULL );
-#endif
 
-    if ( dbf == NULL ) {
-       cout << "Error opening " << file << endl;
-       exit(-1);
-    } else {
-       cout << "successfully opened " << file << endl;
+// search for the airport nearest the specified position
+FGAirport FGAirportList::search( double lon_deg, double lat_deg,
+                                 bool with_metar ) {
+    int closest = 0;
+    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]->longitude)
+            + fabs(lat_deg - airports_array[i]->latitude);
+        if ( d < min_dist ) {
+            if ( !with_metar || (with_metar && airports_array[i]->has_metar) ) {
+                closest = i;
+                min_dist = d;
+            }
+        }
     }
 
-    iterator current = airports.begin();
-    const_iterator end = airports.end();
-    while ( current != end ) {
-       datum key;
-       key.dptr = (char *)current->id.c_str();
-       key.dsize = current->id.length();
-
-       datum content;
-       FGAirport tmp = *current;
-       content.dptr = (char *)(& tmp);
-       content.dsize = sizeof( *current );
-
-       gdbm_store( dbf, key, content, GDBM_REPLACE );
-
-       ++current;
-    }
+    return *airports_array[closest];
+}
 
-    gdbm_close( dbf );
 
-    return true;
+// Destructor
+FGAirportList::~FGAirportList( void ) {
 }
 
-
-// search for the specified id
-bool
-FGAirportsUtil::search( const string& id, FGAirport* a ) const
+int
+FGAirportList::size () const
 {
-    const_iterator it = airports.find( FGAirport(id) );
-    if ( it != airports.end() )
-    {
-       *a = *it;
-       return true;
-    }
-    else
-    {
-       return false;
-    }
+    return airports_array.size();
 }
 
-
-FGAirport
-FGAirportsUtil::search( const string& id ) const
+const FGAirport *FGAirportList::getAirport( int index ) const
 {
-    FGAirport a;
-    this->search( id, &a );
-    return a;
+    return airports_array[index];
 }
 
 
-// Destructor
-FGAirportsUtil::~FGAirportsUtil( void ) {
+/**
+ * Mark the specified airport record as not having metar
+ */
+void FGAirportList::no_metar( const string &id ) {
+    airports_by_id[id].has_metar = false;
 }
-
-