From 715c48e2d7bda63c8ca8b6960f624dc30d38334c Mon Sep 17 00:00:00 2001 From: Christian Schmitt Date: Thu, 21 Feb 2013 22:47:01 +0100 Subject: [PATCH] Convert runway parser and all internals to metric units and 2 runway ends. This eliminates many conversations between ft and m and gives us runway start/end points that are needed for many calculations. Also, this prepares the internals for the upcoming apt.dat 850+ format that uses the metric system as well as start/end points. --- src/Airports/airport.cxx | 4 +-- src/Airports/apt_loader.cxx | 49 ++++++++++++++++++++---------------- src/Airports/runwaybase.cxx | 11 +++----- src/Airports/runwaybase.hxx | 8 +++--- src/Airports/runways.cxx | 2 +- src/Airports/runways.hxx | 4 +-- src/Navaids/NavDataCache.cxx | 13 +++------- 7 files changed, 44 insertions(+), 47 deletions(-) diff --git a/src/Airports/airport.cxx b/src/Airports/airport.cxx index 56edab20c..2f8dc1197 100644 --- a/src/Airports/airport.cxx +++ b/src/Airports/airport.cxx @@ -478,8 +478,8 @@ void FGAirport::processThreshold(SGPropertyNode* aThreshold) SGGeod newThreshold(SGGeod::fromDegM(lon, lat, mPosition.getElevationM())); double newHeading = aThreshold->getDoubleValue("hdg-deg"); - double newDisplacedThreshold = aThreshold->getDoubleValue("displ-m") * SG_METER_TO_FEET; - double newStopway = aThreshold->getDoubleValue("stopw-m") * SG_METER_TO_FEET; + double newDisplacedThreshold = aThreshold->getDoubleValue("displ-m"); + double newStopway = aThreshold->getDoubleValue("stopw-m"); cache->updateRunwayThreshold(id, newThreshold, newHeading, newDisplacedThreshold, newStopway); diff --git a/src/Airports/apt_loader.cxx b/src/Airports/apt_loader.cxx index fc4b0b1ed..e41db5a59 100644 --- a/src/Airports/apt_loader.cxx +++ b/src/Airports/apt_loader.cxx @@ -287,16 +287,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 +311,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 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 +342,7 @@ private: void parseRunwayLine850(const vector& 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,11 +359,8 @@ 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; @@ -366,13 +375,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 +391,7 @@ private: void parseWaterRunwayLine850(const vector& 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 +407,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 +429,8 @@ private: void parseHelipadLine850(const vector& 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() ); diff --git a/src/Airports/runwaybase.cxx b/src/Airports/runwaybase.cxx index 83c838926..0e07c1fa9 100644 --- a/src/Airports/runwaybase.cxx +++ b/src/Airports/runwaybase.cxx @@ -61,10 +61,7 @@ FGRunwayBase::FGRunwayBase(PositionedID aGuid, Type aTy, const string& aIdent, SGGeod FGRunwayBase::pointOnCenterline(double aOffset) const { - double halfLengthMetres = lengthM() * 0.5; - - SGGeod result = SGGeodesy::direct(mPosition, _heading, - aOffset - halfLengthMetres); + SGGeod result = SGGeodesy::direct(mPosition, _heading, aOffset); result.setElevationM(mPosition.getElevationM()); return result; @@ -75,13 +72,11 @@ SGGeod FGRunwayBase::pointOffCenterline(double aOffset, double lateralOffset) co SGGeod result; SGGeod temp; double dummyAz2; - double halfLengthMetres = lengthM() * 0.5; SGGeodesy::direct(mPosition, _heading, - aOffset - halfLengthMetres, - temp, dummyAz2); + aOffset, temp, dummyAz2); - SGGeodesy::direct(temp, (_heading+90.0), + SGGeodesy::direct(temp, SGMiscd::normalizePeriodic(0, 360,_heading+90.0), lateralOffset, result, dummyAz2); diff --git a/src/Airports/runwaybase.hxx b/src/Airports/runwaybase.hxx index 25d234043..e13101b19 100644 --- a/src/Airports/runwaybase.hxx +++ b/src/Airports/runwaybase.hxx @@ -54,16 +54,16 @@ public: SGGeod pointOffCenterline(double aOffset, double lateralOffset) const; double lengthFt() const - { return _length; } + { return _length * SG_METER_TO_FEET; } double lengthM() const - { return _length * SG_FEET_TO_METER; } + { return _length; } double widthFt() const - { return _width; } + { return _width * SG_METER_TO_FEET; } double widthM() const - { return _width * SG_FEET_TO_METER; } + { return _width; } /** * Runway heading in degrees. diff --git a/src/Airports/runways.cxx b/src/Airports/runways.cxx index 72fb1609d..8abed46ca 100644 --- a/src/Airports/runways.cxx +++ b/src/Airports/runways.cxx @@ -121,7 +121,7 @@ SGGeod FGRunway::end() const SGGeod FGRunway::threshold() const { - return pointOnCenterline(_displ_thresh * SG_FEET_TO_METER); + return pointOnCenterline(_displ_thresh); } void FGRunway::setReciprocalRunway(PositionedID other) diff --git a/src/Airports/runways.hxx b/src/Airports/runways.hxx index 0c4cd4e37..b5109de4f 100644 --- a/src/Airports/runways.hxx +++ b/src/Airports/runways.hxx @@ -96,10 +96,10 @@ public: SGGeod end() const; double displacedThresholdM() const - { return _displ_thresh * SG_FEET_TO_METER; } + { return _displ_thresh; } double stopwayM() const - { return _stopway * SG_FEET_TO_METER; } + { return _stopway; } /** * Airport this runway is located at diff --git a/src/Navaids/NavDataCache.cxx b/src/Navaids/NavDataCache.cxx index d8ba979d9..b27736d1b 100644 --- a/src/Navaids/NavDataCache.cxx +++ b/src/Navaids/NavDataCache.cxx @@ -71,7 +71,7 @@ using std::string; namespace { const int MAX_RETRIES = 10; -const int SCHEMA_VERSION = 7; +const int SCHEMA_VERSION = 8; const int CACHE_SIZE_KBYTES= 16000; // bind a std::string to a sqlite statement. The std::string must live the @@ -1579,14 +1579,9 @@ void NavDataCache::updateRunwayThreshold(PositionedID runwayID, const SGGeod &aT sqlite3_bind_double(d->updateRunwayThreshold, 3, aDisplacedThreshold); sqlite3_bind_double(d->updateRunwayThreshold, 4, aStopway); d->execUpdate(d->updateRunwayThreshold); - -// compute the new runway center, based on the threshold lat/lon and length, - double offsetFt = (0.5 * d->runwayLengthFt(runwayID)); - SGGeod newCenter= SGGeodesy::direct(aThreshold, aHeading, offsetFt * SG_FEET_TO_METER); - newCenter.setElevationM(aThreshold.getElevationM()); - -// now update the positional data - updatePosition(runwayID, newCenter); + + // now update the positional data + updatePosition(runwayID, aThreshold); } PositionedID