1
0
Fork 0

MapWidget for the GUI, initial commit.

This commit is contained in:
jmt 2010-03-27 16:55:33 +00:00 committed by Tim Moore
parent ee8437431a
commit e4c4a3a412
10 changed files with 1787 additions and 43 deletions

View file

@ -1828,6 +1828,8 @@
</File>
<File RelativePath="..\..\..\src\GUI\WaypointList.cxx"></File>
<File RelativePath="..\..\..\src\GUI\WaypointList.hxx"></File>
<File RelativePath="..\..\..\src\GUI\MapWidget.cxx"></File>
<File RelativePath="..\..\..\src\GUI\MapWidget.hxx"></File>
</Filter>
<Filter
Name="Lib_Input"

View file

@ -2647,6 +2647,8 @@
</File>
<File RelativePath="..\..\..\src\GUI\WaypointList.cxx"></File>
<File RelativePath="..\..\..\src\GUI\WaypointList.hxx"></File>
<File RelativePath="..\..\..\src\GUI\MapWidget.cxx"></File>
<File RelativePath="..\..\..\src\GUI\MapWidget.hxx"></File>
</Filter>
<Filter
Name="Lib_Input"

View file

@ -23,7 +23,8 @@ libGUI_a_SOURCES = \
property_list.cxx property_list.hxx \
layout.cxx layout-props.cxx layout.hxx \
SafeTexFont.cxx SafeTexFont.hxx \
WaypointList.cxx WaypointList.hxx
WaypointList.cxx WaypointList.hxx \
MapWidget.cxx MapWidget.hxx
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src

1613
src/GUI/MapWidget.cxx Normal file

File diff suppressed because it is too large Load diff

109
src/GUI/MapWidget.hxx Normal file
View file

@ -0,0 +1,109 @@
#ifndef GUI_MAPWIDGET_HXX
#define GUI_MAPWIDGET_HXX
#include <simgear/compiler.h>
#include <simgear/math/SGMath.hxx>
#include <simgear/props/props.hxx>
#include <plib/pu.h>
#include "dialog.hxx" // for GUI_ID
// forward decls
class FGRouteMgr;
class FGRunway;
class FGAirport;
class FGNavRecord;
class FGFix;
class MapData;
class SGMagVar;
class MapWidget : public puObject
{
public:
MapWidget(int x, int y, int width, int height);
virtual ~MapWidget();
virtual void setSize(int width, int height);
virtual void doHit( int button, int updown, int x, int y ) ;
virtual void draw( int dx, int dy ) ;
virtual int checkKey(int key, int updown);
void setProperty(SGPropertyNode_ptr prop);
private:
void handlePan(int x, int y);
void pan(const SGVec2d& delta);
void zoomIn();
void zoomOut();
void paintAircraftLocation(const SGGeod& aircraftPos);
void paintRoute();
void paintRuler();
void drawGPSData();
void drawNavRadio(SGPropertyNode_ptr radio);
void drawTunedLocalizer(SGPropertyNode_ptr radio);
void drawLatLonGrid();
SGVec2d gridPoint(int ix, int iy);
bool drawLineClipped(const SGVec2d& a, const SGVec2d& b);
void drawAirports();
void drawAirport(FGAirport* apt);
int scoreAirportRunways(FGAirport* apt);
void drawRunwayPre(FGRunway* rwy);
void drawRunway(FGRunway* rwy);
void drawILS(bool tuned, FGRunway* rwy);
void drawNavaids();
void drawNDB(bool tuned, FGNavRecord* nav);
void drawVOR(bool tuned, FGNavRecord* nav);
void drawFix(FGFix* fix);
void drawTraffic();
void drawAIAircraft(const SGPropertyNode* model, const SGGeod& pos, double hdg);
void drawAIShip(const SGPropertyNode* model, const SGGeod& pos, double hdg);
void drawData();
bool validDataForKey(void* key);
MapData* getOrCreateDataForKey(void* key);
MapData* createDataForKey(void* key);
void setAnchorForKey(void* key, const SGVec2d& anchor);
SGVec2d project(const SGGeod& geod) const;
SGGeod unproject(const SGVec2d& p) const;
double currentScale() const;
void circleAt(const SGVec2d& center, int nSides, double r);
void circleAtAlt(const SGVec2d& center, int nSides, double r, double r2);
void drawLine(const SGVec2d& p1, const SGVec2d& p2);
void drawLegendBox(const SGVec2d& pos, const std::string& t);
int _width, _height;
int _zoom;
double _drawRangeNm;
double _upHeading; // true heading corresponding to +ve y-axis
bool _magneticHeadings;
SGGeod _projectionCenter;
SGGeod _aircraft;
SGGeod _clickGeod;
SGVec2d _hitLocation;
FGRouteMgr* _route;
SGPropertyNode_ptr _root;
SGPropertyNode_ptr _gps;
typedef std::map<void*, MapData*> KeyDataMap;
KeyDataMap _mapData;
std::vector<MapData*> _dataQueue;
SGMagVar* _magVar;
typedef std::map<int, SGVec2d> GridPointCache;
GridPointCache _gridCache;
double _gridSpacing;
SGGeod _gridCenter;
};
#endif // of GUI_MAPWIDGET_HXX

