SnakeWorker.cc 7.52 KB
Newer Older
1
#include "SnakeWorker.h"
Valentin Platzgummer's avatar
Valentin Platzgummer committed
2
#include <QGeoCoordinate>
Valentin Platzgummer's avatar
Valentin Platzgummer committed
3
#include <QMutexLocker>
Valentin Platzgummer's avatar
Valentin Platzgummer committed
4 5


Valentin Platzgummer's avatar
Valentin Platzgummer committed
6 7 8
#include "snake.h"


Valentin Platzgummer's avatar
Valentin Platzgummer committed
9 10 11 12 13 14
SnakeDataManager::SnakeDataManager(QObject *parent)
    : QThread(parent)
  , _pScenario(std::make_shared<snake::Scenario>())
  , _pProgress(std::make_shared<std::vector<int>>())
  , _pFlightplan(std::make_shared<snake::Flightplan>(_pScenario, _pProgress))
  , _pData(std::make_shared<SnakeData>())
Valentin Platzgummer's avatar
Valentin Platzgummer committed
15

Valentin Platzgummer's avatar
Valentin Platzgummer committed
16
{
17
}
Valentin Platzgummer's avatar
Valentin Platzgummer committed
18

Valentin Platzgummer's avatar
Valentin Platzgummer committed
19
SnakeDataManager::~SnakeDataManager()
20
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
21 22 23

}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
24
SnakeDataManager::SnakeDataPtr SnakeDataManager::snakeData()
Valentin Platzgummer's avatar
Valentin Platzgummer committed
25
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
26
    return _pData;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
