Commit 8498d36e authored by DonLakeFlyer's avatar DonLakeFlyer

Support survey polygon drag

parent 950ee021
...@@ -384,7 +384,7 @@ DebugBuild { PX4FirmwarePlugin { PX4FirmwarePluginFactory { APMFirmwarePlugin { ...@@ -384,7 +384,7 @@ DebugBuild { PX4FirmwarePlugin { PX4FirmwarePluginFactory { APMFirmwarePlugin {
src/FactSystem/FactSystemTestGeneric.h \ src/FactSystem/FactSystemTestGeneric.h \
src/FactSystem/FactSystemTestPX4.h \ src/FactSystem/FactSystemTestPX4.h \
src/FactSystem/ParameterManagerTest.h \ src/FactSystem/ParameterManagerTest.h \
src/MissionManager/ComplexMissionItemTest.h \ src/MissionManager/SurveyMissionItemTest.h \
src/MissionManager/MissionCommandTreeTest.h \ src/MissionManager/MissionCommandTreeTest.h \
src/MissionManager/MissionControllerManagerTest.h \ src/MissionManager/MissionControllerManagerTest.h \
src/MissionManager/MissionControllerTest.h \ src/MissionManager/MissionControllerTest.h \
...@@ -412,7 +412,7 @@ DebugBuild { PX4FirmwarePlugin { PX4FirmwarePluginFactory { APMFirmwarePlugin { ...@@ -412,7 +412,7 @@ DebugBuild { PX4FirmwarePlugin { PX4FirmwarePluginFactory { APMFirmwarePlugin {
src/FactSystem/FactSystemTestGeneric.cc \ src/FactSystem/FactSystemTestGeneric.cc \
src/FactSystem/FactSystemTestPX4.cc \ src/FactSystem/FactSystemTestPX4.cc \
src/FactSystem/ParameterManagerTest.cc \ src/FactSystem/ParameterManagerTest.cc \
src/MissionManager/ComplexMissionItemTest.cc \ src/MissionManager/SurveyMissionItemTest.cc \
src/MissionManager/MissionCommandTreeTest.cc \ src/MissionManager/MissionCommandTreeTest.cc \
src/MissionManager/MissionControllerManagerTest.cc \ src/MissionManager/MissionControllerManagerTest.cc \
src/MissionManager/MissionControllerTest.cc \ src/MissionManager/MissionControllerTest.cc \
......
...@@ -85,6 +85,7 @@ ...@@ -85,6 +85,7 @@
<file alias="QGroundControl/Controls/QGCLabel.qml">src/QmlControls/QGCLabel.qml</file> <file alias="QGroundControl/Controls/QGCLabel.qml">src/QmlControls/QGCLabel.qml</file>
<file alias="QGroundControl/Controls/QGCListView.qml">src/QmlControls/QGCListView.qml</file> <file alias="QGroundControl/Controls/QGCListView.qml">src/QmlControls/QGCListView.qml</file>
<file alias="QGroundControl/Controls/QGCMapLabel.qml">src/QmlControls/QGCMapLabel.qml</file> <file alias="QGroundControl/Controls/QGCMapLabel.qml">src/QmlControls/QGCMapLabel.qml</file>
<file alias="QGroundControl/Controls/QGCMapPolygonVisuals.qml">src/MissionManager/QGCMapPolygonVisuals.qml</file>
<file alias="QGroundControl/Controls/QGCMouseArea.qml">src/QmlControls/QGCMouseArea.qml</file> <file alias="QGroundControl/Controls/QGCMouseArea.qml">src/QmlControls/QGCMouseArea.qml</file>
<file alias="QGroundControl/Controls/QGCMovableItem.qml">src/QmlControls/QGCMovableItem.qml</file> <file alias="QGroundControl/Controls/QGCMovableItem.qml">src/QmlControls/QGCMovableItem.qml</file>
<file alias="QGroundControl/Controls/QGCPipable.qml">src/QmlControls/QGCPipable.qml</file> <file alias="QGroundControl/Controls/QGCPipable.qml">src/QmlControls/QGCPipable.qml</file>
......
...@@ -16,15 +16,17 @@ ...@@ -16,15 +16,17 @@
#include <QDebug> #include <QDebug>
#include <QJsonArray> #include <QJsonArray>
const char* QGCMapPolygon::_jsonPolygonKey = "polygon"; const char* QGCMapPolygon::jsonPolygonKey = "polygon";
QGCMapPolygon::QGCMapPolygon(QObject* newCoordParent, QObject* parent) QGCMapPolygon::QGCMapPolygon(QObject* newCoordParent, QObject* parent)
: QObject(parent) : QObject(parent)
, _newCoordParent(newCoordParent) , _newCoordParent(newCoordParent)
, _dirty(false) , _dirty(false)
, _ignoreCenterUpdates(false)
{ {
connect(&_polygonModel, &QmlObjectListModel::dirtyChanged, this, &QGCMapPolygon::_polygonModelDirtyChanged); connect(&_polygonModel, &QmlObjectListModel::dirtyChanged, this, &QGCMapPolygon::_polygonModelDirtyChanged);
connect(&_polygonModel, &QmlObjectListModel::countChanged, this, &QGCMapPolygon::_polygonModelCountChanged); connect(&_polygonModel, &QmlObjectListModel::countChanged, this, &QGCMapPolygon::_polygonModelCountChanged);
connect(&_polygonModel, &QmlObjectListModel::countChanged, this, &QGCMapPolygon::_updateCenter);
} }
void QGCMapPolygon::clear(void) void QGCMapPolygon::clear(void)
...@@ -43,6 +45,8 @@ void QGCMapPolygon::clear(void) ...@@ -43,6 +45,8 @@ void QGCMapPolygon::clear(void)
_polygonModel.clearAndDeleteContents(); _polygonModel.clearAndDeleteContents();
emit cleared();
setDirty(true); setDirty(true);
} }
...@@ -53,6 +57,10 @@ void QGCMapPolygon::adjustVertex(int vertexIndex, const QGeoCoordinate coordinat ...@@ -53,6 +57,10 @@ void QGCMapPolygon::adjustVertex(int vertexIndex, const QGeoCoordinate coordinat
_polygonModel.value<QGCQGeoCoordinate*>(vertexIndex)->setCoordinate(coordinate); _polygonModel.value<QGCQGeoCoordinate*>(vertexIndex)->setCoordinate(coordinate);
if (!_ignoreCenterUpdates) {
_updateCenter();
}
setDirty(true); setDirty(true);
} }
...@@ -111,16 +119,6 @@ bool QGCMapPolygon::containsCoordinate(const QGeoCoordinate& coordinate) const ...@@ -111,16 +119,6 @@ bool QGCMapPolygon::containsCoordinate(const QGeoCoordinate& coordinate) const
} }
} }
QGeoCoordinate QGCMapPolygon::center(void) const
{
if (_polygonPath.count() > 2) {
QPointF centerPoint = _toPolygonF().boundingRect().center();
return _coordFromPointF(centerPoint);
} else {
return QGeoCoordinate();
}
}
void QGCMapPolygon::setPath(const QList<QGeoCoordinate>& path) void QGCMapPolygon::setPath(const QList<QGeoCoordinate>& path)
{ {
_polygonPath.clear(); _polygonPath.clear();
...@@ -152,7 +150,7 @@ void QGCMapPolygon::saveToJson(QJsonObject& json) ...@@ -152,7 +150,7 @@ void QGCMapPolygon::saveToJson(QJsonObject& json)
QJsonValue jsonValue; QJsonValue jsonValue;
JsonHelper::saveGeoCoordinateArray(_polygonPath, false /* writeAltitude*/, jsonValue); JsonHelper::saveGeoCoordinateArray(_polygonPath, false /* writeAltitude*/, jsonValue);
json.insert(_jsonPolygonKey, jsonValue); json.insert(jsonPolygonKey, jsonValue);
setDirty(false); setDirty(false);
} }
...@@ -162,14 +160,14 @@ bool QGCMapPolygon::loadFromJson(const QJsonObject& json, bool required, QString ...@@ -162,14 +160,14 @@ bool QGCMapPolygon::loadFromJson(const QJsonObject& json, bool required, QString
clear(); clear();
if (required) { if (required) {
if (!JsonHelper::validateRequiredKeys(json, QStringList(_jsonPolygonKey), errorString)) { if (!JsonHelper::validateRequiredKeys(json, QStringList(jsonPolygonKey), errorString)) {
return false; return false;
} }
} else if (!json.contains(_jsonPolygonKey)) { } else if (!json.contains(jsonPolygonKey)) {
return true; return true;
} }
if (!JsonHelper::loadGeoCoordinateArray(json[_jsonPolygonKey], false /* altitudeRequired */, _polygonPath, errorString)) { if (!JsonHelper::loadGeoCoordinateArray(json[jsonPolygonKey], false /* altitudeRequired */, _polygonPath, errorString)) {
return false; return false;
} }
setDirty(false); setDirty(false);
...@@ -249,3 +247,38 @@ void QGCMapPolygon::_polygonModelCountChanged(int count) ...@@ -249,3 +247,38 @@ void QGCMapPolygon::_polygonModelCountChanged(int count)
{ {
emit countChanged(count); emit countChanged(count);
} }
void QGCMapPolygon::_updateCenter(void)
{
if (!_ignoreCenterUpdates) {
QGeoCoordinate center;
if (_polygonPath.count() > 2) {
QPointF centerPoint = _toPolygonF().boundingRect().center();
center = _coordFromPointF(centerPoint);
}
_center = center;
emit centerChanged(center);
}
}
void QGCMapPolygon::setCenter(QGeoCoordinate newCenter)
{
if (newCenter != _center) {
_ignoreCenterUpdates = true;
// Adjust polygon vertices to new center
double distance = _center.distanceTo(newCenter);
double azimuth = _center.azimuthTo(newCenter);
for (int i=0; i<count(); i++) {
QGeoCoordinate oldVertex = _polygonPath[i].value<QGeoCoordinate>();
QGeoCoordinate newVertex = oldVertex.atDistanceAndAzimuth(distance, azimuth);
adjustVertex(i, newVertex);
}
_ignoreCenterUpdates = false;
_updateCenter();
}
}
...@@ -26,10 +26,11 @@ class QGCMapPolygon : public QObject ...@@ -26,10 +26,11 @@ class QGCMapPolygon : public QObject
public: public:
QGCMapPolygon(QObject* newCoordParent, QObject* parent = NULL); QGCMapPolygon(QObject* newCoordParent, QObject* parent = NULL);
Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(QVariantList path READ path NOTIFY pathChanged) Q_PROPERTY(QVariantList path READ path NOTIFY pathChanged)
Q_PROPERTY(QmlObjectListModel* pathModel READ qmlPathModel CONSTANT) Q_PROPERTY(QmlObjectListModel* pathModel READ qmlPathModel CONSTANT)
Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged) Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged)
Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged)
Q_INVOKABLE void clear(void); Q_INVOKABLE void clear(void);
Q_INVOKABLE void appendVertex(const QGeoCoordinate& coordinate); Q_INVOKABLE void appendVertex(const QGeoCoordinate& coordinate);
...@@ -43,9 +44,6 @@ public: ...@@ -43,9 +44,6 @@ public:
/// Splits the segment comprised of vertextIndex -> vertexIndex + 1 /// Splits the segment comprised of vertextIndex -> vertexIndex + 1
Q_INVOKABLE void splitPolygonSegment(int vertexIndex); Q_INVOKABLE void splitPolygonSegment(int vertexIndex);
/// Returns the center point coordinate for the polygon
Q_INVOKABLE QGeoCoordinate center(void) const;
/// Returns true if the specified coordinate is within the polygon /// Returns true if the specified coordinate is within the polygon
Q_INVOKABLE bool containsCoordinate(const QGeoCoordinate& coordinate) const; Q_INVOKABLE bool containsCoordinate(const QGeoCoordinate& coordinate) const;
...@@ -65,9 +63,11 @@ public: ...@@ -65,9 +63,11 @@ public:
// Property methods // Property methods
int count (void) const { return _polygonPath.count(); } int count (void) const { return _polygonPath.count(); }
bool dirty (void) const { return _dirty; } bool dirty (void) const { return _dirty; }
void setDirty(bool dirty); void setDirty(bool dirty);
QGeoCoordinate center (void) const { return _center; }
QVariantList path (void) const { return _polygonPath; } QVariantList path (void) const { return _polygonPath; }
QmlObjectListModel* qmlPathModel(void) { return &_polygonModel; } QmlObjectListModel* qmlPathModel(void) { return &_polygonModel; }
...@@ -75,15 +75,21 @@ public: ...@@ -75,15 +75,21 @@ public:
void setPath(const QList<QGeoCoordinate>& path); void setPath(const QList<QGeoCoordinate>& path);
void setPath(const QVariantList& path); void setPath(const QVariantList& path);
void setCenter(QGeoCoordinate newCenter);
static const char* jsonPolygonKey;
signals: signals:
void countChanged(int count); void countChanged (int count);
void pathChanged(void); void pathChanged (void);
void dirtyChanged(bool dirty); void dirtyChanged (bool dirty);
void cleared (void);
void centerChanged (QGeoCoordinate center);
private slots: private slots:
void _polygonModelCountChanged(int count); void _polygonModelCountChanged(int count);
void _polygonModelDirtyChanged(bool dirty); void _polygonModelDirtyChanged(bool dirty);
void _updateCenter(void);
private: private:
QPolygonF _toPolygonF(void) const; QPolygonF _toPolygonF(void) const;
...@@ -94,8 +100,8 @@ private: ...@@ -94,8 +100,8 @@ private:
QVariantList _polygonPath; QVariantList _polygonPath;
QmlObjectListModel _polygonModel; QmlObjectListModel _polygonModel;
bool _dirty; bool _dirty;
QGeoCoordinate _center;
static const char* _jsonPolygonKey; bool _ignoreCenterUpdates;
}; };
#endif #endif
/****************************************************************************
*
* (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.
*
****************************************************************************/
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtLocation 5.3
import QtPositioning 5.3
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FlightMap 1.0
/// QGCMapPolygon map visuals
Item {
id: _root
property var mapControl ///< Map control to place item in
property var mapPolygon ///< QGCMapPolygon object
property var _polygonComponent
property var _dragHandlesComponent
property var _splitHandlesComponent
property var _centerDragHandleComponent
function addVisuals() {
_polygonComponent = polygonComponent.createObject(mapControl)
mapControl.addMapItem(_polygonComponent)
}
function removeVisuals() {
_polygonComponent.destroy()
}
function addHandles() {
_dragHandlesComponent = dragHandlesComponent.createObject(mapControl)
_splitHandlesComponent = splitHandlesComponent.createObject(mapControl)
_centerDragHandleComponent = centerDragHandleComponent.createObject(mapControl)
}
function removeHandles() {
if (_dragHandlesComponent) {
_dragHandlesComponent.destroy()
_dragHandlesComponent = undefined
}
if (_splitHandlesComponent) {
_splitHandlesComponent.destroy()
_splitHandlesComponent = undefined
}
if (_centerDragHandleComponent) {
_centerDragHandleComponent.destroy()
_centerDragHandleComponent = undefined
}
}
Component.onDestruction: {
removeVisuals()
removeHandles()
}
Component {
id: polygonComponent
MapPolygon {
color: "green"
opacity: 0.5
path: mapPolygon.path
}
}
Component {
id: splitHandleComponent
MapQuickItem {
id: mapQuickItem
anchorPoint.x: dragHandle.width / 2
anchorPoint.y: dragHandle.height / 2
z: QGroundControl.zOrderMapItems + 1
property int vertexIndex
sourceItem: Rectangle {
id: dragHandle
width: ScreenTools.defaultFontPixelHeight * 1.5
height: width
radius: width / 2
color: "white"
opacity: .50
QGCLabel {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text: "+"
}
QGCMouseArea {
fillItem: parent
onClicked: mapPolygon.splitPolygonSegment(mapQuickItem.vertexIndex)
}
}
}
}
Component {
id: splitHandlesComponent
Repeater {
model: mapPolygon.path
delegate: Item {
property var _splitHandle
property var _vertices: mapPolygon.path
function _setHandlePosition() {
var nextIndex = index + 1
if (nextIndex > _vertices.length - 1) {
nextIndex = 0
}
var distance = _vertices[index].distanceTo(_vertices[nextIndex])
var azimuth = _vertices[index].azimuthTo(_vertices[nextIndex])
_splitHandle.coordinate = _vertices[index].atDistanceAndAzimuth(distance / 2, azimuth)
}
Component.onCompleted: {
_splitHandle = splitHandleComponent.createObject(mapControl)
_splitHandle.vertexIndex = index
_setHandlePosition()
mapControl.addMapItem(_splitHandle)
}
Component.onDestruction: {
if (_splitHandle) {
_splitHandle.destroy()
}
}
}
}
}
// Control which is used to drag polygon vertices
Component {
id: dragAreaComponent
MissionItemIndicatorDrag {
id: dragArea
property int polygonVertex
property bool _creationComplete: false
Component.onCompleted: _creationComplete = true
onItemCoordinateChanged: {
if (_creationComplete) {
// During component creation some bad coordinate values got through which screws up polygon draw
mapPolygon.adjustVertex(polygonVertex, itemCoordinate)
}
}
onClicked: mapPolygon.removeVertex(polygonVertex)
}
}
Component {
id: dragHandleComponent
MapQuickItem {
id: mapQuickItem
anchorPoint.x: dragHandle.width / 2
anchorPoint.y: dragHandle.height / 2
z: QGroundControl.zOrderMapItems + 2
sourceItem: Rectangle {
id: dragHandle
width: ScreenTools.defaultFontPixelHeight * 1.5
height: width
radius: width / 2
color: "white"
opacity: .90
}
}
}
// Add all polygon vertex drag handles to the map
Component {
id: dragHandlesComponent
Repeater {
model: mapPolygon.pathModel
delegate: Item {
property var _visuals: [ ]
Component.onCompleted: {
var dragHandle = dragHandleComponent.createObject(mapControl)
dragHandle.coordinate = Qt.binding(function() { return object.coordinate })
mapControl.addMapItem(dragHandle)
var dragArea = dragAreaComponent.createObject(mapControl, { "itemIndicator": dragHandle, "itemCoordinate": object.coordinate })
dragArea.polygonVertex = Qt.binding(function() { return index })
_visuals.push(dragHandle)
_visuals.push(dragArea)
}
Component.onDestruction: {
for (var i=0; i<_visuals.length; i++) {
_visuals[i].destroy()
}
_visuals = [ ]
}
}
}
}
Component {
id: centerDragAreaComponent
MissionItemIndicatorDrag {
onItemCoordinateChanged: mapPolygon.center = itemCoordinate
}
}
Component {
id: centerDragHandleComponent
Item {
property var dragHandle
property var dragArea
Component.onCompleted: {
dragHandle = dragHandleComponent.createObject(mapControl)
dragHandle.coordinate = Qt.binding(function() { return mapPolygon.center })
mapControl.addMapItem(dragHandle)
dragArea = centerDragAreaComponent.createObject(mapControl, { "itemIndicator": dragHandle, "itemCoordinate": mapPolygon.center })
}
Component.onDestruction: {
dragHandle.destroy()
dragArea.destroy()
}
}
}
}
This diff is collapsed.
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "MissionItem.h" #include "MissionItem.h"
#include "SettingsFact.h" #include "SettingsFact.h"
#include "QGCLoggingCategory.h" #include "QGCLoggingCategory.h"
#include "QGCMapPolygon.h"
Q_DECLARE_LOGGING_CATEGORY(SurveyMissionItemLog) Q_DECLARE_LOGGING_CATEGORY(SurveyMissionItemLog)
...@@ -52,25 +53,18 @@ public: ...@@ -52,25 +53,18 @@ public:
Q_PROPERTY(bool refly90Degrees READ refly90Degrees WRITE setRefly90Degrees NOTIFY refly90DegreesChanged) Q_PROPERTY(bool refly90Degrees READ refly90Degrees WRITE setRefly90Degrees NOTIFY refly90DegreesChanged)
Q_PROPERTY(double timeBetweenShots READ timeBetweenShots NOTIFY timeBetweenShotsChanged) Q_PROPERTY(double timeBetweenShots READ timeBetweenShots NOTIFY timeBetweenShotsChanged)
Q_PROPERTY(QVariantList polygonPath READ polygonPath NOTIFY polygonPathChanged)
Q_PROPERTY(QVariantList gridPoints READ gridPoints NOTIFY gridPointsChanged) Q_PROPERTY(QVariantList gridPoints READ gridPoints NOTIFY gridPointsChanged)
Q_PROPERTY(int cameraShots READ cameraShots NOTIFY cameraShotsChanged) Q_PROPERTY(int cameraShots READ cameraShots NOTIFY cameraShotsChanged)
Q_PROPERTY(double coveredArea READ coveredArea NOTIFY coveredAreaChanged) Q_PROPERTY(double coveredArea READ coveredArea NOTIFY coveredAreaChanged)
Q_PROPERTY(QGCMapPolygon* mapPolygon READ mapPolygon CONSTANT)
#if 0
// The polygon vertices are also exposed as a list mode since MapItemView will only work with a QAbstractItemModel as // The polygon vertices are also exposed as a list mode since MapItemView will only work with a QAbstractItemModel as
// opposed to polygonPath which is a QVariantList. // opposed to polygonPath which is a QVariantList.
Q_PROPERTY(QmlObjectListModel* polygonModel READ polygonModel CONSTANT) Q_PROPERTY(QmlObjectListModel* polygonModel READ polygonModel CONSTANT)
Q_PROPERTY(QVariantList polygonPath READ polygonPath NOTIFY polygonPathChanged)
Q_INVOKABLE void clearPolygon(void); #endif
Q_INVOKABLE void addPolygonCoordinate(const QGeoCoordinate coordinate);
Q_INVOKABLE void adjustPolygonCoordinate(int vertexIndex, const QGeoCoordinate coordinate);
Q_INVOKABLE void removePolygonVertex(int vertexIndex);
// Splits the segment between vertextIndex and the next vertex in half
Q_INVOKABLE void splitPolygonSegment(int vertexIndex);
QVariantList polygonPath (void) { return _polygonPath; }
QmlObjectListModel* polygonModel(void) { return &_polygonModel; }
QVariantList gridPoints (void) { return _simpleGridPoints; } QVariantList gridPoints (void) { return _simpleGridPoints; }
...@@ -96,11 +90,12 @@ public: ...@@ -96,11 +90,12 @@ public:
Fact* fixedValueIsAltitude (void) { return &_fixedValueIsAltitudeFact; } Fact* fixedValueIsAltitude (void) { return &_fixedValueIsAltitudeFact; }
Fact* camera (void) { return &_cameraFact; } Fact* camera (void) { return &_cameraFact; }
int cameraShots (void) const; int cameraShots (void) const;
double coveredArea (void) const { return _coveredArea; } double coveredArea (void) const { return _coveredArea; }
double timeBetweenShots (void) const; double timeBetweenShots (void) const;
bool hoverAndCaptureAllowed (void) const; bool hoverAndCaptureAllowed (void) const;
bool refly90Degrees (void) const { return _refly90Degrees; } bool refly90Degrees (void) const { return _refly90Degrees; }
QGCMapPolygon* mapPolygon (void) { return &_mapPolygon; }
void setRefly90Degrees(bool refly90Degrees); void setRefly90Degrees(bool refly90Degrees);
...@@ -179,6 +174,8 @@ signals: ...@@ -179,6 +174,8 @@ signals:
private slots: private slots:
void _setDirty(void); void _setDirty(void);
void _polygonDirtyChanged(bool dirty);
void _clearInternal(void);
private: private:
enum CameraTriggerCode { enum CameraTriggerCode {
...@@ -188,9 +185,7 @@ private: ...@@ -188,9 +185,7 @@ private:
CameraTriggerHoverAndCapture CameraTriggerHoverAndCapture
}; };
void _clear(void);
void _setExitCoordinate(const QGeoCoordinate& coordinate); void _setExitCoordinate(const QGeoCoordinate& coordinate);
void _clearGrid(void);
void _generateGrid(void); void _generateGrid(void);
void _updateCoordinateAltitude(void); void _updateCoordinateAltitude(void);
int _gridGenerator(const QList<QPointF>& polygonPoints, QList<QPointF>& simpleGridPoints, QList<QList<QPointF>>& transectSegments, bool refly); int _gridGenerator(const QList<QPointF>& polygonPoints, QList<QPointF>& simpleGridPoints, QList<QList<QPointF>>& transectSegments, bool refly);
...@@ -216,8 +211,7 @@ private: ...@@ -216,8 +211,7 @@ private:
int _sequenceNumber; int _sequenceNumber;
bool _dirty; bool _dirty;
QVariantList _polygonPath; QGCMapPolygon _mapPolygon;
QmlObjectListModel _polygonModel;
QVariantList _simpleGridPoints; ///< Grid points for drawing simple grid visuals QVariantList _simpleGridPoints; ///< Grid points for drawing simple grid visuals
QList<QList<QGeoCoordinate>> _transectSegments; ///< Internal transect segments including grid exit, turnaround and internal camera points QList<QList<QGeoCoordinate>> _transectSegments; ///< Internal transect segments including grid exit, turnaround and internal camera points
QList<QList<QGeoCoordinate>> _reflyTransectSegments; ///< Refly segments QList<QList<QGeoCoordinate>> _reflyTransectSegments; ///< Refly segments
...@@ -257,7 +251,6 @@ private: ...@@ -257,7 +251,6 @@ private:
SettingsFact _fixedValueIsAltitudeFact; SettingsFact _fixedValueIsAltitudeFact;
SettingsFact _cameraFact; SettingsFact _cameraFact;
static const char* _jsonPolygonObjectKey;
static const char* _jsonGridObjectKey; static const char* _jsonGridObjectKey;
static const char* _jsonGridAltitudeKey; static const char* _jsonGridAltitudeKey;
static const char* _jsonGridAltitudeRelativeKey; static const char* _jsonGridAltitudeRelativeKey;
......
...@@ -8,15 +8,15 @@ ...@@ -8,15 +8,15 @@
****************************************************************************/ ****************************************************************************/
#include "ComplexMissionItemTest.h" #include "SurveyMissionItemTest.h"
ComplexMissionItemTest::ComplexMissionItemTest(void) SurveyMissionItemTest::SurveyMissionItemTest(void)
{ {
_polyPoints << QGeoCoordinate(47.633550640000003, -122.08982199) << QGeoCoordinate(47.634129020000003, -122.08887249) << _polyPoints << QGeoCoordinate(47.633550640000003, -122.08982199) << QGeoCoordinate(47.634129020000003, -122.08887249) <<
QGeoCoordinate(47.633619320000001, -122.08811074) << QGeoCoordinate(47.633189139999999, -122.08900124); QGeoCoordinate(47.633619320000001, -122.08811074) << QGeoCoordinate(47.633189139999999, -122.08900124);
} }
void ComplexMissionItemTest::init(void) void SurveyMissionItemTest::init(void)
{ {
_rgComplexMissionItemSignals[polygonPathChangedIndex] = SIGNAL(polygonPathChanged()); _rgComplexMissionItemSignals[polygonPathChangedIndex] = SIGNAL(polygonPathChanged());
_rgComplexMissionItemSignals[lastSequenceNumberChangedIndex] = SIGNAL(lastSequenceNumberChanged(int)); _rgComplexMissionItemSignals[lastSequenceNumberChangedIndex] = SIGNAL(lastSequenceNumberChanged(int));
...@@ -45,7 +45,8 @@ void ComplexMissionItemTest::init(void) ...@@ -45,7 +45,8 @@ void ComplexMissionItemTest::init(void)
_rgComplexMissionItemSignals[exitCoordinateHasRelativeAltitudeChangedIndex] = SIGNAL(exitCoordinateHasRelativeAltitudeChanged(bool)); _rgComplexMissionItemSignals[exitCoordinateHasRelativeAltitudeChangedIndex] = SIGNAL(exitCoordinateHasRelativeAltitudeChanged(bool));
_rgComplexMissionItemSignals[exitCoordinateSameAsEntryChangedIndex] = SIGNAL(exitCoordinateSameAsEntryChanged(bool)); _rgComplexMissionItemSignals[exitCoordinateSameAsEntryChangedIndex] = SIGNAL(exitCoordinateSameAsEntryChanged(bool));
_complexItem = new SurveyMissionItem(NULL /* Vehicle */, this); _surveyItem = new SurveyMissionItem(NULL /* Vehicle */, this);
_mapPolygon = _surveyItem->mapPolygon();
// It's important to check that the right signals are emitted at the right time since that drives ui change. // It's important to check that the right signals are emitted at the right time since that drives ui change.
// It's also important to check that things are not being over-signalled when they should not be, since that can lead // It's also important to check that things are not being over-signalled when they should not be, since that can lead
...@@ -53,66 +54,66 @@ void ComplexMissionItemTest::init(void) ...@@ -53,66 +54,66 @@ void ComplexMissionItemTest::init(void)
_multiSpy = new MultiSignalSpy(); _multiSpy = new MultiSignalSpy();
Q_CHECK_PTR(_multiSpy); Q_CHECK_PTR(_multiSpy);
QCOMPARE(_multiSpy->init(_complexItem, _rgComplexMissionItemSignals, _cComplexMissionItemSignals), true); QCOMPARE(_multiSpy->init(_surveyItem, _rgComplexMissionItemSignals, _cComplexMissionItemSignals), true);
} }
void ComplexMissionItemTest::cleanup(void) void SurveyMissionItemTest::cleanup(void)
{ {
delete _complexItem; delete _surveyItem;
delete _multiSpy; delete _multiSpy;
} }
void ComplexMissionItemTest::_testDirty(void) void SurveyMissionItemTest::_testDirty(void)
{ {
QVERIFY(!_complexItem->dirty()); QVERIFY(!_surveyItem->dirty());
_complexItem->setDirty(false); _surveyItem->setDirty(false);
QVERIFY(!_complexItem->dirty()); QVERIFY(!_surveyItem->dirty());
QVERIFY(_multiSpy->checkNoSignals()); QVERIFY(_multiSpy->checkNoSignals());
_complexItem->setDirty(true); _surveyItem->setDirty(true);
QVERIFY(_complexItem->dirty()); QVERIFY(_surveyItem->dirty());
QVERIFY(_multiSpy->checkOnlySignalByMask(dirtyChangedMask)); QVERIFY(_multiSpy->checkOnlySignalByMask(dirtyChangedMask));
QVERIFY(_multiSpy->pullBoolFromSignalIndex(dirtyChangedIndex)); QVERIFY(_multiSpy->pullBoolFromSignalIndex(dirtyChangedIndex));
_multiSpy->clearAllSignals(); _multiSpy->clearAllSignals();
_complexItem->setDirty(false); _surveyItem->setDirty(false);
QVERIFY(!_complexItem->dirty()); QVERIFY(!_surveyItem->dirty());
QVERIFY(_multiSpy->checkOnlySignalByMask(dirtyChangedMask)); QVERIFY(_multiSpy->checkOnlySignalByMask(dirtyChangedMask));
QVERIFY(!_multiSpy->pullBoolFromSignalIndex(dirtyChangedIndex)); QVERIFY(!_multiSpy->pullBoolFromSignalIndex(dirtyChangedIndex));
} }
void ComplexMissionItemTest::_testAddPolygonCoordinate(void) void SurveyMissionItemTest::_testAddPolygonCoordinate(void)
{ {
QCOMPARE(_complexItem->polygonPath().count(), 0); QCOMPARE(_mapPolygon->count(), 0);
// First call to addPolygonCoordinate should trigger: // First call to addPolygonCoordinate should trigger:
// polygonPathChanged // polygonPathChanged
// dirtyChanged // dirtyChanged
_complexItem->addPolygonCoordinate(_polyPoints[0]); _mapPolygon->appendVertex(_polyPoints[0]);
QVERIFY(_multiSpy->checkOnlySignalByMask(polygonPathChangedMask | dirtyChangedMask)); QVERIFY(_multiSpy->checkOnlySignalByMask(polygonPathChangedMask | dirtyChangedMask));
// Validate object data // Validate object data
QVariantList polyList = _complexItem->polygonPath(); QVariantList polyList = _mapPolygon->path();
QCOMPARE(polyList.count(), 1); QCOMPARE(polyList.count(), 1);
QCOMPARE(polyList[0].value<QGeoCoordinate>(), _polyPoints[0]); QCOMPARE(polyList[0].value<QGeoCoordinate>(), _polyPoints[0]);
// Reset // Reset
_complexItem->setDirty(false); _surveyItem->setDirty(false);
_multiSpy->clearAllSignals(); _multiSpy->clearAllSignals();
// Second call to addPolygonCoordinate should only trigger: // Second call to addPolygonCoordinate should only trigger:
// polygonPathChanged // polygonPathChanged
// dirtyChanged // dirtyChanged
_complexItem->addPolygonCoordinate(_polyPoints[1]); _mapPolygon->appendVertex(_polyPoints[1]);
QVERIFY(_multiSpy->checkOnlySignalByMask(polygonPathChangedMask | dirtyChangedMask)); QVERIFY(_multiSpy->checkOnlySignalByMask(polygonPathChangedMask | dirtyChangedMask));
polyList = _complexItem->polygonPath(); polyList = _mapPolygon->path();
QCOMPARE(polyList.count(), 2); QCOMPARE(polyList.count(), 2);
for (int i=0; i<polyList.count(); i++) { for (int i=0; i<polyList.count(); i++) {
QCOMPARE(polyList[i].value<QGeoCoordinate>(), _polyPoints[i]); QCOMPARE(polyList[i].value<QGeoCoordinate>(), _polyPoints[i]);
} }
_complexItem->setDirty(false); _surveyItem->setDirty(false);
_multiSpy->clearAllSignals(); _multiSpy->clearAllSignals();
// Third call to addPolygonCoordinate should trigger: // Third call to addPolygonCoordinate should trigger:
...@@ -126,33 +127,33 @@ void ComplexMissionItemTest::_testAddPolygonCoordinate(void) ...@@ -126,33 +127,33 @@ void ComplexMissionItemTest::_testAddPolygonCoordinate(void)
// lastSequenceNumberChanged - number of internal mission items changes // lastSequenceNumberChanged - number of internal mission items changes
// gridPointsChanged - grid points show up for the first time // gridPointsChanged - grid points show up for the first time
_complexItem->addPolygonCoordinate(_polyPoints[2]); _mapPolygon->appendVertex(_polyPoints[2]);
QVERIFY(_multiSpy->checkOnlySignalByMask(polygonPathChangedMask | lastSequenceNumberChangedMask | gridPointsChangedMask | coordinateChangedMask | QVERIFY(_multiSpy->checkOnlySignalByMask(polygonPathChangedMask | lastSequenceNumberChangedMask | gridPointsChangedMask | coordinateChangedMask |
exitCoordinateChangedMask | specifiesCoordinateChangedMask | dirtyChangedMask)); exitCoordinateChangedMask | specifiesCoordinateChangedMask | dirtyChangedMask));
int seqNum = _multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex); int seqNum = _multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex);
QVERIFY(seqNum > 0); QVERIFY(seqNum > 0);
polyList = _complexItem->polygonPath(); polyList = _mapPolygon->path();
QCOMPARE(polyList.count(), 3); QCOMPARE(polyList.count(), 3);
for (int i=0; i<polyList.count(); i++) { for (int i=0; i<polyList.count(); i++) {
QCOMPARE(polyList[i].value<QGeoCoordinate>(), _polyPoints[i]); QCOMPARE(polyList[i].value<QGeoCoordinate>(), _polyPoints[i]);
} }
// Test that number of waypoints is doubled when using turnaround waypoints // Test that number of waypoints is doubled when using turnaround waypoints
_complexItem->setTurnaroundDist(60.0); _surveyItem->setTurnaroundDist(60.0);
QVariantList gridPoints = _complexItem->gridPoints(); QVariantList gridPoints = _surveyItem->gridPoints();
_complexItem->setTurnaroundDist(0.0); _surveyItem->setTurnaroundDist(0.0);
QVariantList gridPointsNoT = _complexItem->gridPoints(); QVariantList gridPointsNoT = _surveyItem->gridPoints();
QCOMPARE(gridPoints.count(), 2 * gridPointsNoT.count()); QCOMPARE(gridPoints.count(), 2 * gridPointsNoT.count());
} }
void ComplexMissionItemTest::_testClearPolygon(void) void SurveyMissionItemTest::_testClearPolygon(void)
{ {
for (int i=0; i<3; i++) { for (int i=0; i<3; i++) {
_complexItem->addPolygonCoordinate(_polyPoints[i]); _mapPolygon->appendVertex(_polyPoints[i]);
} }
_complexItem->setDirty(false); _surveyItem->setDirty(false);
_multiSpy->clearAllSignals(); _multiSpy->clearAllSignals();
// Call to clearPolygon should trigger: // Call to clearPolygon should trigger:
...@@ -163,49 +164,49 @@ void ComplexMissionItemTest::_testClearPolygon(void) ...@@ -163,49 +164,49 @@ void ComplexMissionItemTest::_testClearPolygon(void)
// dirtyChangedMask // dirtyChangedMask
// specifiesCoordinateChangedMask // specifiesCoordinateChangedMask
_complexItem->clearPolygon(); _mapPolygon->clear();
QVERIFY(_multiSpy->checkOnlySignalByMask(polygonPathChangedMask | lastSequenceNumberChangedMask | gridPointsChangedMask | dirtyChangedMask | QVERIFY(_multiSpy->checkOnlySignalByMask(polygonPathChangedMask | lastSequenceNumberChangedMask | gridPointsChangedMask | dirtyChangedMask |
specifiesCoordinateChangedMask)); specifiesCoordinateChangedMask));
QVERIFY(!_multiSpy->pullBoolFromSignalIndex(specifiesCoordinateChangedIndex)); QVERIFY(!_multiSpy->pullBoolFromSignalIndex(specifiesCoordinateChangedIndex));
QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), 0); QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), 0);
QCOMPARE(_complexItem->polygonPath().count(), 0); QCOMPARE(_mapPolygon->path().count(), 0);
QCOMPARE(_complexItem->gridPoints().count(), 0); QCOMPARE(_surveyItem->gridPoints().count(), 0);
_complexItem->setDirty(false); _surveyItem->setDirty(false);
_multiSpy->clearAllSignals(); _multiSpy->clearAllSignals();
} }
void ComplexMissionItemTest::_testCameraTrigger(void) void SurveyMissionItemTest::_testCameraTrigger(void)
{ {
QCOMPARE(_complexItem->property("cameraTrigger").toBool(), true); QCOMPARE(_surveyItem->property("cameraTrigger").toBool(), true);
// Set up a grid // Set up a grid
for (int i=0; i<3; i++) { for (int i=0; i<3; i++) {
_complexItem->addPolygonCoordinate(_polyPoints[i]); _mapPolygon->appendVertex(_polyPoints[i]);
} }
_complexItem->setDirty(false); _surveyItem->setDirty(false);
_multiSpy->clearAllSignals(); _multiSpy->clearAllSignals();
int lastSeq = _complexItem->lastSequenceNumber(); int lastSeq = _surveyItem->lastSequenceNumber();
QVERIFY(lastSeq > 0); QVERIFY(lastSeq > 0);
// Turning off camera triggering should remove two camera trigger mission items, this should trigger: // Turning off camera triggering should remove two camera trigger mission items, this should trigger:
// lastSequenceNumberChanged // lastSequenceNumberChanged
// dirtyChanged // dirtyChanged
_complexItem->setProperty("cameraTrigger", false); _surveyItem->setProperty("cameraTrigger", false);
QVERIFY(_multiSpy->checkOnlySignalByMask(lastSequenceNumberChangedMask | dirtyChangedMask | cameraTriggerChangedMask)); QVERIFY(_multiSpy->checkOnlySignalByMask(lastSequenceNumberChangedMask | dirtyChangedMask | cameraTriggerChangedMask));
QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), lastSeq - 2); QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), lastSeq - 2);
_complexItem->setDirty(false); _surveyItem->setDirty(false);
_multiSpy->clearAllSignals(); _multiSpy->clearAllSignals();
// Turn on camera triggering and make sure things go back to previous count // Turn on camera triggering and make sure things go back to previous count
_complexItem->setProperty("cameraTrigger", true); _surveyItem->setProperty("cameraTrigger", true);
QVERIFY(_multiSpy->checkOnlySignalByMask(lastSequenceNumberChangedMask | dirtyChangedMask | cameraTriggerChangedMask)); QVERIFY(_multiSpy->checkOnlySignalByMask(lastSequenceNumberChangedMask | dirtyChangedMask | cameraTriggerChangedMask));
QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), lastSeq); QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), lastSeq);
} }
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
****************************************************************************/ ****************************************************************************/
#ifndef ComplexMissionItemTest_H #ifndef SurveyMissionItemTest_H
#define ComplexMissionItemTest_H #define SurveyMissionItemTest_H
#include "UnitTest.h" #include "UnitTest.h"
#include "TCPLink.h" #include "TCPLink.h"
...@@ -19,12 +19,12 @@ ...@@ -19,12 +19,12 @@
#include <QGeoCoordinate> #include <QGeoCoordinate>
/// Unit test for SimpleMissionItem /// Unit test for SimpleMissionItem
class ComplexMissionItemTest : public UnitTest class SurveyMissionItemTest : public UnitTest
{ {
Q_OBJECT Q_OBJECT
public: public:
ComplexMissionItemTest(void); SurveyMissionItemTest(void);
protected: protected:
void init(void) final; void init(void) final;
...@@ -95,7 +95,8 @@ private: ...@@ -95,7 +95,8 @@ private:
const char* _rgComplexMissionItemSignals[_cComplexMissionItemSignals]; const char* _rgComplexMissionItemSignals[_cComplexMissionItemSignals];
MultiSignalSpy* _multiSpy; MultiSignalSpy* _multiSpy;
SurveyMissionItem* _complexItem; SurveyMissionItem* _surveyItem;
QGCMapPolygon* _mapPolygon;
QList<QGeoCoordinate> _polyPoints; QList<QGeoCoordinate> _polyPoints;
}; };
......
...@@ -25,56 +25,31 @@ Item { ...@@ -25,56 +25,31 @@ Item {
property var map ///< Map control to place item in property var map ///< Map control to place item in
property var _missionItem: object property var _missionItem: object
property var _polygon property var _mapPolygon: object.mapPolygon
property var _grid property var _gridComponent
property var _entryCoordinate property var _entryCoordinate
property var _exitCoordinate property var _exitCoordinate
property var _dragHandles
property var _splitHandles
signal clicked(int sequenceNumber) signal clicked(int sequenceNumber)
function _addVisualElements() { function _addVisualElements() {
_polygon = polygonComponent.createObject(map) _gridComponent = gridComponent.createObject(map)
_grid = gridComponent.createObject(map)
_entryCoordinate = entryPointComponent.createObject(map) _entryCoordinate = entryPointComponent.createObject(map)
_exitCoordinate = exitPointComponent.createObject(map) _exitCoordinate = exitPointComponent.createObject(map)
map.addMapItem(_polygon) map.addMapItem(_gridComponent)
map.addMapItem(_grid)
map.addMapItem(_entryCoordinate) map.addMapItem(_entryCoordinate)
map.addMapItem(_exitCoordinate) map.addMapItem(_exitCoordinate)
} }
function _destroyVisualElements() { function _destroyVisualElements() {
_polygon.destroy() _gridComponent.destroy()
_grid.destroy()
_entryCoordinate.destroy() _entryCoordinate.destroy()
_exitCoordinate.destroy() _exitCoordinate.destroy()
} }
function _addDragHandles() {
if (!_dragHandles) {
_dragHandles = dragHandlesComponent.createObject(map)
}
if (!_splitHandles) {
_splitHandles = splitHandlesComponent.createObject(map)
}
}
function _destroyDragHandles() {
if (_dragHandles) {
_dragHandles.destroy()
_dragHandles = undefined
}
if (_splitHandles) {
_splitHandles.destroy()
_splitHandles = undefined
}
}
/// Add an initial 4 sided polygon if there is none /// Add an initial 4 sided polygon if there is none
function _addInitialPolygon() { function _addInitialPolygon() {
if (_missionItem.polygonPath.length < 3) { if (_mapPolygon.count < 3) {
// Initial polygon is inset to take 2/3rds space // Initial polygon is inset to take 2/3rds space
var rect = Qt.rect(map.centerViewport.x, map.centerViewport.y, map.centerViewport.width, map.centerViewport.height) var rect = Qt.rect(map.centerViewport.x, map.centerViewport.y, map.centerViewport.width, map.centerViewport.height)
console.log(map.centerViewport) console.log(map.centerViewport)
...@@ -87,46 +62,44 @@ Item { ...@@ -87,46 +62,44 @@ Item {
var topRight = Qt.point(rect.x + rect.width, rect.y) var topRight = Qt.point(rect.x + rect.width, rect.y)
var bottomLeft = Qt.point(rect.x, rect.y + rect.height) var bottomLeft = Qt.point(rect.x, rect.y + rect.height)
var bottomRight = Qt.point(rect.x + rect.width, rect.y + rect.height) var bottomRight = Qt.point(rect.x + rect.width, rect.y + rect.height)
_missionItem.addPolygonCoordinate(map.toCoordinate(topLeft, false /* clipToViewPort */)) _mapPolygon.appendVertex(map.toCoordinate(topLeft, false /* clipToViewPort */))
_missionItem.addPolygonCoordinate(map.toCoordinate(topRight, false /* clipToViewPort */)) _mapPolygon.appendVertex(map.toCoordinate(topRight, false /* clipToViewPort */))
_missionItem.addPolygonCoordinate(map.toCoordinate(bottomRight, false /* clipToViewPort */)) _mapPolygon.appendVertex(map.toCoordinate(bottomRight, false /* clipToViewPort */))
_missionItem.addPolygonCoordinate(map.toCoordinate(bottomLeft, false /* clipToViewPort */)) _mapPolygon.appendVertex(map.toCoordinate(bottomLeft, false /* clipToViewPort */))
} }
} }
Component.onCompleted: { Component.onCompleted: {
_addInitialPolygon() _addInitialPolygon()
_addVisualElements() _addVisualElements()
if (_missionItem.isCurrentItem) {
_addDragHandles()
}
} }
Component.onDestruction: { Component.onDestruction: {
_destroyVisualElements() _destroyVisualElements()
_destroyDragHandles()
} }
Connections { QGCMapPolygonVisuals {
target: _missionItem id: mapPolygonVisuals
mapControl: map
mapPolygon: _mapPolygon
onIsCurrentItemChanged: { Component.onCompleted: {
mapPolygonVisuals.addVisuals()
if (_missionItem.isCurrentItem) { if (_missionItem.isCurrentItem) {
_addDragHandles() mapPolygonVisuals.addHandles()
} else {
_destroyDragHandles()
} }
} }
}
// Survey area polygon Connections {
Component { target: _missionItem
id: polygonComponent
MapPolygon { onIsCurrentItemChanged: {
color: "green" if (_missionItem.isCurrentItem) {
opacity: 0.5 mapPolygonVisuals.addHandles()
path: _missionItem.polygonPath } else {
mapPolygonVisuals.removeHandles()
}
}
} }
} }
...@@ -180,148 +153,4 @@ Item { ...@@ -180,148 +153,4 @@ Item {
} }
} }
} }
Component {
id: splitHandleComponent
MapQuickItem {
id: mapQuickItem
anchorPoint.x: dragHandle.width / 2
anchorPoint.y: dragHandle.height / 2
z: QGroundControl.zOrderMapItems + 1
property int vertexIndex
sourceItem: Rectangle {
id: dragHandle
width: ScreenTools.defaultFontPixelHeight * 1.5
height: width
radius: width / 2
color: "white"
opacity: .50
QGCLabel {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text: "+"
}
QGCMouseArea {
fillItem: parent
onClicked: _missionItem.splitPolygonSegment(mapQuickItem.vertexIndex)
}
}
}
}
Component {
id: splitHandlesComponent
Repeater {
model: _missionItem.polygonPath
delegate: Item {
property var _splitHandle
property var _vertices: _missionItem.polygonPath
function _setHandlePosition() {
var nextIndex = index + 1
if (nextIndex > _vertices.length - 1) {
nextIndex = 0
}
var distance = _vertices[index].distanceTo(_vertices[nextIndex])
var azimuth = _vertices[index].azimuthTo(_vertices[nextIndex])
_splitHandle.coordinate = _vertices[index].atDistanceAndAzimuth(distance / 2, azimuth)
}
Component.onCompleted: {
_splitHandle = splitHandleComponent.createObject(map)
_splitHandle.vertexIndex = index
_setHandlePosition()
map.addMapItem(_splitHandle)
}
Component.onDestruction: {
if (_splitHandle) {
_splitHandle.destroy()
}
}
}
}
}
// Control which is used to drag polygon vertices
Component {
id: dragAreaComponent
MissionItemIndicatorDrag {
id: dragArea
property int polygonVertex
property bool _creationComplete: false
Component.onCompleted: _creationComplete = true
onItemCoordinateChanged: {
if (_creationComplete) {
// During component creation some bad coordinate values got through which screws up polygon draw
_missionItem.adjustPolygonCoordinate(polygonVertex, itemCoordinate)
}
}
onClicked: _missionItem.removePolygonVertex(polygonVertex)
}
}
Component {
id: dragHandleComponent
MapQuickItem {
id: mapQuickItem
anchorPoint.x: dragHandle.width / 2
anchorPoint.y: dragHandle.height / 2
z: QGroundControl.zOrderMapItems + 2
sourceItem: Rectangle {
id: dragHandle
width: ScreenTools.defaultFontPixelHeight * 1.5
height: width
radius: width / 2
color: "white"
opacity: .90
}
}
}
// Add all polygon vertex drag handles to the map
Component {
id: dragHandlesComponent
Repeater {
model: _missionItem.polygonModel
delegate: Item {
property var _visuals: [ ]
Component.onCompleted: {
var dragHandle = dragHandleComponent.createObject(map)
dragHandle.coordinate = Qt.binding(function() { return object.coordinate })
map.addMapItem(dragHandle)
var dragArea = dragAreaComponent.createObject(map, { "itemIndicator": dragHandle, "itemCoordinate": object.coordinate })
dragArea.polygonVertex = Qt.binding(function() { return index })
_visuals.push(dragHandle)
_visuals.push(dragArea)
}
Component.onDestruction: {
for (var i=0; i<_visuals.length; i++) {
_visuals[i].destroy()
}
_visuals = [ ]
}
}
}
}
} }
...@@ -39,6 +39,7 @@ QGCGroupBox 1.0 QGCGroupBox.qml ...@@ -39,6 +39,7 @@ QGCGroupBox 1.0 QGCGroupBox.qml
QGCLabel 1.0 QGCLabel.qml QGCLabel 1.0 QGCLabel.qml
QGCListView 1.0 QGCListView.qml QGCListView 1.0 QGCListView.qml
QGCMapLabel 1.0 QGCMapLabel.qml QGCMapLabel 1.0 QGCMapLabel.qml
QGCMapPolygonVisuals 1.0 QGCMapPolygonVisuals.qml
QGCMouseArea 1.0 QGCMouseArea.qml QGCMouseArea 1.0 QGCMouseArea.qml
QGCMovableItem 1.0 QGCMovableItem.qml QGCMovableItem 1.0 QGCMovableItem.qml
QGCPipable 1.0 QGCPipable.qml QGCPipable 1.0 QGCPipable.qml
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include "MessageBoxTest.h" #include "MessageBoxTest.h"
#include "MissionItemTest.h" #include "MissionItemTest.h"
#include "SimpleMissionItemTest.h" #include "SimpleMissionItemTest.h"
#include "ComplexMissionItemTest.h" #include "SurveyMissionItemTest.h"
#include "MissionControllerTest.h" #include "MissionControllerTest.h"
#include "MissionManagerTest.h" #include "MissionManagerTest.h"
#include "RadioConfigTest.h" #include "RadioConfigTest.h"
...@@ -61,5 +61,5 @@ UT_REGISTER_TEST(SendMavCommandTest) ...@@ -61,5 +61,5 @@ UT_REGISTER_TEST(SendMavCommandTest)
//UT_REGISTER_TEST(FileManagerTest) //UT_REGISTER_TEST(FileManagerTest)
// Needs to be update for latest changes // Needs to be update for latest changes
//UT_REGISTER_TEST(ComplexMissionItemTest) //UT_REGISTER_TEST(SurveyMissionItemTest)
//UT_REGISTER_TEST(MavlinkLogTest) //UT_REGISTER_TEST(MavlinkLogTest)
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