Browse Source

Added option to enable/disable Airspaces on map

Limit all queries to areas smaller than 500km^2. If an area of interest is greater, clip to 500km^2 centered on current ROI's center.
Removed the identifier "Airmap" from error messages coming from Airmap.
Added a clipping function to QGCGeoBoundingCube (clip polygon to given area)
QGC4.4
Gus Grubba 7 years ago
parent
commit
5c956faa7d
  1. 6
      src/Airmap/AirMap.SettingsGroup.json
  2. 3
      src/Airmap/AirMapAdvisoryManager.cc
  3. 14
      src/Airmap/AirMapManager.cc
  4. 1
      src/Airmap/AirMapManager.h
  5. 17
      src/Airmap/AirMapRestrictionManager.cc
  6. 3
      src/Airmap/AirMapRulesetsManager.cc
  7. 2
      src/Airmap/AirMapSettings.cc
  8. 3
      src/Airmap/AirMapSettings.h
  9. 7
      src/Airmap/AirmapSettings.qml
  10. 1
      src/AirspaceManagement/AirspaceManager.cc
  11. 4
      src/AirspaceManagement/AirspaceManager.h
  12. 5
      src/FlightDisplay/FlightDisplayViewMap.qml
  13. 20
      src/QmlControls/QGCGeoBoundingCube.cc
  14. 2
      src/QmlControls/QGCGeoBoundingCube.h

6
src/Airmap/AirMap.SettingsGroup.json

