Base diagram can draw airways
This commit is contained in:
parent
69dbfc0a27
commit
cd0b493426
2 changed files with 108 additions and 15 deletions
|
@ -32,9 +32,13 @@
|
||||||
#include <Navaids/positioned.hxx>
|
#include <Navaids/positioned.hxx>
|
||||||
#include <Airports/airport.hxx>
|
#include <Airports/airport.hxx>
|
||||||
#include <Navaids/PolyLine.hxx>
|
#include <Navaids/PolyLine.hxx>
|
||||||
|
#include <Navaids/NavDataCache.hxx>
|
||||||
|
#include <Navaids/airways.hxx>
|
||||||
|
|
||||||
#include "QtLauncher_fwd.hxx"
|
#include "QtLauncher_fwd.hxx"
|
||||||
|
|
||||||
|
using namespace flightgear;
|
||||||
|
|
||||||
/* equatorial and polar earth radius */
|
/* equatorial and polar earth radius */
|
||||||
const double rec = 6378137; // earth radius, equator (?)
|
const double rec = 6378137; // earth radius, equator (?)
|
||||||
const double rpol = 6356752.314; // earth radius, polar (?)
|
const double rpol = 6356752.314; // earth radius, polar (?)
|
||||||
|
@ -103,7 +107,9 @@ void BaseDiagram::extendRect(QRectF &r, const QPointF &p)
|
||||||
|
|
||||||
QRect BaseDiagram::rect() const
|
QRect BaseDiagram::rect() const
|
||||||
{
|
{
|
||||||
return QRect(0, 0, width(), height());
|
return QRect(0, 0,
|
||||||
|
static_cast<int>(width()),
|
||||||
|
static_cast<int>(height()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseDiagram::paint(QPainter* p)
|
void BaseDiagram::paint(QPainter* p)
|
||||||
|
@ -123,6 +129,7 @@ void BaseDiagram::paint(QPainter* p)
|
||||||
m_baseDeviceTransform = p->deviceTransform();
|
m_baseDeviceTransform = p->deviceTransform();
|
||||||
m_viewportTransform = transform();
|
m_viewportTransform = transform();
|
||||||
p->setWorldTransform(m_viewportTransform * m_baseDeviceTransform);
|
p->setWorldTransform(m_viewportTransform * m_baseDeviceTransform);
|
||||||
|
m_projectedPositions.clear();
|
||||||
|
|
||||||
paintPolygonData(p);
|
paintPolygonData(p);
|
||||||
paintNavaids(p);
|
paintNavaids(p);
|
||||||
|
@ -196,9 +203,8 @@ void BaseDiagram::paintGeodVec(QPainter* painter, const flightgear::SGGeodVec& v
|
||||||
{
|
{
|
||||||
QVector<QPointF> projected;
|
QVector<QPointF> projected;
|
||||||
projected.reserve(vec.size());
|
projected.reserve(vec.size());
|
||||||
flightgear::SGGeodVec::const_iterator it;
|
for (auto v: vec) {
|
||||||
for (it=vec.begin(); it != vec.end(); ++it) {
|
projected.append(project(v));
|
||||||
projected.append(project(*it));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->drawPolyline(projected.data(), projected.size());
|
painter->drawPolyline(projected.data(), projected.size());
|
||||||
|
@ -224,7 +230,7 @@ public:
|
||||||
|
|
||||||
MapFilter(LauncherController::AircraftType aircraft)
|
MapFilter(LauncherController::AircraftType aircraft)
|
||||||
{
|
{
|
||||||
// addType(FGPositioned::FIX);
|
addType(FGPositioned::FIX);
|
||||||
addType(FGPositioned::NDB);
|
addType(FGPositioned::NDB);
|
||||||
addType(FGPositioned::VOR);
|
addType(FGPositioned::VOR);
|
||||||
|
|
||||||
|
@ -242,15 +248,13 @@ public:
|
||||||
virtual bool pass(FGPositioned* aPos) const
|
virtual bool pass(FGPositioned* aPos) const
|
||||||
{
|
{
|
||||||
bool ok = TypeFilter::pass(aPos);
|
bool ok = TypeFilter::pass(aPos);
|
||||||
// fix-filtering code disabled since fixed are entirely disabled
|
|
||||||
#if 0
|
|
||||||
if (ok && (aPos->type() == FGPositioned::FIX)) {
|
if (ok && (aPos->type() == FGPositioned::FIX)) {
|
||||||
// ignore fixes which end in digits
|
// ignore fixes which end in digits
|
||||||
if (aPos->ident().length() > 4 && isdigit(aPos->ident()[3]) && isdigit(aPos->ident()[4])) {
|
if (aPos->ident().length() > 4 && isdigit(aPos->ident()[3]) && isdigit(aPos->ident()[4])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -301,6 +305,9 @@ void BaseDiagram::paintNavaids(QPainter* painter)
|
||||||
ports.resize(40);
|
ports.resize(40);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// paint airways underneath
|
||||||
|
paintAirways(painter, navaids);
|
||||||
|
|
||||||
m_labelRects.clear();
|
m_labelRects.clear();
|
||||||
m_labelRects.reserve(items.size());
|
m_labelRects.reserve(items.size());
|
||||||
painter->setTransform(m_baseDeviceTransform);
|
painter->setTransform(m_baseDeviceTransform);
|
||||||
|
@ -316,6 +323,65 @@ void BaseDiagram::paintNavaids(QPainter* painter)
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseDiagram::paintAirways(QPainter* painter, const FGPositionedList& navs)
|
||||||
|
{
|
||||||
|
// FIXME: specify the network
|
||||||
|
|
||||||
|
struct AirwaySegment
|
||||||
|
{
|
||||||
|
AirwaySegment(PositionedID t, PositionedID f, int a) :
|
||||||
|
to(t), from(f), airway(a)
|
||||||
|
{}
|
||||||
|
|
||||||
|
PositionedID to, from;
|
||||||
|
int airway;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<AirwaySegment> segmentsToDraw;
|
||||||
|
|
||||||
|
for (auto n : navs) {
|
||||||
|
const auto navGuid = n->guid();
|
||||||
|
AirwayEdgeVec edges = NavDataCache::instance()->airwayEdgesFrom(Airway::HighLevel, n->guid());
|
||||||
|
|
||||||
|
for (auto e : edges) {
|
||||||
|
const auto edgeEndGuid = e.second;
|
||||||
|
auto it = std::find_if(segmentsToDraw.begin(), segmentsToDraw.end(),
|
||||||
|
[edgeEndGuid, navGuid](const AirwaySegment& segment)
|
||||||
|
{
|
||||||
|
return ((segment.to == edgeEndGuid) && (segment.from == navGuid)) ||
|
||||||
|
((segment.from == edgeEndGuid) && (segment.to == navGuid));
|
||||||
|
});
|
||||||
|
if (it == segmentsToDraw.end()) {
|
||||||
|
segmentsToDraw.emplace_back(navGuid, edgeEndGuid, e.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QLineF> lines;
|
||||||
|
lines.reserve(segmentsToDraw.size());
|
||||||
|
|
||||||
|
for (auto seg : segmentsToDraw) {
|
||||||
|
QPointF p1 = projectedPosition(seg.from);
|
||||||
|
QPointF p2 = projectedPosition(seg.to);
|
||||||
|
|
||||||
|
const auto d = QVector2D(p2 - p1).normalized();
|
||||||
|
p1 += (d.toPointF() * 100);
|
||||||
|
p2 += (d.toPointF() * -100);
|
||||||
|
|
||||||
|
lines.append(QLineF(p1, p2));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPen linePen(Qt::cyan, 1);
|
||||||
|
linePen.setCosmetic(true);
|
||||||
|
painter->setPen(linePen);
|
||||||
|
painter->drawLines(lines);
|
||||||
|
|
||||||
|
// find airway names
|
||||||
|
|
||||||
|
// draw airway name on top
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QRect boundsOfLines(const QVector<QLineF>& lines)
|
QRect boundsOfLines(const QVector<QLineF>& lines)
|
||||||
{
|
{
|
||||||
QRect r;
|
QRect r;
|
||||||
|
@ -365,7 +431,7 @@ void BaseDiagram::paintNavaid(QPainter* painter, const FGPositionedRef &pos)
|
||||||
|
|
||||||
if (drawAsIcon) {
|
if (drawAsIcon) {
|
||||||
QPixmap pm = iconForPositioned(pos);
|
QPixmap pm = iconForPositioned(pos);
|
||||||
QPointF loc = m_viewportTransform.map(project(pos->geod()));
|
QPointF loc = m_viewportTransform.map(projectedPosition(pos));
|
||||||
const auto sz = pm.size() / pm.devicePixelRatio();
|
const auto sz = pm.size() / pm.devicePixelRatio();
|
||||||
iconRect = QRect(QPoint(0,0), sz);
|
iconRect = QRect(QPoint(0,0), sz);
|
||||||
iconRect.moveCenter(loc.toPoint());
|
iconRect.moveCenter(loc.toPoint());
|
||||||
|
@ -573,6 +639,7 @@ void BaseDiagram::wheelEvent(QWheelEvent *we)
|
||||||
|
|
||||||
void BaseDiagram::paintContents(QPainter* painter)
|
void BaseDiagram::paintContents(QPainter* painter)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(painter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseDiagram::recomputeBounds(bool resetZoom)
|
void BaseDiagram::recomputeBounds(bool resetZoom)
|
||||||
|
@ -791,12 +858,7 @@ QPixmap BaseDiagram::iconForAirport(FGAirport* apt, const IconOptions& options)
|
||||||
QVector<QLineF> BaseDiagram::projectAirportRuwaysWithCenter(FGAirportRef apt, const SGGeod& c)
|
QVector<QLineF> BaseDiagram::projectAirportRuwaysWithCenter(FGAirportRef apt, const SGGeod& c)
|
||||||
{
|
{
|
||||||
QVector<QLineF> r;
|
QVector<QLineF> r;
|
||||||
|
for (auto rwy : apt->getRunwaysWithoutReciprocals()) {
|
||||||
const FGRunwayList& runways(apt->getRunwaysWithoutReciprocals());
|
|
||||||
FGRunwayList::const_iterator it;
|
|
||||||
|
|
||||||
for (it = runways.begin(); it != runways.end(); ++it) {
|
|
||||||
FGRunwayRef rwy = *it;
|
|
||||||
QPointF p1 = project(rwy->geod(), c);
|
QPointF p1 = project(rwy->geod(), c);
|
||||||
QPointF p2 = project(rwy->end(), c);
|
QPointF p2 = project(rwy->end(), c);
|
||||||
r.append(QLineF(p1, p2));
|
r.append(QLineF(p1, p2));
|
||||||
|
@ -837,3 +899,27 @@ QVector<QLineF> BaseDiagram::projectAirportRuwaysIntoRect(FGAirportRef apt, cons
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPointF BaseDiagram::projectedPosition(PositionedID pid) const
|
||||||
|
{
|
||||||
|
if (m_projectedPositions.contains(pid))
|
||||||
|
return m_projectedPositions.value(pid);
|
||||||
|
|
||||||
|
FGPositionedRef pos = NavDataCache::instance()->loadById(pid);
|
||||||
|
if (!pos)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
QPointF pt = project(pos->geod());
|
||||||
|
m_projectedPositions[pid] = pt;
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF BaseDiagram::projectedPosition(FGPositionedRef pos) const
|
||||||
|
{
|
||||||
|
if (m_projectedPositions.contains(pos->guid()))
|
||||||
|
return m_projectedPositions.value(pos->guid());
|
||||||
|
|
||||||
|
QPointF pt = project(pos->geod());
|
||||||
|
m_projectedPositions[pos->guid()] = pt;
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
|
|
@ -96,6 +96,11 @@ protected:
|
||||||
static SGGeod unproject(const QPointF &xy, const SGGeod ¢er);
|
static SGGeod unproject(const QPointF &xy, const SGGeod ¢er);
|
||||||
|
|
||||||
void paintAirplaneIcon(QPainter *painter, const SGGeod &geod, int headingDeg);
|
void paintAirplaneIcon(QPainter *painter, const SGGeod &geod, int headingDeg);
|
||||||
|
void paintAirways(QPainter* painter, const FGPositionedList& navs);
|
||||||
|
|
||||||
|
QPointF projectedPosition(PositionedID pid) const;
|
||||||
|
QPointF projectedPosition(FGPositionedRef pos) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum LabelPosition
|
enum LabelPosition
|
||||||
{
|
{
|
||||||
|
@ -127,6 +132,8 @@ private:
|
||||||
mutable QHash<PositionedID, LabelPosition> m_labelPositions;
|
mutable QHash<PositionedID, LabelPosition> m_labelPositions;
|
||||||
mutable QVector<QRect> m_labelRects;
|
mutable QVector<QRect> m_labelRects;
|
||||||
|
|
||||||
|
mutable QHash<PositionedID, QPointF> m_projectedPositions;
|
||||||
|
|
||||||
static int textFlagsForLabelPosition(LabelPosition pos);
|
static int textFlagsForLabelPosition(LabelPosition pos);
|
||||||
|
|
||||||
void splitItems(const FGPositionedList &in, FGPositionedList &navaids, FGPositionedList &ports);
|
void splitItems(const FGPositionedList &in, FGPositionedList &navaids, FGPositionedList &ports);
|
||||||
|
|
Loading…
Reference in a new issue