-
-// Return the runway number of the runway closest to a given heading
-string FGRunwayList::search( const string& aptid, const int hdg ) {
- //SG_LOG(SG_GENERAL, SG_ALERT, "searching runway for " << aptid
- // << " with target heading " << hdg);
-
- FGRunway r;
- if (!search(aptid, &r)) {
- SG_LOG(SG_GENERAL, SG_ALERT, "Failed to find "
- << aptid << " in database.");
- return "NN";
- }
-
- SGPropertyNode *param = fgGetNode("/sim/airport/runways/search", true);
- double lenwgt = param->getDoubleValue("length-weight", 0.01);
- double widwgt = param->getDoubleValue("width-weight", 0.01);
- double surfwgt = param->getDoubleValue("surface-weight", 10);
- double devwgt = param->getDoubleValue("deviation-weight", 1);
-
- FGRunway best;
- double max = 0.0;
- bool reversed = false;
-
- do {
- if (r._id != aptid)
- break;
- if (r._type != "runway")
- continue;
-
- int surface = 1;
- if (r._surface_code == 12 || r._surface_code == 5) // dry lakebed & gravel
- surface = 2;
- else if (r._surface_code == 1 || r._surface_code == 2) // asphalt & concrete
- surface = 3;
-
- double quality, bad, diff;
- double good = lenwgt * r._length + widwgt * r._width + surfwgt * surface + 1e-20;
-
- // this side
- diff = hdg - r._heading;
- while (diff < -180)
- diff += 360;
- while (diff >= 180)
- diff -= 360;
- bad = fabs(devwgt * diff) + 1e-20;
-
- quality = good / bad;
- //SG_LOG(SG_GENERAL, SG_ALERT, " runway " << r._rwy_no << " -> " << quality);
- if (quality > max) {
- max = quality;
- best = r;
- reversed = false;
- }
-
- // other side
- diff = hdg - r._heading - 180;
- while (diff < -180)
- diff += 360;
- while (diff >= 180)
- diff -= 360;
- bad = fabs(devwgt * diff) + 1e-20;
-
- quality = good / bad;
- //SG_LOG(SG_GENERAL, SG_ALERT, " runway " << GetReverseRunwayNo(r._rwy_no)
- // << " -> " << quality);
- if (quality > max) {
- max = quality;
- best = r;
- reversed = true;
- }
-
- } while (next(&r));
-
- return reversed ? GetReverseRunwayNo(best._rwy_no) : best._rwy_no;
+void FGRunway::processThreshold(SGPropertyNode* aThreshold)
+{
+ assert(ident() == aThreshold->getStringValue("rwy"));
+
+ double lon = aThreshold->getDoubleValue("lon"),
+ lat = aThreshold->getDoubleValue("lat");
+ SGGeod newThreshold(SGGeod::fromDegM(lon, lat, mPosition.getElevationM()));
+
+ _heading = aThreshold->getDoubleValue("hdg-deg");
+ _displ_thresh = aThreshold->getDoubleValue("displ-m") * SG_METER_TO_FEET;
+ _stopway = aThreshold->getDoubleValue("stopw-m") * SG_METER_TO_FEET;
+
+ // compute the new runway center, based on the threshold lat/lon and length,
+ double offsetFt = (0.5 * _length);
+ SGGeod newCenter;
+ double dummy;
+ SGGeodesy::direct(newThreshold, _heading, offsetFt * SG_FEET_TO_METER, newCenter, dummy);
+ mPosition = newCenter;
+}
+
+void FGRunway::setReciprocalRunway(FGRunway* other)
+{
+ assert(_reciprocal==NULL);
+ assert((other->_reciprocal == NULL) || (other->_reciprocal == this));
+
+ _reciprocal = other;