@ -36,6 +36,12 @@
"defaultValue": false "defaultValue": false
}, },
{ {
"name": "enableAirspace",
"shortDescription": "Show Airspace on Map (Experimental)",
"type": "bool",
"defaultValue": false
},
{
"name": "enableTelemetry", "name": "enableTelemetry",
"shortDescription": "Enable AirMap Telemetry", "shortDescription": "Enable AirMap Telemetry",
"type": "bool", "type": "bool",

3
src/Airmap/AirMapAdvisoryManager.cc

@ -75,7 +75,8 @@ AirMapAdvisoryManager::_requestAdvisories()
Advisory::Search::Parameters params; Advisory::Search::Parameters params;
//-- Geometry //-- Geometry
Geometry::Polygon polygon; Geometry::Polygon polygon;
for (const auto& qcoord : _lastROI.polygon2D()) { //-- Get ROI bounding box, clipping to max area of interest
for (const auto& qcoord : _lastROI.polygon2D(qgcApp()->toolbox()->airspaceManager()->maxAreaOfInterest())) {
Geometry::Coordinate coord; Geometry::Coordinate coord;
coord.latitude = qcoord.latitude(); coord.latitude = qcoord.latitude();
coord.longitude = qcoord.longitude(); coord.longitude = qcoord.longitude();

14
src/Airmap/AirMapManager.cc

@ -72,6 +72,7 @@ AirMapManager::setToolbox(QGCToolbox* toolbox)
connect(ap->clientID(), &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged); connect(ap->clientID(), &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged);
connect(ap->userName(), &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged); connect(ap->userName(), &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged);
connect(ap->password(), &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged); connect(ap->password(), &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged);
connect(ap->enableAirspace(), &Fact::rawValueChanged, this, &AirMapManager::_airspaceEnabled);
connect(&_settingsTimer, &QTimer::timeout, this, &AirMapManager::_settingsTimeout); connect(&_settingsTimer, &QTimer::timeout, this, &AirMapManager::_settingsTimeout);
_settingsTimeout(); _settingsTimeout();
} }
@ -88,7 +89,7 @@ void
AirMapManager::_error(const QString& what, const QString& airmapdMessage, const QString& airmapdDetails) AirMapManager::_error(const QString& what, const QString& airmapdMessage, const QString& airmapdDetails)
{ {
qCDebug(AirMapManagerLog) << "Error: "<<what<<", msg: "<<airmapdMessage<<", details: "<<airmapdDetails; qCDebug(AirMapManagerLog) << "Error: "<<what<<", msg: "<<airmapdMessage<<", details: "<<airmapdDetails;
qgcApp()->showMessage(QString("AirMap Error: %1. %2").arg(what).arg(airmapdMessage)); qgcApp()->showMessage(QString("Error: %1. %2").arg(what).arg(airmapdMessage));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -108,6 +109,17 @@ AirMapManager::_settingsChanged()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
AirMapManager::_airspaceEnabled()
{
if(qgcApp()->toolbox()->settingsManager()->airMapSettings()->enableAirspace()->rawValue().toBool()) {
if(_airspaces) {
_airspaces->setROI(_roi, true);
}
}
}
//-----------------------------------------------------------------------------
void
AirMapManager::_settingsTimeout() AirMapManager::_settingsTimeout()
{ {
qCDebug(AirMapManagerLog) << "AirMap settings changed"; qCDebug(AirMapManagerLog) << "AirMap settings changed";

1
src/Airmap/AirMapManager.h

@ -56,6 +56,7 @@ private slots:
void _error (const QString& what, const QString& airmapdMessage, const QString& airmapdDetails); void _error (const QString& what, const QString& airmapdMessage, const QString& airmapdDetails);
void _settingsChanged (); void _settingsChanged ();
void _settingsTimeout (); void _settingsTimeout ();
void _airspaceEnabled ();
void _authStatusChanged (AirspaceManager::AuthStatus status); void _authStatusChanged (AirspaceManager::AuthStatus status);
private: private:

17
src/Airmap/AirMapRestrictionManager.cc

@ -11,6 +11,9 @@
#include "AirMapManager.h" #include "AirMapManager.h"
#include "AirspaceRestriction.h" #include "AirspaceRestriction.h"
#include "QGCApplication.h"
#include "SettingsManager.h"
#define RESTRICTION_UPDATE_DISTANCE 500 //-- 500m threshold for updates #define RESTRICTION_UPDATE_DISTANCE 500 //-- 500m threshold for updates
using namespace airmap; using namespace airmap;
@ -25,12 +28,20 @@ AirMapRestrictionManager::AirMapRestrictionManager(AirMapSharedState& shared)
void void
AirMapRestrictionManager::setROI(const QGCGeoBoundingCube& roi, bool reset) AirMapRestrictionManager::setROI(const QGCGeoBoundingCube& roi, bool reset)
{ {
if(qgcApp()->toolbox()->settingsManager()->airMapSettings()->enableAirspace()->rawValue().toBool()) {
//-- If first time or we've moved more than RESTRICTION_UPDATE_DISTANCE, ask for updates. //-- If first time or we've moved more than RESTRICTION_UPDATE_DISTANCE, ask for updates.
if(reset || (!_lastROI.isValid() || _lastROI.pointNW.distanceTo(roi.pointNW) > RESTRICTION_UPDATE_DISTANCE || _lastROI.pointSE.distanceTo(roi.pointSE) > RESTRICTION_UPDATE_DISTANCE)) { if(reset ||
//-- No more than 40000 km^2 (!_lastROI.isValid() || _lastROI.pointNW.distanceTo(roi.pointNW) > RESTRICTION_UPDATE_DISTANCE || _lastROI.pointSE.distanceTo(roi.pointSE) > RESTRICTION_UPDATE_DISTANCE) ||
if(roi.area() < 40000.0) { (_polygons.count() == 0 && _circles.count() == 0)) {
//-- Limit area of interest
qCDebug(AirMapManagerLog) << "ROI Area:" << roi.area() << "km^2";
if(roi.area() < qgcApp()->toolbox()->airspaceManager()->maxAreaOfInterest()) {
_lastROI = roi; _lastROI = roi;
_requestRestrictions(roi); _requestRestrictions(roi);
} else {
_polygons.clear();
_circles.clear();
}
} }
} }
} }

3
src/Airmap/AirMapRulesetsManager.cc

@ -247,7 +247,8 @@ void AirMapRulesetsManager::setROI(const QGCGeoBoundingCube& roi, bool reset)
RuleSets::Search::Parameters params; RuleSets::Search::Parameters params;
//-- Geometry: Polygon //-- Geometry: Polygon
Geometry::Polygon polygon; Geometry::Polygon polygon;
for (const auto& qcoord : roi.polygon2D()) { //-- Get ROI bounding box, clipping to max area of interest
for (const auto& qcoord : roi.polygon2D(qgcApp()->toolbox()->airspaceManager()->maxAreaOfInterest())) {
Geometry::Coordinate coord; Geometry::Coordinate coord;
coord.latitude = qcoord.latitude(); coord.latitude = qcoord.latitude();
coord.longitude = qcoord.longitude(); coord.longitude = qcoord.longitude();

2
src/Airmap/AirMapSettings.cc

@ -21,6 +21,7 @@ DECLARE_SETTINGGROUP(AirMap)
INIT_SETTINGFACT(userName); INIT_SETTINGFACT(userName);
INIT_SETTINGFACT(password); INIT_SETTINGFACT(password);
INIT_SETTINGFACT(enableAirMap); INIT_SETTINGFACT(enableAirMap);
INIT_SETTINGFACT(enableAirspace);
INIT_SETTINGFACT(enableTelemetry); INIT_SETTINGFACT(enableTelemetry);
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
qmlRegisterUncreatableType<AirMapSettings>("QGroundControl.SettingsManager", 1, 0, "AirMapSettings", "Reference only"); qmlRegisterUncreatableType<AirMapSettings>("QGroundControl.SettingsManager", 1, 0, "AirMapSettings", "Reference only");
@ -32,4 +33,5 @@ DECLARE_SETTINGSFACT(AirMapSettings, clientID)
DECLARE_SETTINGSFACT(AirMapSettings, userName) DECLARE_SETTINGSFACT(AirMapSettings, userName)
DECLARE_SETTINGSFACT(AirMapSettings, password) DECLARE_SETTINGSFACT(AirMapSettings, password)
DECLARE_SETTINGSFACT(AirMapSettings, enableAirMap) DECLARE_SETTINGSFACT(AirMapSettings, enableAirMap)
DECLARE_SETTINGSFACT(AirMapSettings, enableAirspace)
DECLARE_SETTINGSFACT(AirMapSettings, enableTelemetry) DECLARE_SETTINGSFACT(AirMapSettings, enableTelemetry)

3
src/Airmap/AirMapSettings.h

@ -15,7 +15,7 @@ class AirMapSettings : public SettingsGroup
{ {
Q_OBJECT Q_OBJECT
public: public:
AirMapSettings(QObject* parent = NULL); AirMapSettings(QObject* parent = nullptr);
DEFINE_SETTINGGROUP(AirMap) DEFINE_SETTINGGROUP(AirMap)
@ -25,6 +25,7 @@ public:
DEFINE_SETTINGFACT(userName) DEFINE_SETTINGFACT(userName)
DEFINE_SETTINGFACT(password) DEFINE_SETTINGFACT(password)
DEFINE_SETTINGFACT(enableAirMap) DEFINE_SETTINGFACT(enableAirMap)
DEFINE_SETTINGFACT(enableAirspace)
DEFINE_SETTINGFACT(enableTelemetry) DEFINE_SETTINGFACT(enableTelemetry)
}; };

7
src/Airmap/AirmapSettings.qml

@ -100,6 +100,13 @@ QGCView {
enabled: _airMapEnabled enabled: _airMapEnabled
property Fact _enableTelemetryFact: QGroundControl.settingsManager.airMapSettings.enableTelemetry property Fact _enableTelemetryFact: QGroundControl.settingsManager.airMapSettings.enableTelemetry
} }
FactCheckBox {
text: qsTr("Show Airspace on Map (Experimental)")
fact: _enableAirspaceFact
visible: _enableAirspaceFact.visible
enabled: _airMapEnabled
property Fact _enableAirspaceFact: QGroundControl.settingsManager.airMapSettings.enableAirspace
}
} }
QGCButton { QGCButton {
text: qsTr("Clear Saved Answers") text: qsTr("Clear Saved Answers")

1
src/AirspaceManagement/AirspaceManager.cc

@ -25,7 +25,6 @@ QGC_LOGGING_CATEGORY(AirspaceManagementLog, "AirspaceManagementLog")
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
AirspaceManager::AirspaceManager(QGCApplication* app, QGCToolbox* toolbox) AirspaceManager::AirspaceManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox) : QGCTool(app, toolbox)
, _airspaceVisible(false)
{ {
_ruleUpdateTimer.setInterval(2000); _ruleUpdateTimer.setInterval(2000);
_ruleUpdateTimer.setSingleShot(true); _ruleUpdateTimer.setSingleShot(true);

4
src/AirspaceManagement/AirspaceManager.h

@ -93,6 +93,7 @@ public:
virtual void setAirspaceVisible (bool set) { _airspaceVisible = set; emit airspaceVisibleChanged(); } virtual void setAirspaceVisible (bool set) { _airspaceVisible = set; emit airspaceVisibleChanged(); }
virtual bool connected () const = 0; virtual bool connected () const = 0;
virtual QString connectStatus () const { return QString(); } virtual QString connectStatus () const { return QString(); }
virtual double maxAreaOfInterest() const { return _maxAreaOfInterest; }
virtual AirspaceManager::AuthStatus authStatus () const { return Anonymous; } virtual AirspaceManager::AuthStatus authStatus () const { return Anonymous; }
@ -125,12 +126,13 @@ protected:
virtual AirspaceFlightPlanProvider* _instantiateAirspaceFlightPlanProvider () = 0; virtual AirspaceFlightPlanProvider* _instantiateAirspaceFlightPlanProvider () = 0;
protected: protected:
bool _airspaceVisible; bool _airspaceVisible = false;
AirspaceRulesetsProvider* _ruleSetsProvider = nullptr; ///< Rulesets AirspaceRulesetsProvider* _ruleSetsProvider = nullptr; ///< Rulesets
AirspaceWeatherInfoProvider* _weatherProvider = nullptr; ///< Weather info AirspaceWeatherInfoProvider* _weatherProvider = nullptr; ///< Weather info
AirspaceAdvisoryProvider* _advisories = nullptr; ///< Advisory info AirspaceAdvisoryProvider* _advisories = nullptr; ///< Advisory info
AirspaceRestrictionProvider* _airspaces = nullptr; ///< Airspace info AirspaceRestrictionProvider* _airspaces = nullptr; ///< Airspace info
AirspaceFlightPlanProvider* _flightPlan = nullptr; ///< Flight plan management AirspaceFlightPlanProvider* _flightPlan = nullptr; ///< Flight plan management
double _maxAreaOfInterest = 500.0; ///< Ignore area larger than 500km^2
QTimer _ruleUpdateTimer; QTimer _ruleUpdateTimer;
QTimer _updateTimer; QTimer _updateTimer;
QGCGeoBoundingCube _roi; QGCGeoBoundingCube _roi;

5
src/FlightDisplay/FlightDisplayViewMap.qml

@ -434,7 +434,7 @@ FlightMap {
// Airspace overlap support // Airspace overlap support
MapItemView { MapItemView {
model: _airspaceEnabled && QGroundControl.airspaceManager.airspaceVisible ? QGroundControl.airspaceManager.airspaces.circles : [] model: _airspaceEnabled && QGroundControl.settingsManager.airMapSettings.enableAirspace && QGroundControl.airspaceManager.airspaceVisible ? QGroundControl.airspaceManager.airspaces.circles : []
delegate: MapCircle { delegate: MapCircle {
center: object.center center: object.center
radius: object.radius radius: object.radius
@ -445,7 +445,7 @@ FlightMap {
} }
MapItemView { MapItemView {
model: _airspaceEnabled && QGroundControl.airspaceManager.airspaceVisible ? QGroundControl.airspaceManager.airspaces.polygons : [] model: _airspaceEnabled && QGroundControl.settingsManager.airMapSettings.enableAirspace && QGroundControl.airspaceManager.airspaceVisible ? QGroundControl.airspaceManager.airspaces.polygons : []
delegate: MapPolygon { delegate: MapPolygon {
path: object.polygon path: object.polygon
color: object.color color: object.color
@ -453,4 +453,5 @@ FlightMap {
border.width: object.lineWidth border.width: object.lineWidth
} }
} }
} }

20
src/QmlControls/QGCGeoBoundingCube.cc

@ -9,6 +9,7 @@
#include "QGCGeoBoundingCube.h" #include "QGCGeoBoundingCube.h"
#include <QDebug> #include <QDebug>
#include <cmath>
double QGCGeoBoundingCube::MaxAlt = 1000000.0; double QGCGeoBoundingCube::MaxAlt = 1000000.0;
double QGCGeoBoundingCube::MinAlt = -1000000.0; double QGCGeoBoundingCube::MinAlt = -1000000.0;
@ -47,16 +48,32 @@ QGCGeoBoundingCube::center() const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QList<QGeoCoordinate> QList<QGeoCoordinate>
QGCGeoBoundingCube::polygon2D() const QGCGeoBoundingCube::polygon2D(double clipTo) const
{ {
QList<QGeoCoordinate> coords; QList<QGeoCoordinate> coords;
if(isValid()) { if(isValid()) {
//-- Should we clip it?
if(clipTo > 0.0 && area() > clipTo) {
//-- Clip it to a square of given area centered on current bounding box center.
double side = sqrt(clipTo);
QGeoCoordinate c = center();
double a = pow((side * 0.5), 2);
double h = sqrt(a + a) * 1000.0;
QGeoCoordinate nw = c.atDistanceAndAzimuth(h, 315.0);
QGeoCoordinate se = c.atDistanceAndAzimuth(h, 135.0);
coords.append(QGeoCoordinate(nw.latitude(), nw.longitude(), se.altitude()));
coords.append(QGeoCoordinate(nw.latitude(), se.longitude(), se.altitude()));
coords.append(QGeoCoordinate(se.latitude(), se.longitude(), se.altitude()));
coords.append(QGeoCoordinate(se.latitude(), nw.longitude(), se.altitude()));
coords.append(QGeoCoordinate(nw.latitude(), nw.longitude(), se.altitude()));
} else {
coords.append(QGeoCoordinate(pointNW.latitude(), pointNW.longitude(), pointSE.altitude())); coords.append(QGeoCoordinate(pointNW.latitude(), pointNW.longitude(), pointSE.altitude()));
coords.append(QGeoCoordinate(pointNW.latitude(), pointSE.longitude(), pointSE.altitude())); coords.append(QGeoCoordinate(pointNW.latitude(), pointSE.longitude(), pointSE.altitude()));
coords.append(QGeoCoordinate(pointSE.latitude(), pointSE.longitude(), pointSE.altitude())); coords.append(QGeoCoordinate(pointSE.latitude(), pointSE.longitude(), pointSE.altitude()));
coords.append(QGeoCoordinate(pointSE.latitude(), pointNW.longitude(), pointSE.altitude())); coords.append(QGeoCoordinate(pointSE.latitude(), pointNW.longitude(), pointSE.altitude()));
coords.append(QGeoCoordinate(pointNW.latitude(), pointNW.longitude(), pointSE.altitude())); coords.append(QGeoCoordinate(pointNW.latitude(), pointNW.longitude(), pointSE.altitude()));
} }
}
return coords; return coords;
} }
@ -100,7 +117,6 @@ QGCGeoBoundingCube::area() const
return 0.0; return 0.0;
// Area in km^2 // Area in km^2
double a = (height() / 1000.0) * (width() / 1000.0); double a = (height() / 1000.0) * (width() / 1000.0);
//qDebug() << "Area:" << a;
return a; return a;
} }

2
src/QmlControls/QGCGeoBoundingCube.h

@ -64,7 +64,7 @@ public:
} }
//-- 2D //-- 2D
QList<QGeoCoordinate> polygon2D() const; QList<QGeoCoordinate> polygon2D(double clipTo = 0.0) const;
Q_INVOKABLE double width () const; Q_INVOKABLE double width () const;
Q_INVOKABLE double height () const; Q_INVOKABLE double height () const;

Loading…
Cancel
Save