diff --git a/src/KMLFileHelper.cc b/src/KMLFileHelper.cc index b37c4e3fb033977b2e1f33dd7047739c3d159011..f6f2a0718ea76d9e14594490ad2547c41607347d 100644 --- a/src/KMLFileHelper.cc +++ b/src/KMLFileHelper.cc @@ -100,7 +100,7 @@ bool KMLFileHelper::loadPolygonFromFile(const QString& kmlFile, QList(vertexIndex)->setCoordinate(coordinate); if (!_centerDrag) { - // When dragging center we don't signal path changed until add vertices are updated + // When dragging center we don't signal path changed until all vertices are updated emit pathChanged(); } setDirty(true); @@ -340,7 +340,7 @@ void QGCMapPolygon::setCenter(QGeoCoordinate newCenter) } if (_centerDrag) { - // When center dragging signals are delayed until all vertices are updated + // When center dragging, signals from adjustVertext are not sent. So we need to signal here when all adjusting is complete. emit pathChanged(); } @@ -486,3 +486,30 @@ double QGCMapPolygon::area(void) const } return 0.5 * fabs(coveredArea); } + +void QGCMapPolygon::verifyClockwiseWinding(void) +{ + if (_polygonPath.count() <= 2) { + return; + } + + double sum = 0; + for (int i=0; i<_polygonPath.count(); i++) { + QGeoCoordinate coord1 = _polygonPath[i].value(); + QGeoCoordinate coord2 = (i == _polygonPath.count() - 1) ? _polygonPath[0].value() : _polygonPath[i+1].value(); + + sum += (coord2.longitude() - coord1.longitude()) * (coord2.latitude() + coord1.latitude()); + } + + if (sum < 0.0) { + // Winding is counter-clockwise and needs reversal + + QList rgReversed; + for (const QVariant& varCoord: _polygonPath) { + rgReversed.prepend(varCoord.value()); + } + + clear(); + appendVertices(rgReversed); + } +} diff --git a/src/MissionManager/QGCMapPolygon.h b/src/MissionManager/QGCMapPolygon.h index 68dc0145e98451078387058575ebed43bfa6a0a9..d112a58d2ef0f86c35ae55783a33a0d1d7a54023 100644 --- a/src/MissionManager/QGCMapPolygon.h +++ b/src/MissionManager/QGCMapPolygon.h @@ -66,6 +66,9 @@ public: /// Returns the QGeoCoordinate for the vertex specified Q_INVOKABLE QGeoCoordinate vertexCoordinate(int vertex) const; + /// Adjust polygon winding order to be clockwise (if needed) + Q_INVOKABLE void verifyClockwiseWinding(void); + /// Saves the polygon to the json object. /// @param json Json object to save to void saveToJson(QJsonObject& json); diff --git a/src/MissionManager/QGCMapPolygonVisuals.qml b/src/MissionManager/QGCMapPolygonVisuals.qml index c4f9da4a8afc54025de0754e8f9d015104795ad1..8c9a093fb6bf20cc6ed38f7c22ca368f642b1e3c 100644 --- a/src/MissionManager/QGCMapPolygonVisuals.qml +++ b/src/MissionManager/QGCMapPolygonVisuals.qml @@ -344,6 +344,7 @@ Item { mapControl: _root.mapControl z: _zorderDragHandle visible: !_circle + onDragStop: mapPolygon.verifyClockwiseWinding() property int polygonVertex @@ -466,7 +467,10 @@ Item { EditPositionDialog { coordinate: mapPolygon.vertexCoordinate(menu._editingVertexIndex) - onCoordinateChanged: mapPolygon.adjustVertex(menu._editingVertexIndex, coordinate) + onCoordinateChanged: { + mapPolygon.adjustVertex(menu._editingVertexIndex, coordinate) + mapPolygon.verifyClockwiseWinding() + } } }