]> git.mxchange.org Git - flightgear.git/commitdiff
Work on launcher diagrams.
authorJames Turner <zakalawe@mac.com>
Thu, 12 Nov 2015 00:10:06 +0000 (00:10 +0000)
committerJames Turner <zakalawe@mac.com>
Mon, 23 Nov 2015 00:47:01 +0000 (00:47 +0000)
12 files changed:
src/GUI/AirportDiagram.cxx
src/GUI/BaseDiagram.cxx
src/GUI/BaseDiagram.hxx
src/GUI/NavaidDiagram.cxx
src/GUI/airplane-icon.png [new file with mode: 0644]
src/GUI/ndb-large-icon.png [new file with mode: 0644]
src/GUI/ndb-small-icon .png [new file with mode: 0644]
src/GUI/resources.qrc
src/Navaids/CacheSchema.h
src/Navaids/navdb.cxx
src/Navaids/navrecord.cxx
src/Navaids/navrecord.hxx

index a800bf1e217b1275add7eb4e4f3fb6f9432a55b6..449957dfd9879982c726429c42684f2c9346c219 100644 (file)
@@ -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) {
index 1c938a0a0b51d8199e3354b4d7b20a9f9e9e9af6..bced50f42ceeda67d5fbe662a27eec17b49a0d9a 100644 (file)
@@ -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");
 
index 9ad65eb8483a9096c70cc24ddbee82c53ab4f0ef..9c82d21abecf7dc50bfbcb73879249cb9e17352a 100644 (file)
@@ -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
index fa6b78c2c241cae2377caa2b47a5baaa3623eb95..c2b139ef6d3a45aea4793e84c48ad3b6858f1feb 100644 (file)
@@ -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 (file)
index 0000000..b688e51
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 (file)
index 0000000..72424eb
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 (file)
index 0000000..d50bc58
Binary files /dev/null and b/src/GUI/ndb-small-icon .png differ
index c48a7d40f75547735b770d4608992bc4d17bdef4..6eb011e58bff5411fd406f45be2c8c95614c8eb2 100644 (file)
@@ -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>
index 297ab3e11161c2d659e633416a9ab9e4a68a5553..b3665beb210dec42484097f8c6f2803295b11313 100644 (file)
@@ -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);" \
index 486a27d97322df6ff4417e967a276582f6eea9b1..ac0cd6e31a0accc13991d45588dee40f6c9e08a3 100644 (file)
@@ -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)) {
index fabc9a0d08ffe4c6ab6129e200439daf30422b0d..c65e9491bbab1b0eff2a8e46cf085f7e6fe2cc78 100644 (file)
@@ -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;
index 0091ac6518651e0b447fc4529926c02ecdfdb45d..f2178fcf980976aac86156f8b22dc7d9076e82b6 100644 (file)
@@ -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);
 };