#include <limits>
+#include <simgear/sg_inlines.h>
+
#include <QPainter>
#include <QDebug>
#include <QVector2D>
#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)
{
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()
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();
}
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));
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;
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)