diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro
index 84ad18b..f62752a 100644
--- a/qgroundcontrol.pro
+++ b/qgroundcontrol.pro
@@ -384,7 +384,7 @@ DebugBuild { PX4FirmwarePlugin { PX4FirmwarePluginFactory { APMFirmwarePlugin {
src/FactSystem/FactSystemTestGeneric.h \
src/FactSystem/FactSystemTestPX4.h \
src/FactSystem/ParameterManagerTest.h \
- src/MissionManager/ComplexMissionItemTest.h \
+ src/MissionManager/SurveyMissionItemTest.h \
src/MissionManager/MissionCommandTreeTest.h \
src/MissionManager/MissionControllerManagerTest.h \
src/MissionManager/MissionControllerTest.h \
@@ -412,7 +412,7 @@ DebugBuild { PX4FirmwarePlugin { PX4FirmwarePluginFactory { APMFirmwarePlugin {
src/FactSystem/FactSystemTestGeneric.cc \
src/FactSystem/FactSystemTestPX4.cc \
src/FactSystem/ParameterManagerTest.cc \
- src/MissionManager/ComplexMissionItemTest.cc \
+ src/MissionManager/SurveyMissionItemTest.cc \
src/MissionManager/MissionCommandTreeTest.cc \
src/MissionManager/MissionControllerManagerTest.cc \
src/MissionManager/MissionControllerTest.cc \
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index 79aa711..ca44465 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -85,6 +85,7 @@
src/QmlControls/QGCLabel.qml
src/QmlControls/QGCListView.qml
src/QmlControls/QGCMapLabel.qml
+ src/MissionManager/QGCMapPolygonVisuals.qml
src/QmlControls/QGCMouseArea.qml
src/QmlControls/QGCMovableItem.qml
src/QmlControls/QGCPipable.qml
diff --git a/src/MissionManager/QGCMapPolygon.cc b/src/MissionManager/QGCMapPolygon.cc
index cdc31d2..61017ef 100644
--- a/src/MissionManager/QGCMapPolygon.cc
+++ b/src/MissionManager/QGCMapPolygon.cc
@@ -16,15 +16,17 @@
#include
#include
-const char* QGCMapPolygon::_jsonPolygonKey = "polygon";
+const char* QGCMapPolygon::jsonPolygonKey = "polygon";
QGCMapPolygon::QGCMapPolygon(QObject* newCoordParent, QObject* parent)
: QObject(parent)
, _newCoordParent(newCoordParent)
, _dirty(false)
+ , _ignoreCenterUpdates(false)
{
connect(&_polygonModel, &QmlObjectListModel::dirtyChanged, this, &QGCMapPolygon::_polygonModelDirtyChanged);
connect(&_polygonModel, &QmlObjectListModel::countChanged, this, &QGCMapPolygon::_polygonModelCountChanged);
+ connect(&_polygonModel, &QmlObjectListModel::countChanged, this, &QGCMapPolygon::_updateCenter);
}
void QGCMapPolygon::clear(void)
@@ -43,6 +45,8 @@ void QGCMapPolygon::clear(void)
_polygonModel.clearAndDeleteContents();
+ emit cleared();
+
setDirty(true);
}
@@ -53,6 +57,10 @@ void QGCMapPolygon::adjustVertex(int vertexIndex, const QGeoCoordinate coordinat
_polygonModel.value(vertexIndex)->setCoordinate(coordinate);
+ if (!_ignoreCenterUpdates) {
+ _updateCenter();
+ }
+
setDirty(true);
}
@@ -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& path)
{
_polygonPath.clear();
@@ -152,7 +150,7 @@ void QGCMapPolygon::saveToJson(QJsonObject& json)
QJsonValue jsonValue;
JsonHelper::saveGeoCoordinateArray(_polygonPath, false /* writeAltitude*/, jsonValue);
- json.insert(_jsonPolygonKey, jsonValue);
+ json.insert(jsonPolygonKey, jsonValue);
setDirty(false);
}
@@ -162,14 +160,14 @@ bool QGCMapPolygon::loadFromJson(const QJsonObject& json, bool required, QString
clear();
if (required) {
- if (!JsonHelper::validateRequiredKeys(json, QStringList(_jsonPolygonKey), errorString)) {
+ if (!JsonHelper::validateRequiredKeys(json, QStringList(jsonPolygonKey), errorString)) {
return false;
}
- } else if (!json.contains(_jsonPolygonKey)) {
+ } else if (!json.contains(jsonPolygonKey)) {
return true;
}
- if (!JsonHelper::loadGeoCoordinateArray(json[_jsonPolygonKey], false /* altitudeRequired */, _polygonPath, errorString)) {
+ if (!JsonHelper::loadGeoCoordinateArray(json[jsonPolygonKey], false /* altitudeRequired */, _polygonPath, errorString)) {
return false;
}
setDirty(false);
@@ -249,3 +247,38 @@ void QGCMapPolygon::_polygonModelCountChanged(int 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();
+ QGeoCoordinate newVertex = oldVertex.atDistanceAndAzimuth(distance, azimuth);
+ adjustVertex(i, newVertex);
+ }
+
+ _ignoreCenterUpdates = false;
+ _updateCenter();
+ }
+}
diff --git a/src/MissionManager/QGCMapPolygon.h b/src/MissionManager/QGCMapPolygon.h
index 4e534f0..4a4f7f2 100644
--- a/src/MissionManager/QGCMapPolygon.h
+++ b/src/MissionManager/QGCMapPolygon.h
@@ -26,10 +26,11 @@ class QGCMapPolygon : public QObject
public:
QGCMapPolygon(QObject* newCoordParent, QObject* parent = NULL);
- Q_PROPERTY(int count READ count NOTIFY countChanged)
- Q_PROPERTY(QVariantList path READ path NOTIFY pathChanged)
- Q_PROPERTY(QmlObjectListModel* pathModel READ qmlPathModel CONSTANT)
- Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged)
+ Q_PROPERTY(int count READ count NOTIFY countChanged)
+ Q_PROPERTY(QVariantList path READ path NOTIFY pathChanged)
+ Q_PROPERTY(QmlObjectListModel* pathModel READ qmlPathModel CONSTANT)
+ 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 appendVertex(const QGeoCoordinate& coordinate);
@@ -43,9 +44,6 @@ public:
/// Splits the segment comprised of vertextIndex -> vertexIndex + 1
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
Q_INVOKABLE bool containsCoordinate(const QGeoCoordinate& coordinate) const;
@@ -65,9 +63,11 @@ public:
// Property methods
- int count (void) const { return _polygonPath.count(); }
- bool dirty (void) const { return _dirty; }
- void setDirty(bool dirty);
+ int count (void) const { return _polygonPath.count(); }
+ bool dirty (void) const { return _dirty; }
+ void setDirty(bool dirty);
+ QGeoCoordinate center (void) const { return _center; }
+
QVariantList path (void) const { return _polygonPath; }
QmlObjectListModel* qmlPathModel(void) { return &_polygonModel; }
@@ -75,15 +75,21 @@ public:
void setPath(const QList& path);
void setPath(const QVariantList& path);
+ void setCenter(QGeoCoordinate newCenter);
+
+ static const char* jsonPolygonKey;
signals:
- void countChanged(int count);
- void pathChanged(void);
- void dirtyChanged(bool dirty);
+ void countChanged (int count);
+ void pathChanged (void);
+ void dirtyChanged (bool dirty);
+ void cleared (void);
+ void centerChanged (QGeoCoordinate center);
private slots:
void _polygonModelCountChanged(int count);
void _polygonModelDirtyChanged(bool dirty);
+ void _updateCenter(void);
private:
QPolygonF _toPolygonF(void) const;
@@ -94,8 +100,8 @@ private:
QVariantList _polygonPath;
QmlObjectListModel _polygonModel;
bool _dirty;
-
- static const char* _jsonPolygonKey;
+ QGeoCoordinate _center;
+ bool _ignoreCenterUpdates;
};
#endif
diff --git a/src/MissionManager/QGCMapPolygonVisuals.qml b/src/MissionManager/QGCMapPolygonVisuals.qml
new file mode 100644
index 0000000..9e5b0d5
--- /dev/null
+++ b/src/MissionManager/QGCMapPolygonVisuals.qml
@@ -0,0 +1,251 @@
+/****************************************************************************
+ *
+ * (c) 2009-2016 QGROUNDCONTROL PROJECT
+ *
+ * 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()
+ }
+ }
+ }
+}
+
+
diff --git a/src/MissionManager/SurveyMissionItem.cc b/src/MissionManager/SurveyMissionItem.cc
index 1478a29..350aaaa 100644
--- a/src/MissionManager/SurveyMissionItem.cc
+++ b/src/MissionManager/SurveyMissionItem.cc
@@ -21,7 +21,6 @@ QGC_LOGGING_CATEGORY(SurveyMissionItemLog, "SurveyMissionItemLog")
const char* SurveyMissionItem::jsonComplexItemTypeValue = "survey";
-const char* SurveyMissionItem::_jsonPolygonObjectKey = "polygon";
const char* SurveyMissionItem::_jsonGridObjectKey = "grid";
const char* SurveyMissionItem::_jsonGridAltitudeKey = "altitude";
const char* SurveyMissionItem::_jsonGridAltitudeRelativeKey = "relativeAltitude";
@@ -74,6 +73,7 @@ SurveyMissionItem::SurveyMissionItem(Vehicle* vehicle, QObject* parent)
: ComplexMissionItem(vehicle, parent)
, _sequenceNumber(0)
, _dirty(false)
+ , _mapPolygon(this)
, _cameraOrientationFixed(false)
, _missionCommandCount(0)
, _refly90Degrees(false)
@@ -134,6 +134,9 @@ SurveyMissionItem::SurveyMissionItem(Vehicle* vehicle, QObject* parent)
connect(&_cameraOrientationLandscapeFact, &Fact::valueChanged, this, &SurveyMissionItem::_cameraValueChanged);
connect(&_cameraTriggerDistanceFact, &Fact::valueChanged, this, &SurveyMissionItem::timeBetweenShotsChanged);
+
+ connect(&_mapPolygon, &QGCMapPolygon::dirtyChanged, this, &SurveyMissionItem::_polygonDirtyChanged);
+ connect(&_mapPolygon, &QGCMapPolygon::pathChanged, this, &SurveyMissionItem::_generateGrid);
}
void SurveyMissionItem::_setSurveyDistance(double surveyDistance)
@@ -160,115 +163,24 @@ void SurveyMissionItem::_setCoveredArea(double coveredArea)
}
}
-
-void SurveyMissionItem::clearPolygon(void)
+void SurveyMissionItem::_clearInternal(void)
{
- // Bug workaround, see below
- while (_polygonPath.count() > 1) {
- _polygonPath.takeLast();
+ // Bug workaround
+ while (_simpleGridPoints.count() > 1) {
+ _simpleGridPoints.takeLast();
}
- emit polygonPathChanged();
-
- // Although this code should remove the polygon from the map it doesn't. There appears
- // to be a bug in MapPolygon which causes it to not be redrawn if the list is empty. So
- // we work around it by using the code above to remove all but the last point which in turn
- // will cause the polygon to go away.
- _polygonPath.clear();
+ emit gridPointsChanged();
+ _simpleGridPoints.clear();
+ _transectSegments.clear();
- _polygonModel.clearAndDeleteContents();
+ _missionCommandCount = 0;
- _clearGrid();
setDirty(true);
emit specifiesCoordinateChanged();
emit lastSequenceNumberChanged(lastSequenceNumber());
}
-void SurveyMissionItem::addPolygonCoordinate(const QGeoCoordinate coordinate)
-{
- _polygonModel.append(new QGCQGeoCoordinate(coordinate, this));
-
- _polygonPath << QVariant::fromValue(coordinate);
- emit polygonPathChanged();
-
- int pointCount = _polygonPath.count();
- if (pointCount >= 3) {
- if (pointCount == 3) {
- emit specifiesCoordinateChanged();
- }
- _generateGrid();
- }
- setDirty(true);
-}
-
-void SurveyMissionItem::adjustPolygonCoordinate(int vertexIndex, const QGeoCoordinate coordinate)
-{
- if (vertexIndex < 0 && vertexIndex > _polygonPath.length() - 1) {
- qWarning() << "Call to adjustPolygonCoordinate with bad vertexIndex:count" << vertexIndex << _polygonPath.length();
- return;
- }
-
- _polygonModel.value(vertexIndex)->setCoordinate(coordinate);
- _polygonPath[vertexIndex] = QVariant::fromValue(coordinate);
- emit polygonPathChanged();
- _generateGrid();
- setDirty(true);
-}
-
-void SurveyMissionItem::splitPolygonSegment(int vertexIndex)
-{
- int nextIndex = vertexIndex + 1;
- if (nextIndex > _polygonPath.length() - 1) {
- nextIndex = 0;
- }
-
- QGeoCoordinate firstVertex = _polygonPath[vertexIndex].value();
- QGeoCoordinate nextVertex = _polygonPath[nextIndex].value();
-
- double distance = firstVertex.distanceTo(nextVertex);
- double azimuth = firstVertex.azimuthTo(nextVertex);
- QGeoCoordinate newVertex = firstVertex.atDistanceAndAzimuth(distance / 2, azimuth);
-
- if (nextIndex == 0) {
- addPolygonCoordinate(newVertex);
- } else {
- _polygonModel.insert(nextIndex, new QGCQGeoCoordinate(newVertex, this));
- _polygonPath.insert(nextIndex, QVariant::fromValue(newVertex));
- emit polygonPathChanged();
-
- int pointCount = _polygonPath.count();
- if (pointCount >= 3) {
- if (pointCount == 3) {
- emit specifiesCoordinateChanged();
- }
- _generateGrid();
- }
- setDirty(true);
- }
-}
-
-void SurveyMissionItem::removePolygonVertex(int vertexIndex)
-{
- if (vertexIndex < 0 && vertexIndex > _polygonPath.length() - 1) {
- qWarning() << "Call to removePolygonCoordinate with bad vertexIndex:count" << vertexIndex << _polygonPath.length();
- return;
- }
-
- if (_polygonPath.length() <= 3) {
- // Don't allow the user to trash the polygon
- return;
- }
-
- QObject* coordObj = _polygonModel.removeAt(vertexIndex);
- coordObj->deleteLater();
-
- _polygonPath.removeAt(vertexIndex);
- emit polygonPathChanged();
-
- _generateGrid();
- setDirty(true);
-}
-
int SurveyMissionItem::lastSequenceNumber(void) const
{
return _sequenceNumber + _missionCommandCount;
@@ -333,9 +245,7 @@ void SurveyMissionItem::save(QJsonArray& missionItems)
}
// Polygon shape
- QJsonArray polygonArray;
- JsonHelper::savePolygon(_polygonModel, polygonArray);
- saveObject[_jsonPolygonObjectKey] = polygonArray;
+ _mapPolygon.saveToJson(saveObject);
missionItems.append(saveObject);
}
@@ -349,13 +259,6 @@ void SurveyMissionItem::setSequenceNumber(int sequenceNumber)
}
}
-void SurveyMissionItem::_clear(void)
-{
- clearPolygon();
- _clearGrid();
-}
-
-
bool SurveyMissionItem::load(const QJsonObject& complexObject, int sequenceNumber, QString& errorString)
{
QJsonObject v2Object = complexObject;
@@ -385,7 +288,7 @@ bool SurveyMissionItem::load(const QJsonObject& complexObject, int sequenceNumbe
{ JsonHelper::jsonVersionKey, QJsonValue::Double, true },
{ VisualMissionItem::jsonTypeKey, QJsonValue::String, true },
{ ComplexMissionItem::jsonComplexItemTypeKey, QJsonValue::String, true },
- { _jsonPolygonObjectKey, QJsonValue::Array, true },
+ { QGCMapPolygon::jsonPolygonKey, QJsonValue::Array, true },
{ _jsonGridObjectKey, QJsonValue::Object, true },
{ _jsonCameraObjectKey, QJsonValue::Object, false },
{ _jsonCameraTriggerKey, QJsonValue::Bool, true },
@@ -406,7 +309,7 @@ bool SurveyMissionItem::load(const QJsonObject& complexObject, int sequenceNumbe
return false;
}
- _clear();
+ _mapPolygon.clear();
setSequenceNumber(sequenceNumber);
@@ -487,16 +390,15 @@ bool SurveyMissionItem::load(const QJsonObject& complexObject, int sequenceNumbe
}
// Polygon shape
- QJsonArray polygonArray(v2Object[_jsonPolygonObjectKey].toArray());
- if (!JsonHelper::loadPolygon(polygonArray, _polygonModel, this, errorString)) {
- _clear();
+ /// Load a polygon from json
+ /// @param json Json object to load from
+ /// @param required true: no polygon in object will generate error
+ /// @param errorString Error string if return is false
+ /// @return true: success, false: failure (errorString set)
+ if (!_mapPolygon.loadFromJson(v2Object, true /* required */, errorString)) {
+ _mapPolygon.clear();
return false;
}
- for (int i=0; i<_polygonModel.count(); i++) {
- _polygonPath << QVariant::fromValue(_polygonModel.value(i)->coordinate());
- }
-
- _generateGrid();
return true;
}
@@ -524,20 +426,7 @@ void SurveyMissionItem::_setExitCoordinate(const QGeoCoordinate& coordinate)
bool SurveyMissionItem::specifiesCoordinate(void) const
{
- return _polygonPath.count() > 2;
-}
-
-void SurveyMissionItem::_clearGrid(void)
-{
- // Bug workaround
- while (_simpleGridPoints.count() > 1) {
- _simpleGridPoints.takeLast();
- }
- emit gridPointsChanged();
- _simpleGridPoints.clear();
- _transectSegments.clear();
-
- _missionCommandCount = 0;
+ return _mapPolygon.count() > 2;
}
void _calcCameraShots()
@@ -578,8 +467,8 @@ void SurveyMissionItem::_convertPointsToGeo(const QList& pointsNED, con
void SurveyMissionItem::_generateGrid(void)
{
- if (_polygonPath.count() < 3 || _gridSpacingFact.rawValue().toDouble() <= 0) {
- _clearGrid();
+ if (_mapPolygon.count() < 3 || _gridSpacingFact.rawValue().toDouble() <= 0) {
+ _clearInternal();
return;
}
@@ -593,12 +482,13 @@ void SurveyMissionItem::_generateGrid(void)
// Convert polygon to Qt coordinate system (y positive is down)
qCDebug(SurveyMissionItemLog) << "Convert polygon";
- QGeoCoordinate tangentOrigin = _polygonPath[0].value();
- for (int i=0; i<_polygonPath.count(); i++) {
+ QGeoCoordinate tangentOrigin = _mapPolygon.path()[0].value();
+ for (int i=0; i<_mapPolygon.count(); i++) {
double y, x, down;
- convertGeoToNed(_polygonPath[i].value(), tangentOrigin, &y, &x, &down);
+ QGeoCoordinate vertex = _mapPolygon.pathModel().value(i)->coordinate();
+ convertGeoToNed(vertex, tangentOrigin, &y, &x, &down);
polygonPoints += QPointF(x, -y);
- qCDebug(SurveyMissionItemLog) << _polygonPath[i].value() << polygonPoints.last().x() << polygonPoints.last().y();
+ qCDebug(SurveyMissionItemLog) << vertex << polygonPoints.last().x() << polygonPoints.last().y();
}
double coveredArea = 0.0;
@@ -1176,3 +1066,10 @@ void SurveyMissionItem::setRefly90Degrees(bool refly90Degrees)
emit refly90DegreesChanged(refly90Degrees);
}
}
+
+void SurveyMissionItem::_polygonDirtyChanged(bool dirty)
+{
+ if (dirty) {
+ setDirty(true);
+ }
+}
diff --git a/src/MissionManager/SurveyMissionItem.h b/src/MissionManager/SurveyMissionItem.h
index 0eda140..9c80730 100644
--- a/src/MissionManager/SurveyMissionItem.h
+++ b/src/MissionManager/SurveyMissionItem.h
@@ -15,6 +15,7 @@
#include "MissionItem.h"
#include "SettingsFact.h"
#include "QGCLoggingCategory.h"
+#include "QGCMapPolygon.h"
Q_DECLARE_LOGGING_CATEGORY(SurveyMissionItemLog)
@@ -52,25 +53,18 @@ public:
Q_PROPERTY(bool refly90Degrees READ refly90Degrees WRITE setRefly90Degrees NOTIFY refly90DegreesChanged)
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(int cameraShots READ cameraShots NOTIFY cameraShotsChanged)
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
// opposed to polygonPath which is a QVariantList.
Q_PROPERTY(QmlObjectListModel* polygonModel READ polygonModel CONSTANT)
-
- Q_INVOKABLE void clearPolygon(void);
- 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; }
+ Q_PROPERTY(QVariantList polygonPath READ polygonPath NOTIFY polygonPathChanged)
+#endif
QVariantList gridPoints (void) { return _simpleGridPoints; }
@@ -96,11 +90,12 @@ public:
Fact* fixedValueIsAltitude (void) { return &_fixedValueIsAltitudeFact; }
Fact* camera (void) { return &_cameraFact; }
- int cameraShots (void) const;
- double coveredArea (void) const { return _coveredArea; }
- double timeBetweenShots (void) const;
- bool hoverAndCaptureAllowed (void) const;
- bool refly90Degrees (void) const { return _refly90Degrees; }
+ int cameraShots (void) const;
+ double coveredArea (void) const { return _coveredArea; }
+ double timeBetweenShots (void) const;
+ bool hoverAndCaptureAllowed (void) const;
+ bool refly90Degrees (void) const { return _refly90Degrees; }
+ QGCMapPolygon* mapPolygon (void) { return &_mapPolygon; }
void setRefly90Degrees(bool refly90Degrees);
@@ -179,6 +174,8 @@ signals:
private slots:
void _setDirty(void);
+ void _polygonDirtyChanged(bool dirty);
+ void _clearInternal(void);
private:
enum CameraTriggerCode {
@@ -188,9 +185,7 @@ private:
CameraTriggerHoverAndCapture
};
- void _clear(void);
void _setExitCoordinate(const QGeoCoordinate& coordinate);
- void _clearGrid(void);
void _generateGrid(void);
void _updateCoordinateAltitude(void);
int _gridGenerator(const QList& polygonPoints, QList& simpleGridPoints, QList>& transectSegments, bool refly);
@@ -216,8 +211,7 @@ private:
int _sequenceNumber;
bool _dirty;
- QVariantList _polygonPath;
- QmlObjectListModel _polygonModel;
+ QGCMapPolygon _mapPolygon;
QVariantList _simpleGridPoints; ///< Grid points for drawing simple grid visuals
QList> _transectSegments; ///< Internal transect segments including grid exit, turnaround and internal camera points
QList> _reflyTransectSegments; ///< Refly segments
@@ -257,7 +251,6 @@ private:
SettingsFact _fixedValueIsAltitudeFact;
SettingsFact _cameraFact;
- static const char* _jsonPolygonObjectKey;
static const char* _jsonGridObjectKey;
static const char* _jsonGridAltitudeKey;
static const char* _jsonGridAltitudeRelativeKey;
diff --git a/src/MissionManager/ComplexMissionItemTest.cc b/src/MissionManager/SurveyMissionItemTest.cc
similarity index 78%
rename from src/MissionManager/ComplexMissionItemTest.cc
rename to src/MissionManager/SurveyMissionItemTest.cc
index a91e37d..0fbef43 100644
--- a/src/MissionManager/ComplexMissionItemTest.cc
+++ b/src/MissionManager/SurveyMissionItemTest.cc
@@ -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) <<
QGeoCoordinate(47.633619320000001, -122.08811074) << QGeoCoordinate(47.633189139999999, -122.08900124);
}
-void ComplexMissionItemTest::init(void)
+void SurveyMissionItemTest::init(void)
{
_rgComplexMissionItemSignals[polygonPathChangedIndex] = SIGNAL(polygonPathChanged());
_rgComplexMissionItemSignals[lastSequenceNumberChangedIndex] = SIGNAL(lastSequenceNumberChanged(int));
@@ -45,7 +45,8 @@ void ComplexMissionItemTest::init(void)
_rgComplexMissionItemSignals[exitCoordinateHasRelativeAltitudeChangedIndex] = SIGNAL(exitCoordinateHasRelativeAltitudeChanged(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 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)
_multiSpy = new MultiSignalSpy();
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;
}
-void ComplexMissionItemTest::_testDirty(void)
+void SurveyMissionItemTest::_testDirty(void)
{
- QVERIFY(!_complexItem->dirty());
- _complexItem->setDirty(false);
- QVERIFY(!_complexItem->dirty());
+ QVERIFY(!_surveyItem->dirty());
+ _surveyItem->setDirty(false);
+ QVERIFY(!_surveyItem->dirty());
QVERIFY(_multiSpy->checkNoSignals());
- _complexItem->setDirty(true);
- QVERIFY(_complexItem->dirty());
+ _surveyItem->setDirty(true);
+ QVERIFY(_surveyItem->dirty());
QVERIFY(_multiSpy->checkOnlySignalByMask(dirtyChangedMask));
QVERIFY(_multiSpy->pullBoolFromSignalIndex(dirtyChangedIndex));
_multiSpy->clearAllSignals();
- _complexItem->setDirty(false);
- QVERIFY(!_complexItem->dirty());
+ _surveyItem->setDirty(false);
+ QVERIFY(!_surveyItem->dirty());
QVERIFY(_multiSpy->checkOnlySignalByMask(dirtyChangedMask));
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:
// polygonPathChanged
// dirtyChanged
- _complexItem->addPolygonCoordinate(_polyPoints[0]);
+ _mapPolygon->appendVertex(_polyPoints[0]);
QVERIFY(_multiSpy->checkOnlySignalByMask(polygonPathChangedMask | dirtyChangedMask));
// Validate object data
- QVariantList polyList = _complexItem->polygonPath();
+ QVariantList polyList = _mapPolygon->path();
QCOMPARE(polyList.count(), 1);
QCOMPARE(polyList[0].value(), _polyPoints[0]);
// Reset
- _complexItem->setDirty(false);
+ _surveyItem->setDirty(false);
_multiSpy->clearAllSignals();
// Second call to addPolygonCoordinate should only trigger:
// polygonPathChanged
// dirtyChanged
- _complexItem->addPolygonCoordinate(_polyPoints[1]);
+ _mapPolygon->appendVertex(_polyPoints[1]);
QVERIFY(_multiSpy->checkOnlySignalByMask(polygonPathChangedMask | dirtyChangedMask));
- polyList = _complexItem->polygonPath();
+ polyList = _mapPolygon->path();
QCOMPARE(polyList.count(), 2);
for (int i=0; i(), _polyPoints[i]);
}
- _complexItem->setDirty(false);
+ _surveyItem->setDirty(false);
_multiSpy->clearAllSignals();
// Third call to addPolygonCoordinate should trigger:
@@ -126,33 +127,33 @@ void ComplexMissionItemTest::_testAddPolygonCoordinate(void)
// lastSequenceNumberChanged - number of internal mission items changes
// gridPointsChanged - grid points show up for the first time
- _complexItem->addPolygonCoordinate(_polyPoints[2]);
+ _mapPolygon->appendVertex(_polyPoints[2]);
QVERIFY(_multiSpy->checkOnlySignalByMask(polygonPathChangedMask | lastSequenceNumberChangedMask | gridPointsChangedMask | coordinateChangedMask |
exitCoordinateChangedMask | specifiesCoordinateChangedMask | dirtyChangedMask));
int seqNum = _multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex);
QVERIFY(seqNum > 0);
- polyList = _complexItem->polygonPath();
+ polyList = _mapPolygon->path();
QCOMPARE(polyList.count(), 3);
for (int i=0; i(), _polyPoints[i]);
}
// Test that number of waypoints is doubled when using turnaround waypoints
- _complexItem->setTurnaroundDist(60.0);
- QVariantList gridPoints = _complexItem->gridPoints();
- _complexItem->setTurnaroundDist(0.0);
- QVariantList gridPointsNoT = _complexItem->gridPoints();
+ _surveyItem->setTurnaroundDist(60.0);
+ QVariantList gridPoints = _surveyItem->gridPoints();
+ _surveyItem->setTurnaroundDist(0.0);
+ QVariantList gridPointsNoT = _surveyItem->gridPoints();
QCOMPARE(gridPoints.count(), 2 * gridPointsNoT.count());
}
-void ComplexMissionItemTest::_testClearPolygon(void)
+void SurveyMissionItemTest::_testClearPolygon(void)
{
for (int i=0; i<3; i++) {
- _complexItem->addPolygonCoordinate(_polyPoints[i]);
+ _mapPolygon->appendVertex(_polyPoints[i]);
}
- _complexItem->setDirty(false);
+ _surveyItem->setDirty(false);
_multiSpy->clearAllSignals();
// Call to clearPolygon should trigger:
@@ -163,49 +164,49 @@ void ComplexMissionItemTest::_testClearPolygon(void)
// dirtyChangedMask
// specifiesCoordinateChangedMask
- _complexItem->clearPolygon();
+ _mapPolygon->clear();
QVERIFY(_multiSpy->checkOnlySignalByMask(polygonPathChangedMask | lastSequenceNumberChangedMask | gridPointsChangedMask | dirtyChangedMask |
specifiesCoordinateChangedMask));
QVERIFY(!_multiSpy->pullBoolFromSignalIndex(specifiesCoordinateChangedIndex));
QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), 0);
- QCOMPARE(_complexItem->polygonPath().count(), 0);
- QCOMPARE(_complexItem->gridPoints().count(), 0);
+ QCOMPARE(_mapPolygon->path().count(), 0);
+ QCOMPARE(_surveyItem->gridPoints().count(), 0);
- _complexItem->setDirty(false);
+ _surveyItem->setDirty(false);
_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
for (int i=0; i<3; i++) {
- _complexItem->addPolygonCoordinate(_polyPoints[i]);
+ _mapPolygon->appendVertex(_polyPoints[i]);
}
- _complexItem->setDirty(false);
+ _surveyItem->setDirty(false);
_multiSpy->clearAllSignals();
- int lastSeq = _complexItem->lastSequenceNumber();
+ int lastSeq = _surveyItem->lastSequenceNumber();
QVERIFY(lastSeq > 0);
// Turning off camera triggering should remove two camera trigger mission items, this should trigger:
// lastSequenceNumberChanged
// dirtyChanged
- _complexItem->setProperty("cameraTrigger", false);
+ _surveyItem->setProperty("cameraTrigger", false);
QVERIFY(_multiSpy->checkOnlySignalByMask(lastSequenceNumberChangedMask | dirtyChangedMask | cameraTriggerChangedMask));
QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), lastSeq - 2);
- _complexItem->setDirty(false);
+ _surveyItem->setDirty(false);
_multiSpy->clearAllSignals();
// 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));
QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), lastSeq);
}
diff --git a/src/MissionManager/ComplexMissionItemTest.h b/src/MissionManager/SurveyMissionItemTest.h
similarity index 94%
rename from src/MissionManager/ComplexMissionItemTest.h
rename to src/MissionManager/SurveyMissionItemTest.h
index a252439..9da27b5 100644
--- a/src/MissionManager/ComplexMissionItemTest.h
+++ b/src/MissionManager/SurveyMissionItemTest.h
@@ -8,8 +8,8 @@
****************************************************************************/
-#ifndef ComplexMissionItemTest_H
-#define ComplexMissionItemTest_H
+#ifndef SurveyMissionItemTest_H
+#define SurveyMissionItemTest_H
#include "UnitTest.h"
#include "TCPLink.h"
@@ -19,12 +19,12 @@
#include
/// Unit test for SimpleMissionItem
-class ComplexMissionItemTest : public UnitTest
+class SurveyMissionItemTest : public UnitTest
{
Q_OBJECT
public:
- ComplexMissionItemTest(void);
+ SurveyMissionItemTest(void);
protected:
void init(void) final;
@@ -95,7 +95,8 @@ private:
const char* _rgComplexMissionItemSignals[_cComplexMissionItemSignals];
MultiSignalSpy* _multiSpy;
- SurveyMissionItem* _complexItem;
+ SurveyMissionItem* _surveyItem;
+ QGCMapPolygon* _mapPolygon;
QList _polyPoints;
};
diff --git a/src/PlanView/SurveyMapVisual.qml b/src/PlanView/SurveyMapVisual.qml
index 18c16c5..00d1d51 100644
--- a/src/PlanView/SurveyMapVisual.qml
+++ b/src/PlanView/SurveyMapVisual.qml
@@ -25,56 +25,31 @@ Item {
property var map ///< Map control to place item in
property var _missionItem: object
- property var _polygon
- property var _grid
+ property var _mapPolygon: object.mapPolygon
+ property var _gridComponent
property var _entryCoordinate
property var _exitCoordinate
- property var _dragHandles
- property var _splitHandles
signal clicked(int sequenceNumber)
function _addVisualElements() {
- _polygon = polygonComponent.createObject(map)
- _grid = gridComponent.createObject(map)
+ _gridComponent = gridComponent.createObject(map)
_entryCoordinate = entryPointComponent.createObject(map)
_exitCoordinate = exitPointComponent.createObject(map)
- map.addMapItem(_polygon)
- map.addMapItem(_grid)
+ map.addMapItem(_gridComponent)
map.addMapItem(_entryCoordinate)
map.addMapItem(_exitCoordinate)
}
function _destroyVisualElements() {
- _polygon.destroy()
- _grid.destroy()
+ _gridComponent.destroy()
_entryCoordinate.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
function _addInitialPolygon() {
- if (_missionItem.polygonPath.length < 3) {
+ if (_mapPolygon.count < 3) {
// 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)
console.log(map.centerViewport)
@@ -87,46 +62,44 @@ Item {
var topRight = Qt.point(rect.x + rect.width, rect.y)
var bottomLeft = Qt.point(rect.x, rect.y + rect.height)
var bottomRight = Qt.point(rect.x + rect.width, rect.y + rect.height)
- _missionItem.addPolygonCoordinate(map.toCoordinate(topLeft, false /* clipToViewPort */))
- _missionItem.addPolygonCoordinate(map.toCoordinate(topRight, false /* clipToViewPort */))
- _missionItem.addPolygonCoordinate(map.toCoordinate(bottomRight, false /* clipToViewPort */))
- _missionItem.addPolygonCoordinate(map.toCoordinate(bottomLeft, false /* clipToViewPort */))
+ _mapPolygon.appendVertex(map.toCoordinate(topLeft, false /* clipToViewPort */))
+ _mapPolygon.appendVertex(map.toCoordinate(topRight, false /* clipToViewPort */))
+ _mapPolygon.appendVertex(map.toCoordinate(bottomRight, false /* clipToViewPort */))
+ _mapPolygon.appendVertex(map.toCoordinate(bottomLeft, false /* clipToViewPort */))
}
}
Component.onCompleted: {
_addInitialPolygon()
_addVisualElements()
- if (_missionItem.isCurrentItem) {
- _addDragHandles()
- }
}
Component.onDestruction: {
_destroyVisualElements()
- _destroyDragHandles()
}
- Connections {
- target: _missionItem
+ QGCMapPolygonVisuals {
+ id: mapPolygonVisuals
+ mapControl: map
+ mapPolygon: _mapPolygon
- onIsCurrentItemChanged: {
+ Component.onCompleted: {
+ mapPolygonVisuals.addVisuals()
if (_missionItem.isCurrentItem) {
- _addDragHandles()
- } else {
- _destroyDragHandles()
+ mapPolygonVisuals.addHandles()
}
}
- }
- // Survey area polygon
- Component {
- id: polygonComponent
+ Connections {
+ target: _missionItem
- MapPolygon {
- color: "green"
- opacity: 0.5
- path: _missionItem.polygonPath
+ onIsCurrentItemChanged: {
+ if (_missionItem.isCurrentItem) {
+ mapPolygonVisuals.addHandles()
+ } else {
+ mapPolygonVisuals.removeHandles()
+ }
+ }
}
}
@@ -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 = [ ]
- }
- }
- }
- }
}
-
diff --git a/src/QmlControls/QGroundControl.Controls.qmldir b/src/QmlControls/QGroundControl.Controls.qmldir
index dbd7b9d..11503bb 100644
--- a/src/QmlControls/QGroundControl.Controls.qmldir
+++ b/src/QmlControls/QGroundControl.Controls.qmldir
@@ -39,6 +39,7 @@ QGCGroupBox 1.0 QGCGroupBox.qml
QGCLabel 1.0 QGCLabel.qml
QGCListView 1.0 QGCListView.qml
QGCMapLabel 1.0 QGCMapLabel.qml
+QGCMapPolygonVisuals 1.0 QGCMapPolygonVisuals.qml
QGCMouseArea 1.0 QGCMouseArea.qml
QGCMovableItem 1.0 QGCMovableItem.qml
QGCPipable 1.0 QGCPipable.qml
diff --git a/src/qgcunittest/UnitTestList.cc b/src/qgcunittest/UnitTestList.cc
index 61a11dd..92e8b39 100644
--- a/src/qgcunittest/UnitTestList.cc
+++ b/src/qgcunittest/UnitTestList.cc
@@ -20,7 +20,7 @@
#include "MessageBoxTest.h"
#include "MissionItemTest.h"
#include "SimpleMissionItemTest.h"
-#include "ComplexMissionItemTest.h"
+#include "SurveyMissionItemTest.h"
#include "MissionControllerTest.h"
#include "MissionManagerTest.h"
#include "RadioConfigTest.h"
@@ -61,5 +61,5 @@ UT_REGISTER_TEST(SendMavCommandTest)
//UT_REGISTER_TEST(FileManagerTest)
// Needs to be update for latest changes
-//UT_REGISTER_TEST(ComplexMissionItemTest)
+//UT_REGISTER_TEST(SurveyMissionItemTest)
//UT_REGISTER_TEST(MavlinkLogTest)