+bool finalizeMetar()
+{
+ if (!fgGetBool("/environment/realwx/enabled")) {
+ return true;
+ }
+
+ double hdg = fgGetDouble( "/environment/metar/base-wind-dir-deg", 9999.0 );
+ string apt = fgGetString("/sim/presets/airport-id");
+ string rwy = fgGetString("/sim/presets/runway");
+ double strthdg = fgGetDouble( "/sim/startup/options/heading-deg", 9999.0 );
+ string parkpos = fgGetString( "/sim/presets/parkpos" );
+ bool onground = fgGetBool( "/sim/presets/onground", false );
+ // this logic is taken from former startup.nas
+ bool needMetar = (hdg < 360.0) && !apt.empty() && (strthdg > 360.0) &&
+ rwy.empty() && onground && parkpos.empty();
+
+ if (needMetar) {
+ // timeout so we don't spin forever if the network is down
+ if (global_finalizeTime.elapsedMSec() > fgGetInt("/sim/startup/metar-fetch-timeout-msec", 6000)) {
+ SG_LOG(SG_GENERAL, SG_WARN, "finalizePosition: timed out waiting for METAR fetch");
+ return true;
+ }
+
+ if (fgGetBool( "/environment/metar/failure" )) {
+ SG_LOG(SG_ENVIRONMENT, SG_INFO, "metar download failed, not waiting");
+ return true;
+ }
+
+ if (!fgGetBool( "/environment/metar/valid" )) {
+ return false;
+ }
+
+ SG_LOG(SG_ENVIRONMENT, SG_INFO,
+ "Using METAR for runway selection: '" << fgGetString("/environment/metar/data") << "'" );
+ setPosFromAirportIDandHdg( apt, hdg );
+ // fall through to return true
+ } // of need-metar case
+
+ return true;
+}
+
+void finalizePosition()
+{
+ // first call to finalize after an initPosition call
+ if (global_finalizeTime.get_usec() == 0) {
+ global_finalizeTime = SGTimeStamp::now();
+ }
+
+ bool done = true;
+
+ /* Scenarios require Nasal, so FGAIManager loads the scenarios,
+ * including its models such as a/c carriers, in its 'postinit',
+ * which is the very last thing we do.
+ * flightgear::initPosition is called very early in main.cxx/fgIdleFunction,
+ * one of the first things we do, long before scenarios/carriers are
+ * loaded. => When requested "initial preset position" relates to a
+ * carrier, recalculate the 'initial' position here
+ */
+ std::string carrier = fgGetString("/sim/presets/carrier","");
+ if (!carrier.empty())
+ {
+ SG_LOG(SG_GENERAL, SG_INFO, "finalizePositioned: re-init-ing position on carrier");
+ // clear preset location and re-trigger position setup
+ fgSetDouble("/sim/presets/longitude-deg", 9999);
+ fgSetDouble("/sim/presets/latitude-deg", 9999);
+ initPosition();
+ } else {
+ done = finalizeMetar();
+ }
+
+ fgSetBool("/sim/position-finalized", done);
+ if (done) {
+ globals->get_event_mgr()->removeTask("finalizePosition");
+ global_callbackRegistered = false;
+ }
+}
+