]> git.mxchange.org Git - flightgear.git/blobdiff - src/GUI/AirportDiagram.cxx
Initial work on rendering parking locations.
[flightgear.git] / src / GUI / AirportDiagram.cxx
index 07cd4f91e1637ba9c3804b6950dc65d10c089175..d268bc2f9d9f3a37d6a8dac39ab0677f94aaa1e4 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <limits>
 
+#include <simgear/sg_inlines.h>
+
 #include <QPainter>
 #include <QDebug>
 #include <QVector2D>
@@ -32,6 +34,8 @@
 #include <Airports/parking.hxx>
 #include <Airports/pavement.hxx>
 
+#include <Navaids/navrecord.hxx>
+
 static double distanceToLineSegment(const QVector2D& p, const QVector2D& a,
                                     const QVector2D& b, double* outT = NULL)
 {
@@ -80,6 +84,19 @@ AirportDiagram::AirportDiagram(QWidget* pr) :
     BaseDiagram(pr),
     m_approachDistanceNm(-1.0)
 {
+    m_parkingIconPath.moveTo(0,0);
+    m_parkingIconPath.lineTo(-16, -16);
+    m_parkingIconPath.lineTo(-64, -16);
+    m_parkingIconPath.lineTo(-64, 16);
+    m_parkingIconPath.lineTo(-16, 16);
+    m_parkingIconPath.lineTo(0, 0);
+
+    m_parkingIconLeftPath.moveTo(0,0);
+    m_parkingIconLeftPath.lineTo(16, -16);
+    m_parkingIconLeftPath.lineTo(64, -16);
+    m_parkingIconLeftPath.lineTo(64, 16);
+    m_parkingIconLeftPath.lineTo(16, 16);
+    m_parkingIconLeftPath.lineTo(0, 0);
 }
 
 AirportDiagram::~AirportDiagram()
@@ -93,12 +110,16 @@ void AirportDiagram::setAirport(FGAirportRef apt)
     m_projectionCenter = apt ? apt->geod() : SGGeod();
     m_runways.clear();
     m_approachDistanceNm = -1.0;
+    m_parking.clear();
 
     if (apt) {
         buildTaxiways();
         buildPavements();
     }
 
+    clearIgnoredNavaids();
+    addIgnoredNavaid(apt);
+
     recomputeBounds(true);
     update();
 }
@@ -178,14 +199,7 @@ void AirportDiagram::addParking(FGParkingRef park)
 
 void AirportDiagram::paintContents(QPainter* p)
 {
-      // fit bounds within our available space, allowing for a margin
-//    const int MARGIN = 32; // pixels
- //   double ratioInX = (width() - MARGIN * 2) / m_bounds.width();
- //   double ratioInY = (height() - MARGIN * 2) / m_bounds.height();
-  //  double scale = std::min(ratioInX, ratioInY);
-
-    QTransform t(transform());
-    p->setTransform(t);
+    QTransform t = p->transform();
 
 // pavements
     QBrush brush(QColor(0x9f, 0x9f, 0x9f));
@@ -201,12 +215,32 @@ void AirportDiagram::paintContents(QPainter* p)
         p->drawLine(t.p1, t.p2);
     }
 
+
+    drawParkings(p);
+
 // runways
     QFont f;
     f.setPixelSize(14);
     p->setFont(f);
 
