Skip to content

Commit

Permalink
[FEATURE] Rework routes logic (again)
Browse files Browse the repository at this point in the history
Only "Display all routes" respects the "Only show short-term route parts"
setting.

Full routes are alays shows when an airport/pilot is right-clicked or
"plot route" is selected from the detail dialog.
  • Loading branch information
jonaseberle committed Jun 18, 2023
1 parent 95e05d5 commit 0c371a0
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 155 deletions.
2 changes: 0 additions & 2 deletions src/Airport.cpp
Expand Up @@ -108,8 +108,6 @@ Airport::Airport(const QStringList& list, unsigned int debugLineNumber)

lat = list[4].toDouble();
lon = list[5].toDouble();

showRoutes = Settings::showRoutes();
}

Airport::~Airport() {
Expand Down
2 changes: 1 addition & 1 deletion src/Airport.h
Expand Up @@ -79,7 +79,7 @@ class Airport

Metar metar;
QString id, name, city, countryCode;
bool showRoutes;
bool showRoutes = false;
bool active;
private:
GLuint _appDisplayList, _twrDisplayList, _gndDisplayList, _delDisplayList;
Expand Down
153 changes: 82 additions & 71 deletions src/GLWidget.cpp
Expand Up @@ -294,7 +294,20 @@ void GLWidget::createPilotsList() {
|| m_hoveredObjects.contains(p->destAirport())
;

if (!isHovered && !p->showDepLine() && !p->showDestLine()) {
const bool isShowRouteDepAirport = p->depAirport() != 0 && p->depAirport()->showRoutes;
const bool isShowRouteDestAirport = p->destAirport() != 0 && p->destAirport()->showRoutes;
const bool isShowRouteAirport = isShowRouteDepAirport || isShowRouteDestAirport;

const bool isShowOverride = isHovered || isShowRouteAirport || p->showRoute;
const bool isShowOnlyImmediate = !isShowOverride && Settings::showRoutes() && Settings::onlyShowImmediateRoutePart();

const bool isShowDepToPlaneRoute = (isShowOverride || Settings::showRoutes()) && !isShowOnlyImmediate && !qFuzzyIsNull(Settings::depLineStrength());
const bool isShowPlaneToImmediateRoute = (isShowOverride || Settings::showRoutes()) && !qFuzzyIsNull(Settings::destImmediateLineStrength());
const bool isShowImmediateToDestRoute = (isShowOverride || Settings::showRoutes()) && !isShowOnlyImmediate && !qFuzzyIsNull(Settings::destLineStrength());

const bool isShowPlaneDestRoute = isShowPlaneToImmediateRoute || isShowImmediateToDestRoute;

if (!isShowDepToPlaneRoute && !isShowPlaneDestRoute) {
continue;
}

Expand All @@ -304,12 +317,7 @@ void GLWidget::createPilotsList() {
QList<DoublePair> points; // these are the points that really get drawn

// Dep -> plane
if (
(
isHovered || (p->showDepLine() && !Settings::onlyShowImmediateRoutePart())
)
&& !qFuzzyIsNull(Settings::depLineStrength())
) {
if (isShowDepToPlaneRoute) {
for (int i = 0; i < next; i++) {
if (!m_usedWaypointMapObjects.contains(waypoints[i])) {
m_usedWaypointMapObjects.append(waypoints[i]);
Expand All @@ -336,78 +344,81 @@ void GLWidget::createPilotsList() {
points.append(DoublePair(p->lat, p->lon));

// plane -> Dest
if ((isHovered || p->showDestLine()) && next < waypoints.size()) {
// immediate
auto destImmediateNm = p->groundspeed * (Settings::destImmediateDurationMin() / 60.);

auto lastPoint = DoublePair(p->lat, p->lon);
double distanceFromPlane = 0;
int i = next;
if (!qFuzzyIsNull(Settings::destImmediateLineStrength())) {
for (; i < waypoints.size(); i++) {
double distance = NavData::distance(lastPoint.first, lastPoint.second, waypoints[i]->lat, waypoints[i]->lon);
if (distanceFromPlane + distance < destImmediateNm) {
if (!m_usedWaypointMapObjects.contains(waypoints[i])) {
m_usedWaypointMapObjects.append(waypoints[i]);
}
const auto _p = DoublePair(waypoints[i]->lat, waypoints[i]->lon);
if (!points.contains(_p)) { // very cautious for duplicates here
points.append(_p);
}
distanceFromPlane += distance;
lastPoint = DoublePair(waypoints[i]->lat, waypoints[i]->lon);
continue;
}
if (next >= waypoints.size() || !isShowPlaneDestRoute) {
continue;
}
// immediate
auto destImmediateNm = p->groundspeed * (Settings::destImmediateDurationMin() / 60.);

if (!points.contains(lastPoint)) {
points.append(lastPoint);
auto lastPoint = DoublePair(p->lat, p->lon);
double distanceFromPlane = 0;
int i = next;
if (isShowPlaneToImmediateRoute) {
for (; i < waypoints.size(); i++) {
double distance = NavData::distance(lastPoint.first, lastPoint.second, waypoints[i]->lat, waypoints[i]->lon);
if (distanceFromPlane + distance < destImmediateNm) {
if (!m_usedWaypointMapObjects.contains(waypoints[i])) {
m_usedWaypointMapObjects.append(waypoints[i]);
}
const float neededFraction = (destImmediateNm - distanceFromPlane) / qMax(distance, 1.);
const auto absoluteLast = NavData::greatCircleFraction(lastPoint.first, lastPoint.second, waypoints[i]->lat, waypoints[i]->lon, neededFraction);
if (!points.contains(absoluteLast)) {
points.append(absoluteLast);
const auto _p = DoublePair(waypoints[i]->lat, waypoints[i]->lon);
if (!points.contains(_p)) { // very cautious for duplicates here
points.append(_p);
}
break;
distanceFromPlane += distance;
lastPoint = DoublePair(waypoints[i]->lat, waypoints[i]->lon);
continue;
}

glPushAttrib(GL_ENABLE_BIT);
if (!isHovered && Settings::onlyShowImmediateRoutePart()) {
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_TEXTURE_1D);
glBindTexture(GL_TEXTURE_1D, _immediateRouteTex);
if (!points.contains(lastPoint)) {
points.append(lastPoint);
}
qglColor(Settings::destImmediateLineColor());
glLineWidth(Settings::destImmediateLineStrength());
glBegin(GL_LINE_STRIP);
NavData::plotGreatCirclePoints(points);
glEnd();
glPopAttrib();
const float neededFraction = (destImmediateNm - distanceFromPlane) / qMax(distance, 1.);
const auto absoluteLast = NavData::greatCircleFraction(lastPoint.first, lastPoint.second, waypoints[i]->lat, waypoints[i]->lon, neededFraction);
if (!points.contains(absoluteLast)) {
points.append(absoluteLast);
}
break;
}

// rest
if ((isHovered || !Settings::onlyShowImmediateRoutePart()) && !qFuzzyIsNull(Settings::destLineStrength())) {
while (points.size() > 1) {
points.takeFirst();
}
for (; i < waypoints.size(); i++) {
if (!m_usedWaypointMapObjects.contains(waypoints[i])) {
m_usedWaypointMapObjects.append(waypoints[i]);
}
points.append(DoublePair(waypoints[i]->lat, waypoints[i]->lon));
}
qglColor(Settings::destLineColor());
if (Settings::destLineDashed()) {
glLineStipple(3, 0xAAAA);
}
glLineWidth(Settings::destLineStrength());
glBegin(GL_LINE_STRIP);
NavData::plotGreatCirclePoints(points);
glEnd();
glPushAttrib(GL_ENABLE_BIT);
if (!isShowImmediateToDestRoute) {
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_TEXTURE_1D);
glBindTexture(GL_TEXTURE_1D, _immediateRouteTex);
}
qglColor(Settings::destImmediateLineColor());
glLineWidth(Settings::destImmediateLineStrength());
glBegin(GL_LINE_STRIP);
NavData::plotGreatCirclePoints(points);
glEnd();
glPopAttrib();
}

if (Settings::destLineDashed()) {
glLineStipple(1, 0xFFFF);
}
// rest
if (!isShowImmediateToDestRoute) {
continue;
}

while (points.size() > 1) {
points.takeFirst();
}
for (; i < waypoints.size(); i++) {
if (!m_usedWaypointMapObjects.contains(waypoints[i])) {
m_usedWaypointMapObjects.append(waypoints[i]);
}
points.append(DoublePair(waypoints[i]->lat, waypoints[i]->lon));
}
qglColor(Settings::destLineColor());
if (Settings::destLineDashed()) {
glLineStipple(3, 0xAAAA);
}
glLineWidth(Settings::destLineStrength());
glBegin(GL_LINE_STRIP);
NavData::plotGreatCirclePoints(points);
glEnd();

if (Settings::destLineDashed()) {
glLineStipple(1, 0xFFFF);
}
}
m_isUsedWaypointMapObjectsDirty = false;
Expand Down Expand Up @@ -1539,10 +1550,10 @@ void GLWidget::rightClick(const QPoint& pos) {
} else if (pilot != 0) {
// display flight path for pilot
GuiMessages::message(
QString("toggled route for %1 [%2]").arg(pilot->callsign, pilot->showDepDestLine? "off": "on"),
QString("toggled route for %1 [%2]").arg(pilot->callsign, pilot->showRoute? "off": "on"),
"routeTogglePilot"
);
pilot->showDepDestLine = !pilot->showDepDestLine;
pilot->showRoute = !pilot->showRoute;
if (PilotDetails::instance(false) != 0) {
PilotDetails::instance()->refresh();
}
Expand Down
33 changes: 0 additions & 33 deletions src/Pilot.cpp
Expand Up @@ -175,7 +175,6 @@ Pilot::Pilot(const QJsonObject& json, const WhazzupData* whazzup)
dayOfFlight = whazzupTime.date().addDays(-1); // started the day before

}
showDepDestLine = Settings::showRoutes();

checkStatus();
}
Expand Down Expand Up @@ -677,38 +676,6 @@ int Pilot::nextPointOnRoute(const QList<Waypoint*> &waypoints) const { // next p
return qMin(nextPoint, waypoints.size());
}

bool Pilot::showDepLine() const {
if (qFuzzyIsNull(Settings::depLineStrength())) {
return false;
}

if (showDepDestLine) {
return true;
}

if (depAirport() != 0) {
return depAirport()->showRoutes;
}

return false;
}

bool Pilot::showDestLine() const {
if (qFuzzyIsNull(Settings::destLineStrength()) && qFuzzyIsNull(Settings::destImmediateLineStrength())) {
return false;
}

if (showDepDestLine) {
return true;
}

if (destAirport() != 0) {
return destAirport()->showRoutes;
}

return false;
}

QString Pilot::livestreamString(bool shortened) const {
return Client::livestreamString(planRemarks, shortened);
}
Expand Down
4 changes: 1 addition & 3 deletions src/Pilot.h
Expand Up @@ -61,8 +61,6 @@ class Pilot
QString flOrEmpty() const; // altitude prefixed with F
QPair<double, double> positionInFuture(int seconds) const;
int nextPointOnRoute(const QList<Waypoint*> &waypoints) const;
bool showDepLine() const,
showDestLine() const;
QString routeWaypointsString();
QList<Waypoint*> routeWaypoints();
QList<Waypoint*> routeWaypointsWithDepDest();
Expand All @@ -80,7 +78,7 @@ class Pilot
qnh_mb;
int pilotRating = -99, militaryRating = -99;
double trueHeading, qnh_inHg;
bool showDepDestLine;
bool showRoute = false;
QDateTime whazzupTime; // need some local reference to that
QList<Waypoint*> routeWaypointsCache; // caching calculated routeWaypoints
Airline* airline;
Expand Down
2 changes: 1 addition & 1 deletion src/WhazzupData.cpp
Expand Up @@ -384,7 +384,7 @@ void WhazzupData::updatePilotsFrom(const WhazzupData &data) {
Pilot* p = new Pilot(*data.pilots[s]);
pilots[s] = p;
} else { // existing pilots: data saved in the object needs to be transferred
data.pilots[s]->showDepDestLine = pilots[s]->showDepDestLine;
data.pilots[s]->showRoute = pilots[s]->showRoute;
data.pilots[s]->routeWaypointsCache = pilots[s]->routeWaypointsCache;
data.pilots[s]->routeWaypointsPlanDepCache = pilots[s]->routeWaypointsPlanDepCache;
data.pilots[s]->routeWaypointsPlanDestCache = pilots[s]->routeWaypointsPlanDestCache;
Expand Down
27 changes: 18 additions & 9 deletions src/dialogs/AirportDetails.cpp
Expand Up @@ -218,7 +218,17 @@ void AirportDetails::refresh(Airport* newAirport) {
groupBoxAtc->setTitle(QString("ATC (%1)").arg(atcContent.size()));
treeAtc->header()->resizeSections(QHeaderView::ResizeToContents);

cbPlotRoutes->setChecked(_airport->showRoutes);
bool isShowRouteExternal = Settings::showRoutes();

if (!isShowRouteExternal && !_airport->showRoutes) {
cbPlotRoutes->setCheckState(Qt::Unchecked);
}
if (isShowRouteExternal && !_airport->showRoutes) {
cbPlotRoutes->setCheckState(Qt::PartiallyChecked);
}
if (_airport->showRoutes) {
cbPlotRoutes->setCheckState(Qt::Checked);
}
}

void AirportDetails::atcSelected(const QModelIndex& index) {
Expand All @@ -234,15 +244,14 @@ void AirportDetails::departureSelected(const QModelIndex& index) {
}

void AirportDetails::togglePlotRoutes(bool checked) {
if (_airport->showRoutes != checked) {
_airport->showRoutes = checked;
if (Window::instance(false) != 0) {
Window::instance()->mapScreen->glWidget->invalidatePilots();
}
if (PilotDetails::instance(false) != 0) {
PilotDetails::instance()->refresh();
}
_airport->showRoutes = checked;
if (Window::instance(false) != 0) {
Window::instance()->mapScreen->glWidget->invalidatePilots();
}
if (PilotDetails::instance(false) != 0) {
PilotDetails::instance()->refresh();
}
refresh();
}

void AirportDetails::refreshMetar() {
Expand Down
36 changes: 14 additions & 22 deletions src/dialogs/PilotDetails.cpp
Expand Up @@ -170,25 +170,22 @@ void PilotDetails::refresh(Pilot* pilot) {
// check if we know position
buttonShowOnMap->setDisabled(qFuzzyIsNull(_pilot->lon) && qFuzzyIsNull(_pilot->lat));

// plotted?
bool plottedAirports = false;
if (_pilot->depAirport() != 0) {
plottedAirports |= _pilot->depAirport()->showRoutes;
}
if (_pilot->destAirport() != 0) {
plottedAirports |= _pilot->destAirport()->showRoutes;
}
// routes
bool isShowRouteExternal = Settings::showRoutes()
|| (_pilot->depAirport() != 0 && _pilot->depAirport()->showRoutes)
|| (_pilot->destAirport() != 0 && _pilot->destAirport()->showRoutes);

if (!plottedAirports && !_pilot->showDepDestLine) {
if (!isShowRouteExternal && !_pilot->showRoute) {
cbPlotRoute->setCheckState(Qt::Unchecked);
}
if (plottedAirports && !_pilot->showDepDestLine) {
if (isShowRouteExternal && !_pilot->showRoute) {
cbPlotRoute->setCheckState(Qt::PartiallyChecked);
}
if (_pilot->showDepDestLine) {
if (_pilot->showRoute) {
cbPlotRoute->setCheckState(Qt::Checked);
}
if (_pilot->showDepDestLine || plottedAirports) {

if (_pilot->showRoute || isShowRouteExternal) {
lblPlotStatus->setText(
QString(
"<span style='color: "
Expand All @@ -197,10 +194,7 @@ void PilotDetails::refresh(Pilot* pilot) {
).arg(_pilot->routeWaypointsString())
);
}
lblPlotStatus->setVisible(_pilot->showDepDestLine || plottedAirports);

// @see https://github.com/qutescoop/qutescoop/issues/124
// adjustSize();
lblPlotStatus->setVisible(_pilot->showRoute || isShowRouteExternal);
}

void PilotDetails::on_buttonDest_clicked() {
Expand All @@ -227,13 +221,11 @@ void PilotDetails::on_buttonAddFriend_clicked() {
}

void PilotDetails::on_cbPlotRoute_clicked(bool checked) {
if (_pilot->showDepDestLine != checked) {
_pilot->showDepDestLine = checked;
if (Window::instance(false) != 0) {
Window::instance()->mapScreen->glWidget->invalidatePilots();
}
refresh();
_pilot->showRoute = checked;
if (Window::instance(false) != 0) {
Window::instance()->mapScreen->glWidget->invalidatePilots();
}
refresh();
}

void PilotDetails::closeEvent(QCloseEvent* event) {
Expand Down

0 comments on commit 0c371a0

Please sign in to comment.