1
0
Fork 0

Base diagram can draw airways

This commit is contained in:
James Turner 2018-08-11 22:01:52 +02:00
parent 69dbfc0a27
commit cd0b493426
2 changed files with 108 additions and 15 deletions

View file

@ -32,9 +32,13 @@
#include <Navaids/positioned.hxx>
#include <Airports/airport.hxx>
#include <Navaids/PolyLine.hxx>
#include <Navaids/NavDataCache.hxx>
#include <Navaids/airways.hxx>
#include "QtLauncher_fwd.hxx"
using namespace flightgear;
/* equatorial and polar earth radius */
const double rec = 6378137; // earth radius, equator (?)
const double rpol = 6356752.314; // earth radius, polar (?)
@ -103,7 +107,9 @@ void BaseDiagram::extendRect(QRectF &r, const QPointF &p)
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)
@ -123,6 +129,7 @@ void BaseDiagram::paint(QPainter* p)
m_baseDeviceTransform = p->deviceTransform();
m_viewportTransform = transform();
p->setWorldTransform(m_viewportTransform * m_baseDeviceTransform);
m_projectedPositions.clear();
paintPolygonData(p);
paintNavaids(p);
@ -196,9 +203,8 @@ void BaseDiagram::paintGeodVec(QPainter* painter, const flightgear::SGGeodVec& v
{
QVector<QPointF> projected;
projected.reserve(vec.size());
flightgear::SGGeodVec::const_iterator it;
for (it=vec.begin(); it != vec.end(); ++it) {
projected.append(project(*it));
for (auto v: vec) {
projected.append(project(v));
}
painter->drawPolyline(projected.data(), projected.size());
@ -224,7 +230,7 @@ public:
MapFilter(LauncherController::AircraftType aircraft)
{
// addType(FGPositioned::FIX);
addType(FGPositioned::FIX);
addType(FGPositioned::NDB);
addType(FGPositioned::VOR);
@ -242,15 +248,13 @@ public:
virtual bool pass(FGPositioned* aPos) const
{
bool ok = TypeFilter::pass(aPos);
// fix-filtering code disabled since fixed are entirely disabled
#if 0
if (ok && (aPos->type() == FGPositioned::FIX)) {
// ignore fixes which end in digits
if (aPos->ident().length() > 4 && isdigit(aPos->ident()[3]) && isdigit(aPos->ident()[4])) {
return false;
}
}
#endif
return ok;
}
};
@ -301,6 +305,9 @@ void BaseDiagram::paintNavaids(QPainter* painter)
ports.resize(40);
}
// paint airways underneath
paintAirways(painter, navaids);
m_labelRects.clear();
m_labelRects.reserve(items.size());
painter->setTransform(m_baseDeviceTransform);
@ -316,6 +323,65 @@ void BaseDiagram::paintNavaids(QPainter* painter)
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 r;
@ -365,7 +431,7 @@ void BaseDiagram::paintNavaid(QPainter* painter, const FGPositionedRef &pos)
if (drawAsIcon) {
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();
iconRect = QRect(QPoint(0,0), sz);
iconRect.moveCenter(loc.toPoint());
@ -573,6 +639,7 @@ void BaseDiagram::wheelEvent(QWheelEvent *we)
void BaseDiagram::paintContents(QPainter* painter)
{
Q_UNUSED(painter);
}
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> r;
const FGRunwayList& runways(apt->getRunwaysWithoutReciprocals());
FGRunwayList::const_iterator it;
for (it = runways.begin(); it != runways.end(); ++it) {
FGRunwayRef rwy = *it;
for (auto rwy : apt->getRunwaysWithoutReciprocals()) {
QPointF p1 = project(rwy->geod(), c);
QPointF p2 = project(rwy->end(), c);
r.append(QLineF(p1, p2));
@ -837,3 +899,27 @@ QVector<QLineF> BaseDiagram::projectAirportRuwaysIntoRect(FGAirportRef apt, cons
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;
}

View file

@ -96,6 +96,11 @@ protected:
static SGGeod unproject(const QPointF &xy, const SGGeod &center);
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:
enum LabelPosition
{
@ -127,6 +132,8 @@ private:
mutable QHash<PositionedID, LabelPosition> m_labelPositions;
mutable QVector<QRect> m_labelRects;
mutable QHash<PositionedID, QPointF> m_projectedPositions;
static int textFlagsForLabelPosition(LabelPosition pos);
void splitItems(const FGPositionedList &in, FGPositionedList &navaids, FGPositionedList &ports);