Commit 5c956faa authored by Gus Grubba's avatar Gus Grubba

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)
parent 72ba6b07
......@@ -35,6 +35,12 @@
"type": "bool",
"defaultValue": false
},
{
"name": "enableAirspace",
"shortDescription": "Show Airspace on Map (Experimental)",
"type": "bool",
"defaultValue": false
},
{
"name": "enableTelemetry",
"shortDescription": "Enable AirMap Telemetry",
......
......@@ -75,7 +75,8 @@ AirMapAdvisoryManager::_requestAdvisories()
Advisory::Search::Parameters params;
//-- Geometry
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;
coord.latitude = qcoord.latitude();
coord.longitude = qcoord.longitude();
......
......@@ -72,6 +72,7 @@ AirMapManager::setToolbox(QGCToolbox* toolbox)
connect(ap->clientID(), &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged);
connect(ap->userName(), &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);
_settingsTimeout();
}
......@@ -88,7 +89,7 @@ void
AirMapManager::_error(const QString& what, const QString& airmapdMessage, const QString& 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));
}
//-----------------------------------------------------------------------------
......@@ -106,6 +107,17 @@ AirMapManager::_settingsChanged()
_settingsTimer.start(1000);
}
//-----------------------------------------------------------------------------
void
AirMapManager::_airspaceEnabled()
{
if(qgcApp()->toolbox()->settingsManager()->airMapSettings()->enableAirspace()->rawValue().toBool()) {
if(_airspaces) {
_airspaces->setROI(_roi, true);
}
}
}
//-----------------------------------------------------------------------------
void
AirMapManager::_settingsTimeout()
......
......@@ -56,6 +56,7 @@ private slots:
void _error (const QString& what, const QString& airmapdMessage, const QString& airmapdDetails);
void _settingsChanged ();
void _settingsTimeout ();
void _airspaceEnabled ();
void _authStatusChanged (AirspaceManager::AuthStatus status);
private:
......
......@@ -11,6 +11,9 @@
#include "AirMapManager.h"
#include "AirspaceRestriction.h"
#include "QGCApplication.h"
#include "SettingsManager.h"
#define RESTRICTION_UPDATE_DISTANCE 500 //-- 500m threshold for updates
using namespace airmap;
......@@ -25,12 +28,20 @@ AirMapRestrictionManager::AirMapRestrictionManager(AirMapSharedState& shared)
void
AirMapRestrictionManager::setROI(const QGCGeoBoundingCube& roi, bool reset)
{
//-- 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)) {
//-- No more than 40000 km^2
if(roi.area() < 40000.0) {
_lastROI = roi;
_requestRestrictions(roi);
if(qgcApp()->toolbox()->settingsManager()->airMapSettings()->enableAirspace()->rawValue().toBool()) {
//-- 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) ||
(_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;
_requestRestrictions(roi);
} else {
_polygons.clear();
_circles.clear();
}
}
}
}
......
......@@ -247,7 +247,8 @@ void AirMapRulesetsManager::setROI(const QGCGeoBoundingCube& roi, bool reset)
RuleSets::Search::Parameters params;
//-- Geometry: 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;
coord.latitude = qcoord.latitude();
coord.longitude = qcoord.longitude();
......
......@@ -21,6 +21,7 @@ DECLARE_SETTINGGROUP(AirMap)
INIT_SETTINGFACT(userName);
INIT_SETTINGFACT(password);
INIT_SETTINGFACT(enableAirMap);
INIT_SETTINGFACT(enableAirspace);
INIT_SETTINGFACT(enableTelemetry);
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
qmlRegisterUncreatableType<AirMapSettings>("QGroundControl.SettingsManager", 1, 0, "AirMapSettings", "Reference only");
......@@ -32,4 +33,5 @@ DECLARE_SETTINGSFACT(AirMapSettings, clientID)
DECLARE_SETTINGSFACT(AirMapSettings, userName)
DECLARE_SETTINGSFACT(AirMapSettings, password)
DECLARE_SETTINGSFACT(AirMapSettings, enableAirMap)
DECLARE_SETTINGSFACT(AirMapSettings, enableAirspace)
DECLARE_SETTINGSFACT(AirMapSettings, enableTelemetry)
......@@ -15,7 +15,7 @@ class AirMapSettings : public SettingsGroup
{
Q_OBJECT
public:
AirMapSettings(QObject* parent = NULL);
AirMapSettings(QObject* parent = nullptr);
DEFINE_SETTINGGROUP(AirMap)
......@@ -25,6 +25,7 @@ public:
DEFINE_SETTINGFACT(userName)
DEFINE_SETTINGFACT(password)
DEFINE_SETTINGFACT(enableAirMap)
DEFINE_SETTINGFACT(enableAirspace)
DEFINE_SETTINGFACT(enableTelemetry)
};
......@@ -100,6 +100,13 @@ QGCView {
enabled: _airMapEnabled
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 {
text: qsTr("Clear Saved Answers")
......
......@@ -25,7 +25,6 @@ QGC_LOGGING_CATEGORY(AirspaceManagementLog, "AirspaceManagementLog")
//-----------------------------------------------------------------------------
AirspaceManager::AirspaceManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _airspaceVisible(false)
{
_ruleUpdateTimer.setInterval(2000);
_ruleUpdateTimer.setSingleShot(true);
......
......@@ -75,7 +75,7 @@ public:
Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
Q_PROPERTY(QString connectStatus READ connectStatus NOTIFY connectStatusChanged)
Q_PROPERTY(AirspaceManager::AuthStatus authStatus READ authStatus NOTIFY authStatusChanged)
Q_PROPERTY(bool airspaceVisible READ airspaceVisible WRITE setAirspaceVisible NOTIFY airspaceVisibleChanged)
Q_PROPERTY(bool airspaceVisible READ airspaceVisible WRITE setAirspaceVisible NOTIFY airspaceVisibleChanged)
Q_INVOKABLE void setROI (const QGeoCoordinate& pointNW, const QGeoCoordinate& pointSE, bool planView, bool reset = false);
......@@ -93,6 +93,7 @@ public:
virtual void setAirspaceVisible (bool set) { _airspaceVisible = set; emit airspaceVisibleChanged(); }
virtual bool connected () const = 0;
virtual QString connectStatus () const { return QString(); }
virtual double maxAreaOfInterest() const { return _maxAreaOfInterest; }
virtual AirspaceManager::AuthStatus authStatus () const { return Anonymous; }
......@@ -125,12 +126,13 @@ protected:
virtual AirspaceFlightPlanProvider* _instantiateAirspaceFlightPlanProvider () = 0;
protected:
bool _airspaceVisible;
AirspaceRulesetsProvider* _ruleSetsProvider = nullptr; ///< Rulesets
AirspaceWeatherInfoProvider* _weatherProvider = nullptr; ///< Weather info
AirspaceAdvisoryProvider* _advisories = nullptr; ///< Advisory info
AirspaceRestrictionProvider* _airspaces = nullptr; ///< Airspace info
AirspaceFlightPlanProvider* _flightPlan = nullptr; ///< Flight plan management
bool _airspaceVisible = false;
AirspaceRulesetsProvider* _ruleSetsProvider = nullptr; ///< Rulesets
AirspaceWeatherInfoProvider* _weatherProvider = nullptr; ///< Weather info
AirspaceAdvisoryProvider* _advisories = nullptr; ///< Advisory info
AirspaceRestrictionProvider* _airspaces = nullptr; ///< Airspace info
AirspaceFlightPlanProvider* _flightPlan = nullptr; ///< Flight plan management
double _maxAreaOfInterest = 500.0; ///< Ignore area larger than 500km^2
QTimer _ruleUpdateTimer;
QTimer _updateTimer;
QGCGeoBoundingCube _roi;
......
......@@ -434,7 +434,7 @@ FlightMap {
// Airspace overlap support
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 {
center: object.center
radius: object.radius
......@@ -445,7 +445,7 @@ FlightMap {
}
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 {
path: object.polygon
color: object.color
......@@ -453,4 +453,5 @@ FlightMap {
border.width: object.lineWidth
}
}
}
......@@ -9,6 +9,7 @@
#include "QGCGeoBoundingCube.h"
#include <QDebug>
#include <cmath>
double QGCGeoBoundingCube::MaxAlt = 1000000.0;
double QGCGeoBoundingCube::MinAlt = -1000000.0;
......@@ -47,15 +48,31 @@ QGCGeoBoundingCube::center() const
//-----------------------------------------------------------------------------
QList<QGeoCoordinate>
QGCGeoBoundingCube::polygon2D() const
QGCGeoBoundingCube::polygon2D(double clipTo) const
{
QList<QGeoCoordinate> coords;
if(isValid()) {
coords.append(QGeoCoordinate(pointNW.latitude(), pointNW.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(), pointNW.longitude(), pointSE.altitude()));
coords.append(QGeoCoordinate(pointNW.latitude(), pointNW.longitude(), pointSE.altitude()));
//-- 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(), 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(pointNW.latitude(), pointNW.longitude(), pointSE.altitude()));
}
}
return coords;
}
......@@ -100,7 +117,6 @@ QGCGeoBoundingCube::area() const
return 0.0;
// Area in km^2
double a = (height() / 1000.0) * (width() / 1000.0);
//qDebug() << "Area:" << a;
return a;
}
......
......@@ -64,7 +64,7 @@ public:
}
//-- 2D
QList<QGeoCoordinate> polygon2D() const;
QList<QGeoCoordinate> polygon2D(double clipTo = 0.0) const;
Q_INVOKABLE double width () const;
Q_INVOKABLE double height () const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment