buildPavements();
}
+ clearIgnoredNavaids();
+ addIgnoredNavaid(apt);
+
recomputeBounds(true);
update();
}
p->setFont(f);
// draw ILS first so underneath all runways
- QPen pen(Qt::magenta);
- pen.setWidth(1.0 / m_scale);
+ QPen pen(QColor(0x5f, 0x5f, 0x5f));
+ pen.setWidth(1);
+ pen.setCosmetic(true);
p->setPen(pen);
Q_FOREACH(const RunwayData& r, m_runways) {
return t;
}
+void BaseDiagram::clearIgnoredNavaids()
+{
+ m_ignored.clear();
+}
+
+void BaseDiagram::addIgnoredNavaid(FGPositionedRef pos)
+{
+ if (isNavaidIgnored(pos))
+ return;
+ m_ignored.push_back(pos);
+}
+
void BaseDiagram::extendRect(QRectF &r, const QPointF &p)
{
if (p.x() < r.left()) {
FGPositionedList::const_iterator it;
for (it = items.begin(); it != items.end(); ++it) {
+ FGPositionedRef pos(*it);
bool drawAsIcon = true;
+ if (isNavaidIgnored(pos))
+ continue;
- if ((*it)->type() == FGPositioned::AIRPORT) {
- FGAirport* apt = static_cast<FGAirport*>(it->ptr());
+ FGPositioned::Type ty(pos->type());
+ if (ty == FGPositioned::AIRPORT) {
+ FGAirport* apt = static_cast<FGAirport*>(pos.ptr());
if (apt->hasHardRunwayOfLengthFt(minRunwayLengthFt)) {
drawAsIcon = false;
}
if (drawAsIcon) {
- QPixmap pm = iconForPositioned(*it);
- QPointF loc = xf.map(project((*it)->geod()));
- loc -= QPointF(pm.width() >> 1, pm.height() >> 1);
- painter->drawPixmap(loc, pm);
+ QPixmap pm = iconForPositioned(pos, false);
+ QPointF loc = xf.map(project(pos->geod()));
+
+ QPointF iconLoc = loc - QPointF(pm.width() >> 1, pm.height() >> 1);
+ painter->drawPixmap(iconLoc, pm);
+
+ painter->setPen(QColor(0x03, 0x83, 0xbf));
+
+ QString label;
+ if (FGAirport::isAirportType(pos.ptr())) {
+ label = QString::fromStdString((*it)->name());
+ } else {
+ label = QString::fromStdString((*it)->ident());
+ }
+
+ if (ty == FGPositioned::NDB) {
+ FGNavRecord* nav = static_cast<FGNavRecord*>(pos.ptr());
+ label.append("\n").append(QString::number(nav->get_freq() / 100));
+ } else if (ty == FGPositioned::VOR) {
+ FGNavRecord* nav = static_cast<FGNavRecord*>(pos.ptr());
+ label.append("\n").append(QString::number(nav->get_freq() / 100.0, 'f', 1));
+ }
+
+ QRect labelBox(loc.x() + (pm.width()/2) + 4, loc.y() - 50, 100, 100);
+ painter->drawText(labelBox, Qt::AlignVCenter | Qt::AlignLeft | Qt::TextWordWrap,
+ label);
}
}
painter->setTransform(xf);
}
+bool BaseDiagram::isNavaidIgnored(const FGPositionedRef &pos) const
+{
+ return m_ignored.contains(pos);
+}
+
void BaseDiagram::mousePressEvent(QMouseEvent *me)
{
m_lastMousePos = me->pos();
return project(geod, m_projectionCenter);
}
-QPixmap BaseDiagram::iconForPositioned(const FGPositionedRef& pos)
+QPixmap BaseDiagram::iconForPositioned(const FGPositionedRef& pos, bool small)
{
// if airport type, check towered or untowered
switch (pos->type()) {
case FGPositioned::VOR:
- // check for VORTAC
+ if (static_cast<FGNavRecord*>(pos.ptr())->isVORTAC())
+ return QPixmap(":/vortac-icon");
if (static_cast<FGNavRecord*>(pos.ptr())->hasDME())
return QPixmap(":/vor-dme-icon");
case FGPositioned::SEAPORT:
return QPixmap(isTowered ? ":/seaport-tower-icon" : ":/seaport-icon");
case FGPositioned::NDB:
- return QPixmap(":/ndb-icon");
+ return QPixmap(small ? ":/ndb-small-icon" : ":/ndb-icon");
case FGPositioned::FIX:
return QPixmap(":/waypoint-icon");
public:
BaseDiagram(QWidget* pr);
- static QPixmap iconForPositioned(const FGPositionedRef &pos);
+ static QPixmap iconForPositioned(const FGPositionedRef &pos, bool small);
static QPixmap iconForAirport(FGAirport *apt);
static QVector<QLineF> projectAirportRuwaysIntoRect(FGAirportRef apt, const QRectF& bounds);
virtual void paintContents(QPainter*);
+
protected:
void recomputeBounds(bool resetZoom);
QPointF project(const SGGeod& geod) const;
QTransform transform() const;
+ void clearIgnoredNavaids();
+ void addIgnoredNavaid(FGPositionedRef pos);
+
SGGeod m_projectionCenter;
double m_scale;
QRectF m_bounds;
private:
void paintNavaids(QPainter *p);
+ bool isNavaidIgnored(const FGPositionedRef& pos) const;
+
+ QVector<FGPositionedRef> m_ignored;
};
#endif // of GUI_BASEDIAGRAM_HXX
{
QPointF base = project(m_geod);
+ QPointF airplaneIconPos = base;
+
if (m_offsetEnabled) {
double d = m_offsetDistanceNm * SG_NM_TO_METER;
SGGeod offsetGeod = SGGeodesy::direct(m_geod, m_offsetBearingDeg, d);
pen.setCosmetic(true);
painter->setPen(pen);
painter->drawLine(base, offset);
+
+ airplaneIconPos = offset;
}
+
+ QPixmap pix(":/airplane-icon");
+ airplaneIconPos = painter->transform().map(airplaneIconPos);
+ painter->resetTransform();
+ QRect airplaneIconRect = pix.rect();
+ airplaneIconRect.moveCenter(airplaneIconPos.toPoint());
+ painter->drawPixmap(airplaneIconRect, pix);
}
void NavaidDiagram::doComputeBounds()
<file alias="airport-tower-icon">airport-tower-icon.png</file>
<file alias="vor-dme-icon">vor-dme-icon.png</file>
<file alias="seaport-tower-icon">seaport-tower-icon.png</file>
+ <file alias="ndb-small-icon">ndb-small-icon .png</file>
+ <file alias="ndb-large-icon">ndb-large-icon.png</file>
+ <file alias="airplane-icon">airplane-icon.png</file>
</qresource>
</RCC>
#ifndef FG_NAVCACHE_SCHEMA_HXX
#define FG_NAVCACHE_SCHEMA_HXX
-const int SCHEMA_VERSION = 10;
+const int SCHEMA_VERSION = 14;
#define SCHEMA_SQL \
"CREATE TABLE properties (key VARCHAR, value VARCHAR);" \
PositionedID navaid_dme = 0;
if (type == FGPositioned::DME) {
+ // complication here: the database doesn't record TACAN sites at all,
+ // we simply infer their existence from DMEs whose name includes 'VORTAC'
+ // or 'TACAN' (since all TACAN stations include DME)
+ // hence the cache never actually includes entries of type TACAN
FGPositioned::TypeFilter f(FGPositioned::INVALID);
if ( name.find("VOR-DME") != std::string::npos ) {
f.addType(FGPositioned::VOR);
f.addType(FGPositioned::VOR);
} else if ( name.find("NDB-DME") != std::string::npos ) {
f.addType(FGPositioned::NDB);
- } else if ( name.find("TACAN") != std::string::npos ) {
- f.addType(FGPositioned::VOR);
}
if (f.maxType() > 0) {
if ( simgear::strutils::uppercase(navaid_part[0]) == simgear::strutils::uppercase(dme_part[0]) ) {
navaid_dme = ref.get()->guid();
+ } else {
+ SG_LOG(SG_NAVAID, SG_WARN, "DME " << ident << " (" << name << "), closest match has wrong name:"
+ << ref->ident() << " (" << ref->name() << ")");
}
+ } else {
+ SG_LOG(SG_NAVAID, SG_WARN, "Couldn't find navaid for DME:" << ident << " (" << name << ")");
}
- }
+ } // of have a co-located navaid to locate
}
if ((type >= FGPositioned::ILS) && (type <= FGPositioned::GS)) {
return (mColocated > 0);
}
+
+
+bool FGNavRecord::isVORTAC() const
+{
+ if (mType != VOR)
+ return false;
+
+ return mName.find(" VORTAC") != std::string::npos;
+}
+
void FGNavRecord::setColocatedDME(PositionedID other)
{
mColocated = other;
inline bool get_serviceable() const { return serviceable; }
inline const char *get_trans_ident() const { return get_ident(); }
- virtual const std::string& name() const
- { return mName; }
-
- /**
- * Retrieve the runway this navaid is associated with (for ILS/LOC/GS)
- */
- FGRunwayRef runway() const;
-
- /**
- * return the localizer width, in degrees
- * computation is based up ICAO stdandard width at the runway threshold
- * see implementation for further details.
- */
- double localizerWidth() const;
-
- void bindToNode(SGPropertyNode* nd) const;
- void unbindFromNode(SGPropertyNode* nd) const;
-
- void setColocatedDME(PositionedID other);
- bool hasDME();
-
+ virtual const std::string& name() const
+ { return mName; }
+
+ /**
+ * Retrieve the runway this navaid is associated with (for ILS/LOC/GS)
+ */
+ FGRunwayRef runway() const;
+
+ /**
+ * return the localizer width, in degrees
+ * computation is based up ICAO stdandard width at the runway threshold
+ * see implementation for further details.
+ */
+ double localizerWidth() const;
+
+ void bindToNode(SGPropertyNode* nd) const;
+ void unbindFromNode(SGPropertyNode* nd) const;
+
+ void setColocatedDME(PositionedID other);
+ bool hasDME();
+
+ bool isVORTAC() const;
+
void updateFromXML(const SGGeod& geod, double heading);
};