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.
This commit is contained in:
parent
d9026d776c
commit
715c48e2d7
7 changed files with 44 additions and 47 deletions
|
@ -478,8 +478,8 @@ void FGAirport::processThreshold(SGPropertyNode* aThreshold)
|
||||||
SGGeod newThreshold(SGGeod::fromDegM(lon, lat, mPosition.getElevationM()));
|
SGGeod newThreshold(SGGeod::fromDegM(lon, lat, mPosition.getElevationM()));
|
||||||
|
|
||||||
double newHeading = aThreshold->getDoubleValue("hdg-deg");
|
double newHeading = aThreshold->getDoubleValue("hdg-deg");
|
||||||
double newDisplacedThreshold = aThreshold->getDoubleValue("displ-m") * SG_METER_TO_FEET;
|
double newDisplacedThreshold = aThreshold->getDoubleValue("displ-m");
|
||||||
double newStopway = aThreshold->getDoubleValue("stopw-m") * SG_METER_TO_FEET;
|
double newStopway = aThreshold->getDoubleValue("stopw-m");
|
||||||
|
|
||||||
cache->updateRunwayThreshold(id, newThreshold,
|
cache->updateRunwayThreshold(id, newThreshold,
|
||||||
newHeading, newDisplacedThreshold, newStopway);
|
newHeading, newDisplacedThreshold, newStopway);
|
||||||
|
|
|
@ -287,16 +287,21 @@ private:
|
||||||
double heading = atof( token[4].c_str() );
|
double heading = atof( token[4].c_str() );
|
||||||
double length = atoi( token[5].c_str() );
|
double length = atoi( token[5].c_str() );
|
||||||
double width = atoi( token[8].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;
|
last_rwy_heading = heading;
|
||||||
|
|
||||||
int surface_code = atoi( token[10].c_str() );
|
int surface_code = atoi( token[10].c_str() );
|
||||||
SGGeod pos(SGGeod::fromDegFt(lon, lat, last_apt_elev));
|
|
||||||
|
|
||||||
if (rwy_no[0] == 'x') { // Taxiway
|
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);
|
heading, length, width, 0.0, 0.0, surface_code);
|
||||||
} else if (rwy_no[0] == 'H') { // Helipad
|
} else if (rwy_no[0] == 'H') { // Helipad
|
||||||
|
SGGeod pos(SGGeod::fromDegFt(lon, lat, last_apt_elev));
|
||||||
cache->insertRunway(FGPositioned::HELIPAD, rwy_no, pos, currentAirportID,
|
cache->insertRunway(FGPositioned::HELIPAD, rwy_no, pos, currentAirportID,
|
||||||
heading, length, width, 0.0, 0.0, surface_code);
|
heading, length, width, 0.0, 0.0, surface_code);
|
||||||
} else {
|
} else {
|
||||||
|
@ -306,22 +311,29 @@ private:
|
||||||
= simgear::strutils::split( rwy_displ_threshold, "." );
|
= simgear::strutils::split( rwy_displ_threshold, "." );
|
||||||
double displ_thresh1 = atof( displ[0].c_str() );
|
double displ_thresh1 = atof( displ[0].c_str() );
|
||||||
double displ_thresh2 = atof( displ[1].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];
|
string rwy_stopway = token[7];
|
||||||
vector<string> stop
|
vector<string> stop
|
||||||
= simgear::strutils::split( rwy_stopway, "." );
|
= simgear::strutils::split( rwy_stopway, "." );
|
||||||
double stopway1 = atof( stop[0].c_str() );
|
double stopway1 = atof( stop[0].c_str() );
|
||||||
double stopway2 = atof( stop[1].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,
|
currentAirportID, heading, length,
|
||||||
width, displ_thresh1, stopway1,
|
width, displ_thresh1, stopway1,
|
||||||
surface_code);
|
surface_code);
|
||||||
|
|
||||||
PositionedID reciprocal = cache->insertRunway(FGPositioned::RUNWAY,
|
PositionedID reciprocal = cache->insertRunway(FGPositioned::RUNWAY,
|
||||||
FGRunway::reverseIdent(rwy_no), pos,
|
FGRunway::reverseIdent(rwy_no), pos_2,
|
||||||
currentAirportID, heading + 180.0, length,
|
currentAirportID,
|
||||||
width, displ_thresh2, stopway2,
|
SGMiscd::normalizePeriodic(0, 360, heading + 180.0),
|
||||||
|
length, width, displ_thresh2, stopway2,
|
||||||
surface_code);
|
surface_code);
|
||||||
|
|
||||||
cache->setRunwayReciprocal(rwy, reciprocal);
|
cache->setRunwayReciprocal(rwy, reciprocal);
|
||||||
|
@ -330,7 +342,7 @@ private:
|
||||||
|
|
||||||
void parseRunwayLine850(const vector<string>& token)
|
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() );
|
int surface_code = atoi( token[2].c_str() );
|
||||||
|
|
||||||
double lat_1 = atof( token[9].c_str() );
|
double lat_1 = atof( token[9].c_str() );
|
||||||
|
@ -347,11 +359,8 @@ private:
|
||||||
rwy_lon_accum += lon_2;
|
rwy_lon_accum += lon_2;
|
||||||
rwy_count++;
|
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 );
|
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;
|
last_rwy_heading = heading_1;
|
||||||
|
|
||||||
|
@ -366,13 +375,13 @@ private:
|
||||||
double stopway1 = atof( token[12].c_str() );
|
double stopway1 = atof( token[12].c_str() );
|
||||||
double stopway2 = atof( token[21].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,
|
currentAirportID, heading_1, length,
|
||||||
width, displ_thresh1, stopway1,
|
width, displ_thresh1, stopway1,
|
||||||
surface_code);
|
surface_code);
|
||||||
|
|
||||||
PositionedID reciprocal = cache->insertRunway(FGPositioned::RUNWAY,
|
PositionedID reciprocal = cache->insertRunway(FGPositioned::RUNWAY,
|
||||||
rwy_no_2, pos,
|
rwy_no_2, pos_2,
|
||||||
currentAirportID, heading_2, length,
|
currentAirportID, heading_2, length,
|
||||||
width, displ_thresh2, stopway2,
|
width, displ_thresh2, stopway2,
|
||||||
surface_code);
|
surface_code);
|
||||||
|
@ -382,7 +391,7 @@ private:
|
||||||
|
|
||||||
void parseWaterRunwayLine850(const vector<string>& token)
|
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 lat_1 = atof( token[4].c_str() );
|
||||||
double lon_1 = atof( token[5].c_str() );
|
double lon_1 = atof( token[5].c_str() );
|
||||||
|
@ -398,22 +407,20 @@ private:
|
||||||
rwy_lon_accum += lon_2;
|
rwy_lon_accum += lon_2;
|
||||||
rwy_count++;
|
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 );
|
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;
|
last_rwy_heading = heading_1;
|
||||||
|
|
||||||
const string& rwy_no_1(token[3]);
|
const string& rwy_no_1(token[3]);
|
||||||
const string& rwy_no_2(token[6]);
|
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,
|
currentAirportID, heading_1, length,
|
||||||
width, 0.0, 0.0, 13);
|
width, 0.0, 0.0, 13);
|
||||||
|
|
||||||
PositionedID reciprocal = cache->insertRunway(FGPositioned::RUNWAY,
|
PositionedID reciprocal = cache->insertRunway(FGPositioned::RUNWAY,
|
||||||
rwy_no_2, pos,
|
rwy_no_2, pos_2,
|
||||||
currentAirportID, heading_2, length,
|
currentAirportID, heading_2, length,
|
||||||
width, 0.0, 0.0, 13);
|
width, 0.0, 0.0, 13);
|
||||||
|
|
||||||
|
@ -422,8 +429,8 @@ private:
|
||||||
|
|
||||||
void parseHelipadLine850(const vector<string>& token)
|
void parseHelipadLine850(const vector<string>& token)
|
||||||
{
|
{
|
||||||
double length = atof( token[5].c_str() ) * SG_METER_TO_FEET;
|
double length = atof( token[5].c_str() );
|
||||||
double width = atof( token[6].c_str() ) * SG_METER_TO_FEET;
|
double width = atof( token[6].c_str() );
|
||||||
|
|
||||||
double lat = atof( token[2].c_str() );
|
double lat = atof( token[2].c_str() );
|
||||||
double lon = atof( token[3].c_str() );
|
double lon = atof( token[3].c_str() );
|
||||||
|
|
|
@ -61,10 +61,7 @@ FGRunwayBase::FGRunwayBase(PositionedID aGuid, Type aTy, const string& aIdent,
|
||||||
|
|
||||||
SGGeod FGRunwayBase::pointOnCenterline(double aOffset) const
|
SGGeod FGRunwayBase::pointOnCenterline(double aOffset) const
|
||||||
{
|
{
|
||||||
double halfLengthMetres = lengthM() * 0.5;
|
SGGeod result = SGGeodesy::direct(mPosition, _heading, aOffset);
|
||||||
|
|
||||||
SGGeod result = SGGeodesy::direct(mPosition, _heading,
|
|
||||||
aOffset - halfLengthMetres);
|
|
||||||
result.setElevationM(mPosition.getElevationM());
|
result.setElevationM(mPosition.getElevationM());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -75,13 +72,11 @@ SGGeod FGRunwayBase::pointOffCenterline(double aOffset, double lateralOffset) co
|
||||||
SGGeod result;
|
SGGeod result;
|
||||||
SGGeod temp;
|
SGGeod temp;
|
||||||
double dummyAz2;
|
double dummyAz2;
|
||||||
double halfLengthMetres = lengthM() * 0.5;
|
|
||||||
|
|
||||||
SGGeodesy::direct(mPosition, _heading,
|
SGGeodesy::direct(mPosition, _heading,
|
||||||
aOffset - halfLengthMetres,
|
aOffset, temp, dummyAz2);
|
||||||
temp, dummyAz2);
|
|
||||||
|
|
||||||
SGGeodesy::direct(temp, (_heading+90.0),
|
SGGeodesy::direct(temp, SGMiscd::normalizePeriodic(0, 360,_heading+90.0),
|
||||||
lateralOffset,
|
lateralOffset,
|
||||||
result, dummyAz2);
|
result, dummyAz2);
|
||||||
|
|
||||||
|
|
|
@ -54,16 +54,16 @@ public:
|
||||||
SGGeod pointOffCenterline(double aOffset, double lateralOffset) const;
|
SGGeod pointOffCenterline(double aOffset, double lateralOffset) const;
|
||||||
|
|
||||||
double lengthFt() const
|
double lengthFt() const
|
||||||
{ return _length; }
|
{ return _length * SG_METER_TO_FEET; }
|
||||||
|
|
||||||
double lengthM() const
|
double lengthM() const
|
||||||
{ return _length * SG_FEET_TO_METER; }
|
{ return _length; }
|
||||||
|
|
||||||
double widthFt() const
|
double widthFt() const
|
||||||
{ return _width; }
|
{ return _width * SG_METER_TO_FEET; }
|
||||||
|
|
||||||
double widthM() const
|
double widthM() const
|
||||||
{ return _width * SG_FEET_TO_METER; }
|
{ return _width; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runway heading in degrees.
|
* Runway heading in degrees.
|
||||||
|
|
|
@ -121,7 +121,7 @@ SGGeod FGRunway::end() const
|
||||||
|
|
||||||
SGGeod FGRunway::threshold() const
|
SGGeod FGRunway::threshold() const
|
||||||
{
|
{
|
||||||
return pointOnCenterline(_displ_thresh * SG_FEET_TO_METER);
|
return pointOnCenterline(_displ_thresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGRunway::setReciprocalRunway(PositionedID other)
|
void FGRunway::setReciprocalRunway(PositionedID other)
|
||||||
|
|
|
@ -96,10 +96,10 @@ public:
|
||||||
SGGeod end() const;
|
SGGeod end() const;
|
||||||
|
|
||||||
double displacedThresholdM() const
|
double displacedThresholdM() const
|
||||||
{ return _displ_thresh * SG_FEET_TO_METER; }
|
{ return _displ_thresh; }
|
||||||
|
|
||||||
double stopwayM() const
|
double stopwayM() const
|
||||||
{ return _stopway * SG_FEET_TO_METER; }
|
{ return _stopway; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Airport this runway is located at
|
* Airport this runway is located at
|
||||||
|
|
|
@ -71,7 +71,7 @@ using std::string;
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const int MAX_RETRIES = 10;
|
const int MAX_RETRIES = 10;
|
||||||
const int SCHEMA_VERSION = 7;
|
const int SCHEMA_VERSION = 8;
|
||||||
const int CACHE_SIZE_KBYTES= 16000;
|
const int CACHE_SIZE_KBYTES= 16000;
|
||||||
|
|
||||||
// bind a std::string to a sqlite statement. The std::string must live the
|
// 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, 3, aDisplacedThreshold);
|
||||||
sqlite3_bind_double(d->updateRunwayThreshold, 4, aStopway);
|
sqlite3_bind_double(d->updateRunwayThreshold, 4, aStopway);
|
||||||
d->execUpdate(d->updateRunwayThreshold);
|
d->execUpdate(d->updateRunwayThreshold);
|
||||||
|
|
||||||
// compute the new runway center, based on the threshold lat/lon and length,
|
// now update the positional data
|
||||||
double offsetFt = (0.5 * d->runwayLengthFt(runwayID));
|
updatePosition(runwayID, aThreshold);
|
||||||
SGGeod newCenter= SGGeodesy::direct(aThreshold, aHeading, offsetFt * SG_FEET_TO_METER);
|
|
||||||
newCenter.setElevationM(aThreshold.getElevationM());
|
|
||||||
|
|
||||||
// now update the positional data
|
|
||||||
updatePosition(runwayID, newCenter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PositionedID
|
PositionedID
|
||||||
|
|
Loading…
Reference in a new issue