]> git.mxchange.org Git - flightgear.git/blobdiff - src/GUI/MapWidget.cxx
Fix windows build
[flightgear.git] / src / GUI / MapWidget.cxx
index e166e24a69bea821a647e8b6fcc1f1fbf6a58858..a161e822abe0069c57c384f72e7845d68ff6dfe2 100644 (file)
@@ -8,8 +8,6 @@
 #include <algorithm> // for std::sort
 #include <plib/puAux.h>
 
-#include <simgear/sg_inlines.h>
-#include <simgear/route/waypoint.hxx>
 #include <simgear/sg_inlines.h>
 #include <simgear/misc/strutils.hxx>
 #include <simgear/magvar/magvar.hxx>
@@ -27,6 +25,7 @@
 #include <Airports/runways.hxx>
 #include <Main/fg_os.hxx>      // fgGetKeyModifiers()
 #include <Navaids/routePath.hxx>
+#include <Aircraft/FlightHistory.hxx>
 
 const char* RULER_LEGEND_KEY = "ruler-legend";
 
@@ -387,7 +386,8 @@ MapWidget::MapWidget(int x, int y, int maxX, int maxY) :
   _width = maxX - x;
   _height = maxY - y;
   _hasPanned = false;
-
+  _orthoAzimuthProject = false;
+  
   MapData::setFont(legendFont);
   MapData::setPalette(colour);
 
@@ -412,6 +412,7 @@ void MapWidget::setProperty(SGPropertyNode_ptr prop)
   _root->setIntValue("max-zoom", MAX_ZOOM);
   _root->setBoolValue("centre-on-aircraft", true);
   _root->setBoolValue("draw-data", false);
+  _root->setBoolValue("draw-flight-history", false);
   _root->setBoolValue("magnetic-headings", true);
 }
 
@@ -536,8 +537,7 @@ void MapWidget::zoomOut()
 
 void MapWidget::draw(int dx, int dy)
 {
-  _aircraft = SGGeod::fromDeg(fgGetDouble("/position/longitude-deg"),
-    fgGetDouble("/position/latitude-deg"));
+  _aircraft = globals->get_aircraft_position();
     
   bool mag = _root->getBoolValue("magnetic-headings");
   if (mag != _magneticHeadings) {
@@ -612,6 +612,7 @@ void MapWidget::draw(int dx, int dy)
   drawNavRadio(fgGetNode("/instrumentation/nav[0]", false));
   drawNavRadio(fgGetNode("/instrumentation/nav[1]", false));
   paintAircraftLocation(_aircraft);
+  drawFlightHistory();
   paintRoute();
   paintRuler();
 
@@ -681,7 +682,7 @@ void MapWidget::paintRoute()
     return;
   }
 
-  RoutePath path(_route->waypts());
+  RoutePath path(_route->flightPlan());
 
 // first pass, draw the actual lines
   glLineWidth(2.0);
@@ -749,6 +750,28 @@ void MapWidget::paintRoute()
   } // of second waypoint iteration
 }
 
