From: James Turner <zakalawe@mac.com>
Date: Thu, 12 Nov 2015 00:10:06 +0000 (+0000)
Subject: Work on launcher diagrams.
X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=b9acb26c073e18da3057df45057553605e04b54b;p=flightgear.git

Work on launcher diagrams.
---

diff --git a/src/GUI/AirportDiagram.cxx b/src/GUI/AirportDiagram.cxx
index a800bf1e2..449957dfd 100644
--- a/src/GUI/AirportDiagram.cxx
+++ b/src/GUI/AirportDiagram.cxx
@@ -103,6 +103,9 @@ void AirportDiagram::setAirport(FGAirportRef apt)
         buildPavements();
     }
 
+    clearIgnoredNavaids();
+    addIgnoredNavaid(apt);
+
     recomputeBounds(true);
     update();
 }
@@ -204,8 +207,9 @@ void AirportDiagram::paintContents(QPainter* p)
     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) {
diff --git a/src/GUI/BaseDiagram.cxx b/src/GUI/BaseDiagram.cxx
index 1c938a0a0..bced50f42 100644
--- a/src/GUI/BaseDiagram.cxx
+++ b/src/GUI/BaseDiagram.cxx
@@ -66,6 +66,18 @@ QTransform BaseDiagram::transform() const
     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()) {
@@ -148,10 +160,14 @@ void BaseDiagram::paintNavaids(QPainter* painter)
 
     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;
@@ -173,10 +189,32 @@ void BaseDiagram::paintNavaids(QPainter* painter)
         }
 
         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);
         }
     }
 
@@ -184,6 +222,11 @@ void BaseDiagram::paintNavaids(QPainter* painter)
     painter->setTransform(xf);
 }
 
+bool BaseDiagram::isNavaidIgnored(const FGPositionedRef &pos) const
+{
+    return m_ignored.contains(pos);
+}
+
 void BaseDiagram::mousePressEvent(QMouseEvent *me)
 {
     m_lastMousePos = me->pos();
@@ -336,7 +379,7 @@ QPointF BaseDiagram::project(const SGGeod& geod) const
     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
 
@@ -348,7 +391,8 @@ QPixmap BaseDiagram::iconForPositioned(const FGPositionedRef& pos)
 
     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");
@@ -363,7 +407,7 @@ QPixmap BaseDiagram::iconForPositioned(const FGPositionedRef& pos)
     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");
 
diff --git a/src/GUI/BaseDiagram.hxx b/src/GUI/BaseDiagram.hxx
index 9ad65eb84..9c82d21ab 100644
--- a/src/GUI/BaseDiagram.hxx
+++ b/src/GUI/BaseDiagram.hxx
@@ -35,7 +35,7 @@ class BaseDiagram : public QWidget
 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);
@@ -50,6 +50,7 @@ protected:
 
     virtual void paintContents(QPainter*);
 
+
 protected:
     void recomputeBounds(bool resetZoom);
 
@@ -59,6 +60,9 @@ protected:
     QPointF project(const SGGeod& geod) const;
     QTransform transform() const;
     
+    void clearIgnoredNavaids();
+    void addIgnoredNavaid(FGPositionedRef pos);
+
     SGGeod m_projectionCenter;
     double m_scale;
     QRectF m_bounds;
@@ -75,6 +79,9 @@ protected:
 private:
     void paintNavaids(QPainter *p);
 
+    bool isNavaidIgnored(const FGPositionedRef& pos) const;
+
+    QVector<FGPositionedRef> m_ignored;
 };
 
 #endif // of GUI_BASEDIAGRAM_HXX
diff --git a/src/GUI/NavaidDiagram.cxx b/src/GUI/NavaidDiagram.cxx
index fa6b78c2c..c2b139ef6 100644
--- a/src/GUI/NavaidDiagram.cxx
+++ b/src/GUI/NavaidDiagram.cxx
@@ -77,6 +77,8 @@ void NavaidDiagram::paintContents(QPainter *painter)
 {
     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);
@@ -86,7 +88,16 @@ void NavaidDiagram::paintContents(QPainter *painter)
         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()
diff --git a/src/GUI/airplane-icon.png b/src/GUI/airplane-icon.png
new file mode 100644
index 000000000..b688e513f
Binary files /dev/null and b/src/GUI/airplane-icon.png differ
diff --git a/src/GUI/ndb-large-icon.png b/src/GUI/ndb-large-icon.png
new file mode 100644
index 000000000..72424eba9
Binary files /dev/null and b/src/GUI/ndb-large-icon.png differ
diff --git a/src/GUI/ndb-small-icon .png b/src/GUI/ndb-small-icon .png
new file mode 100644
index 000000000..d50bc587d
Binary files /dev/null and b/src/GUI/ndb-small-icon .png differ
diff --git a/src/GUI/resources.qrc b/src/GUI/resources.qrc
index c48a7d40f..6eb011e58 100644
--- a/src/GUI/resources.qrc
+++ b/src/GUI/resources.qrc
@@ -15,5 +15,8 @@
         <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>
diff --git a/src/Navaids/CacheSchema.h b/src/Navaids/CacheSchema.h
index 297ab3e11..b3665beb2 100644
--- a/src/Navaids/CacheSchema.h
+++ b/src/Navaids/CacheSchema.h
@@ -1,7 +1,7 @@
 #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);" \
diff --git a/src/Navaids/navdb.cxx b/src/Navaids/navdb.cxx
index 486a27d97..ac0cd6e31 100644
--- a/src/Navaids/navdb.cxx
+++ b/src/Navaids/navdb.cxx
@@ -184,6 +184,10 @@ static PositionedID readNavFromStream(std::istream& aStream,
   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);
@@ -194,8 +198,6 @@ static PositionedID readNavFromStream(std::istream& aStream,
       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) {
@@ -206,9 +208,14 @@ static PositionedID readNavFromStream(std::istream& aStream,
 
         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)) {
diff --git a/src/Navaids/navrecord.cxx b/src/Navaids/navrecord.cxx
index fabc9a0d0..c65e9491b 100644
--- a/src/Navaids/navrecord.cxx
+++ b/src/Navaids/navrecord.cxx
@@ -98,6 +98,16 @@ bool FGNavRecord::hasDME()
   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;
diff --git a/src/Navaids/navrecord.hxx b/src/Navaids/navrecord.hxx
index 0091ac651..f2178fcf9 100644
--- a/src/Navaids/navrecord.hxx
+++ b/src/Navaids/navrecord.hxx
@@ -79,27 +79,29 @@ class FGNavRecord : public FGPositioned
     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);
 };