Skip to content

Commit

Permalink
Added true bearing indicator for airport MSA.
Browse files Browse the repository at this point in the history
Fixed bearings for MSA sectors in X-Plane and DFD compilers.
albar965/littlenavmap#498
  • Loading branch information
albar965 committed Oct 26, 2021
1 parent 050ffa4 commit ebf16a0
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 8 deletions.
1 change: 1 addition & 0 deletions resources/sql/fs/db/create_nav_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ create table airport_msa
vor_has_dme integer,
region varchar(2), -- ICAO two letter region identifier
multiple_code varchar(1), -- ICAO ident
true_bearing integer, -- 1 if bearing values in geometry are true (does not apply to cicrle)
mag_var double, -- Magnetic variance in degree < 0 for West and > 0 for East
left_lonx double, -- Bounding rectangle of the whole MSA sector
top_laty double , -- "
Expand Down
13 changes: 13 additions & 0 deletions src/atools.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,19 @@ const TYPE& at(const QVector<TYPE>& list, int index, const QString& msg, const T
return defaultType;
}

/* Functions roll over to first position on overflow */
template<typename TYPE>
const TYPE& atRoll(const QVector<TYPE>& list, int index)
{
return index < list.size() ? list.at(index) : list.first();
}

template<typename TYPE>
const TYPE& atRoll(const QList<TYPE>& list, int index)
{
return index < list.size() ? list.at(index) : list.first();
}

/* Writes a warning message includiing the string list */
QString at(const QStringList& columns, int index, bool error);

Expand Down
11 changes: 7 additions & 4 deletions src/fs/common/binarymsageometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,28 @@ BinaryMsaGeometry::BinaryMsaGeometry(const QByteArray& bytes)
readFromByteArray(bytes);
}

void BinaryMsaGeometry::calculate(const atools::geo::Pos& center, float radiusNm, float magvar)
void BinaryMsaGeometry::calculate(const atools::geo::Pos& center, float radiusNm, float magvar, bool trueBearing)
{
geometry.clear();
labelPositions.clear();
bearingEndPositions.clear();

float radiusMeter = atools::geo::nmToMeter(radiusNm);

if(trueBearing)
magvar = 0.f;

for(int i = 0; i < bearings.size(); i++)
{
float bearingFromTrue = bearings.at(i) + magvar;
// Roll over to start if last
float bearingToTrue = i >= bearings.size() - 1 ? bearings.at(0) + magvar : bearings.at(i + 1) + magvar;
float bearingToTrue = atools::atRoll(bearings, i + 1) + magvar;

float labelBrg = 0.f; // Default is north of center
if(bearings.size() > 1)
// Calculate a bearing for label in the middle of a sector
labelBrg = atools::geo::normalizeCourse(bearingFromTrue + atools::geo::angleAbsDiff(bearingFromTrue,
bearingToTrue) / 2.f);
labelBrg = atools::geo::normalizeCourse(bearingFromTrue +
atools::geo::angleAbsDiff(bearingFromTrue, bearingToTrue) / 2.f);
// Calculate label position
Pos lbl = center.endpoint(radiusMeter / 2.f, labelBrg);

Expand Down
2 changes: 1 addition & 1 deletion src/fs/common/binarymsageometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class BinaryMsaGeometry
void addSectors(const QVector<float>& bearingDegAltitudeFt);

/* Calculate circle/arc geomentry, label points and bearing endpoints */
void calculate(const atools::geo::Pos& center, float radiusNm, float magvar);
void calculate(const atools::geo::Pos& center, float radiusNm, float magvar, bool trueBearing);

/* Read from database BLOB */
void readFromByteArray(const QByteArray& bytes);
Expand Down
3 changes: 2 additions & 1 deletion src/fs/dfd/dfdcompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1436,7 +1436,7 @@ void DfdCompiler::writeAirportMsa()
bool trueBearing = query.valueStr("magnetic_true_indicator") == "T";

// Calculate geometry for arcs, label points and bearing endpoints to speed up drawing
geo.calculate(center, radius, trueBearing ? 0.f : magvar);
geo.calculate(center, radius, magvar, trueBearing);

if(geo.isValid())
{
Expand All @@ -1463,6 +1463,7 @@ void DfdCompiler::writeAirportMsa()
insertQuery.bindNullInt(":vor_has_dme");
}

insertQuery.bindValue(":true_bearing", trueBearing);
insertQuery.bindValue(":mag_var", magvar);
insertQuery.bindValue(":radius", radius);

Expand Down
5 changes: 3 additions & 2 deletions src/fs/xp/xpairportmsawriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ void XpAirportMsaWriter::write(const QStringList& line, const XpWriterContext& c
Pos airportPos = airportIndex->getAirportPos(airportIdent);

QString region = at(line, REGION);
bool trueBearing = at(line, MAG_TRUE) == "T";

int navId = -1;
float magvar = 0.f;
Expand Down Expand Up @@ -195,7 +194,8 @@ void XpAirportMsaWriter::write(const QStringList& line, const XpWriterContext& c
}

// Calculate geometry for arcs, label points and bearing endpoints to speed up drawing
geo.calculate(center, radius, trueBearing ? 0.f : magvar);
bool trueBearing = at(line, MAG_TRUE) == "T";
geo.calculate(center, radius, magvar, trueBearing);

if(geo.isValid())
{
Expand All @@ -221,6 +221,7 @@ void XpAirportMsaWriter::write(const QStringList& line, const XpWriterContext& c
}

insertQuery->bindValue(":region", region);
insertQuery->bindValue(":true_bearing", trueBearing);
insertQuery->bindValue(":mag_var", magvar);
insertQuery->bindValue(":radius", radius);

Expand Down

0 comments on commit ebf16a0

Please sign in to comment.