/**************************************************************************** * * (c) 2009-2020 QGROUNDCONTROL PROJECT * * QGroundControl is licensed according to the terms in the file * COPYING.md in the root of the source code directory. * ****************************************************************************/ #pragma once #include "MissionItem.h" #include "QGCLoggingCategory.h" #include "SettingsFact.h" #include "TransectStyleComplexItem.h" Q_DECLARE_LOGGING_CATEGORY(SurveyComplexItemLog) class PlanMasterController; class SurveyComplexItem : public TransectStyleComplexItem { Q_OBJECT public: /// @param flyView true: Created for use in the Fly View, false: Created for /// use in the Plan View /// @param kmlOrShpFile Polygon comes from this file, empty for default /// polygon SurveyComplexItem(PlanMasterController *masterController, bool flyView, const QString &kmlOrShpFile, QObject *parent); Q_PROPERTY(Fact *gridAngle READ gridAngle CONSTANT) Q_PROPERTY(Fact *flyAlternateTransects READ flyAlternateTransects CONSTANT) Q_PROPERTY(Fact *splitConcavePolygons READ splitConcavePolygons CONSTANT) Fact *gridAngle(void) { return &_gridAngleFact; } Fact *flyAlternateTransects(void) { return &_flyAlternateTransectsFact; } Fact *splitConcavePolygons(void) { return &_splitConcavePolygonsFact; } Q_INVOKABLE void rotateEntryPoint(void); // Overrides from ComplexMissionItem QString patternName(void) const final { return name; } bool load(const QJsonObject &complexObject, int sequenceNumber, QString &errorString) final; QString mapVisualQML(void) const final { return QStringLiteral("SurveyMapVisual.qml"); } QString presetsSettingsGroup(void) { return settingsGroup; } void savePreset(const QString &name); void loadPreset(const QString &name); // Overrides from TransectStyleComplexItem void save(QJsonObject &planItems) final; bool specifiesCoordinate(void) const final { return true; } double timeBetweenShots(void) final; // Overrides from VisualMissionionItem QString commandDescription(void) const final { return tr("Survey"); } QString commandName(void) const final { return tr("Survey"); } QString abbreviation(void) const final { return tr("S"); } ReadyForSaveState readyForSaveState(void) const final; double additionalTimeDelay(void) const final; // Must match json spec for GridEntryLocation enum EntryLocation { EntryLocationFirst, EntryLocationTopLeft = EntryLocationFirst, EntryLocationTopRight, EntryLocationBottomLeft, EntryLocationBottomRight, EntryLocationLast = EntryLocationBottomRight }; static const QString name; static const char *jsonComplexItemTypeValue; static const char *settingsGroup; static const char *gridAngleName; static const char *gridEntryLocationName; static const char *flyAlternateTransectsName; static const char *splitConcavePolygonsName; static const char *jsonV3ComplexItemTypeValue; signals: void refly90DegreesChanged(bool refly90Degrees); private slots: void _updateWizardMode(void); // Overrides from TransectStyleComplexItem void _rebuildTransectsPhase1(void) final; void _recalcCameraShots(void) final; private: enum CameraTriggerCode { CameraTriggerNone, CameraTriggerOn, CameraTriggerOff, CameraTriggerHoverAndCapture }; QPointF _rotatePoint(const QPointF &point, const QPointF &origin, double angle); void _intersectLinesWithRect(const QList &lineList, const QRectF &boundRect, QList &resultLines); void _intersectLinesWithPolygon(const QList &lineList, const QPolygonF &polygon, QList &resultLines); void _adjustLineDirection(const QList &lineList, QList &resultLines); bool _nextTransectCoord(const QList &transectPoints, int pointIndex, QGeoCoordinate &coord); bool _appendMissionItemsWorker(QList &items, QObject *missionItemParent, int &seqNum, bool hasRefly, bool buildRefly); void _optimizeTransectsForShortestDistance( const QGeoCoordinate &distanceCoord, QList> &transects); qreal _ccw(QPointF pt1, QPointF pt2, QPointF pt3); qreal _dp(QPointF pt1, QPointF pt2); void _swapPoints(QList &points, int index1, int index2); void _reverseTransectOrder(QList> &transects); void _reverseInternalTransectPoints(QList> &transects); void _adjustTransectsToEntryPointLocation(QList> &transects); bool _gridAngleIsNorthSouthTransects(); double _clampGridAngle90(double gridAngle); bool _imagesEverywhere(void) const; bool _triggerCamera(void) const; bool _hasTurnaround(void) const; double _turnaroundDistance(void) const; bool _hoverAndCaptureEnabled(void) const; bool _loadV3(const QJsonObject &complexObject, int sequenceNumber, QString &errorString); bool _loadV4V5(const QJsonObject &complexObject, int sequenceNumber, QString &errorString, int version, bool forPresets); void _saveWorker(QJsonObject &complexObject); void _rebuildTransectsPhase1Worker(bool refly); void _rebuildTransectsPhase1WorkerSinglePolygon(bool refly); void _rebuildTransectsPhase1WorkerSplitPolygons(bool refly); /// Adds to the _transects array from one polygon void _rebuildTransectsFromPolygon(bool refly, const QPolygonF &polygon, const QGeoCoordinate &tangentOrigin, const QPointF *const transitionPoint); // Decompose polygon into list of convex sub polygons void _PolygonDecomposeConvex(const QPolygonF &polygon, QList &decomposedPolygons); // return true if vertex a can see vertex b bool _VertexCanSeeOther(const QPolygonF &polygon, const QPointF *vertexA, const QPointF *vertexB); bool _VertexIsReflex(const QPolygonF &polygon, const QPointF *vertex); QMap _metaDataMap; SettingsFact _gridAngleFact; SettingsFact _flyAlternateTransectsFact; SettingsFact _splitConcavePolygonsFact; int _entryPoint; static const char *_jsonGridAngleKey; static const char *_jsonEntryPointKey; static const char *_jsonFlyAlternateTransectsKey; static const char *_jsonSplitConcavePolygonsKey; static const char *_jsonV3GridObjectKey; static const char *_jsonV3GridAltitudeKey; static const char *_jsonV3GridAltitudeRelativeKey; static const char *_jsonV3GridAngleKey; static const char *_jsonV3GridSpacingKey; static const char *_jsonV3EntryPointKey; static const char *_jsonV3TurnaroundDistKey; static const char *_jsonV3CameraTriggerDistanceKey; static const char *_jsonV3CameraTriggerInTurnaroundKey; static const char *_jsonV3HoverAndCaptureKey; static const char *_jsonV3GroundResolutionKey; static const char *_jsonV3FrontalOverlapKey; static const char *_jsonV3SideOverlapKey; static const char *_jsonV3CameraSensorWidthKey; static const char *_jsonV3CameraSensorHeightKey; static const char *_jsonV3CameraResolutionWidthKey; static const char *_jsonV3CameraResolutionHeightKey; static const char *_jsonV3CameraFocalLengthKey; static const char *_jsonV3CameraMinTriggerIntervalKey; static const char *_jsonV3ManualGridKey; static const char *_jsonV3CameraObjectKey; static const char *_jsonV3CameraNameKey; static const char *_jsonV3CameraOrientationLandscapeKey; static const char *_jsonV3FixedValueIsAltitudeKey; static const char *_jsonV3Refly90DegreesKey; };