View file

@ -14,6 +14,7 @@
#include "property_list.hxx"
#include "layout.hxx"
#include "WaypointList.hxx"
#include "MapWidget.hxx"
enum format_type { f_INVALID, f_INT, f_LONG, f_FLOAT, f_DOUBLE, f_STRING };
static const int FORMAT_BUFSIZE = 255;
@ -815,7 +816,10 @@ FGDialog::makeObject (SGPropertyNode *props, int parentWidth, int parentHeight)
setupObject(obj, props);
setColor(obj, props);
return obj;
} else if (type == "map") {
MapWidget* mapWidget = new MapWidget(x, y, x + width, y + height);
setupObject(mapWidget, props);
return mapWidget;
} else if (type == "combo") {
fgComboBox *obj = new fgComboBox(x, y, x + width, y + height, props,
props->getBoolValue("editable", false));
@ -953,12 +957,21 @@ FGDialog::setupObject (puObject *object, SGPropertyNode *props)
name = "";
const char *propname = props->getStringValue("property");
SGPropertyNode_ptr node = fgGetNode(propname, true);
copy_to_pui(node, object);
if (type == "map") {
// mapWidget binds to a sub-tree of properties, and
// ignroes the puValue mechanism, so special case things here
MapWidget* mw = static_cast<MapWidget*>(object);
mw->setProperty(node);
} else {
// normal widget, creating PropertyObject
copy_to_pui(node, object);
PropertyObject *po = new PropertyObject(name, object, node);
_propertyObjects.push_back(po);
if (props->getBoolValue("live"))
_liveObjects.push_back(po);
}
PropertyObject *po = new PropertyObject(name, object, node);
_propertyObjects.push_back(po);
if (props->getBoolValue("live"))
_liveObjects.push_back(po);
}
SGPropertyNode *dest = fgGetNode("/sim/bindings/gui", true);

View file