+    // draw ILS first so underneath all runways
+    QPen pen(QColor(0x5f, 0x5f, 0x5f));
+    pen.setWidth(1);
+    pen.setCosmetic(true);
+    p->setPen(pen);
+
     Q_FOREACH(const RunwayData& r, m_runways) {
+        drawILS(p, r.runway);
+        drawILS(p, r.runway->reciprocalRunway());
+    }
+
+    bool drawAircraft = false;
+    SGGeod aircraftPos;
+    int headingDeg;
+
+    // now draw the runways for real
+    Q_FOREACH(const RunwayData& r, m_runways) {
+
         QColor color(Qt::magenta);
         if ((r.runway == m_selectedRunway) || (r.runway->reciprocalRunway() == m_selectedRunway)) {
             color = Qt::yellow;
@@ -243,16 +277,100 @@ void AirportDiagram::paintContents(QPainter* p)
         p->drawText(QRect(-100, 5, 200, 200), recipIdent, Qt::AlignHCenter | Qt::AlignTop);
     }
 
+    if (m_selectedRunway) {
+        drawAircraft = true;
+        aircraftPos = m_selectedRunway->geod();
+        headingDeg = m_selectedRunway->headingDeg();
+    }
+
     if (m_selectedRunway && (m_approachDistanceNm > 0.0)) {
         p->setTransform(t);
         // draw approach extension point
         double d = SG_NM_TO_METER * m_approachDistanceNm;
         QPointF pt = project(m_selectedRunway->pointOnCenterline(-d));
         QPointF pt2 = project(m_selectedRunway->geod());
-        QPen pen(Qt::yellow, 10);
+        QPen pen(Qt::yellow);
+        pen.setWidth(2.0 / m_scale);
         p->setPen(pen);
         p->drawLine(pt, pt2);
+
+        aircraftPos = m_selectedRunway->pointOnCenterline(-d);
     }
+
+    if (drawAircraft) {
+        p->setTransform(t);
+        paintAirplaneIcon(p, aircraftPos, headingDeg);
+    }
+}
+
+
+void AirportDiagram::drawParkings(QPainter* painter)
+{
+    QTransform t = painter->transform();
+
+
+    QFont f = painter->font();
+    f.setPixelSize(16);
+    painter->setFont(f);
+
+    Q_FOREACH(const ParkingData& p, m_parking) {
+        painter->setTransform(t);
+        painter->translate(p.pt);
+
+        double hdg = p.parking->getHeading();
+        bool useLeftIcon = false;
+        QRect labelRect(-62, -14, 40, 28);
+
+        if (hdg > 180.0) {
+            hdg += 90;
+            useLeftIcon = true;
+            labelRect = QRect(22, -14, 40, 28);
+        } else {
+            hdg -= 90;
+        }
+
+        painter->rotate(hdg);
+
+        painter->setBrush(QColor(255, 196, 196)); // kind of pink
+        painter->drawPath(useLeftIcon ? m_parkingIconLeftPath : m_parkingIconPath);
+
+        painter->fillRect(labelRect, Qt::white);
+
+        // draw text
+        painter->setPen(Qt::black);
+        painter->drawText(labelRect,
+                          Qt::AlignVCenter | Qt::AlignHCenter,
+                          QString::fromStdString(p.parking->name()));
+    }
+
+    painter->setTransform(t);
+}
+
+void AirportDiagram::drawILS(QPainter* painter, FGRunwayRef runway) const
+{
+    if (!runway)
+        return;
+
+    FGNavRecord* loc = runway->ILS();
+    if (!loc)
+        return;
+
+    double halfBeamWidth = loc->localizerWidth() * 0.5;
+    QPointF threshold = project(runway->threshold());
+    double rangeM = loc->get_range() * SG_NM_TO_METER;
+    double radial = loc->get_multiuse();
+    SG_NORMALIZE_RANGE(radial, 0.0, 360.0);
+
+// compute the three end points at the wide end of the arrow
+    QPointF endCentre = project(SGGeodesy::direct(loc->geod(), radial, -rangeM));
+    QPointF endR = project(SGGeodesy::direct(loc->geod(), radial + halfBeamWidth, -rangeM * 1.1));
+    QPointF endL = project(SGGeodesy::direct(loc->geod(), radial - halfBeamWidth, -rangeM * 1.1));
+
+    painter->drawLine(threshold, endCentre);
+    painter->drawLine(threshold, endL);
+    painter->drawLine(threshold, endR);
+    painter->drawLine(endL, endCentre);
+    painter->drawLine(endR, endCentre);
 }
 
 void AirportDiagram::mouseReleaseEvent(QMouseEvent* me)