+void MapWidget::drawFlightHistory()
+{
+  FGFlightHistory* history = (FGFlightHistory*) globals->get_subsystem("history");
+  if (!history || !_root->getBoolValue("draw-flight-history")) {
+    return;
+  }
+  
+  // first pass, draw the actual lines
+  glLineWidth(2.0);
+  
+  SGGeodVec gv(history->pathForHistory());
+  glColor4f(0.0, 0.0, 1.0, 0.7);
+
+  glBegin(GL_LINE_STRIP);
+  for (unsigned int i=0; i<gv.size(); ++i) {
+    SGVec2d p = project(gv[i]);
+    glVertex2d(p.x(), p.y());
+  }
+  
+  glEnd();
+}
+
 /**
  * Round a SGGeod to an arbitrary precision.
  * For example, passing precision of 0.5 will round to the nearest 0.5 of
@@ -888,7 +911,7 @@ public:
   {
     _heliports = nd->getBoolValue("show-heliports", false);
     _hardRunwaysOnly = nd->getBoolValue("hard-surfaced-airports", true);
-    _minLengthFt = nd->getDoubleValue("min-runway-length-ft", 2000.0);
+    _minLengthFt = fgGetDouble("/sim/navdb/min-runway-length-ft", 2000);
   }
 
   virtual FGPositioned::Type maxType() const {
@@ -912,7 +935,8 @@ private:
 void MapWidget::drawAirports()
 {
   MapAirportFilter af(_root);
-  FGPositioned::List apts = FGPositioned::findWithinRange(_projectionCenter, _drawRangeNm, &af);
+  bool partial = false;
+  FGPositioned::List apts = FGPositioned::findWithinRangePartial(_projectionCenter, _drawRangeNm, &af, partial);
   for (unsigned int i=0; i<apts.size(); ++i) {
     drawAirport((FGAirport*) apts[i].get());
   }
@@ -938,11 +962,11 @@ public:
   }
 
   virtual FGPositioned::Type minType() const {
-    return _fixes ? FGPositioned::FIX : FGPositioned::VOR;
+    return _fixes ? FGPositioned::FIX : FGPositioned::NDB;
   }
 
   virtual FGPositioned::Type maxType() const {
-    return _navaids ? FGPositioned::NDB : FGPositioned::FIX;
+    return _navaids ? FGPositioned::VOR : FGPositioned::FIX;
   }
 
 private:
@@ -1070,7 +1094,9 @@ void MapWidget::drawNavRadio(SGPropertyNode_ptr radio)
   // identify the tuned station - unfortunately we don't get lat/lon directly,
   // need to do the frequency search again
   double mhz = radio->getDoubleValue("frequencies/selected-mhz", 0.0);
-  FGNavRecord* nav = globals->get_navlist()->findByFreq(mhz, _aircraft);
+
+  FGNavRecord* nav = FGNavList::findByFreq(mhz, _aircraft,
+                                           FGNavList::navFilter());
   if (!nav || (nav->ident() != radio->getStringValue("nav-id"))) {
     // mismatch between navradio selection logic and ours!
     return;
@@ -1112,7 +1138,7 @@ void MapWidget::drawNavRadio(SGPropertyNode_ptr radio)
 void MapWidget::drawTunedLocalizer(SGPropertyNode_ptr radio)
 {
   double mhz = radio->getDoubleValue("frequencies/selected-mhz", 0.0);
-  FGNavRecord* loc = globals->get_loclist()->findByFreq(mhz, _aircraft);
+  FGNavRecord* loc = FGNavList::findByFreq(mhz, _aircraft, FGNavList::locFilter());
   if (!loc || (loc->ident() != radio->getStringValue("nav-id"))) {
     // mismatch between navradio selection logic and ours!
     return;
@@ -1446,13 +1472,30 @@ void MapWidget::drawAIShip(const SGPropertyNode* model, const SGGeod& pos, doubl
 
 SGVec2d MapWidget::project(const SGGeod& geod) const
 {
-  // Sanson-Flamsteed projection, relative to the projection center
+  SGVec2d p;
   double r = earth_radius_lat(geod.getLatitudeRad());
-  double lonDiff = geod.getLongitudeRad() - _projectionCenter.getLongitudeRad(),
-    latDiff = geod.getLatitudeRad() - _projectionCenter.getLatitudeRad();
-
-  SGVec2d p = SGVec2d(cos(geod.getLatitudeRad()) * lonDiff, latDiff) * r * currentScale();
+  
+  if (_orthoAzimuthProject) {
+    // http://mathworld.wolfram.com/OrthographicProjection.html
+    double cosTheta = cos(geod.getLatitudeRad());
+    double sinDLambda = sin(geod.getLongitudeRad() - _projectionCenter.getLongitudeRad());
+    double cosDLambda = cos(geod.getLongitudeRad() - _projectionCenter.getLongitudeRad());
+    double sinTheta1 = sin(_projectionCenter.getLatitudeRad());
+    double sinTheta = sin(geod.getLatitudeRad());
+    double cosTheta1 = cos(_projectionCenter.getLatitudeRad());
+    
+    p = SGVec2d(cosTheta * sinDLambda,
+                (cosTheta1 * sinTheta) - (sinTheta1 * cosTheta * cosDLambda)) * r * currentScale();
+    
+  } else {
+    // Sanson-Flamsteed projection, relative to the projection center
+    double lonDiff = geod.getLongitudeRad() - _projectionCenter.getLongitudeRad(),
+      latDiff = geod.getLatitudeRad() - _projectionCenter.getLatitudeRad();
 
+    p = SGVec2d(cos(geod.getLatitudeRad()) * lonDiff, latDiff) * r * currentScale();
+      
+  }
+  
 // rotate as necessary
   double cost = cos(_upHeading * SG_DEGREES_TO_RADIANS),
     sint = sin(_upHeading * SG_DEGREES_TO_RADIANS);
@@ -1472,10 +1515,21 @@ SGGeod MapWidget::unproject(const SGVec2d& p) const
   double r = earth_radius_lat(_projectionCenter.getLatitudeRad());
   SGVec2d unscaled = ur * (1.0 / (currentScale() * r));
 
-  double lat = unscaled.y() + _projectionCenter.getLatitudeRad();
-  double lon = (unscaled.x() / cos(lat)) + _projectionCenter.getLongitudeRad();
-
-  return SGGeod::fromRad(lon, lat);
+  if (_orthoAzimuthProject) {
+      double phi = length(p);
+      double c = asin(phi);
+      double sinTheta1 = sin(_projectionCenter.getLatitudeRad());
+      double cosTheta1 = cos(_projectionCenter.getLatitudeRad());
+      
+      double lat = asin(cos(c) * sinTheta1 + ((unscaled.y() * sin(c) * cosTheta1) / phi));
+      double lon = _projectionCenter.getLongitudeRad() + 
+        atan((unscaled.x()* sin(c)) / (phi  * cosTheta1 * cos(c) - unscaled.y() * sinTheta1 * sin(c)));
+      return SGGeod::fromRad(lon, lat);
+  } else {
+      double lat = unscaled.y() + _projectionCenter.getLatitudeRad();
+      double lon = (unscaled.x() / cos(lat)) + _projectionCenter.getLongitudeRad();
+      return SGGeod::fromRad(lon, lat);
+  }
 }
 
 double MapWidget::currentScale() const