Newer
Older
#include "CircularSurvey.h"
#include "RoutingThread.h"
#include "JsonHelper.h"
#include "QGCApplication.h"
#include "clipper/clipper.hpp"
#include "Geometry/GenericCircle.h"
#include <boost/units/io.hpp>
#include <boost/units/systems/si.hpp>
QGC_LOGGING_CATEGORY(CircularSurveyLog, "CircularSurveyLog")
using namespace ClipperLib;
template <> auto get<0>(const IntPoint &p) { return p.X; }
template <> auto get<1>(const IntPoint &p) { return p.Y; }
template <class Functor> class CommandRAII {
public:
CommandRAII(Functor f) : fun(f) {}
~CommandRAII() { fun(); }
private:
Functor fun;
};
template <typename T>
constexpr typename std::underlying_type<T>::type integral(T value) {
return static_cast<typename std::underlying_type<T>::type>(value);
}
bool circularTransects(const snake::FPolygon &polygon,
const std::vector<snake::FPolygon> &tiles,
snake::Length deltaR, snake::Angle deltaAlpha,
snake::Length minLength, snake::Transects &transects);
bool linearTransects(const snake::FPolygon &polygon,
const std::vector<snake::FPolygon> &tiles,
snake::Length distance, snake::Angle angle,
snake::Length minLength, snake::Transects &transects);
const char *CircularSurvey::settingsGroup = "CircularSurvey";
const char *CircularSurvey::transectDistanceName = "TransectDistance";
const char *CircularSurvey::alphaName = "Alpha";
const char *CircularSurvey::minLengthName = "MinLength";
const char *CircularSurvey::typeName = "Type";
const char *CircularSurvey::CircularSurveyName = "CircularSurvey";
const char *CircularSurvey::refPointLatitudeName = "ReferencePointLat";
const char *CircularSurvey::refPointLongitudeName = "ReferencePointLong";
const char *CircularSurvey::refPointAltitudeName = "ReferencePointAlt";
const char *CircularSurvey::variantName = "Variant";
const char *CircularSurvey::numRunsName = "NumRuns";
const char *CircularSurvey::runName = "Run";
CircularSurvey::CircularSurvey(Vehicle *vehicle, bool flyView,
const QString &kmlOrShpFile, QObject *parent)
: TransectStyleComplexItem(vehicle, flyView, settingsGroup, parent),
_referencePoint(QGeoCoordinate(0, 0, 0)),
_metaDataMap(FactMetaData::createMapFromJsonFile(
QStringLiteral(":/json/CircularSurvey.SettingsGroup.json"), this)),
_transectDistance(settingsGroup, _metaDataMap[transectDistanceName]),
_alpha(settingsGroup, _metaDataMap[alphaName]),
_minLength(settingsGroup, _metaDataMap[minLengthName]),
_type(settingsGroup, _metaDataMap[typeName]),
_variant(settingsGroup, _metaDataMap[variantName]),
_numRuns(settingsGroup, _metaDataMap[numRunsName]),
_run(settingsGroup, _metaDataMap[runName]),
_pWorker(std::make_unique<RoutingThread>()), _state(STATE::DEFAULT),
_hidePolygon(false) {
Q_UNUSED(kmlOrShpFile)
_editorQml = "qrc:/qml/CircularSurveyItemEditor.qml";
connect(&_transectDistance, &Fact::valueChanged, this,
&CircularSurvey::_rebuildTransects);
&CircularSurvey::_rebuildTransects);
connect(&_minLength, &Fact::valueChanged, this,
&CircularSurvey::_rebuildTransects);
connect(this, &CircularSurvey::refPointChanged, this,
&CircularSurvey::_rebuildTransects);
connect(this, &CircularSurvey::depotChanged, this,
&CircularSurvey::_rebuildTransects);
connect(&this->_type, &Fact::rawValueChanged, this,
&CircularSurvey::_rebuildTransects);
connect(&this->_variant, &Fact::rawValueChanged, this,
&CircularSurvey::_changeVariant);
connect(&this->_run, &Fact::rawValueChanged, this,
&CircularSurvey::_changeRun);
connect(&this->_numRuns, &Fact::rawValueChanged, this,
&CircularSurvey::_rebuildTransects);
// Areas.
connect(this, &CircularSurvey::measurementAreaChanged, this,
&CircularSurvey::_rebuildTransects);
connect(this, &CircularSurvey::joinedAreaChanged, this,
&CircularSurvey::_rebuildTransects);
connect(this->_pWorker.get(), &RoutingThread::result, this,
&CircularSurvey::_setTransects);
connect(this->_pWorker.get(), &RoutingThread::calculatingChanged, this,
&CircularSurvey::calculatingChanged);
// Altitude
connect(&_cameraCalc, &CameraCalc::distanceToSurfaceRelativeChanged, this,
&CircularSurvey::coordinateHasRelativeAltitudeChanged);
connect(&_cameraCalc, &CameraCalc::distanceToSurfaceRelativeChanged, this,
&CircularSurvey::exitCoordinateHasRelativeAltitudeChanged);
CircularSurvey::~CircularSurvey() {}
void CircularSurvey::resetReference() { setRefPoint(_mArea.center()); }
void CircularSurvey::reverse() {
this->_state = STATE::REVERSE;
this->_rebuildTransects();
}
void CircularSurvey::setRefPoint(const QGeoCoordinate &refPt) {
if (refPt != _referencePoint) {
_referencePoint = refPt;
emit refPointChanged();
}
}
QGeoCoordinate CircularSurvey::refPoint() const { return _referencePoint; }
Fact *CircularSurvey::transectDistance() { return &_transectDistance; }
Fact *CircularSurvey::alpha() { return &_alpha; }
bool CircularSurvey::hidePolygon() const { return _hidePolygon; }
QList<QString> CircularSurvey::variantNames() const { return _variantNames; }
QList<QString> CircularSurvey::runNames() const { return _runNames; }
QGeoCoordinate CircularSurvey::depot() const { return this->_depot; }
const QList<QList<QGeoCoordinate>> &CircularSurvey::rawTransects() const {
return this->_rawTransects;
}
void CircularSurvey::setHidePolygon(bool hide) {
if (this->_hidePolygon != hide) {
this->_hidePolygon = hide;
emit hidePolygonChanged();
}
}
void CircularSurvey::setMeasurementArea(const WimaMeasurementAreaData &mArea) {
if (this->_mArea != mArea) {
this->_mArea = mArea;
emit measurementAreaChanged();
}
}
void CircularSurvey::setJoinedArea(const WimaJoinedAreaData &jArea) {
if (this->_jArea != jArea) {
this->_jArea = jArea;
emit joinedAreaChanged();
void CircularSurvey::setMeasurementArea(const WimaMeasurementArea &mArea) {
if (this->_mArea != mArea) {
this->_mArea = mArea;
emit measurementAreaChanged();
}
}
void CircularSurvey::setJoinedArea(const WimaJoinedArea &jArea) {
if (this->_jArea != jArea) {
this->_jArea = jArea;
emit joinedAreaChanged();
void CircularSurvey::setDepot(const QGeoCoordinate &depot) {
if (this->_depot.latitude() != depot.latitude() ||
this->_depot.longitude() != depot.longitude()) {
this->_depot = depot;
this->_depot.setAltitude(0);
emit depotChanged();
}
}
bool CircularSurvey::load(const QJsonObject &complexObject, int sequenceNumber,
Loading
Loading full blame...