@ -891,7 +891,7 @@ void FGNavRadio::search()
} else { // ILS or LOC
_gs = globals->get_gslist()->findByFreq(freq, pos);
has_gs_node->setBoolValue(_gs != NULL);
_localizerWidth = localizerWidth(nav);
_localizerWidth = nav->localizerWidth();
twist = 0.0;
effective_range = nav->get_range();
@ -941,36 +941,6 @@ void FGNavRadio::search()
id_c4_node->setIntValue( (int)identBuffer[3] );
}
double FGNavRadio::localizerWidth(FGNavRecord* aLOC)
{
FGRunway* rwy = aLOC->runway();
assert(rwy);
SGVec3d thresholdCart(SGVec3d::fromGeod(rwy->threshold()));
double axisLength = dist(aLOC->cart(), thresholdCart);
double landingLength = dist(thresholdCart, SGVec3d::fromGeod(rwy->end()));
// Reference: http://dcaa.slv.dk:8000/icaodocs/
// ICAO standard width at threshold is 210 m = 689 feet = approx 700 feet.
// ICAO 3.1.1 half course = DDM = 0.0775
// ICAO 3.1.3.7.1 Sensitivity 0.00145 DDM/m at threshold
// implies peg-to-peg of 214 m ... we will stick with 210.
// ICAO 3.1.3.7.1 "Course sector angle shall not exceed 6 degrees."
// Very short runway: less than 1200 m (4000 ft) landing length:
if (landingLength < 1200.0) {
// ICAO fudges localizer sensitivity for very short runways.
// This produces a non-monotonic sensitivity-versus length relation.
axisLength += 1050.0;
}
// Example: very short: San Diego KMYF (Montgomery Field) ILS RWY 28R
// Example: short: Tom's River KMJX (Robert J. Miller) ILS RWY 6
// Example: very long: Denver KDEN (Denver) ILS RWY 16R
double raw_width = 210.0 / axisLength * SGD_RADIANS_TO_DEGREES;
return raw_width < 6.0? raw_width : 6.0;
}
void FGNavRadio::audioNavidChanged()
{
if (_sgr->exists(nav_fx_name)) {

View file

@ -191,11 +191,6 @@ class FGNavRadio : public SGSubsystem, public SGPropertyChangeListener
void clearOutputs();
/**
* Compute the localizer width in degrees - see implementation for
* more information on the relevant standards and formulae.
*/
double localizerWidth(FGNavRecord* aLOC);
FGNavRecord* findPrimaryNavaid(const SGGeod& aPos, double aFreqMHz);
/// accessor for tied, read-only 'operable' property

View file

@ -181,6 +181,38 @@ void FGNavRecord::alignLocaliserWithRunway(double aThreshold)
}
}
double FGNavRecord::localizerWidth() const
{
if (!mRunway) {
return 6.0;
}
SGVec3d thresholdCart(SGVec3d::fromGeod(mRunway->threshold()));
double axisLength = dist(cart(), thresholdCart);
double landingLength = dist(thresholdCart, SGVec3d::fromGeod(mRunway->end()));
// Reference: http://dcaa.slv.dk:8000/icaodocs/
// ICAO standard width at threshold is 210 m = 689 feet = approx 700 feet.
// ICAO 3.1.1 half course = DDM = 0.0775
// ICAO 3.1.3.7.1 Sensitivity 0.00145 DDM/m at threshold
// implies peg-to-peg of 214 m ... we will stick with 210.
// ICAO 3.1.3.7.1 "Course sector angle shall not exceed 6 degrees."
// Very short runway: less than 1200 m (4000 ft) landing length:
if (landingLength < 1200.0) {
// ICAO fudges localizer sensitivity for very short runways.
// This produces a non-monotonic sensitivity-versus length relation.
axisLength += 1050.0;
}
// Example: very short: San Diego KMYF (Montgomery Field) ILS RWY 28R
// Example: short: Tom's River KMJX (Robert J. Miller) ILS RWY 6
// Example: very long: Denver KDEN (Denver) ILS RWY 16R
double raw_width = 210.0 / axisLength * SGD_RADIANS_TO_DEGREES;
return raw_width < 6.0? raw_width : 6.0;
}
FGTACANRecord::FGTACANRecord(void) :
channel(""),
freq(0)

View file

@ -96,6 +96,13 @@ public:
* Retrieve the runway this navaid is associated with (for ILS/LOC/GS)
*/
FGRunway* runway() const { return mRunway; }
/**
* return the localizer width, in degrees
* computation is based up ICAO stdandard width at the runway threshold
* see implementation for further details.
*/
double localizerWidth() const;
};
class FGTACANRecord : public SGReferenced {