]> git.mxchange.org Git - flightgear.git/blobdiff - src/GUI/MapWidget.cxx
accomodate changes to osgDB::DatabasePager interface
[flightgear.git] / src / GUI / MapWidget.cxx
index 0e06b18b936907c33b4093f6701fc1d4ccd7861b..0b786f5a34d3538c68ce25732a582d9900936b86 100644 (file)
@@ -25,6 +25,7 @@
 #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";
   
@@ -532,18 +533,18 @@ void MapWidget::draw(int dx, int dy)
   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];
@@ -657,77 +658,73 @@ void MapWidget::paintAircraftLocation(const SGGeod& aircraftPos)
 
 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::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
 }
 
@@ -1288,6 +1285,22 @@ void MapWidget::drawILS(bool tuned, FGRunway* rwy)
                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()
@@ -1305,7 +1318,7 @@ 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;
     }
 
@@ -1379,7 +1392,47 @@ void MapWidget::drawAIAircraft(const SGPropertyNode* model, const SGGeod& pos, d
 
 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