27 28
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
29
bool SnakeDataManager::precondition() const
Valentin Platzgummer's avatar
Valentin Platzgummer committed
30 31
{

Valentin Platzgummer's avatar
Valentin Platzgummer committed
32 33 34
    return _mArea.size() > 0
            && _sArea.size() > 0
            && _corridor.size() > 0
Valentin Platzgummer's avatar
Valentin Platzgummer committed
35
            && _pProgress->size() > 0;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
36 37
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
38
double SnakeDataManager::lineDistance() const
39
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
40
    _pFlightplan->lineDistance();
41 42
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
43
void SnakeDataManager::run()
Valentin Platzgummer's avatar
Valentin Platzgummer committed
44
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
45 46 47 48
    {
        QMutexLocker lk(&_pData->m);
        _pData->clear();
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
49

Valentin Platzgummer's avatar
Valentin Platzgummer committed
50
    if ( !precondition() )
Valentin Platzgummer's avatar
Valentin Platzgummer committed
51 52
        return;

Valentin Platzgummer's avatar
Valentin Platzgummer committed
53 54 55 56 57
    if ( _mArea.size() <= 0
         || _sArea.size() <= 0
         || _corridor.size() <= 0 ){
        QMutexLocker lk(&_pData->m);
        _pData->errorMessage = "At least one area invald. Size < 1.";
Valentin Platzgummer's avatar
Valentin Platzgummer committed
58 59
    }

Valentin Platzgummer's avatar
Valentin Platzgummer committed
60 61 62 63 64 65 66 67 68 69 70 71
    auto origin = _mArea.front();
    // Measurement area update necessary.
    if ( _mArea.size() != _pScenario->measurementArea().outer().size() ){
        {
            QMutexLocker lk(&_pData->m);
            _pData->ENUorigin = origin;
        }
        for (auto geoVertex : _mArea){
            snake::BoostPoint p;
            snake::toENU(origin, geoVertex, p);
            _pScenario->measurementArea().outer().push_back(p);
        }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
72 73
    }

Valentin Platzgummer's avatar
Valentin Platzgummer committed
74 75 76 77 78 79 80
    // Service area update necessary.
    if ( _sArea.size() != _pScenario->serviceArea().outer().size() ){
        for (auto geoVertex : _sArea){
            snake::BoostPoint p;
            snake::toENU(origin, geoVertex, p);
            _pScenario->serviceArea().outer().push_back(p);
        }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
81 82
    }

Valentin Platzgummer's avatar
Valentin Platzgummer committed
83 84 85 86 87 88 89 90
    // Service area update necessary.
    if ( _corridor.size() != _pScenario->corridor().outer().size() ){
        for (auto geoVertex : _corridor){
            snake::BoostPoint p;
            snake::toENU(origin, geoVertex, p);
            _pScenario->corridor().outer().push_back(p);
        }
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
91

Valentin Platzgummer's avatar
Valentin Platzgummer committed
92 93 94 95 96 97 98
    if ( !_pScenario->update() ){
        {
            QMutexLocker lk(&_pData->m);
            for (auto c : _pScenario->errorString){
                _pData->errorMessage.push_back(QChar(c));
            }
        }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
99
        return;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
100
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
101

Valentin Platzgummer's avatar
Valentin Platzgummer committed
102 103
    // Asynchronously update flightplan.
    auto future = std::async(std::bind(&snake::Flightplan::update, _pFlightplan));
Valentin Platzgummer's avatar
Valentin Platzgummer committed
104

Valentin Platzgummer's avatar
Valentin Platzgummer committed
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
    // Continue with storing scenario data in the mean time.
    {
        QMutexLocker lk(&_pData->m);
        // Get tiles.
        const auto &tiles = _pScenario->tiles();
        const auto &centerPoints = _pScenario->tileCenterPoints();
        for ( unsigned int i=0; i < tiles.size(); ++i ) {
            const auto &tile = tiles[i];
            GeoTile     geoTile;
            Polygon2D   enuTile;
            for ( size_t i = tile.outer().size(); i < tile.outer().size()-1; ++i) {
                auto &p = tile.outer()[i];
                QPointF enuVertex(p.get<0>(), p.get<1>(), 0.0);
                QGeoCoordinate geoVertex;
                snake::fromENU(origin, *it, geoVertex);
                enuTile.polygon().push_back(enuVertex);
                geoTile.push_back(QVertex);
            }
            const auto &boostPoint = centerPoints[i];
            QPointF enuVertex(boostPoint.get<0>(), boostPoint.get<1>(), 0.0);
            QGeoCoordinate geoVertex;
            snake::fromENU(origin, enuVertex, geoVertex);
            geoTile.setCenter(geoVertex);
            _pData->tiles.polygons().push_back(geoTile);
            _pData->tileCenterPoints.push_back(QVariant::fromValue(geoVertex));
            _pData->tilesENU.polygons().push_back(enuTile);
            _pData->tileCenterPointsENU.push_back(enuVertex);
         }
    }

    future.wait();
Valentin Platzgummer's avatar
Valentin Platzgummer committed
136
    // Trying to generate flight plan.
Valentin Platzgummer's avatar
Valentin Platzgummer committed
137
    if ( !future.get() ){
Valentin Platzgummer's avatar
Valentin Platzgummer committed
138
        // error
Valentin Platzgummer's avatar
Valentin Platzgummer committed
139 140 141
        QMutexLocker lk(&_pData->m);
        for (auto c : _pFlightplan->errorString){
            _pData->errorMessage.push_back(QChar(c));
Valentin Platzgummer's avatar
Valentin Platzgummer committed
142 143 144
        }
    } else {
        //success!!!
Valentin Platzgummer's avatar
Valentin Platzgummer committed
145 146 147 148 149 150 151 152
        QMutexLocker lk(&_pData->m);
        // Store waypoints.
        for (auto boostVertex : _pFlightplan->waypoints()){
            QPointF enuVertex{boostVertex.get<0>(), boostVertex.get<1>(), 0.0};
            QGeoCoordinate geoVertex;
            snake::fromENU(origin, enuVertex, geoVertex);
            _pData->waypointsENU.push_back(enuVertex);
            _pData->waypoints.push_back(geoVertex);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
153
        }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
154 155 156 157 158 159 160
        // Store arrival path.
        for (auto boostVertex : _pFlightplan->arrivalPath()){
            QPointF enuVertex{boostVertex.get<0>(), boostVertex.get<1>(), 0.0};
            QGeoCoordinate geoVertex;
            snake::fromENU(origin, enuVertex, geoVertex);
            _pData->arrivalPathENU.push_back(enuVertex);
            _pData->arrivalPath.push_back(geoVertex);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
161
        }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
162 163 164 165 166 167 168
        // Store return path.
        for (auto boostVertex : _pFlightplan->returnPath()){
            QPointF enuVertex{boostVertex.get<0>(), boostVertex.get<1>(), 0.0};
            QGeoCoordinate geoVertex;
            snake::fromENU(origin, enuVertex, geoVertex);
            _pData->returnPathENU.push_back(enuVertex);
            _pData->returnPath.push_back(geoVertex);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
169 170 171
        }
    }
}
Valentin Platzgummer's avatar
Valentin Platzgummer committed
172

Valentin Platzgummer's avatar
Valentin Platzgummer committed
173
double SnakeDataManager::minTransectLength() const
Valentin Platzgummer's avatar
Valentin Platzgummer committed
174
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
175
    return _pFlightplan->minTransectLength();
Valentin Platzgummer's avatar
Valentin Platzgummer committed
176 177
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
178
void SnakeDataManager::setMinTransectLength(double minTransectLength)
Valentin Platzgummer's avatar
Valentin Platzgummer committed
179
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
180
    _pFlightplan->setMinTransectLength(minTransectLength);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
181 182
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
183
double SnakeDataManager::minTileArea() const
Valentin Platzgummer's avatar
Valentin Platzgummer committed
184
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
185
    return _pScenario->minTileArea();
Valentin Platzgummer's avatar
Valentin Platzgummer committed
186 187
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
188
void SnakeDataManager::setLineDistance(double lineDistance)
Valentin Platzgummer's avatar
Valentin Platzgummer committed
189
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
190
    _pFlightplan->setLineDistance(lineDistance);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
191 192
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
193
double SnakeDataManager::tileWidth() const
Valentin Platzgummer's avatar
Valentin Platzgummer committed
194
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
195
    return _pScenario->tileWidth();
Valentin Platzgummer's avatar
Valentin Platzgummer committed
196 197
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
198
void SnakeDataManager::setTileWidth(double tileWidth)
Valentin Platzgummer's avatar
Valentin Platzgummer committed
199
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
200
    _pScenario->setTileWidth(tileWidth);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
201 202
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
203
double SnakeDataManager::tileHeight() const
Valentin Platzgummer's avatar
Valentin Platzgummer committed
204
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
205
    return _pScenario->_tileHeight();
Valentin Platzgummer's avatar
Valentin Platzgummer committed
206 207
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
208
void SnakeDataManager::setTileHeight(double tileHeight)
Valentin Platzgummer's avatar
Valentin Platzgummer committed
209
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
210
    _pScenario->setTileHeight(tileHeight);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
211 212
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
213
void SnakeDataManager::setMinTileArea(double minTileArea)
Valentin Platzgummer's avatar
Valentin Platzgummer committed
214
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
215
    _pScenario->setMinTileArea(minTileArea);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
216 217
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
218 219 220 221 222 223
SnakeData::SnakeData()
{

}

void SnakeData::clear()
Valentin Platzgummer's avatar
Valentin Platzgummer committed
224 225
{
    this->waypoints.clear();
Valentin Platzgummer's avatar
Valentin Platzgummer committed
226 227
    this->arrivalPath.clear();
    this->returnPath.clear();
Valentin Platzgummer's avatar
Valentin Platzgummer committed
228 229 230
    this->tiles.polygons().clear();
    this->tilesLocal.polygons().clear();
    this->tileCenterPoints.clear();
Valentin Platzgummer's avatar
Valentin Platzgummer committed
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
    this->waypointsENU.clear();
    this->arrivalPathENU.clear();
    this->returnPathENU.clear();
    this->tilesENU.polygons().clear();
    this->tileCenterPoints.clear();
    this->errorMessage = "";
}

void SnakeDataManager::setCorridor(const QList<QGeoCoordinate> &corridor)
{
    _corridor.clear();
    _pScenario->corridor().clear();
    for (auto vertex : corridor) {
        _corridor.push_back(vertex);
    }
}

void SnakeDataManager::setProgress(const QList<IntType> &progress)
{
    _pProgress->clear();
    for (auto p : progress) {
        assert(p >= -1 && p <= 100);
        _pProgress->push_back(p);
    }
}

void SnakeDataManager::setServiceArea(const QList<QGeoCoordinate> &serviceArea)
{
    _sArea.clear();
    _pScenario->serviceArea().clear();
    for (auto vertex : serviceArea) {
        _sArea.push_back(vertex);
    }
}

void SnakeDataManager::setMeasurementArea(const QList<QGeoCoordinate> &measurementArea)
{
    _mArea.clear();
    _pScenario->measurementArea().clear();
    for (auto vertex : measurementArea) {
        _mArea.push_back(vertex);
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
273
}