diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index fb874cc97562a83baca600012f0410d9854d4c48..80fa382b73a37229cfb6c8b93439af1e9549a003 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -220,7 +220,7 @@
src/WimaView/WimaMeasurementAreaMapVisual.qml
src/WimaView/WimaCorridorMapVisual.qml
src/WimaView/WimaMeasurementAreaEditor.qml
- src/PlanView/CircularSurveyItemEditor.qml
+ src/PlanView/CircularSurveyItemEditor.qml
src/WimaView/DragCoordinate.qml
src/WimaView/CoordinateIndicatorDrag.qml
src/WimaView/CoordinateIndicator.qml
@@ -229,7 +229,7 @@
src/FlightMap/MapItems/WimaPlanMapItems.qml
src/PlanView/WimaMissionItemMapVisual.qml
src/FlightDisplay/FlightDisplayWimaMenu.qml
- src/WimaView/CircularSurveyMapVisual.qml
+ src/WimaView/CircularSurveyMapVisual.qml
src/Settings/APMMavlinkStreamRate.SettingsGroup.json
diff --git a/src/MissionManager/TransectStyleComplexItem.cc b/src/MissionManager/TransectStyleComplexItem.cc
index 36ec81206e68d04bcfb4ebc84da673ba1d717567..c09291a02b7e496e5b1b48a7004ec5ad937509a4 100644
--- a/src/MissionManager/TransectStyleComplexItem.cc
+++ b/src/MissionManager/TransectStyleComplexItem.cc
@@ -358,10 +358,10 @@ void TransectStyleComplexItem::_rebuildTransects(void)
}
//CALLGRIND_TOGGLE_COLLECT;
- auto startTime = std::chrono::high_resolution_clock::now();
+ //auto startTime = std::chrono::high_resolution_clock::now();
_rebuildTransectsPhase1();
- auto delta = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - startTime).count();
- qWarning() << "TransectStyleComplexItem::_rebuildTransects(): time: " << delta << " us";
+ //auto delta = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - startTime).count();
+ //qWarning() << "TransectStyleComplexItem::_rebuildTransects(): time: " << delta << " us";
//CALLGRIND_TOGGLE_COLLECT;
if (_followTerrain) {
diff --git a/src/PlanView/CircularSurveyItemEditor.qml b/src/PlanView/CircularSurveyItemEditor.qml
index 347a348c4253410f89058eaba0e124bd00aff223..1ed15fdc4c44ae948afddc9a7366f57298529bf8 100644
--- a/src/PlanView/CircularSurveyItemEditor.qml
+++ b/src/PlanView/CircularSurveyItemEditor.qml
@@ -166,18 +166,35 @@ Rectangle {
onClicked: missionItem.resetReference();
Layout.fillWidth: true
}
+ }
- /*
- Temporarily removed due to bug https://github.com/mavlink/qgroundcontrol/issues/7005
- FactCheckBox {
- text: qsTr("Split concave polygons")
- fact: _splitConcave
- visible: _splitConcave.visible
- property Fact _splitConcave: missionItem.splitConcavePolygons
- }
- */
+ SectionHeader {
+ id: miscellaneousHeader
+ text: qsTr("Miscellaneous")
}
+ ColumnLayout {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ spacing: _margin
+ visible: miscellaneousHeader.checked
+
+ GridLayout {
+ Layout.fillWidth: true
+ columnSpacing: _margin
+ rowSpacing: _margin
+ columns: 2
+
+ QGCLabel { text: qsTr("Max Waypoints") }
+ FactTextField {
+ fact: missionItem.maxWaypoints
+ Layout.fillWidth: true
+ }
+ } // GridLayout
+ } // ColumnLayout
+
+ /*
+ // The following code causes seg. faults from time to time
SectionHeader {
id: terrainHeader
text: qsTr("Terrain")
@@ -222,7 +239,7 @@ Rectangle {
Layout.fillWidth: true
}
}
- }
+ }*/
/*SectionHeader {
id: statsHeader
diff --git a/src/Terrain/TerrainQuery.cc b/src/Terrain/TerrainQuery.cc
index b2d1dada9cf3c539581f261fc570ba2d46e411f1..6b01d6ba959a50030f48ea60b3b4a8f28cca10d0 100644
--- a/src/Terrain/TerrainQuery.cc
+++ b/src/Terrain/TerrainQuery.cc
@@ -362,10 +362,13 @@ void TerrainTileManager::addCoordinateQuery(TerrainOfflineAirMapQuery* terrainQu
void TerrainTileManager::addPathQuery(TerrainOfflineAirMapQuery* terrainQueryInterface, const QGeoCoordinate &startPoint, const QGeoCoordinate &endPoint)
{
// Convert to individual coordinate queries
+ //qDebug() << "TerrainTileManager::addPathQuery()" << startPoint;
QList coordinates;
double lat = startPoint.latitude();
double lon = startPoint.longitude();
double steps = ceil(endPoint.distanceTo(startPoint) / TerrainTile::terrainAltitudeSpacing);
+// if (qFuzzyIsNull(steps))
+// return;
double latDiff = endPoint.latitude() - lat;
double lonDiff = endPoint.longitude() - lon;
for (double i = 0.0; i <= steps; i = i + 1) {
diff --git a/src/Wima/CircularSurvey.SettingsGroup.json b/src/Wima/CircularSurvey.SettingsGroup.json
index 2c54c8954347bd3b05e733d4ccedbb0dba4e23dd..42ac9584313430a951fc5fefe4f1e80f7b646761 100644
--- a/src/Wima/CircularSurvey.SettingsGroup.json
+++ b/src/Wima/CircularSurvey.SettingsGroup.json
@@ -35,8 +35,15 @@
},
{
"name": "Reverse",
- "shortDescription": "Reverses the transect path",
+ "shortDescription": "Reverses the transect path.",
"type": "bool",
"defaultValue": 0
+},
+{
+ "name": "MaxWaypoints",
+ "shortDescription": "The maximum number of waypoints the circular survey can containt. To many waypoints cause a performance hit.",
+ "type": "uint32",
+ "defaultValue": 2000,
+ "min": 1
}
]
diff --git a/src/Wima/CircularSurveyComplexItem.cc b/src/Wima/CircularSurveyComplexItem.cc
index 121a1061ee82ef274d7dc28bf65b9d157cf5c6a3..ca613e297db6224a830916be1aa06fa495f4436b 100644
--- a/src/Wima/CircularSurveyComplexItem.cc
+++ b/src/Wima/CircularSurveyComplexItem.cc
@@ -10,6 +10,7 @@ const char* CircularSurveyComplexItem::deltaAlphaName = "DeltaAlpha"
const char* CircularSurveyComplexItem::transectMinLengthName = "TransectMinLength";
const char* CircularSurveyComplexItem::isSnakePathName = "IsSnakePath";
const char* CircularSurveyComplexItem::reverseName = "Reverse";
+const char* CircularSurveyComplexItem::maxWaypointsName = "MaxWaypoints";
const char* CircularSurveyComplexItem::jsonComplexItemTypeValue = "circularSurvey";
@@ -17,6 +18,7 @@ const char* CircularSurveyComplexItem::jsonDeltaRKey = "deltaR"
const char* CircularSurveyComplexItem::jsonDeltaAlphaKey = "deltaAlpha";
const char* CircularSurveyComplexItem::jsonTransectMinLengthKey = "transectMinLength";
const char* CircularSurveyComplexItem::jsonIsSnakePathKey = "isSnakePath";
+const char* CircularSurveyComplexItem::jsonReverseKey = "reverse";
const char* CircularSurveyComplexItem::jsonReferencePointLatKey = "referencePointLat";
const char* CircularSurveyComplexItem::jsonReferencePointLongKey = "referencePointLong";
const char* CircularSurveyComplexItem::jsonReferencePointAltKey = "referencePointAlt";
@@ -30,6 +32,7 @@ CircularSurveyComplexItem::CircularSurveyComplexItem(Vehicle *vehicle, bool flyV
, _transectMinLength (settingsGroup, _metaDataMap[transectMinLengthName])
, _isSnakePath (settingsGroup, _metaDataMap[isSnakePathName])
, _reverse (settingsGroup, _metaDataMap[reverseName])
+ , _maxWaypoints (settingsGroup, _metaDataMap[maxWaypointsName])
, _isInitialized (false)
, _reverseOnly (false)
, _referencePointBeingChanged (false)
@@ -41,6 +44,7 @@ CircularSurveyComplexItem::CircularSurveyComplexItem(Vehicle *vehicle, bool flyV
connect(&_deltaAlpha, &Fact::valueChanged, this, &CircularSurveyComplexItem::_rebuildTransects);
connect(&_transectMinLength, &Fact::valueChanged, this, &CircularSurveyComplexItem::_rebuildTransects);
connect(&_isSnakePath, &Fact::valueChanged, this, &CircularSurveyComplexItem::_rebuildTransects);
+ connect(&_maxWaypoints, &Fact::valueChanged, this, &CircularSurveyComplexItem::_rebuildTransects);
connect(&_reverse, &Fact::valueChanged, this, &CircularSurveyComplexItem::_reverseTransects);
connect(this, &CircularSurveyComplexItem::refPointChanged, this, &CircularSurveyComplexItem::_rebuildTransects);
//connect(&_cameraCalc.distanceToSurface(), &Fact::rawValueChanged, this->)
@@ -123,6 +127,7 @@ bool CircularSurveyComplexItem::load(const QJsonObject &complexObject, int seque
{ jsonDeltaAlphaKey, QJsonValue::Double, true },
{ jsonTransectMinLengthKey, QJsonValue::Double, true },
{ jsonIsSnakePathKey, QJsonValue::Bool, true },
+ { jsonReverseKey, QJsonValue::Bool, true },
{ jsonReferencePointLatKey, QJsonValue::Double, true },
{ jsonReferencePointLongKey, QJsonValue::Double, true },
{ jsonReferencePointAltKey, QJsonValue::Double, true },
@@ -160,6 +165,7 @@ bool CircularSurveyComplexItem::load(const QJsonObject &complexObject, int seque
_referencePoint.setLatitude (complexObject[jsonReferencePointLatKey].toDouble());
_referencePoint.setAltitude (complexObject[jsonReferencePointAltKey].toDouble());
_isSnakePath.setRawValue (complexObject[jsonIsSnakePathKey].toBool());
+ _reverse.setRawValue (complexObject[jsonReverseKey].toBool());
setIsInitialized(true);
_ignoreRecalc = false;
@@ -187,6 +193,7 @@ void CircularSurveyComplexItem::save(QJsonArray &planItems)
saveObject[jsonDeltaAlphaKey] = _deltaAlpha.rawValue().toDouble();
saveObject[jsonTransectMinLengthKey] = _transectMinLength.rawValue().toDouble();
saveObject[jsonIsSnakePathKey] = _isSnakePath.rawValue().toBool();
+ saveObject[jsonReverseKey] = _reverse.rawValue().toBool();
saveObject[jsonReferencePointLongKey] = _referencePoint.longitude();
saveObject[jsonReferencePointLatKey] = _referencePoint.latitude();
saveObject[jsonReferencePointAltKey] = _referencePoint.altitude();
@@ -372,6 +379,7 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
return;
_updateCounter++;
+ unsigned int waypointCounter = 0;
// If the transects are getting rebuilt then any previously loaded mission items are now invalid
if (_loadedMissionItemsParent) {
@@ -389,21 +397,23 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
// reverse transects and return
if (_reverseOnly) {
- QList> transectsReverse;
+ _reverseOnly = false;
- for (auto list : _transects) {
- QList listReverse;
- for (auto coordinate : list)
- listReverse.prepend(coordinate);
+ if (_transects.size() > 1) {
+ QList> transectsReverse;
+ transectsReverse.reserve(_transects.size());
- transectsReverse.prepend(listReverse);
- }
+ for (auto list : _transects) {
+ QList listReverse;
+ for (auto coordinate : list)
+ listReverse.prepend(coordinate);
- _transects.clear();
- _transects.append(transectsReverse);
+ transectsReverse.prepend(listReverse);
+ }
+ _transects = transectsReverse;
- _reverseOnly = false;
- return;
+ return;
+ }
}
_transects.clear();
@@ -437,6 +447,7 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
double lmin = _transectMinLength.rawValue().toDouble();
double r_min = dr; // meter
double r_max = (*std::max_element(distances.begin(), distances.end())); // meter
+ unsigned int maxWaypoints = _maxWaypoints.rawValue().toUInt();
QPointF origin(0, 0);
IntersectType type;
@@ -546,14 +557,21 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
QVector sectorPath = circle.approximateSektor(numNodes, alpha1, alpha2);
// use shortestPath() here if necessary, could be a problem if dr >>
- if (sectorPath.size() > 0)
+ if (sectorPath.size() > 0) {
+ waypointCounter += uint(sectorPath.size());
+ if (waypointCounter > maxWaypoints )
+ return;
transectPath.append(sectorPath);
+ }
}
} else if (originInside) {
// circle fully inside polygon
int numNodes = int(ceil(2*M_PI/dalpha)) + 1;
QVector sectorPath = circle.approximateSektor(numNodes, 0, 2*M_PI);
// use shortestPath() here if necessary, could be a problem if dr >>
+ waypointCounter += uint(sectorPath.size());
+ if (waypointCounter > maxWaypoints )
+ return;
transectPath.append(sectorPath);
}
r += dr;
@@ -613,6 +631,9 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
optiPath.append(currentSection); // append last section
+ if (optiPath.size() > _maxWaypoints.rawValue().toInt())
+ return;
+
// convert to CoordInfo_t
if (_reverse.rawValue().toBool())
@@ -669,6 +690,11 @@ Fact *CircularSurveyComplexItem::reverse()
return &_reverse;
}
+Fact *CircularSurveyComplexItem::maxWaypoints()
+{
+ return &_maxWaypoints;
+}
+
diff --git a/src/Wima/CircularSurveyComplexItem.h b/src/Wima/CircularSurveyComplexItem.h
index f9be3a8b51804b23e280cd3ea38e96ffb609fc3b..e6cf37f34d82316bcbca77db45ebf571b40581ab 100644
--- a/src/Wima/CircularSurveyComplexItem.h
+++ b/src/Wima/CircularSurveyComplexItem.h
@@ -24,6 +24,7 @@ public:
Q_PROPERTY(Fact* transectMinLength READ transectMinLength CONSTANT)
Q_PROPERTY(Fact* isSnakePath READ isSnakePath CONSTANT)
Q_PROPERTY(Fact* reverse READ reverse CONSTANT)
+ Q_PROPERTY(Fact* maxWaypoints READ maxWaypoints CONSTANT)
Q_PROPERTY(bool isInitialized READ isInitialized WRITE setIsInitialized NOTIFY isInitializedChanged)
Q_INVOKABLE void resetReference(void);
@@ -41,6 +42,7 @@ public:
Fact *transectMinLength();
Fact *isSnakePath();
Fact *reverse();
+ Fact *maxWaypoints();
// Is true if survey was automatically generated, prevents initialisation from gui.
bool isInitialized();
bool referencePointBeingChanged(); // returns true if the referencepoint is being changed (dragged by user)
@@ -69,12 +71,14 @@ public:
static const char* transectMinLengthName;
static const char* isSnakePathName;
static const char* reverseName;
+ static const char* maxWaypointsName;
static const char* jsonComplexItemTypeValue;
static const char* jsonDeltaRKey;
static const char* jsonDeltaAlphaKey;
- static const char* jsonTransectMinLengthKey;
+ static const char* jsonTransectMinLengthKey;
static const char* jsonIsSnakePathKey;
+ static const char* jsonReverseKey;
static const char* jsonReferencePointLongKey;
static const char* jsonReferencePointLatKey;
static const char* jsonReferencePointAltKey;
@@ -108,6 +112,7 @@ private:
SettingsFact _transectMinLength; // minimal transect lenght, transects are rejected if they are shorter than this value
SettingsFact _isSnakePath; // bool value, determining if transects are connected in a snake like or zig zag like manner
SettingsFact _reverse; // reverses the _transects path
+ SettingsFact _maxWaypoints; // the maximum number of waypoints _transects (TransectStyleComplexItem) can contain (to avoid performance hits)
QTimer _updateTimer;