AirMapAdvisoryManager.cc 4.37 KB
Newer Older
Gus Grubba's avatar
Gus Grubba committed
1 2 3 4 5 6 7 8 9
/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

Gus Grubba's avatar
Gus Grubba committed
10
#include "AirMapAdvisoryManager.h"
11
#include "AirspaceRestriction.h"
Gus Grubba's avatar
Gus Grubba committed
12 13
#include "AirMapManager.h"

14 15 16 17
#include <QTimer>

#include "airmap/airspaces.h"

Gus Grubba's avatar
Gus Grubba committed
18 19 20 21
#define ADVISORY_UPDATE_DISTANCE    500     //-- 500m threshold for updates

using namespace airmap;

Gus Grubba's avatar
Gus Grubba committed
22 23 24 25 26 27 28
//-----------------------------------------------------------------------------
AirMapAdvisory::AirMapAdvisory(QObject* parent)
    : AirspaceAdvisory(parent)
{
}

//-----------------------------------------------------------------------------
Gus Grubba's avatar
Gus Grubba committed
29
AirMapAdvisoryManager::AirMapAdvisoryManager(AirMapSharedState& shared, QObject *parent)
Gus Grubba's avatar
Gus Grubba committed
30 31 32 33 34 35
    : AirspaceAdvisoryProvider(parent)
    , _valid(false)
    , _shared(shared)
{
}

Gus Grubba's avatar
Gus Grubba committed
36
//-----------------------------------------------------------------------------
Gus Grubba's avatar
Gus Grubba committed
37
void
38
AirMapAdvisoryManager::setROI(const QGCGeoBoundingCube& roi)
Gus Grubba's avatar
Gus Grubba committed
39 40
{
    //-- If first time or we've moved more than ADVISORY_UPDATE_DISTANCE, ask for updates.
41 42
    if(!_lastROI.isValid() || _lastROI.pointNW.distanceTo(roi.pointNW) > ADVISORY_UPDATE_DISTANCE || _lastROI.pointSE.distanceTo(roi.pointSE) > ADVISORY_UPDATE_DISTANCE) {
        _lastROI = roi;
43
        _requestAdvisories();
Gus Grubba's avatar
Gus Grubba committed
44 45 46
    }
}

Gus Grubba's avatar
Gus Grubba committed
47 48 49 50 51 52 53
//-----------------------------------------------------------------------------
static bool
adv_sort(QObject* a, QObject* b)
{
    AirMapAdvisory* aa = qobject_cast<AirMapAdvisory*>(a);
    AirMapAdvisory* bb = qobject_cast<AirMapAdvisory*>(b);
    if(!aa || !bb) return false;
Gus Grubba's avatar
Gus Grubba committed
54
    return (int)aa->color() > (int)bb->color();
Gus Grubba's avatar
Gus Grubba committed
55 56 57
}

//-----------------------------------------------------------------------------
Gus Grubba's avatar
Gus Grubba committed
58
void
59
AirMapAdvisoryManager::_requestAdvisories()
Gus Grubba's avatar
Gus Grubba committed
60 61 62 63 64 65 66 67 68
{
    qCDebug(AirMapManagerLog) << "Advisories Request";
    if (!_shared.client()) {
        qCDebug(AirMapManagerLog) << "No AirMap client instance. Not updating Advisories";
        _valid = false;
        emit advisoryChanged();
        return;
    }
    _valid = false;
69
    _advisories.clearAndDeleteContents();
Gus Grubba's avatar
Gus Grubba committed
70
    Status::GetStatus::Parameters params;
71 72
    params.longitude = _lastROI.center().longitude();
    params.latitude  = _lastROI.center().latitude();
73
    params.types     = Airspace::Type::all;
Gus Grubba's avatar
Gus Grubba committed
74
    params.weather   = false;
75 76 77
    double diagonal  = _lastROI.pointNW.distanceTo(_lastROI.pointSE);
    params.buffer    = fmax(fmin(diagonal, 10000.0), 500.0);
    params.flight_date_time = Clock::universal_time();
78 79 80
    std::weak_ptr<LifetimeChecker> isAlive(_instance);
    _shared.client()->status().get_status_by_point(params, [this, isAlive](const Status::GetStatus::Result& result) {
        if (!isAlive.lock()) return;
Gus Grubba's avatar
Gus Grubba committed
81
        if (result) {
Gus Grubba's avatar
Gus Grubba committed
82 83 84 85 86 87 88 89 90
            qCDebug(AirMapManagerLog) << "Successful advisory search. Items:" << result.value().advisories.size();
            _airspaceColor = (AirspaceAdvisoryProvider::AdvisoryColor)(int)result.value().advisory_color;
            const std::vector<Status::Advisory> advisories = result.value().advisories;
            for (const auto& advisory : advisories) {
                AirMapAdvisory* pAdvisory = new AirMapAdvisory(this);
                pAdvisory->_id          = QString::fromStdString(advisory.airspace.id());
                pAdvisory->_name        = QString::fromStdString(advisory.airspace.name());
                pAdvisory->_type        = (AirspaceAdvisory::AdvisoryType)(int)advisory.airspace.type();
                pAdvisory->_color       = (AirspaceAdvisoryProvider::AdvisoryColor)(int)advisory.color;
91
                _advisories.append(pAdvisory);
Gus Grubba's avatar
Gus Grubba committed
92
                qCDebug(AirMapManagerLog) << "Adding advisory" << pAdvisory->name();
Gus Grubba's avatar
Gus Grubba committed
93
            }
Gus Grubba's avatar
Gus Grubba committed
94
            //-- Sort in order of color (priority)
95 96 97
            _advisories.beginReset();
            std::sort(_advisories.objectList()->begin(), _advisories.objectList()->end(), adv_sort);
            _advisories.endReset();
Gus Grubba's avatar
Gus Grubba committed
98
            _valid = true;
Gus Grubba's avatar
Gus Grubba committed
99
        } else {
100 101
            QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : "");
            qCDebug(AirMapManagerLog) << "Advisories Request Failed" << QString::fromStdString(result.error().message()) << description;
Gus Grubba's avatar
Gus Grubba committed
102 103 104 105
        }
        emit advisoryChanged();
    });
}