]> git.mxchange.org Git - flightgear.git/blobdiff - src/Airports/apt_loader.cxx
Interim windows build fix
[flightgear.git] / src / Airports / apt_loader.cxx
index fc4b0b1ed5ce607c626614f25f5c4a1ec3690ca1..9e6a475884228a25fd99206f89c82afbac7b1493 100644 (file)
@@ -67,6 +67,8 @@ static FGPositioned::Type fptypeFromRobinType(int aType)
   }
 }
 
+// generated by 'wc -l' on the uncompressed file
+const unsigned int LINES_IN_APT_DAT = 2465648;
 
 namespace flightgear
 {
@@ -90,7 +92,7 @@ public:
 
     if ( !in.is_open() ) {
         SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << aptdb_file );
-        exit(-1);
+        throw sg_io_exception("cannot open APT file", aptdb_file);
     }
 
     string line;
@@ -109,6 +111,12 @@ public:
         continue;
       }
 
+        if ((line_num % 100) == 0) {
+            // every 100 lines
+            unsigned int percent = (line_num * 100) / LINES_IN_APT_DAT;
+            cache->setRebuildPhaseProgress(NavDataCache::REBUILD_AIRPORTS, percent);
+        }
+
       if (line.size() >= 3) {
           char *p = (char *)memchr(tmp, ' ', 3);
           if ( p )
@@ -151,9 +159,7 @@ public:
         double lat = atof( token[1].c_str() );
         double lon = atof( token[2].c_str() );
         double elev = atof( token[3].c_str() );
-        tower = SGGeod::fromDegFt(lon, lat, elev + last_apt_elev);
-        got_tower = true;
-        
+        tower = SGGeod::fromDegFt(lon, lat, elev + last_apt_elev);        
         cache->insertTower(currentAirportID, tower);
       } else if ( line_id == 19 ) {
           // windsock entry (ignore)
@@ -186,7 +192,7 @@ public:
       } else {
           SG_LOG( SG_GENERAL, SG_ALERT, 
                   "Unknown line(#" << line_num << ") in apt.dat file: " << line );
-          exit( -1 );
+          throw sg_format_exception("malformed line in apt.dat:", line);
       }
     }
 
@@ -199,7 +205,6 @@ private:
   double rwy_lon_accum;
   double last_rwy_heading;
   int rwy_count;
-  bool got_tower;
   string last_apt_id;
   double last_apt_elev;
   SGGeod tower;
@@ -230,17 +235,6 @@ private:
     double lat = rwy_lat_accum / (double)rwy_count;
     double lon = rwy_lon_accum / (double)rwy_count;
 
-    if (!got_tower) {
-      // tower height hard coded for now...
-      const float tower_height = 50.0f;
-      // make a little off the heading for 1 runway airports...
-      float fudge_lon = fabs(sin(last_rwy_heading * SGD_DEGREES_TO_RADIANS)) * .003f;
-      float fudge_lat = .003f - fudge_lon;
-      tower = SGGeod::fromDegFt(lon + fudge_lon, lat + fudge_lat, last_apt_elev + tower_height);
-      
-      cache->insertTower(currentAirportID, tower);
-    }
-
     SGGeod pos(SGGeod::fromDegFt(lon, lat, last_apt_elev));
     cache->updatePosition(currentAirportID, pos);
     
@@ -256,7 +250,6 @@ private:
     finishAirport();
             
     last_apt_elev = elev;
-    got_tower = false;
 
     string name;
     // build the name
@@ -287,16 +280,21 @@ private:
     double heading = atof( token[4].c_str() );
     double length = atoi( token[5].c_str() );
     double width = atoi( token[8].c_str() );
+    length *= SG_FEET_TO_METER;
+    width *= SG_FEET_TO_METER;
+
+    // adjust lat / lon to the start of the runway/taxiway, not the middle
+    SGGeod pos_1 = SGGeodesy::direct( SGGeod::fromDegFt(lon, lat, last_apt_elev), heading, -length/2 );
 
     last_rwy_heading = heading;
 
     int surface_code = atoi( token[10].c_str() );
-    SGGeod pos(SGGeod::fromDegFt(lon, lat, last_apt_elev));
 
     if (rwy_no[0] == 'x') {  // Taxiway
-      cache->insertRunway(FGPositioned::TAXIWAY, rwy_no, pos, currentAirportID,
+      cache->insertRunway(FGPositioned::TAXIWAY, rwy_no, pos_1, currentAirportID,
                           heading, length, width, 0.0, 0.0, surface_code);
     } else if (rwy_no[0] == 'H') {  // Helipad
+      SGGeod pos(SGGeod::fromDegFt(lon, lat, last_apt_elev));
       cache->insertRunway(FGPositioned::HELIPAD, rwy_no, pos, currentAirportID,
                           heading, length, width, 0.0, 0.0, surface_code);
     } else {
@@ -306,22 +304,29 @@ private:
           = simgear::strutils::split( rwy_displ_threshold, "." );
       double displ_thresh1 = atof( displ[0].c_str() );
       double displ_thresh2 = atof( displ[1].c_str() );
+      displ_thresh1 *= SG_FEET_TO_METER;
+      displ_thresh2 *= SG_FEET_TO_METER;
 
       string rwy_stopway = token[7];
       vector<string> stop
           = simgear::strutils::split( rwy_stopway, "." );
       double stopway1 = atof( stop[0].c_str() );
       double stopway2 = atof( stop[1].c_str() );
+      stopway1 *= SG_FEET_TO_METER;
+      stopway2 *= SG_FEET_TO_METER;
 
-      PositionedID rwy = cache->insertRunway(FGPositioned::RUNWAY, rwy_no, pos,
+      SGGeod pos_2 = SGGeodesy::direct( pos_1, heading, length );
+
+      PositionedID rwy = cache->insertRunway(FGPositioned::RUNWAY, rwy_no, pos_1,
                                              currentAirportID, heading, length,
                                              width, displ_thresh1, stopway1,
                                              surface_code);
       
       PositionedID reciprocal = cache->insertRunway(FGPositioned::RUNWAY,
-                                              FGRunway::reverseIdent(rwy_no), pos,
-                                             currentAirportID, heading + 180.0, length,
-                                             width, displ_thresh2, stopway2,
+                                             FGRunway::reverseIdent(rwy_no), pos_2,
+                                             currentAirportID,
+                                             SGMiscd::normalizePeriodic(0, 360, heading + 180.0),
+                                             length, width, displ_thresh2, stopway2,
                                              surface_code);
 
       cache->setRunwayReciprocal(rwy, reciprocal);
@@ -330,7 +335,7 @@ private:
 
   void parseRunwayLine850(const vector<string>& token)
   {
-    double width = atof( token[1].c_str() ) * SG_METER_TO_FEET;
+    double width = atof( token[1].c_str() );
     int surface_code = atoi( token[2].c_str() );
 
     double lat_1 = atof( token[9].c_str() );
@@ -347,17 +352,14 @@ private:
     rwy_lon_accum += lon_2;
     rwy_count++;
 
-    double length, heading_1, heading_2, dummy;
+    double length, heading_1, heading_2;
     SGGeodesy::inverse( pos_1, pos_2, heading_1, heading_2, length );
-    SGGeod pos;
-    SGGeodesy::direct( pos_1, heading_1, length / 2.0, pos, dummy );
-    length *= SG_METER_TO_FEET;
 
     last_rwy_heading = heading_1;
 
     const string& rwy_no_1(token[8]);
     const string& rwy_no_2(token[17]);
-    if ( rwy_no_1.size() == 0 || rwy_no_2.size() == 0 )
+    if ( rwy_no_1.empty() || rwy_no_2.empty() )
         return;
 
     double displ_thresh1 = atof( token[11].c_str() );
@@ -366,13 +368,13 @@ private:
     double stopway1 = atof( token[12].c_str() );
     double stopway2 = atof( token[21].c_str() );
 
-    PositionedID rwy = cache->insertRunway(FGPositioned::RUNWAY, rwy_no_1, pos,
+    PositionedID rwy = cache->insertRunway(FGPositioned::RUNWAY, rwy_no_1, pos_1,
                                            currentAirportID, heading_1, length,
                                            width, displ_thresh1, stopway1,
                                            surface_code);
     
     PositionedID reciprocal = cache->insertRunway(FGPositioned::RUNWAY,
-                                                  rwy_no_2, pos,
+                                                  rwy_no_2, pos_2,
                                                   currentAirportID, heading_2, length,
                                                   width, displ_thresh2, stopway2,
                                                   surface_code);
@@ -382,7 +384,7 @@ private:
 
   void parseWaterRunwayLine850(const vector<string>& token)
   {
-    double width = atof( token[1].c_str() ) * SG_METER_TO_FEET;
+    double width = atof( token[1].c_str() );
 
     double lat_1 = atof( token[4].c_str() );
     double lon_1 = atof( token[5].c_str() );
@@ -398,22 +400,20 @@ private:
     rwy_lon_accum += lon_2;
     rwy_count++;
 
-    double length, heading_1, heading_2, dummy;
+    double length, heading_1, heading_2;
     SGGeodesy::inverse( pos_1, pos_2, heading_1, heading_2, length );
-    SGGeod pos;
-    SGGeodesy::direct( pos_1, heading_1, length / 2.0, pos, dummy );
 
     last_rwy_heading = heading_1;
 
     const string& rwy_no_1(token[3]);
     const string& rwy_no_2(token[6]);
 
-    PositionedID rwy = cache->insertRunway(FGPositioned::RUNWAY, rwy_no_1, pos,
+    PositionedID rwy = cache->insertRunway(FGPositioned::RUNWAY, rwy_no_1, pos_1,
                                            currentAirportID, heading_1, length,
                                            width, 0.0, 0.0, 13);
     
     PositionedID reciprocal = cache->insertRunway(FGPositioned::RUNWAY,
-                                                  rwy_no_2, pos,
+                                                  rwy_no_2, pos_2,
                                                   currentAirportID, heading_2, length,
                                                   width, 0.0, 0.0, 13);
     
@@ -422,8 +422,8 @@ private:
 
   void parseHelipadLine850(const vector<string>& token)
   {
-    double length = atof( token[5].c_str() ) * SG_METER_TO_FEET;
-    double width = atof( token[6].c_str() ) * SG_METER_TO_FEET;
+    double length = atof( token[5].c_str() );
+    double width = atof( token[6].c_str() );
 
     double lat = atof( token[2].c_str() );
     double lon = atof( token[3].c_str() );
@@ -550,6 +550,7 @@ bool metarDataLoad(const SGPath& metar_file)
   }
   
   NavDataCache* cache = NavDataCache::instance();
+
   string ident;
   while ( metar_in ) {
     metar_in >> ident;