#include <Airports/simple.hxx>
#include <Airports/runways.hxx>
#include <Main/fg_os.hxx> // fgGetKeyModifiers()
+#include <Navaids/routePath.hxx>
const char* RULER_LEGEND_KEY = "ruler-legend";
double julianDate = globals->get_time_params()->getJD();
_magVar->update(_projectionCenter, julianDate);
- SGGeod topLeft = unproject(SGVec2d(_width/2, _height/2));
- // compute draw range, including a fudge factor for ILSs and other 'long'
- // symbols
- _drawRangeNm = SGGeodesy::distanceNm(_projectionCenter, topLeft) + 10.0;
-
bool aircraftUp = _root->getBoolValue("aircraft-heading-up");
if (aircraftUp) {
_upHeading = fgGetDouble("/orientation/heading-deg");
} else {
_upHeading = 0.0;
}
-
+
+ SGGeod topLeft = unproject(SGVec2d(_width/2, _height/2));
+ // compute draw range, including a fudge factor for ILSs and other 'long'
+ // symbols
+ _drawRangeNm = SGGeodesy::distanceNm(_projectionCenter, topLeft) + 10.0;
+
// drawing operations
GLint sx = (int) abox.min[0],
sy = (int) abox.min[1];
void MapWidget::paintRoute()
{
- if (_route->size() < 2) {
+ if (_route->numWaypts() < 2) {
return;
}
-// first pass, draw the actual line
- glLineWidth(2.0);
- glBegin(GL_LINE_STRIP);
+ RoutePath path(_route->waypts());
- SGVec2d prev = project(_route->get_waypoint(0).get_target());
- glVertex2d(prev.x(), prev.y());
+// first pass, draw the actual lines
+ glLineWidth(2.0);
- for (int w=1; w < _route->size(); ++w) {
-
- SGVec2d p = project(_route->get_waypoint(w).get_target());
+ for (int w=0; w<_route->numWaypts(); ++w) {
+ SGGeodVec gv(path.pathForIndex(w));
+ if (gv.empty()) {
+ continue;
+ }
- if (w < _route->currentWaypoint()) {
+ if (w < _route->currentIndex()) {
glColor4f(0.5, 0.5, 0.5, 0.7);
} else {
glColor4f(1.0, 0.0, 1.0, 1.0);
}
- glVertex2d(p.x(), p.y());
+ flightgear::WayptRef wpt(_route->wayptAtIndex(w));
+ if (wpt->flag(flightgear::WPT_MISS)) {
+ glEnable(GL_LINE_STIPPLE);
+ glLineStipple(1, 0x00FF);
+ }
+
+ glBegin(GL_LINE_STRIP);
+ for (unsigned int i=0; i<gv.size(); ++i) {
+ SGVec2d p = project(gv[i]);
+ glVertex2d(p.x(), p.y());
+ }
+ glEnd();
+ glDisable(GL_LINE_STIPPLE);
}
- glEnd();
glLineWidth(1.0);
// second pass, draw waypoint symbols and data
- for (int w=0; w < _route->size(); ++w) {
- const SGWayPoint& wpt(_route->get_waypoint(w));
- SGVec2d p = project(wpt.get_target());
+ for (int w=0; w < _route->numWaypts(); ++w) {
+ flightgear::WayptRef wpt(_route->wayptAtIndex(w));
+ SGGeod g = path.positionForIndex(w);
+ if (g == SGGeod()) {
+ continue; // Vectors or similar
+ }
+
+ SGVec2d p = project(g);
glColor4f(1.0, 0.0, 1.0, 1.0);
circleAtAlt(p, 8, 12, 5);
std::ostringstream legend;
- legend << wpt.get_id();
- if (wpt.get_target_alt() > -9990.0) {
- legend << '\n' << SGMiscd::roundToInt(wpt.get_target_alt()) << '\'';
+ legend << wpt->ident();
+ if (wpt->altitudeRestriction() != flightgear::RESTRICT_NONE) {
+ legend << '\n' << SGMiscd::roundToInt(wpt->altitudeFt()) << '\'';
}
- if (wpt.get_speed() > 0.0) {
- legend << '\n' << SGMiscd::roundToInt(wpt.get_speed()) << "Kts";
+ if (wpt->speedRestriction() == flightgear::SPEED_RESTRICT_MACH) {
+ legend << '\n' << wpt->speedMach() << "M";
+ } else if (wpt->speedRestriction() != flightgear::RESTRICT_NONE) {
+ legend << '\n' << SGMiscd::roundToInt(wpt->speedKts()) << "Kts";
}
MapData* d = getOrCreateDataForKey(reinterpret_cast<void*>(w * 2));
d->setText(legend.str());
- d->setLabel(wpt.get_id());
+ d->setLabel(wpt->ident());
d->setAnchor(p);
d->setOffset(MapData::VALIGN_TOP | MapData::HALIGN_CENTER, 15);
- d->setPriority(w < _route->currentWaypoint() ? 9000 : 12000);
-
- if (w > 0) {
- SGVec2d legMid = (prev + p) * 0.5;
- std::ostringstream legLegend;
-
- double track = wpt.get_track();
- if (_magneticHeadings) {
- track -= _magVar->get_magvar(); // show magnetic track for leg
- }
-
- legLegend << SGMiscd::roundToInt(track) << " "
- << SGMiscd::roundToInt(wpt.get_distance() * SG_METER_TO_NM) << "Nm";
+ d->setPriority(w < _route->currentIndex() ? 9000 : 12000);
- MapData* ld = getOrCreateDataForKey(reinterpret_cast<void*>(w * 2 + 1));
- ld->setText(legLegend.str());
- ld->setAnchor(legMid);
- ld->setOffset(MapData::VALIGN_TOP | MapData::HALIGN_CENTER, 15);
- ld->setPriority(w < _route->currentWaypoint() ? 8000 : 11000);
- } // of draw leg data
-
- prev = p;
} // of second waypoint iteration
}
glVertex2dv(endCentre.data());
glVertex2dv(endR.data());
glEnd();
+
+ if (validDataForKey(loc)) {
+ setAnchorForKey(loc, endR);
+ return;
+ }
+
+ char buffer[1024];
+ ::snprintf(buffer, 1024, "%s\n%s\n%3.2fMHz",
+ loc->name().c_str(), loc->ident().c_str(),loc->get_freq()/100.0);
+
+ MapData* d = createDataForKey(loc);
+ d->setPriority(40);
+ d->setLabel(loc->ident());
+ d->setText(buffer);
+ d->setOffset(MapData::HALIGN_CENTER | MapData::VALIGN_BOTTOM, 10);
+ d->setAnchor(endR);
}
void MapWidget::drawTraffic()
for (int i = 0; i < ai->nChildren(); ++i) {
const SGPropertyNode *model = ai->getChild(i);
// skip bad or dead entries
- if (!model || model->getIntValue("id", -1) < 0) {
+ if (!model || model->getIntValue("id", -1) == -1) {
continue;
}
void MapWidget::drawAIShip(const SGPropertyNode* model, const SGGeod& pos, double hdg)
{
+ SGVec2d p = project(pos);
+ glColor3f(0.0, 0.0, 0.0);
+ glLineWidth(2.0);
+ circleAt(p, 4, 6.0); // black diamond
+
+// draw heading vector
+ int speedKts = static_cast<int>(model->getDoubleValue("velocities/true-airspeed-kt"));
+ if (speedKts > 1) {
+ glLineWidth(1.0);
+
+ const double dt = 15.0 / (3600.0); // 15 seconds look-ahead
+ double distanceM = speedKts * SG_NM_TO_METER * dt;
+
+ SGGeod advance;
+ double az2;
+ SGGeodesy::direct(pos, hdg, distanceM, advance, az2);
+
+ drawLine(p, project(advance));
+ }
+
+ if (validDataForKey((void*) model)) {
+ setAnchorForKey((void*) model, p);
+ return;
+ }
+
+ // draw callsign / altitude / speed
+
+
+ char buffer[1024];
+ ::snprintf(buffer, 1024, "%s\n%d'\n%dkts",
+ model->getStringValue("callsign", "<>"),
+ static_cast<int>(pos.getElevationFt() / 50.0) * 50,
+ speedKts);
+
+ MapData* d = createDataForKey((void*) model);
+ d->setText(buffer);
+ d->setLabel(model->getStringValue("callsign", "<>"));
+ d->setPriority(speedKts > 5 ? 60 : 10); // low priority for parked aircraft
+ d->setOffset(MapData::VALIGN_CENTER | MapData::HALIGN_LEFT, 10);
+ d->setAnchor(p);
}
SGVec2d MapWidget::project(const SGGeod& geod) const