Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
8da5e19a
Commit
8da5e19a
authored
Nov 27, 2020
by
Valentin Platzgummer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
measurement works mostly, some smaller issues left
parent
5a5b161e
Changes
42
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
2086 additions
and
3394 deletions
+2086
-3394
qgroundcontrol.qrc
qgroundcontrol.qrc
+8
-5
AreaData.cc
src/MeasurementComplexItem/AreaData.cc
+182
-44
AreaData.h
src/MeasurementComplexItem/AreaData.h
+21
-4
CircularGenerator.cpp
src/MeasurementComplexItem/CircularGenerator.cpp
+3
-3
GeneratorBase.cc
src/MeasurementComplexItem/GeneratorBase.cc
+15
-4
GeneratorBase.h
src/MeasurementComplexItem/GeneratorBase.h
+1
-1
LinearGenerator.cpp
src/MeasurementComplexItem/LinearGenerator.cpp
+3
-3
MeasurementComplexItem.cc
src/MeasurementComplexItem/MeasurementComplexItem.cc
+79
-65
MeasurementComplexItem.h
src/MeasurementComplexItem/MeasurementComplexItem.h
+12
-5
WimaPlaner.cc
src/MeasurementComplexItem/WimaPlaner.cc
+0
-1002
WimaPlaner.h
src/MeasurementComplexItem/WimaPlaner.h
+0
-196
WimaStateMachine.cpp
src/MeasurementComplexItem/WimaStateMachine.cpp
+0
-380
WimaStateMachine.h
src/MeasurementComplexItem/WimaStateMachine.h
+0
-64
GeoArea.cc
src/MeasurementComplexItem/geometry/GeoArea.cc
+37
-3
GeoArea.h
src/MeasurementComplexItem/geometry/GeoArea.h
+12
-1
MeasurementArea.cc
src/MeasurementComplexItem/geometry/MeasurementArea.cc
+22
-2
MeasurementArea.h
src/MeasurementComplexItem/geometry/MeasurementArea.h
+1
-0
SafeArea.cc
src/MeasurementComplexItem/geometry/SafeArea.cc
+55
-38
SafeArea.h
src/MeasurementComplexItem/geometry/SafeArea.h
+5
-4
MeasurementArea.SettingsGroup.json
...plexItem/geometry/json/MeasurementArea.SettingsGroup.json
+10
-10
snake.h
src/MeasurementComplexItem/geometry/snake.h
+31
-15
CircularGenerator.SettingsGroup.json
...mentComplexItem/json/CircularGenerator.SettingsGroup.json
+6
-6
LinearGenerator.SettingsGroup.json
...rementComplexItem/json/LinearGenerator.SettingsGroup.json
+6
-6
MeasurementComplexItem.SettingsGroup.json
...omplexItem/json/MeasurementComplexItem.SettingsGroup.json
+4
-4
AreaDataEditor.qml
src/MeasurementComplexItem/qml/AreaDataEditor.qml
+127
-0
CircularGeneratorEditor.qml
src/MeasurementComplexItem/qml/CircularGeneratorEditor.qml
+5
-1
GeoAreaVisualLoader.qml
src/MeasurementComplexItem/qml/GeoAreaVisualLoader.qml
+3
-2
ItemDragger.qml
src/MeasurementComplexItem/qml/ItemDragger.qml
+76
-0
LinearGeneratorEditor.qml
src/MeasurementComplexItem/qml/LinearGeneratorEditor.qml
+6
-2
MeasurementAreaEditor.qml
src/MeasurementComplexItem/qml/MeasurementAreaEditor.qml
+73
-118
MeasurementAreaMapVisual.qml
src/MeasurementComplexItem/qml/MeasurementAreaMapVisual.qml
+1
-0
MeasurementComplexItem.qmldir
src/MeasurementComplexItem/qml/MeasurementComplexItem.qmldir
+6
-0
MeasurementItemEditor.qml
src/MeasurementComplexItem/qml/MeasurementItemEditor.qml
+75
-240
MeasurementItemMapVisual.qml
src/MeasurementComplexItem/qml/MeasurementItemMapVisual.qml
+17
-9
ParameterEditor.qml
src/MeasurementComplexItem/qml/ParameterEditor.qml
+190
-0
ProgressIndicator.qml
src/MeasurementComplexItem/qml/ProgressIndicator.qml
+0
-119
SafeAreaEditor.qml
src/MeasurementComplexItem/qml/SafeAreaEditor.qml
+33
-82
SafeAreaMapVisual.qml
src/MeasurementComplexItem/qml/SafeAreaMapVisual.qml
+44
-84
QGCMapPolygon.h
src/MissionManager/QGCMapPolygon.h
+152
-144
QGCMapPolygonVisuals.qml
src/MissionManager/QGCMapPolygonVisuals.qml
+691
-656
qmldir
src/QmlControls/QGroundControl/Controls/qmldir
+1
-3
QmlObjectListModel.h
src/QmlControls/QmlObjectListModel.h
+73
-69
No files found.
qgroundcontrol.qrc
View file @
8da5e19a
...
...
@@ -261,19 +261,18 @@
<file alias="QmlTest.qml">src/QmlControls/QmlTest.qml</file>
<file alias="RadioComponent.qml">src/AutoPilotPlugins/Common/RadioComponent.qml</file>
<file alias="SerialSettings.qml">src/ui/preferences/SerialSettings.qml</file>
<file alias="CircularGeneratorEditor.qml">src/MeasurementComplexItem/qml/CircularGeneratorEditor.qml</file>
<file alias="
MeasurementComplexItem/
CircularGeneratorEditor.qml">src/MeasurementComplexItem/qml/CircularGeneratorEditor.qml</file>
<file alias="QGroundControl/Controls/CircularGeneratorMapVisual.qml">src/MeasurementComplexItem/qml/CircularGeneratorMapVisual.qml</file>
<file alias="MeasurementItemEditor.qml">src/MeasurementComplexItem/qml/MeasurementItemEditor.qml</file>
<file alias="QGroundControl/Controls/MeasurementItemMapVisual.qml">src/MeasurementComplexItem/qml/MeasurementItemMapVisual.qml</file>
<file alias="QGroundControl/Controls/CoordinateIndicator.qml">src/MeasurementComplexItem/qml/CoordinateIndicator.qml</file>
<file alias="QGroundControl/Controls/CoordinateIndicatorDrag.qml">src/MeasurementComplexItem/qml/CoordinateIndicatorDrag.qml</file>
<file alias="QGroundControl/Controls/DragCoordinate.qml">src/MeasurementComplexItem/qml/DragCoordinate.qml</file>
<file alias="LinearGeneratorEditor.qml">src/MeasurementComplexItem/qml/LinearGeneratorEditor.qml</file>
<file alias="ProgressIndicator.qml">src/MeasurementComplexItem/qml/ProgressIndicator.qml</file>
<file alias="MeasurementComplexItem/LinearGeneratorEditor.qml">src/MeasurementComplexItem/qml/LinearGeneratorEditor.qml</file>
<file alias="QGroundControl/Controls/GeoAreaVisualLoader.qml">src/MeasurementComplexItem/qml/GeoAreaVisualLoader.qml</file>
<file alias="MeasurementAreaEditor.qml">src/MeasurementComplexItem/qml/MeasurementAreaEditor.qml</file>
<file alias="Measurement
ComplexItem/Measurement
AreaEditor.qml">src/MeasurementComplexItem/qml/MeasurementAreaEditor.qml</file>
<file alias="QGroundControl/Controls/MeasurementAreaMapVisual.qml">src/MeasurementComplexItem/qml/MeasurementAreaMapVisual.qml</file>
<file alias="SafeAreaEditor.qml">src/MeasurementComplexItem/qml/SafeAreaEditor.qml</file>
<file alias="
MeasurementComplexItem/
SafeAreaEditor.qml">src/MeasurementComplexItem/qml/SafeAreaEditor.qml</file>
<file alias="QGroundControl/Controls/SafeAreaMapVisual.qml">src/MeasurementComplexItem/qml/SafeAreaMapVisual.qml</file>
<file alias="SetupParameterEditor.qml">src/VehicleSetup/SetupParameterEditor.qml</file>
<file alias="SetupView.qml">src/VehicleSetup/SetupView.qml</file>
...
...
@@ -290,6 +289,10 @@
<file alias="VirtualJoystick.qml">src/FlightDisplay/VirtualJoystick.qml</file>
<file alias="VTOLLandingPatternEditor.qml">src/PlanView/VTOLLandingPatternEditor.qml</file>
<file>src/MeasurementComplexItem/qml/GeoAreaEditorLoader.qml</file>
<file alias="QGroundControl/Controls/ItemDragger.qml">src/MeasurementComplexItem/qml/ItemDragger.qml</file>
<file alias="MeasurementComplexItem/AreaDataEditor.qml">src/MeasurementComplexItem/qml/AreaDataEditor.qml</file>
<file alias="MeasurementComplexItem/ParameterEditor.qml">src/MeasurementComplexItem/qml/ParameterEditor.qml</file>
<file alias="MeasurementComplexItem/qmldir">src/MeasurementComplexItem/qml/MeasurementComplexItem.qmldir</file>
</qresource>
<qresource prefix="/FirstRunPromptDialogs">
<file alias="UnitsFirstRunPrompt.qml">src/FirstRunPromptDialogs/UnitsFirstRunPrompt.qml</file>
...
...
src/MeasurementComplexItem/AreaData.cc
View file @
8da5e19a
This diff is collapsed.
Click to expand it.
src/MeasurementComplexItem/AreaData.h
View file @
8da5e19a
...
...
@@ -18,6 +18,8 @@ public:
AreaData
&
operator
=
(
const
AreaData
&
other
);
Q_PROPERTY
(
QmlObjectListModel
*
areaList
READ
areaList
NOTIFY
areaListChanged
)
Q_PROPERTY
(
bool
showErrorMessages
READ
showErrorMessages
WRITE
setShowErrorMessages
NOTIFY
showErrorMessagesChanged
)
// Member Methodes
//!
...
...
@@ -27,7 +29,8 @@ public:
//!
//! \brief remove
//! \param areaData Removes the area.
//! \note Deletes the area if it has no parent.
//! \note Deletes the area if it has either no parent or the parent is this
//! object.
void
remove
(
GeoArea
*
areaData
);
void
clear
();
//!
...
...
@@ -46,8 +49,7 @@ public:
//! \note Origin might change if the list of areas changes.
const
QGeoCoordinate
&
origin
()
const
;
Q_INVOKABLE
bool
isValid
()
const
;
Q_INVOKABLE
bool
tryMakeValid
();
Q_INVOKABLE
bool
isCorrect
();
//!
//! \brief initialize Initializes the areas in a valid way, such that they
//! area inside the bounding box. \param bottomLeft bottom left corner of the
...
...
@@ -65,18 +67,33 @@ public:
//! either.
//!
Q_INVOKABLE
bool
initialized
();
Q_INVOKABLE
void
intersection
();
bool
operator
==
(
const
AreaData
&
other
)
const
;
bool
operator
!=
(
const
AreaData
&
other
)
const
;
QString
errorString
()
const
;
// Contains a message about the last error.
bool
showErrorMessages
()
const
;
void
setShowErrorMessages
(
bool
showErrorMessages
);
signals:
void
areaListChanged
();
void
originChanged
();
void
error
();
// Emitted if errorString() contains a new message.
void
showErrorMessagesChanged
();
private
slots
:
void
_updateOrigin
();
private:
void
_setOrigin
(
const
QGeoCoordinate
&
origin
);
QGeoCoordinate
_newOrigin
();
void
_processError
(
const
QString
&
str
);
bool
_areasCorrect
();
bool
_getAreas
(
MeasurementArea
**
measurementArea
,
SafeArea
**
safeArea
);
QGeoCoordinate
_origin
;
QmlObjectListModel
_areaList
;
bool
_initialized
;
QString
_errorString
;
bool
_showErrorMessages
;
};
src/MeasurementComplexItem/CircularGenerator.cpp
View file @
8da5e19a
...
...
@@ -62,7 +62,7 @@ QString CircularGenerator::abbreviation() { return QStringLiteral("C. Gen."); }
bool
CircularGenerator
::
get
(
Generator
&
generator
)
{
if
(
this
->
_d
)
{
if
(
this
->
_d
->
is
Valid
())
{
if
(
this
->
_d
->
is
Correct
())
{
// Prepare data.
auto
origin
=
this
->
_d
->
origin
();
origin
.
setAltitude
(
0
);
...
...
@@ -200,7 +200,7 @@ void CircularGenerator::resetReference() {
}
void
CircularGenerator
::
establishConnections
()
{
if
(
this
->
_d
&&
!
this
->
_connectionsEstablished
)
{
if
(
this
->
_d
!=
nullptr
&&
!
this
->
_connectionsEstablished
)
{
auto
measurementArea
=
getGeoArea
<
const
MeasurementArea
*>
(
*
this
->
_d
->
areaList
());
auto
serviceArea
=
getGeoArea
<
const
SafeArea
*>
(
*
this
->
_d
->
areaList
());
...
...
@@ -233,7 +233,7 @@ void CircularGenerator::establishConnections() {
}
void
CircularGenerator
::
deleteConnections
()
{
if
(
this
->
_d
&&
this
->
_connectionsEstablished
)
{
if
(
this
->
_d
!=
nullptr
&&
this
->
_connectionsEstablished
)
{
auto
measurementArea
=
getGeoArea
<
const
MeasurementArea
*>
(
*
this
->
_d
->
areaList
());
auto
serviceArea
=
getGeoArea
<
const
SafeArea
*>
(
*
this
->
_d
->
areaList
());
...
...
src/MeasurementComplexItem/GeneratorBase.cc
View file @
8da5e19a
...
...
@@ -8,16 +8,26 @@ GeneratorBase::GeneratorBase(QObject *parent)
GeneratorBase
::
GeneratorBase
(
GeneratorBase
::
Data
d
,
QObject
*
parent
)
:
QObject
(
parent
),
_d
(
d
)
{
establishConnections
();
connect
(
_d
,
&
AreaData
::
areaListChanged
,
this
,
&
GeneratorBase
::
_areaListChangedHandler
);
}
GeneratorBase
::~
GeneratorBase
()
{}
GeneratorBase
::
Data
GeneratorBase
::
data
()
const
{
return
_d
;
}
void
GeneratorBase
::
setData
(
const
Data
&
d
)
{
void
GeneratorBase
::
setData
(
Data
d
)
{
if
(
d
!=
nullptr
)
{
if
(
_d
!=
nullptr
)
{
disconnect
(
_d
,
&
AreaData
::
areaListChanged
,
this
,
&
GeneratorBase
::
_areaListChangedHandler
);
}
deleteConnections
();
_d
=
d
;
establishConnections
();
connect
(
_d
,
&
AreaData
::
areaListChanged
,
this
,
&
GeneratorBase
::
_areaListChangedHandler
);
}
}
void
GeneratorBase
::
establishConnections
()
{}
...
...
@@ -27,6 +37,7 @@ void GeneratorBase::deleteConnections() {}
void
GeneratorBase
::
_areaListChangedHandler
()
{
deleteConnections
();
establishConnections
();
emit
generatorChanged
();
}
}
// namespace routing
src/MeasurementComplexItem/GeneratorBase.h
View file @
8da5e19a
...
...
@@ -33,7 +33,7 @@ public:
virtual
bool
get
(
Generator
&
generator
)
=
0
;
Data
data
()
const
;
void
setData
(
const
Data
&
d
);
void
setData
(
Data
d
);
signals:
void
generatorChanged
();
...
...
src/MeasurementComplexItem/LinearGenerator.cpp
View file @
8da5e19a
...
...
@@ -48,7 +48,7 @@ QString LinearGenerator::abbreviation() { return QStringLiteral("L. Gen."); }
bool
LinearGenerator
::
get
(
Generator
&
generator
)
{
if
(
_d
)
{
if
(
this
->
_d
->
is
Valid
())
{
if
(
this
->
_d
->
is
Correct
())
{
// Prepare data.
auto
origin
=
this
->
_d
->
origin
();
origin
.
setAltitude
(
0
);
...
...
@@ -148,7 +148,7 @@ Fact *LinearGenerator::alpha() { return &_alpha; }
Fact
*
LinearGenerator
::
minLength
()
{
return
&
_minLength
;
}
void
LinearGenerator
::
establishConnections
()
{
if
(
this
->
_d
&&
!
this
->
_connectionsEstablished
)
{
if
(
this
->
_d
!=
nullptr
&&
!
this
->
_connectionsEstablished
)
{
auto
measurementArea
=
getGeoArea
<
const
MeasurementArea
*>
(
*
this
->
_d
->
areaList
());
auto
serviceArea
=
getGeoArea
<
const
SafeArea
*>
(
*
this
->
_d
->
areaList
());
...
...
@@ -178,7 +178,7 @@ void LinearGenerator::establishConnections() {
}
void
LinearGenerator
::
deleteConnections
()
{
if
(
this
->
_d
&&
this
->
_connectionsEstablished
)
{
if
(
this
->
_d
!=
nullptr
&&
this
->
_connectionsEstablished
)
{
auto
measurementArea
=
getGeoArea
<
const
MeasurementArea
*>
(
*
this
->
_d
->
areaList
());
auto
serviceArea
=
getGeoArea
<
const
SafeArea
*>
(
*
this
->
_d
->
areaList
());
...
...
src/MeasurementComplexItem/MeasurementComplexItem.cc
View file @
8da5e19a
...
...
@@ -376,14 +376,15 @@ void MeasurementComplexItem::_setAreaData(
}
}
bool
MeasurementComplexItem
::
_updateRoute
()
{
void
MeasurementComplexItem
::
_updateRoute
()
{
if
(
!
editing
())
{
// Reset data.
this
->
_route
.
clear
();
this
->
_variantVector
.
clear
();
this
->
_variantNames
.
clear
();
emit
variantNamesChanged
();
if
(
this
->
_pAreaData
->
isValid
())
{
if
(
this
->
_pAreaData
->
isCorrect
())
{
// Prepare data.
auto
origin
=
this
->
_pAreaData
->
origin
();
...
...
@@ -391,7 +392,7 @@ bool MeasurementComplexItem::_updateRoute() {
if
(
!
origin
.
isValid
())
{
qCDebug
(
MeasurementComplexItemLog
)
<<
"_updateWorker(): origin invalid."
<<
origin
;
return
false
;
return
;
}
// Convert safe area.
...
...
@@ -401,7 +402,7 @@ bool MeasurementComplexItem::_updateRoute() {
if
(
!
(
geoSafeArea
.
size
()
>=
3
))
{
qCDebug
(
MeasurementComplexItemLog
)
<<
"_updateWorker(): safe area invalid."
<<
geoSafeArea
;
return
false
;
return
;
}
for
(
auto
&
v
:
geoSafeArea
)
{
if
(
v
.
isValid
())
{
...
...
@@ -410,7 +411,7 @@ bool MeasurementComplexItem::_updateRoute() {
qCDebug
(
MeasurementComplexItemLog
)
<<
"_updateWorker(): safe area contains invalid coordinate."
<<
geoSafeArea
;
return
false
;
return
;
}
}
...
...
@@ -426,22 +427,25 @@ bool MeasurementComplexItem::_updateRoute() {
if
(
this
->
_pGenerator
->
get
(
g
))
{
// Start/Restart routing worker.
this
->
_pWorker
->
route
(
par
,
g
);
return
true
;
_setState
(
STATE
::
ROUTING
);
return
;
}
else
{
qCDebug
(
MeasurementComplexItemLog
)
<<
"_updateWorker(): generator creation failed."
;
return
false
;
return
;
}
}
else
{
qCDebug
(
MeasurementComplexItemLog
)
<<
"_updateWorker(): pGenerator == nullptr, number of registered "
"generators: "
<<
this
->
_generatorList
.
size
();
return
false
;
return
;
}
}
else
{
qCDebug
(
MeasurementComplexItemLog
)
<<
"_updateWorker(): plan data invalid."
;
return
false
;
qCDebug
(
MeasurementComplexItemLog
)
<<
"_updateWorker(): plan data invalid."
;
return
;
}
}
}
...
...
@@ -471,7 +475,7 @@ void MeasurementComplexItem::_changeVariant() {
}
auto
&
newVariantCoordinates
=
this
->
_variantVector
[
variant
];
this
->
_route
.
swap
(
newVariantCoordinates
);
emit
routeChanged
();
}
else
{
// error
qCDebug
(
MeasurementComplexItemLog
)
<<
"Variant out of bounds (variant ="
<<
variant
<<
")."
;
...
...
@@ -497,6 +501,7 @@ void MeasurementComplexItem::_reverseRoute() {
auto
&
t
=
this
->
_route
;
std
::
reverse
(
t
.
begin
(),
t
.
end
());
}
emit
routeChanged
();
}
}
...
...
@@ -661,27 +666,35 @@ int MeasurementComplexItem::generatorIndex() {
return
this
->
_generatorList
.
indexOf
(
this
->
_pGenerator
);
}
void
MeasurementComplexItem
::
editingStart
()
{
if
(
!
_editing
(
this
->
_state
))
{
void
MeasurementComplexItem
::
startEditing
()
{
if
(
!
editing
(
))
{
*
_pEditorData
=
*
_pAreaData
;
_setAreaData
(
_pEditorData
);
_setState
(
STATE
::
EDITING
);
}
}
void
MeasurementComplexItem
::
editingStop
()
{
if
(
_editing
(
this
->
_state
))
{
if
(
_pEditorData
->
isValid
())
{
void
MeasurementComplexItem
::
stopEditing
()
{
if
(
editing
())
{
bool
correct
=
_pEditorData
->
isCorrect
();
if
(
correct
)
{
*
_pAreaData
=
*
_pEditorData
;
}
_setAreaData
(
_pAreaData
);
_setState
(
STATE
::
IDLE
);
if
(
_pEditorData
->
isValid
()
&&
*
_pEditorData
!=
*
_pAreaData
)
{
if
(
correct
&&
*
_pEditorData
!=
*
_pAreaData
)
{
_updateRoute
();
}
}
}
void
MeasurementComplexItem
::
abortEditing
()
{
if
(
editing
())
{
_setAreaData
(
_pAreaData
);
_setState
(
STATE
::
IDLE
);
}
}
void
MeasurementComplexItem
::
_storeRoutingData
(
MeasurementComplexItem
::
PtrRoutingData
pRoute
)
{
if
(
this
->
_state
==
STATE
::
ROUTING
)
{
...
...
@@ -781,10 +794,11 @@ void MeasurementComplexItem::_storeRoutingData(
this
->
_variant
.
setCookedValue
(
QVariant
(
0
));
connect
(
&
this
->
_variant
,
&
Fact
::
rawValueChanged
,
this
,
&
MeasurementComplexItem
::
_changeVariant
);
this
->
_changeVariant
();
this
->
_
setState
(
STATE
::
IDLE
);
this
->
_
route
.
swap
(
this
->
_variantVector
.
first
()
);
emit
routeChanged
();
this
->
_setState
(
STATE
::
IDLE
);
}
else
{
qCDebug
(
MeasurementComplexItemLog
)
<<
"_setTransects(): failed, variantVector empty."
;
...
...
src/MeasurementComplexItem/MeasurementComplexItem.h
View file @
8da5e19a
...
...
@@ -105,19 +105,26 @@ public:
// Editing.
//!
//! \brief
editingStart
Starts area data editing.
//! \brief
startEditing
Starts area data editing.
//!
//! Starts area data editing. Route will not be updated bewteen a call
//! sequence of editingStart() and editingStop().
//!
void
editingStart
();
Q_INVOKABLE
void
startEditing
();
//!
//! \brief
editingStop
Stops area editing.
//! \brief
stopEditing
Stops area editing.
//!
//! Stops area editing. Will reset area data to the state before
//! editingStart() if it is invalid. Triggers a route update.
//!
void
editingStop
();
Q_INVOKABLE
void
stopEditing
();
//!
//! \brief abortEditing Aborts area editing.
//!
//! Will reset area data to the state before
//! editingStart().
//!
Q_INVOKABLE
void
abortEditing
();
// Property getters
const
AreaData
*
areaData
()
const
;
...
...
@@ -156,7 +163,7 @@ private slots:
// Worker functions.
void
_storeRoutingData
(
PtrRoutingData
pRoute
);
bool
_updateRoute
();
void
_updateRoute
();
void
_changeVariant
();
void
_reverseRoute
();
...
...
src/MeasurementComplexItem/WimaPlaner.cc
deleted
100644 → 0
View file @
5a5b161e
This diff is collapsed.
Click to expand it.
src/MeasurementComplexItem/WimaPlaner.h
deleted
100644 → 0
View file @
5a5b161e
#pragma once
#include "QmlObjectListModel.h"
#include <QObject>
#include <QScopedPointer>
#include <QSharedPointer>
#include "Geometry/WimaCorridor.h"
#include "Geometry/WimaCorridorData.h"
#include "Geometry/WimaJoinedArea.h"
#include "Geometry/WimaJoinedAreaData.h"
#include "Geometry/WimaMeasurementArea.h"
#include "Geometry/WimaMeasurementAreaData.h"
#include "Geometry/WimaServiceArea.h"
#include "Geometry/WimaServiceAreaData.h"
#include "WimaPlanData.h"
#include "Snake/NemoInterface.h"
#include "JsonHelper.h"
class
MissionController
;
class
PlanMasterController
;
namespace
wima_planer_detail
{
class
WimaStateMachine
;
}
class
WimaPlaner
:
public
QObject
{
Q_OBJECT
enum
FileType
{
WimaFile
,
PlanFile
};
public:
WimaPlaner
(
QObject
*
parent
=
nullptr
);
~
WimaPlaner
();
template
<
class
T
>
WimaPlaner
(
T
t
,
QObject
*
parent
=
nullptr
)
=
delete
;
template
<
class
T
>
WimaPlaner
(
T
t
)
=
delete
;
Q_PROPERTY
(
PlanMasterController
*
masterController
READ
masterController
WRITE
setMasterController
NOTIFY
masterControllerChanged
)
Q_PROPERTY
(
MissionController
*
missionController
READ
missionController
WRITE
setMissionController
NOTIFY
missionControllerChanged
)
Q_PROPERTY
(
QmlObjectListModel
*
visualItems
READ
visualItems
NOTIFY
visualItemsChanged
)
Q_PROPERTY
(
int
currentPolygonIndex
READ
currentPolygonIndex
WRITE
setCurrentPolygonIndex
NOTIFY
currentPolygonIndexChanged
)
Q_PROPERTY
(
QString
currentFile
READ
currentFile
NOTIFY
currentFileChanged
)
Q_PROPERTY
(
QStringList
loadNameFilters
READ
loadNameFilters
CONSTANT
)
Q_PROPERTY
(
QStringList
saveNameFilters
READ
saveNameFilters
CONSTANT
)
Q_PROPERTY
(
QString
fileExtension
READ
fileExtension
CONSTANT
)
Q_PROPERTY
(
QGeoCoordinate
joinedAreaCenter
READ
joinedAreaCenter
CONSTANT
)
Q_PROPERTY
(
NemoInterface
*
nemoInterface
READ
nemoInterface
CONSTANT
)
Q_PROPERTY
(
bool
synchronized
READ
synchronized
NOTIFY
synchronizedChanged
)
Q_PROPERTY
(
bool
needsUpdate
READ
needsUpdate
NOTIFY
needsUpdateChanged
)
Q_PROPERTY
(
bool
readyForSynchronization
READ
readyForSynchronization
NOTIFY
readyForSynchronizationChanged
)
Q_PROPERTY
(
bool
surveyReady
READ
surveyReady
NOTIFY
surveyReadyChanged
)
Q_PROPERTY
(
bool
progressLocked
READ
progressLocked
WRITE
setProgressLocked
NOTIFY
progressLockedChanged
)
// Property accessors
PlanMasterController
*
masterController
(
void
);
MissionController
*
missionController
(
void
);
QmlObjectListModel
*
visualItems
(
void
);
int
currentPolygonIndex
(
void
)
const
;
QString
currentFile
(
void
)
const
;
QStringList
loadNameFilters
(
void
)
const
;
QStringList
saveNameFilters
(
void
)
const
;
QString
fileExtension
(
void
)
const
;
QGeoCoordinate
joinedAreaCenter
(
void
)
const
;
NemoInterface
*
nemoInterface
(
void
);
bool
synchronized
();
bool
needsUpdate
();
bool
readyForSynchronization
();
bool
surveyReady
();
bool
progressLocked
();
// Property setters
void
setMasterController
(
PlanMasterController
*
masterController
);
void
setMissionController
(
MissionController
*
missionController
);
/// Sets the integer index pointing to the current polygon. Current polygon is
/// set interactive.
void
setCurrentPolygonIndex
(
int
index
);
void
setProgressLocked
(
bool
l
);
Q_INVOKABLE
bool
addMeasurementArea
();
/// Removes an area from _visualItems
/// @param index Index of the area to be removed
Q_INVOKABLE
void
removeArea
(
int
index
);
Q_INVOKABLE
bool
addServiceArea
();
Q_INVOKABLE
bool
addCorridor
();
/// Remove all areas from WimaPlaner and all mission items from
/// MissionController
Q_INVOKABLE
void
removeAll
();
/// Recalculates vehicle corridor, flight path, etc.
Q_INVOKABLE
void
update
();
/// Pushes the generated mission data to the wimaController.
Q_INVOKABLE
void
synchronize
();
Q_INVOKABLE
void
saveToCurrent
();
Q_INVOKABLE
void
saveToFile
(
const
QString
&
filename
);
Q_INVOKABLE
bool
loadFromCurrent
();
Q_INVOKABLE
bool
loadFromFile
(
const
QString
&
filename
);
Q_INVOKABLE
void
resetAllInteractive
(
void
);
Q_INVOKABLE
void
setInteractive
(
void
);
QJsonDocument
saveToJson
(
FileType
fileType
);
// static Members
static
const
char
*
wimaFileExtension
;
static
const
char
*
areaItemsName
;
static
const
char
*
missionItemsName
;
signals:
void
masterControllerChanged
(
void
);
void
missionControllerChanged
(
void
);
void
visualItemsChanged
(
void
);
void
currentPolygonIndexChanged
(
int
index
);
void
currentFileChanged
();
void
wimaBridgeChanged
();
void
synchronizedChanged
(
void
);
void
needsUpdateChanged
(
void
);
void
readyForSynchronizationChanged
(
void
);
void
surveyReadyChanged
(
void
);
void
progressLockedChanged
();
private
slots
:
void
updatePolygonInteractivity
(
int
index
);
void
_update
();
void
CSDestroyedHandler
();
void
CSVisualTransectPointsChangedHandler
();
void
mAreaPathChangedHandler
();
void
mAreaTilesChangedHandler
();
void
mAreaProgressChangedHandler
();
void
mAreaProgressAcceptedHandler
();
void
mAreaReadyChangedHandler
();
void
sAreaPathChangedHandler
();
void
corridorPathChangedHandler
();
void
depotChangedHandler
();
void
missionControllerVisualItemsChangedHandler
();
void
missionControllerWaypointPathChangedHandler
();
void
missionControllerNewItemsFromVehicleHandler
();
void
missionControllerMissionItemCountChangedHandler
();
void
nemoInterfaceProgressChangedHandler
();
#ifndef NDEBUG
void
autoLoadMission
(
void
);
#endif
private:
signals:
void
joinedAreaValidChanged
();
void
stateChanged
();
private:
// Member Functions
bool
toPlanData
(
AreaData
&
planData
);
bool
shortestPath
(
const
QGeoCoordinate
&
start
,
const
QGeoCoordinate
&
destination
,
QVector
<
QGeoCoordinate
>
&
path
);
void
setSynchronized
(
bool
s
);
void
enableAreaMonitoring
();
void
disableAreaMonitoring
();
void
enableMissionControllerMonitoring
();
void
disableMissionControllerMonitoring
();
bool
areasMonitored
();
bool
missionControllerMonitored
();
// Member Variables
PlanMasterController
*
_masterController
;
MissionController
*
_missionController
;
int
_currentAreaIndex
;
QString
_currentFile
;
WimaMeasurementArea
_measurementArea
;
WimaServiceArea
_serviceArea
;
WimaCorridor
_corridor
;
WimaJoinedArea
_joinedArea
;
QmlObjectListModel
_visualItems
;
// all areas
CircularSurvey
*
_survey
;
#ifndef NDEBUG
QTimer
_autoLoadTimer
;
// timer to auto load mission after some time, prevents
// seg. faults
#endif
NemoInterface
_nemoInterface
;
// State
QScopedPointer
<
wima_planer_detail
::
WimaStateMachine
>
_stateMachine
;
bool
_areasMonitored
;
bool
_missionControllerMonitored
;
bool
_progressLocked
;
bool
_synchronized
;
// true if planData is synchronized with
// wimaController
};
src/MeasurementComplexItem/WimaStateMachine.cpp
deleted
100644 → 0
View file @
5a5b161e
This diff is collapsed.
Click to expand it.
src/MeasurementComplexItem/WimaStateMachine.h
deleted
100644 → 0
View file @
5a5b161e
#pragma once
#include <QDataStream>
#include <QObject>
namespace
wima_planer_detail
{
enum
class
STATE
{
NEEDS_INIT
,
WAITING_FOR_TILE_UPDATE
,
NEEDS_J_AREA_UPDATE
,
NEEDS_SURVEY_UPDATE
,
WAITING_FOR_SURVEY_UPDATE
,
NEEDS_PATH_UPDATE
,
UP_TO_DATE
};
QDebug
&
operator
<<
(
QDebug
&
ds
,
STATE
s
);
enum
class
EVENT
{
INIT_DONE
,
M_AREA_NOT_READY
,
M_AREA_READY
,
M_AREA_PATH_CHANGED
,
S_AREA_PATH_CHANGED
,
CORRIDOR_PATH_CHANGED
,
M_AREA_TILES_CHANGED
,
M_AREA_PROGRESS_CHANGED
,
J_AREA_UPDATED
,
DEPOT_CHANGED
,
SURVEY_DESTROYED
,
MISSION_ITEMS_DESTROYED
,
SURVEY_UPDATE_TRIGGERED
,
SURVEY_UPDATED
,
PATH_CHANGED
,
PATH_UPDATED
};
QDebug
&
operator
<<
(
QDebug
&
ds
,
EVENT
s
);
class
WimaStateMachine
:
public
QObject
{
Q_OBJECT
public:
explicit
WimaStateMachine
(
QObject
*
parent
=
nullptr
);
STATE
state
();
void
updateState
(
EVENT
e
);
bool
upToDate
();
bool
surveyReady
();
signals:
void
stateChanged
();
void
upToDateChanged
();
void
surveyReadyChanged
();
private:
void
setState
(
STATE
s
);
bool
surveyReady
(
STATE
s
);
bool
upToDate
(
STATE
s
);
STATE
_state
;
};
}
// namespace wima_planer_detail
src/MeasurementComplexItem/geometry/GeoArea.cc
View file @
8da5e19a
#
include
"GeoArea.h"
#include "snake.h"
#include "QGCLoggingCategory.h"
#include "QGCQGeoCoordinate.h"
#include <QDebug>
QGC_LOGGING_CATEGORY
(
GeoAreaLog
,
"GeoAreaLog"
)
const
char
*
GeoArea
::
wimaAreaName
=
"GeoArea"
;
const
char
*
GeoArea
::
areaTypeName
=
"AreaType"
;
const
char
*
GeoArea
::
settingsGroup
=
"GeoArea"
;
...
...
@@ -10,7 +17,7 @@ const char *GeoArea::settingsGroup = "GeoArea";
GeoArea
::
GeoArea
(
QObject
*
parent
)
:
QGCMapPolygon
(
parent
)
{
init
();
}
GeoArea
::
GeoArea
(
const
GeoArea
&
other
,
QObject
*
parent
)
:
QGCMapPolygon
(
other
,
parent
)
{
:
QGCMapPolygon
(
other
,
parent
)
,
_errorString
(
other
.
_errorString
)
{
init
();
}
...
...
@@ -34,13 +41,40 @@ bool GeoArea::loadFromJson(const QJsonObject &json, QString &errorString) {
return
true
;
}
bool
GeoArea
::
isSimplePolygon
()
{
qWarning
()
<<
"WimaArea::isSimplePolygon: impl. missing."
;
bool
GeoArea
::
isCorrect
()
{
if
(
this
->
pathModel
().
count
()
>=
3
)
{
auto
origin
=
this
->
pathModel
().
value
<
QGCQGeoCoordinate
*>
(
0
)
->
coordinate
();
snake
::
FPolygon
polygonENU
;
snake
::
areaToEnu
(
origin
,
this
->
pathModel
(),
polygonENU
);
std
::
string
msg
;
if
(
bg
::
is_valid
(
polygonENU
,
msg
))
{
return
true
;
}
else
{
qCWarning
(
GeoAreaLog
)
<<
msg
.
c_str
();
qCWarning
(
GeoAreaLog
)
<<
"origin: "
<<
origin
;
std
::
stringstream
ss
;
ss
<<
bg
::
wkt
(
polygonENU
);
qCWarning
(
GeoAreaLog
)
<<
"polygonENU: "
<<
ss
.
str
().
c_str
();
setErrorString
(
tr
(
"Area invalid. Area must be a simple polygon."
));
}
}
return
false
;
}
QString
GeoArea
::
errorString
()
const
{
return
this
->
_errorString
;
}
void
GeoArea
::
init
()
{
this
->
setObjectName
(
wimaAreaName
);
}
void
GeoArea
::
setErrorString
(
const
QString
&
str
)
{
this
->
_errorString
=
str
;
emit
errorStringChanged
();
}
void
GeoArea
::
setErrorString
(
const
string
&
str
)
{
this
->
_errorString
=
str
.
c_str
();
emit
errorStringChanged
();
}
bool
copyAreaList
(
const
QmlObjectListModel
&
from
,
QmlObjectListModel
&
to
,
QObject
*
parent
)
{
// Check if elements are valid.
...
...
src/MeasurementComplexItem/geometry/GeoArea.h
View file @
8da5e19a
...
...
@@ -13,6 +13,7 @@ public:
Q_PROPERTY
(
QString
mapVisualQML
READ
mapVisualQML
CONSTANT
)
Q_PROPERTY
(
QString
editorQML
READ
editorQML
CONSTANT
)
Q_PROPERTY
(
QString
errorString
READ
errorString
NOTIFY
errorStringChanged
)
virtual
QString
mapVisualQML
(
void
)
const
=
0
;
virtual
QString
editorQML
(
void
)
const
=
0
;
...
...
@@ -23,15 +24,25 @@ public:
virtual
GeoArea
*
clone
(
QObject
*
parent
=
nullptr
)
const
=
0
;
bool
isSimplePolygon
();
Q_INVOKABLE
virtual
bool
isCorrect
();
Q_INVOKABLE
QString
errorString
()
const
;
// static Members
static
const
char
*
wimaAreaName
;
static
const
char
*
areaTypeName
;
static
const
char
*
settingsGroup
;
signals:
void
errorStringChanged
();
protected:
void
setErrorString
(
const
QString
&
str
);
void
setErrorString
(
const
std
::
string
&
str
);
private:
void
init
();
QString
_errorString
;
};
// Example usage:
...
...
src/MeasurementComplexItem/geometry/MeasurementArea.cc
View file @
8da5e19a
...
...
@@ -91,7 +91,7 @@ MeasurementArea::MeasurementArea(QObject *parent)
MeasurementArea
::
MeasurementArea
(
const
MeasurementArea
&
other
,
QObject
*
parent
)
:
GeoArea
(
other
,
parent
),
_metaDataMap
(
FactMetaData
::
createMapFromJsonFile
(
QStringLiteral
(
":/json/
Wima
MeasurementArea.SettingsGroup.json"
),
QStringLiteral
(
":/json/MeasurementArea.SettingsGroup.json"
),
this
/* QObject parent */
)),
_tileHeight
(
SettingsFact
(
settingsGroup
,
_metaDataMap
[
tileHeightName
],
this
/* QObject parent */
)),
...
...
@@ -103,6 +103,13 @@ MeasurementArea::MeasurementArea(const MeasurementArea &other, QObject *parent)
_showTiles
(
SettingsFact
(
settingsGroup
,
_metaDataMap
[
showTilesName
],
this
/* QObject parent */
)),
_state
(
STATE
::
IDLE
)
{
_tileHeight
=
other
.
_tileHeight
;
_tileWidth
=
other
.
_tileWidth
;
_minTileAreaPercent
=
other
.
_minTileAreaPercent
;
_showTiles
=
other
.
_showTiles
;
_progress
=
other
.
_progress
;
_tileData
=
other
.
_tileData
;
init
();
}
...
...
@@ -115,6 +122,7 @@ MeasurementArea::~MeasurementArea() {}
QString
MeasurementArea
::
mapVisualQML
()
const
{
return
QStringLiteral
(
"MeasurementAreaMapVisual.qml"
);
// return QStringLiteral("");
}
QString
MeasurementArea
::
editorQML
()
const
{
...
...
@@ -211,6 +219,18 @@ bool MeasurementArea::loadFromJson(const QJsonObject &json,
}
}
bool
MeasurementArea
::
isCorrect
()
{
if
(
GeoArea
::
isCorrect
())
{
if
(
ready
())
{
return
true
;
}
else
{
setErrorString
(
tr
(
"Measurement Area tile calculation in progess. Please wait."
));
}
}
return
false
;
}
bool
MeasurementArea
::
setProgress
(
const
QVector
<
int
>
&
p
)
{
if
(
ready
())
{
if
(
p
.
size
()
==
this
->
tiles
()
->
count
()
&&
this
->
_progress
!=
p
)
{
...
...
@@ -240,7 +260,7 @@ void MeasurementArea::doUpdate() {
const
auto
estNumTiles
=
totalArea
/
tileArea
;
// Check some conditions.
if
(
long
(
std
::
ceil
(
estNumTiles
.
value
()))
<=
SNAKE_MAX_TILES
&&
this
->
count
()
>=
3
&&
this
->
isSimplePolygon
())
{
this
->
GeoArea
::
isCorrect
())
{
setState
(
STATE
::
UPDATEING
);
auto
polygon
=
this
->
coordinateList
();
...
...
src/MeasurementComplexItem/geometry/MeasurementArea.h
View file @
8da5e19a
...
...
@@ -50,6 +50,7 @@ public:
MeasurementArea
*
clone
(
QObject
*
parent
=
nullptr
)
const
;
void
saveToJson
(
QJsonObject
&
json
)
override
;
bool
loadFromJson
(
const
QJsonObject
&
json
,
QString
&
errorString
)
override
;
Q_INVOKABLE
virtual
bool
isCorrect
();
// Property getters.
Fact
*
tileHeight
();
...
...
src/MeasurementComplexItem/geometry/SafeArea.cc
View file @
8da5e19a
...
...
@@ -25,7 +25,10 @@ SafeArea &SafeArea::operator=(const SafeArea &other) {
return
*
this
;
}
QString
SafeArea
::
mapVisualQML
()
const
{
return
"SafeAreaMapVisual.qml"
;
}
QString
SafeArea
::
mapVisualQML
()
const
{
return
"SafeAreaMapVisual.qml"
;
// return "";
}
QString
SafeArea
::
editorQML
()
const
{
return
"SafeAreaEditor.qml"
;
}
...
...
@@ -37,11 +40,41 @@ const QGeoCoordinate &SafeArea::depot() const { return _depot; }
QGeoCoordinate
SafeArea
::
depotQml
()
const
{
return
_depot
;
}
bool
SafeArea
::
setDepot
(
const
QGeoCoordinate
&
coordinate
)
{
if
(
_depot
.
latitude
()
!=
coordinate
.
latitude
()
||
_depot
.
longitude
()
!=
coordinate
.
longitude
())
{
if
(
this
->
containsCoordinate
(
coordinate
))
{
_depot
=
coordinate
;
void
SafeArea
::
putDepotInside
()
{
if
(
!
this
->
containsCoordinate
(
this
->
_depot
)
&&
this
->
pathModel
().
count
()
>
0
)
{
if
(
this
->
_depot
.
isValid
())
{
// Use nearest coordinate.
auto
minDist
=
std
::
numeric_limits
<
double
>::
infinity
();
int
minIndex
=
0
;
for
(
int
idx
=
0
;
idx
<
this
->
pathModel
().
count
();
++
idx
)
{
const
QObject
*
obj
=
this
->
pathModel
()[
idx
];
const
auto
*
vertex
=
qobject_cast
<
const
QGCQGeoCoordinate
*>
(
obj
);
if
(
vertex
!=
nullptr
)
{
auto
d
=
vertex
->
coordinate
().
distanceTo
(
this
->
_depot
);
if
(
d
<
minDist
)
{
minDist
=
d
;
minIndex
=
idx
;
}
}
else
{
qCCritical
(
SafeAreaLog
)
<<
"init(): nullptr catched!"
;
}
}
this
->
setDepot
(
this
->
pathModel
().
value
<
QGCQGeoCoordinate
*>
(
minIndex
)
->
coordinate
());
}
else
{
// Use first coordinate.
this
->
setDepot
(
this
->
pathModel
().
value
<
QGCQGeoCoordinate
*>
(
0
)
->
coordinate
());
}
}
}
bool
SafeArea
::
setDepot
(
const
QGeoCoordinate
&
newDepot
)
{
if
(
_depot
.
latitude
()
!=
newDepot
.
latitude
()
||
_depot
.
longitude
()
!=
newDepot
.
longitude
())
{
if
(
this
->
containsCoordinate
(
newDepot
))
{
_depot
=
newDepot
;
_depot
.
setAltitude
(
0
);
emit
depotChanged
();
return
true
;
...
...
@@ -89,38 +122,22 @@ bool SafeArea::loadFromJson(const QJsonObject &json, QString &errorString) {
return
retVal
;
}
void
SafeArea
::
init
()
{
this
->
setObjectName
(
safeAreaName
);
connect
(
this
,
&
GeoArea
::
pathChanged
,
[
this
]
{
if
(
!
this
->
_depot
.
isValid
()
||
!
this
->
containsCoordinate
(
this
->
_depot
))
{
if
(
this
->
containsCoordinate
(
this
->
center
()))
{
// Use center.
this
->
setDepot
(
this
->
center
());
}
else
if
(
this
->
_depot
.
isValid
())
{
// Use nearest coordinate.
auto
minDist
=
std
::
numeric_limits
<
double
>::
infinity
();
int
minIndex
=
0
;
for
(
int
idx
=
0
;
idx
<
this
->
pathModel
().
count
();
++
idx
)
{
const
QObject
*
obj
=
this
->
pathModel
()[
idx
];
const
auto
*
vertex
=
qobject_cast
<
const
QGCQGeoCoordinate
*>
(
obj
);
if
(
vertex
!=
nullptr
)
{
auto
d
=
vertex
->
coordinate
().
distanceTo
(
this
->
_depot
);
if
(
d
<
minDist
)
{
minDist
=
d
;
minIndex
=
idx
;
}
bool
SafeArea
::
isCorrect
()
{
if
(
GeoArea
::
isCorrect
())
{
if
(
this
->
_depot
.
isValid
())
{
if
(
this
->
containsCoordinate
(
this
->
_depot
))
{
return
true
;
}
else
{
qCCritical
(
SafeAreaLog
)
<<
"init(): nullptr catched!"
;
}
setErrorString
(
tr
(
"Depot outside Safe Area"
));
}
this
->
setDepot
(
this
->
pathModel
()
.
value
<
QGCQGeoCoordinate
*>
(
minIndex
)
->
coordinate
());
}
else
if
(
this
->
pathModel
().
count
()
>
0
)
{
// Use first coordinate.
this
->
setDepot
(
this
->
pathModel
().
value
<
QGCQGeoCoordinate
*>
(
0
)
->
coordinate
());
}
else
{
qCritical
(
SafeAreaLog
)
<<
"Depot invalid "
<<
_depot
;
}
}
});
return
false
;
}
void
SafeArea
::
init
()
{
this
->
setObjectName
(
safeAreaName
);
connect
(
this
,
&
GeoArea
::
pathChanged
,
this
,
&
SafeArea
::
putDepotInside
);
}
src/MeasurementComplexItem/geometry/SafeArea.h
View file @
8da5e19a
...
...
@@ -13,15 +13,17 @@ public:
Q_PROPERTY
(
QGeoCoordinate
depot
READ
depotQml
WRITE
setDepot
NOTIFY
depotChanged
)
// Overrides from
WimaPolygon
// Overrides from
GeoArea
QString
mapVisualQML
(
void
)
const
override
;
QString
editorQML
(
void
)
const
override
;
SafeArea
*
clone
(
QObject
*
parent
=
nullptr
)
const
;
void
saveToJson
(
QJsonObject
&
json
)
override
;
bool
loadFromJson
(
const
QJsonObject
&
json
,
QString
&
errorString
)
override
;
Q_INVOKABLE
virtual
bool
isCorrect
();
// Property acessors
const
QGeoCoordinate
&
depot
(
void
)
const
;
bool
setDepot
(
const
QGeoCoordinate
&
newDepot
);
QGeoCoordinate
depotQml
(
void
)
const
;
// static Members
...
...
@@ -31,9 +33,8 @@ public:
static
const
char
*
depotAltitudeName
;
signals:
void
depotChanged
(
void
);
public
slots
:
bool
setDepot
(
const
QGeoCoordinate
&
coordinate
);
private
slots
:
void
putDepotInside
();
private:
// Member Methodes
...
...
src/MeasurementComplexItem/geometry/json/MeasurementArea.SettingsGroup.json
View file @
8da5e19a
...
...
@@ -5,46 +5,46 @@
[
{
"name"
:
"TileHeight"
,
"sh
ortDescription
"
:
"The height of a tile"
,
"sh
rotDesc
"
:
"The height of a tile"
,
"type"
:
"double"
,
"units"
:
"m"
,
"min"
:
0.3
,
"decimalPlaces"
:
2
,
"default
Value
"
:
5
"default"
:
5
},
{
"name"
:
"TileWidth"
,
"sh
ortDescription
"
:
"The height of a tile"
,
"sh
rotDesc
"
:
"The height of a tile"
,
"type"
:
"double"
,
"units"
:
"m"
,
"min"
:
0.3
,
"decimalPlaces"
:
2
,
"default
Value
"
:
5
"default"
:
5
},
{
"name"
:
"MinTileAreaPercent"
,
"sh
ortDescription
"
:
"The minimal allowed area in percent (of width*height)."
,
"sh
rotDesc
"
:
"The minimal allowed area in percent (of width*height)."
,
"type"
:
"double"
,
"units"
:
"%"
,
"min"
:
0
,
"max"
:
100
,
"decimalPlaces"
:
2
,
"default
Value
"
:
20
"default"
:
20
},
{
"name"
:
"ShowTiles"
,
"sh
ortDescription
"
:
"Show tiles"
,
"sh
rotDesc
"
:
"Show tiles"
,
"type"
:
"bool"
,
"default
Value
"
:
true
"default"
:
true
},
{
"name"
:
"BorderPolygonOffset"
,
"sh
ortDescription
"
:
"The distance between the measurement area and it's enclosing polygon"
,
"sh
rotDesc
"
:
"The distance between the measurement area and it's enclosing polygon"
,
"type"
:
"double"
,
"units"
:
"m"
,
"min"
:
0
,
"decimalPlaces"
:
1
,
"default
Value
"
:
5
"default"
:
5
}
]
}
src/MeasurementComplexItem/geometry/snake.h
View file @
8da5e19a
...
...
@@ -20,6 +20,9 @@ namespace bu = boost::units;
#include <GeographicLib/Geocentric.hpp>
#include <GeographicLib/LocalCartesian.hpp>
#include "QGCQGeoCoordinate.h"
#include "QmlObjectListModel.h"
using
namespace
std
;
namespace
snake
{
...
...
@@ -105,13 +108,11 @@ template <class GeoPoint1, class GeoPoint2>
void
toENU
(
const
GeoPoint1
&
origin
,
const
GeoPoint2
&
in
,
FPoint
&
out
)
{
static
GeographicLib
::
Geocentric
earth
(
GeographicLib
::
Constants
::
WGS84_a
(),
GeographicLib
::
Constants
::
WGS84_f
());
GeographicLib
::
LocalCartesian
proj
(
origin
.
latitude
(),
origin
.
longitude
(),
origin
.
altitude
(),
earth
);
GeographicLib
::
LocalCartesian
proj
(
origin
.
latitude
(),
origin
.
longitude
(),
0
,
earth
);
double
x
=
0
,
y
=
0
,
z
=
0
;
auto
alt
=
in
.
altitude
();
alt
=
std
::
isnan
(
alt
)
?
0
:
alt
;
proj
.
Forward
(
in
.
latitude
(),
in
.
longitude
(),
alt
,
x
,
y
,
z
);
proj
.
Forward
(
in
.
latitude
(),
in
.
longitude
(),
0
,
x
,
y
,
z
);
out
.
set
<
0
>
(
x
);
out
.
set
<
1
>
(
y
);
(
void
)
z
;
...
...
@@ -121,13 +122,11 @@ template <class GeoPoint1, class GeoPoint2, class Point>
void
toENU
(
const
GeoPoint1
&
origin
,
const
GeoPoint2
&
in
,
Point
&
out
)
{
static
GeographicLib
::
Geocentric
earth
(
GeographicLib
::
Constants
::
WGS84_a
(),
GeographicLib
::
Constants
::
WGS84_f
());
GeographicLib
::
LocalCartesian
proj
(
origin
.
latitude
(),
origin
.
longitude
(),
origin
.
altitude
(),
earth
);
GeographicLib
::
LocalCartesian
proj
(
origin
.
latitude
(),
origin
.
longitude
(),
0
,
earth
);
double
x
=
0
,
y
=
0
,
z
=
0
;
auto
alt
=
in
.
altitude
();
alt
=
std
::
isnan
(
alt
)
?
0
:
alt
;
proj
.
Forward
(
in
.
latitude
(),
in
.
longitude
(),
alt
,
x
,
y
,
z
);
proj
.
Forward
(
in
.
latitude
(),
in
.
longitude
(),
0
,
x
,
y
,
z
);
out
.
setX
(
x
);
out
.
setY
(
y
);
(
void
)
z
;
...
...
@@ -137,8 +136,8 @@ template <class GeoPoint>
void
fromENU
(
const
GeoPoint
&
origin
,
const
FPoint
&
in
,
GeoPoint
&
out
)
{
static
GeographicLib
::
Geocentric
earth
(
GeographicLib
::
Constants
::
WGS84_a
(),
GeographicLib
::
Constants
::
WGS84_f
());
GeographicLib
::
LocalCartesian
proj
(
origin
.
latitude
(),
origin
.
longitude
(),
origin
.
altitude
(),
earth
);
GeographicLib
::
LocalCartesian
proj
(
origin
.
latitude
(),
origin
.
longitude
(),
0
,
earth
);
double
lat
=
0
,
lon
=
0
,
alt
=
0
;
proj
.
Reverse
(
in
.
get
<
0
>
(),
in
.
get
<
1
>
(),
0
.
0
,
lat
,
lon
,
alt
);
...
...
@@ -166,9 +165,26 @@ void areaToEnu(const GeoPoint &origin, const Container &in, FPolygon &out) {
bg
::
correct
(
out
);
}
template
<
class
GeoPoint
>
void
areaToEnu
(
const
GeoPoint
&
origin
,
QmlObjectListModel
&
in
,
FPolygon
&
out
)
{
FPolygon
buffer
;
for
(
int
i
=
0
;
i
<
in
.
count
();
++
i
)
{
auto
vertex
=
in
.
value
<
const
QGCQGeoCoordinate
*>
(
i
);
if
(
vertex
!=
nullptr
)
{
FPoint
p
;
toENU
(
origin
,
vertex
->
coordinate
(),
p
);
buffer
.
outer
().
push_back
(
p
);
}
else
{
return
;
}
}
bg
::
correct
(
buffer
);
out
=
std
::
move
(
buffer
);
}
template
<
class
GeoPoint
,
class
Container1
,
class
Container2
>
void
areaFromEnu
(
const
GeoPoint
&
origin
,
Container1
&
in
,
const
Container2
&
out
)
{
void
areaFromEnu
(
const
GeoPoint
&
origin
,
const
Container1
&
in
,
Container2
&
out
)
{
for
(
auto
&
vertex
:
in
)
{
typename
Container2
::
value_type
p
;
fromENU
(
origin
,
vertex
,
p
);
...
...
@@ -177,7 +193,7 @@ void areaFromEnu(const GeoPoint &origin, Container1 &in,
}
template
<
class
GeoPoint
,
class
Container
>
void
areaFromEnu
(
const
GeoPoint
&
origin
,
FPolygon
&
in
,
const
Container
&
out
)
{
void
areaFromEnu
(
const
GeoPoint
&
origin
,
const
FPolygon
&
in
,
Container
&
out
)
{
for
(
auto
&
vertex
:
in
.
outer
())
{
typename
Container
::
value_type
p
;
fromENU
(
origin
,
vertex
,
p
);
...
...
src/MeasurementComplexItem/json/CircularGenerator.SettingsGroup.json
View file @
8da5e19a
...
...
@@ -5,31 +5,31 @@
[
{
"name"
:
"TransectDistance"
,
"shortDesc
ription
"
:
"The distance between transects."
,
"shortDesc"
:
"The distance between transects."
,
"type"
:
"double"
,
"units"
:
"m"
,
"min"
:
0.3
,
"decimalPlaces"
:
1
,
"default
Value
"
:
5.0
"default"
:
5.0
},
{
"name"
:
"DeltaAlpha"
,
"shortDesc
ription
"
:
"Angle discretisation."
,
"shortDesc"
:
"Angle discretisation."
,
"type"
:
"double"
,
"units"
:
"Deg"
,
"min"
:
0.3
,
"max"
:
90
,
"decimalPlaces"
:
1
,
"default
Value
"
:
5.0
"default"
:
5.0
},
{
"name"
:
"MinLength"
,
"shortDesc
ription
"
:
"The minimal transect length."
,
"shortDesc"
:
"The minimal transect length."
,
"type"
:
"double"
,
"units"
:
"m"
,
"min"
:
0.3
,
"decimalPlaces"
:
1
,
"default
Value
"
:
5.0
"default"
:
5.0
}
]
}
src/MeasurementComplexItem/json/LinearGenerator.SettingsGroup.json
View file @
8da5e19a
...
...
@@ -5,31 +5,31 @@
[
{
"name"
:
"TransectDistance"
,
"sh
ortDescription"
:
"The distance between transects.
"
,
"sh
rotDesc"
:
"The distan
"
,
"type"
:
"double"
,
"units"
:
"m"
,
"min"
:
0.3
,
"decimalPlaces"
:
1
,
"default
Value
"
:
5.0
"default"
:
5.0
},
{
"name"
:
"Alpha"
,
"sh
ortDescription
"
:
"Transect angle."
,
"sh
rotDesc
"
:
"Transect angle."
,
"type"
:
"double"
,
"units"
:
"Deg"
,
"min"
:
0
,
"max"
:
180
,
"decimalPlaces"
:
1
,
"default
Value
"
:
0.0
"default"
:
0.0
},
{
"name"
:
"MinLength"
,
"sh
ortDescription
"
:
"The minimal transect length."
,
"sh
rotDesc
"
:
"The minimal transect length."
,
"type"
:
"double"
,
"units"
:
"m"
,
"min"
:
0.3
,
"decimalPlaces"
:
1
,
"default
Value
"
:
5.0
"default"
:
5.0
}
]
}
src/MeasurementComplexItem/json/MeasurementComplexItem.SettingsGroup.json
View file @
8da5e19a
...
...
@@ -5,18 +5,18 @@
[
{
"name"
:
"Variant"
,
"sh
ortDescription
"
:
"Route variant."
,
"sh
rotDesc
"
:
"Route variant."
,
"type"
:
"uint64"
,
"default
Value
"
:
0
"default"
:
0
},
{
"name"
:
"Altitude"
,
"sh
ortDescription
"
:
"Altitude"
,
"sh
rotDesc
"
:
"Altitude"
,
"type"
:
"double"
,
"units"
:
"m"
,
"min"
:
1
,
"decimalPlaces"
:
1
,
"default
Value
"
:
10.0
"default"
:
10.0
}
]
}
src/MeasurementComplexItem/qml/AreaDataEditor.qml
0 → 100644
View file @
8da5e19a
import
QtQuick
2.0
import
QtQuick
.
Layouts
1.11
import
QtQuick
.
Controls
1.4
import
QGroundControl
.
Controls
1.0
import
QGroundControl
.
FactControls
1.0
import
QGroundControl
.
ScreenTools
1.0
GridLayout
{
id
:
_root
property
bool
checked
:
true
property
var
missionItem
:
undefined
property
int
availableWidth
:
300
property
var
_areaData
:
missionItem
.
areaData
property
real
_margin
:
ScreenTools
.
defaultFontPixelWidth
/
2
width
:
availableWidth
columnSpacing
:
_margin
rowSpacing
:
_margin
columns
:
2
Component.onCompleted
:
{
console
.
assert
(
missionItem
!==
undefined
,
"
please set the missionItem property
"
)
checkedChangedHandler
()
}
onCheckedChanged
:
checkedChangedHandler
()
ExclusiveGroup
{
id
:
areaGroup
}
Repeater
{
id
:
areaSelector
property
int
selectedIndex
:
-
1
model
:
_missionItem
.
areaData
.
areaList
delegate
:
QGCRadioButton
{
text
:
object
.
objectName
checkable
:
_root
.
checked
Layout.fillWidth
:
true
Layout.columnSpan
:
2
onCheckedChanged
:
{
if
(
checked
){
areaSelector
.
selectedIndex
=
index
}
}
Component
.
onCompleted
:
{
if
(
index
===
0
){
checked
=
true
}
object
.
interactive
=
Qt
.
binding
(
function
(){
return
checked
&&
_root
.
checked
})
}
}
}
// area Repeater
ColumnLayout
{
id
:
editorParent
Layout.fillWidth
:
true
Layout.columnSpan
:
2
}
Repeater
{
id
:
areaEditorRepeater
model
:
_missionItem
.
areaData
.
areaList
delegate
:
Item
{
id
:
editor
visible
:
index
==
areaSelector
.
selectedIndex
property
var
_visualItem
:
undefined
property
var
geoArea
:
object
Component.onCompleted
:
{
if
(
geoArea
.
editorQML
&&
!
_visualItem
)
{
var
component
=
Qt
.
createComponent
(
geoArea
.
editorQML
)
if
(
component
.
status
===
Component
.
Error
)
{
console
.
log
(
"
Error loading Qml:
"
,
geoArea
.
editorQML
,
component
.
errorString
())
}
else
{
_visualItem
=
component
.
createObject
(
editorParent
,
{
geoArea
:
editor
.
geoArea
,
visible
:
Qt
.
binding
(
function
(){
return
editor
.
visible
}),
availableWidth
:
Qt
.
binding
(
function
(){
return
editorParent
.
width
})})
}
}
}
Component
.
onDestruction
:
{
if
(
_visualItem
)
{
_visualItem
.
destroy
()
}
}
}
// editor
}
// areaEditorRepeater
QGCButton
{
text
:
"
Check Rules
"
enabled
:
_root
.
checked
Layout.fillWidth
:
true
onClicked
:
{
_areaData
.
isCorrect
()
}
}
QGCButton
{
text
:
"
Intersection
"
enabled
:
_root
.
checked
Layout.fillWidth
:
true
onClicked
:
{
_areaData
.
intersection
()
}
}
function
checkedChangedHandler
(){
if
(
_root
.
checked
){
missionItem
.
startEditing
()
}
else
{
missionItem
.
stopEditing
()
}
}
}
src/MeasurementComplexItem/qml/CircularGeneratorEditor.qml
View file @
8da5e19a
...
...
@@ -9,7 +9,7 @@ import QGroundControl.ScreenTools 1.0
GridLayout
{
id
:
grid
property
var
generator
// CircularGenerator
property
var
generator
:
undefined
// CircularGenerator
property
var
availableWidth
property
real
_margin
:
ScreenTools
.
defaultFontPixelWidth
/
2
...
...
@@ -18,6 +18,10 @@ GridLayout {
rowSpacing
:
_margin
columns
:
2
Component.onCompleted
:
{
console
.
assert
(
generator
!==
undefined
,
"
please set the generator property
"
)
}
QGCLabel
{
text
:
qsTr
(
"
Distance
"
)
}
FactTextField
{
fact
:
generator
.
distance
...
...
src/MeasurementComplexItem/qml/GeoAreaVisualLoader.qml
View file @
8da5e19a
...
...
@@ -36,11 +36,12 @@ Item {
var
component
=
Qt
.
createComponent
(
_root
.
geoArea
.
mapVisualQML
)
if
(
component
.
status
===
Component
.
Error
)
{
console
.
log
(
"
Error loading Qml:
"
,
_root
.
geoArea
.
mapVisualQML
,
component
.
errorString
())
}
}
else
{
_root
.
_visualItem
=
component
.
createObject
(
_root
.
map
,
{
map
:
_root
.
map
,
geoArea
:
_root
.
geoArea
})
_root
.
_visualItem
.
clicked
.
connect
(
_root
.
clicked
)
}
}
}
Component
.
onDestruction
:
{
if
(
_visualItem
)
{
...
...
src/MeasurementComplexItem/qml/ItemDragger.qml
0 → 100644
View file @
8da5e19a
// Idea from:
// https://stackoverflow.com/questions/42992067/qtquick-dragging-mapquickitem-on-a-map
import
QtQuick
2.3
import
QtLocation
5.3
import
QGroundControl
1.0
import
QGroundControl
.
ScreenTools
1.0
import
QGroundControl
.
Controls
1.0
Rectangle
{
id
:
root
property
var
anchor
:
undefined
property
bool
draggable
:
true
readonly
property
bool
dragged
:
mouseArea
.
drag
.
active
signal
dragStart
signal
dragStop
signal
clicked
property
bool
_mobile
:
ScreenTools
.
isMobile
property
real
_touchWidth
:
Math
.
max
(
anchor
.
width
,
ScreenTools
.
minTouchPixels
)
property
real
_touchHeight
:
Math
.
max
(
anchor
.
height
,
ScreenTools
.
minTouchPixels
)
property
real
_touchMarginHorizontal
:
_mobile
?
(
_touchWidth
-
anchor
.
width
)
/
2
:
0
property
real
_touchMarginVertical
:
_mobile
?
(
_touchHeight
-
anchor
.
height
)
/
2
:
0
x
:
anchor
.
x
-
_touchMarginHorizontal
y
:
anchor
.
y
-
_touchMarginVertical
width
:
anchor
.
width
+
(
_touchMarginHorizontal
*
2
)
height
:
anchor
.
height
+
(
_touchMarginVertical
*
2
)
color
:
"
transparent
"
z
:
QGroundControl
.
zOrderMapItems
+
1
Component.onCompleted
:
{
console
.
assert
(
anchor
!==
undefined
,
"
please set the anchor property
"
)
}
onDraggedChanged
:
{
if
(
dragged
)
{
dragStart
()
}
else
{
dragStop
()
}
}
QGCMouseArea
{
id
:
mouseArea
enabled
:
draggable
preventStealing
:
true
drag.target
:
root
drag.threshold
:
0
anchors.fill
:
parent
cursorShape
:
draggable
?
(
dragged
?
Qt
.
ClosedHandCursor
:
Qt
.
OpenHandCursor
)
:
Qt
.
ArrowCursor
onClicked
:
{
focus
=
true
root
.
clicked
()
}
}
Connections
{
target
:
anchor
onXChanged
:
if
(
!
dragged
)
x
=
anchor
.
x
-
_touchMarginHorizontal
onYChanged
:
if
(
!
dragged
)
y
=
anchor
.
y
-
_touchMarginVertical
}
onXChanged
:
if
(
dragged
)
anchor
.
x
=
x
+
_touchMarginHorizontal
onYChanged
:
if
(
dragged
)
anchor
.
y
=
y
+
_touchMarginVertical
Drag.active
:
true
}
src/MeasurementComplexItem/qml/LinearGeneratorEditor.qml
View file @
8da5e19a
...
...
@@ -8,8 +8,8 @@ import QGroundControl.ScreenTools 1.0
GridLayout
{
property
var
generator
// Circul
arGenerator
property
var
availableWidth
property
var
generator
:
undefined
// Line
arGenerator
property
var
availableWidth
:
300
property
real
_margin
:
ScreenTools
.
defaultFontPixelWidth
/
2
width
:
availableWidth
...
...
@@ -17,6 +17,10 @@ GridLayout {
rowSpacing
:
_margin
columns
:
2
Component.onCompleted
:
{
console
.
assert
(
generator
!==
undefined
,
"
please set the generator property
"
)
}
QGCLabel
{
text
:
qsTr
(
"
Distance
"
)
}
FactTextField
{
fact
:
generator
.
distance
...
...
src/MeasurementComplexItem/qml/MeasurementAreaEditor.qml
View file @
8da5e19a
import
QtQuick
2.3
import
QtQuick
.
Controls
1.2
import
QtQuick
.
Controls
.
Styles
1.4
import
QtQuick
.
Dialogs
1.2
import
QtQuick
.
Extras
1.4
import
QtQuick
.
Layouts
1.2
import
QGroundControl
1.0
...
...
@@ -13,140 +10,98 @@ import QGroundControl.FactControls 1.0
import
QGroundControl
.
Palette
1.0
import
QGroundControl
.
FlightMap
1.0
// Editor for Operating Area items
Rectangle
{
id
:
_root
height
:
visible
?
(
editorColumn
.
height
+
(
_margin
*
2
))
:
0
width
:
availableWidth
color
:
qgcPal
.
windowShadeDark
radius
:
_radius
property
real
_margin
:
ScreenTools
.
defaultFontPixelWidth
/
2
property
real
_fieldWidth
:
ScreenTools
.
defaultFontPixelWidth
*
10.5
property
bool
polygonInteractive
:
areaItem
.
interactive
property
var
polygon
:
areaItem
property
bool
initNecesarry
:
true
onPolygonInteractiveChanged
:
{
polygon
.
interactive
=
polygonInteractive
;
}
QGCPalette
{
id
:
qgcPal
;
colorGroupEnabled
:
true
}
Column
{
GridLayout
{
id
:
editorColumn
anchors.margins
:
_margin
anchors.top
:
parent
.
top
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
spacing
:
_margin
SectionHeader
{
id
:
settingsHeader
text
:
qsTr
(
"
General
"
)
}
Column
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
spacing
:
_margin
visible
:
settingsHeader
.
checked
GridLayout
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
columns
:
2
columnSpacing
:
_margin
rowSpacing
:
_margin
columns
:
2
QGCLabel
{
text
:
qsTr
(
"
Offset
"
)
}
width
:
availableWidth
FactTextField
{
fact
:
areaItem
.
borderPolygonOffset
Layout.fillWidth
:
true
}
}
property
var
geoArea
:
undefined
property
int
availableWidth
FactCheckBox
{
text
:
qsTr
(
"
Border Polygon
"
)
fact
:
areaItem
.
showBorderPolygon
//enabled: !missionItem.followTerrain
}
property
real
_margin
:
ScreenTools
.
defaultFontPixelWidth
/
2
Item
{
height
:
ScreenTools
.
defaultFontPixelHeight
/
2
width
:
1
Component.onCompleted
:
{
console
.
assert
(
geoArea
!==
undefined
,
"
please set the areaItem property
"
)
}
}
// Column - Settings
SectionHeader
{
id
:
tilesHeader
text
:
qsTr
(
"
Tiles
"
)
Layout.columnSpan
:
2
Layout.fillWidth
:
true
}
Column
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
spacing
:
_margin
GridLayout
{
visible
:
tilesHeader
.
checked
GridLayout
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
Layout.fillWidth
:
true
Layout.columnSpan
:
2
columnSpacing
:
_margin
rowSpacing
:
_margin
columns
:
2
QGCLabel
{
text
:
qsTr
(
"
Height
"
)
}
QGCLabel
{
text
:
qsTr
(
"
Height
"
)
Layout.fillWidth
:
true
}
FactTextField
{
fact
:
areaItem
.
tileHeight
fact
:
geoArea
.
tileHeight
Layout.fillWidth
:
true
}
QGCLabel
{
text
:
qsTr
(
"
Width
"
)
}
QGCLabel
{
text
:
qsTr
(
"
Width
"
)
Layout.fillWidth
:
true
}
FactTextField
{
fact
:
areaItem
.
tileWidth
fact
:
geoArea
.
tileWidth
Layout.fillWidth
:
true
}
QGCLabel
{
text
:
qsTr
(
"
Min. Area
"
)
}
QGCLabel
{
text
:
qsTr
(
"
Min. Area
"
)
Layout.fillWidth
:
true
}
FactTextField
{
fact
:
areaItem
.
minTileArea
fact
:
geoArea
.
minTileArea
Layout.fillWidth
:
true
}
FactCheckBox
{
text
:
qsTr
(
"
Show Tiles
"
)
fact
:
areaItem
.
showTiles
fact
:
geoArea
.
showTiles
}
}
}
// Tile GridLayout
}
// Tile Column
SectionHeader
{
id
:
statsHeader
text
:
qsTr
(
"
Statistics
"
)
Layout.fillWidth
:
true
Layout.columnSpan
:
2
}
Grid
{
columns
:
2
columnSpacing
:
ScreenTools
.
defaultFontPixelWidth
GridLayout
{
visible
:
statsHeader
.
checked
Layout.fillWidth
:
true
Layout.columnSpan
:
2
columnSpacing
:
_margin
rowSpacing
:
_margin
columns
:
2
QGCLabel
{
text
:
qsTr
(
"
Area
"
)
}
QGCLabel
{
text
:
QGroundControl
.
squareMetersToAppSettingsAreaUnits
(
areaItem
.
area
).
toFixed
(
2
)
+
"
"
+
QGroundControl
.
appSettingsAreaUnitsString
}
// QGCLabel { text: QGroundControl.squareMetersToAppSettingsAreaUnits(geoArea.area).toFixed(2) + " " + QGroundControl.appSettingsAreaUnitsString }
QGCLabel
{
text
:
qsTr
(
"
Tiles
"
)
}
QGCLabel
{
text
:
areaItem
.
tiles
.
count
}
QGCLabel
{
text
:
geoArea
.
tiles
.
count
}
QGCLabel
{
text
:
qsTr
(
"
Max. Tiles
"
)
}
QGCLabel
{
text
:
areaItem
.
maxTiles
}
QGCLabel
{
text
:
geoArea
.
maxTiles
}
}
}
// Column
}
// Rectangle
}
// Column
src/MeasurementComplexItem/qml/MeasurementAreaMapVisual.qml
View file @
8da5e19a
...
...
@@ -44,6 +44,7 @@ Item {
borderColor
:
"
green
"
interiorColor
:
"
green
"
altColor
:
QGroundControl
.
globalPalette
.
surveyPolygonTerrainCollision
z
:
QGroundControl
.
zOrderMapItems
-
1
interiorOpacity
:
_root
.
opacity
}
...
...
src/MeasurementComplexItem/qml/MeasurementComplexItem.qmldir
0 → 100644
View file @
8da5e19a
ParameterEditor 1.0 ParameterEditor.qml
AreaDataEditor 1.0 AreaDataEditor.qml
LinearGenerator 1.0 LinearGenerator.qml
CircularGenerator 1.0 CircularGenerator.qml
SafeAreaEditor 1.0 SafeAreaEditor.qml
MeasurementAreaEditor 1.0 MeasurementAreaEditor.qml
src/MeasurementComplexItem/qml/MeasurementItemEditor.qml
View file @
8da5e19a
This diff is collapsed.
Click to expand it.
src/MeasurementComplexItem/qml/MeasurementItemMapVisual.qml
View file @
8da5e19a
...
...
@@ -37,21 +37,28 @@ Item {
signal
clicked
(
int
sequenceNumber
)
on_EditingChanged
:
{
_destroyEntryCoordinate
()
_destroyExitCoordinate
()
_destroyTransectsComponent
()
_destroyGeneratorVisuals
()
}
// on_EditingChanged: {
// if (_editing){
// _destroyEntryCoordinate()
// _destroyExitCoordinate()
// _destroyTransectsComponent()
// _destroyGeneratorVisuals()
// } else {
// _addEntryCoordinate()
// _addExitCoordinate()
// _addTransectsComponent()
// _addGeneratorVisuals()
// }
// }
Component.onCompleted
:
{
console
.
assert
(
map
!=
undefined
,
"
please set the map property
"
)
_addEntryCoordinate
()
_addExitCoordinate
()
_addTransectsComponent
()
_addGeneratorVisuals
()
var
bbox
=
boundingBox
()
_missionItem
.
areaData
.
initialize
(
bbox
[
0
],
bbox
[
1
])
console
.
assert
(
map
!=
undefined
,
"
please set the map property
"
)
}
Component.onDestruction
:
{
...
...
@@ -71,10 +78,11 @@ Item {
id
:
visualTransectsComponent
MapPolyline
{
property
var
route
:
_missionItem
.
route
line.color
:
"
white
"
line.width
:
2
path
:
route
.
length
>
0
?
route
:
[]
path
:
_missionItem
.
route
onPathChanged
:
console
.
log
(
"
path:
"
+
path
)
}
}
...
...
src/MeasurementComplexItem/qml/ParameterEditor.qml
0 → 100644
View file @
8da5e19a
import
QtQuick
2.3
import
QtQuick
.
Controls
1.2
import
QtQuick
.
Controls
.
Styles
1.4
import
QtQuick
.
Dialogs
1.2
import
QtQuick
.
Extras
1.4
import
QtQuick
.
Layouts
1.2
import
QGroundControl
1.0
import
QGroundControl
.
ScreenTools
1.0
import
QGroundControl
.
Vehicle
1.0
import
QGroundControl
.
Controls
1.0
import
QGroundControl
.
FactSystem
1.0
import
QGroundControl
.
FactControls
1.0
import
QGroundControl
.
Palette
1.0
import
QGroundControl
.
FlightMap
1.0
ColumnLayout
{
id
:
root
property
int
availableWidth
:
300
property
var
missionItem
:
undefined
///< Mission Item for editor
property
bool
checked
:
true
property
real
_margin
:
ScreenTools
.
defaultFontPixelWidth
/
2
property
var
_generator
:
missionItem
.
generator
property
var
_generatorEditor
:
undefined
width
:
availableWidth
Component.onCompleted
:
{
console
.
assert
(
missionItem
!==
undefined
,
"
please set the missionItem property
"
)
_addGeneratorEditor
()
}
Component.onDestruction
:
{
_destroyGeneratorEditor
()
}
on_GeneratorChanged
:
{
_destroyGeneratorEditor
()
_addGeneratorEditor
()
}
SectionHeader
{
id
:
generalHeader
Layout.fillWidth
:
true
text
:
qsTr
(
"
General
"
)
}
GridLayout
{
id
:
generalGrid
Layout.fillWidth
:
true
columnSpacing
:
_margin
rowSpacing
:
_margin
columns
:
2
visible
:
generalHeader
.
checked
QGCLabel
{
text
:
qsTr
(
"
Altitude!!!
"
)
}
QGCLabel
{
text
:
qsTr
(
"
Relative Altitude!!!
"
)
}
QGCLabel
{
text
:
qsTr
(
"
Variant
"
)
Layout.columnSpan
:
2
visible
:
variantRepeater
.
len
>
0
}
GridLayout
{
Layout.columnSpan
:
2
columnSpacing
:
_margin
rowSpacing
:
_margin
columns
:
6
Repeater
{
id
:
variantRepeater
property
var
fact
:
missionItem
.
variant
property
int
variant
:
fact
.
value
property
var
names
:
missionItem
.
variantNames
property
int
len
:
missionItem
.
variantNames
.
length
model
:
len
delegate
:
QGCRadioButton
{
checked
:
index
===
variantRepeater
.
variant
text
:
variantRepeater
.
names
[
index
]
?
variantRepeater
.
names
[
index
]:
""
onCheckedChanged
:
{
if
(
checked
){
missionItem
.
variant
.
value
=
index
}
checked
=
Qt
.
binding
(
function
(){
return
index
===
variantRepeater
.
variant
})
}
}
}
// variant repeater
}
// variant grid
}
// general grid
// Generator Editor
SectionHeader
{
id
:
generatorHeader
Layout.fillWidth
:
true
text
:
qsTr
(
"
Generator
"
)
}
GridLayout
{
Layout.fillWidth
:
true
columnSpacing
:
_margin
rowSpacing
:
_margin
columns
:
2
visible
:
generatorHeader
.
checked
QGCComboBox
{
property
var
names
:
missionItem
.
generatorNameList
property
int
length
:
names
.
length
enabled
:
root
.
checked
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
currentIndex
:
missionItem
.
generatorIndex
Layout.columnSpan
:
2
model
:
missionItem
.
generatorNameList
onActivated
:
{
if
(
index
!=
-
1
){
missionItem
.
switchToGenerator
(
index
)
}
}
}
}
ColumnLayout
{
id
:
generatorEditorParent
Layout.fillWidth
:
true
visible
:
generatorHeader
.
checked
}
// bussy indicator
ColumnLayout
{
Layout.fillWidth
:
true
spacing
:
_margin
BusyIndicator
{
id
:
indicator
property
bool
calculating
:
missionItem
.
calculating
running
:
calculating
visible
:
calculating
||
timer
.
running
onCalculatingChanged
:
{
if
(
!
calculating
){
// defer hiding
timer
.
restart
()
}
}
Timer
{
id
:
timer
interval
:
1000
repeat
:
false
running
:
false
}
}
}
// indicator column
function
_addGeneratorEditor
(){
if
(
_generator
.
editorQml
&&
!
_generatorEditor
)
{
var
component
=
Qt
.
createComponent
(
_generator
.
editorQml
)
if
(
component
.
status
===
Component
.
Error
)
{
console
.
log
(
"
Error loading Qml:
"
,
_generator
.
editorQml
,
component
.
errorString
())
}
else
{
_generatorEditor
=
component
.
createObject
(
generatorEditorParent
,
{
"
generator
"
:
root
.
_generator
,
"
availableWidth
"
:
generatorEditorParent
.
width
,
})
}
}
}
function
_destroyGeneratorEditor
(){
if
(
_generatorEditor
){
_generatorEditor
.
destroy
()
_generatorEditor
=
undefined
}
}
}
src/MeasurementComplexItem/qml/ProgressIndicator.qml
deleted
100644 → 0
View file @
5a5b161e
import
QtQml
2.2
import
QtQuick
2.0
import
QtLocation
5.3
MapQuickItem
{
id
:
root
width
:
15
height
:
15
anchorPoint.x
:
width
/
2
anchorPoint.y
:
height
/
2
property
color
primaryColor
:
"
orange
"
property
color
secondaryColor
:
"
lightblue
"
property
real
centerWidth
:
width
/
2
property
real
centerHeight
:
height
/
2
property
real
radius
:
Math
.
min
(
canvas
.
width
,
canvas
.
height
)
/
2
property
real
minimumValue
:
0
property
real
maximumValue
:
100
property
real
currentValue
:
33
// this is the angle that splits the circle in two arcs
// first arc is drawn from 0 radians to angle radians
// second arc is angle radians to 2*PI radians
property
real
angle
:
(
currentValue
-
minimumValue
)
/
(
maximumValue
-
minimumValue
)
*
2
*
Math
.
PI
// we want both circle to start / end at 12 o'clock
// without this offset we would start / end at 9 o'clock
property
real
angleOffset
:
-
Math
.
PI
/
2
property
string
text
:
""
signal
clicked
()
onPrimaryColorChanged
:
canvas
.
requestPaint
()
onSecondaryColorChanged
:
canvas
.
requestPaint
()
onMinimumValueChanged
:
canvas
.
requestPaint
()
onMaximumValueChanged
:
canvas
.
requestPaint
()
onCurrentValueChanged
:
canvas
.
requestPaint
()
// draws two arcs (portion of a circle)
// fills the circle with a lighter secondary color
// when pressed
sourceItem
:
Canvas
{
id
:
canvas
width
:
root
.
width
height
:
root
.
height
antialiasing
:
true
onPaint
:
{
var
ctx
=
getContext
(
"
2d
"
);
ctx
.
save
();
ctx
.
clearRect
(
0
,
0
,
canvas
.
width
,
canvas
.
height
);
// fills the mouse area when pressed
// the fill color is a lighter version of the
// secondary color
if
(
mouseArea
.
pressed
)
{
ctx
.
beginPath
();
ctx
.
lineWidth
=
1
;
ctx
.
fillStyle
=
Qt
.
lighter
(
root
.
secondaryColor
,
1.25
);
ctx
.
arc
(
root
.
centerWidth
,
root
.
centerHeight
,
root
.
radius
,
0
,
2
*
Math
.
PI
);
ctx
.
fill
();
}
// First, thinner arc
// From angle to 2*PI
ctx
.
beginPath
();
ctx
.
lineWidth
=
1
;
ctx
.
strokeStyle
=
primaryColor
;
ctx
.
arc
(
root
.
centerWidth
,
root
.
centerHeight
,
root
.
radius
,
angleOffset
+
root
.
angle
,
angleOffset
+
2
*
Math
.
PI
);
ctx
.
stroke
();
// Second, thicker arc
// From 0 to angle
ctx
.
beginPath
();
ctx
.
lineWidth
=
1
;
ctx
.
strokeStyle
=
root
.
secondaryColor
;
ctx
.
arc
(
root
.
centerWidth
,
root
.
centerHeight
,
root
.
radius
,
root
.
angleOffset
,
root
.
angleOffset
+
root
.
angle
);
ctx
.
stroke
();
ctx
.
restore
();
}
Text
{
anchors.centerIn
:
parent
text
:
root
.
text
color
:
root
.
primaryColor
}
MouseArea
{
id
:
mouseArea
anchors.fill
:
parent
onClicked
:
root
.
clicked
()
onPressedChanged
:
canvas
.
requestPaint
()
}
}
}
src/MeasurementComplexItem/qml/SafeAreaEditor.qml
View file @
8da5e19a
import
QtQuick
2.3
import
QtQuick
.
Controls
1.2
import
QtQuick
.
Controls
.
Styles
1.4
import
QtQuick
.
Dialogs
1.2
import
QtQuick
.
Extras
1.4
import
QtQuick
.
Layouts
1.2
import
QGroundControl
1.0
import
QGroundControl
.
ScreenTools
1.0
import
QGroundControl
.
Vehicle
1.0
import
QGroundControl
.
Controls
1.0
import
QGroundControl
.
FactControls
1.0
import
QGroundControl
.
Palette
1.0
import
QGroundControl
.
FlightMap
1.0
// Editor for Operating Area items
Rectangle
{
id
:
_root
height
:
visible
?
(
editorColumn
.
height
+
(
_margin
*
2
))
:
0
width
:
availableWidth
color
:
qgcPal
.
windowShadeDark
radius
:
_radius
property
real
_margin
:
ScreenTools
.
defaultFontPixelWidth
/
2
property
real
_fieldWidth
:
ScreenTools
.
defaultFontPixelWidth
*
10.5
property
bool
polygonInteractive
:
areaItem
.
interactive
property
var
polygon
:
areaItem
property
bool
initNecesarry
:
true
QGCPalette
{
id
:
qgcPal
;
colorGroupEnabled
:
true
}
Column
{
GridLayout
{
id
:
editorColumn
anchors.margins
:
_margin
anchors.top
:
parent
.
top
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
spacing
:
_margin
SectionHeader
{
id
:
scanHeader
text
:
qsTr
(
"
Settings
"
)
}
Column
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
spacing
:
_margin
visible
:
scanHeader
.
checked
GridLayout
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
columns
:
2
columnSpacing
:
_margin
rowSpacing
:
_margin
columns
:
2
QGCLabel
{
text
:
qsTr
(
"
Offset
"
)
}
width
:
availableWidth
FactTextField
{
fact
:
areaItem
.
borderPolygonOffset
Layout.fillWidth
:
true
}
}
property
var
geoArea
:
undefined
property
int
availableWidth
Item
{
height
:
ScreenTools
.
defaultFontPixelHeight
/
2
width
:
1
}
}
property
real
_margin
:
ScreenTools
.
defaultFontPixelWidth
/
2
FactCheckBox
{
text
:
qsTr
(
"
Border Polygon
"
)
fact
:
areaItem
.
showBorderPolygon
//enabled: !missionItem.followTerrain
Component.onCompleted
:
{
console
.
assert
(
geoArea
!==
undefined
,
"
please set the areaItem property
"
)
}
SectionHeader
{
id
:
statsHeader
text
:
qsTr
(
"
Statistics
"
)
Layout.fillWidth
:
true
Layout.columnSpan
:
2
}
Grid
{
GridLayout
{
columns
:
2
columnSpacing
:
ScreenTools
.
defaultFontPixelWidth
columnSpacing
:
_margin
rowSpacing
:
_margin
visible
:
statsHeader
.
checked
Layout.fillWidth
:
true
Layout.columnSpan
:
2
QGCLabel
{
text
:
qsTr
(
"
Area
"
)
}
QGCLabel
{
text
:
QGroundControl
.
squareMetersToAppSettingsAreaUnits
(
areaItem
.
area
).
toFixed
(
2
)
+
"
"
+
QGroundControl
.
appSettingsAreaUnitsString
}
//QGCLabel { text: QGroundControl.squareMetersToAppSettingsAreaUnits(geoArea.area).toFixed(2) + " " + QGroundControl.appSettingsAreaUnitsString }
}
}
// Column
}
// Rectangle
}
src/MeasurementComplexItem/qml/SafeAreaMapVisual.qml
View file @
8da5e19a
...
...
@@ -24,36 +24,13 @@ Item {
property
var
map
:
undefined
///< Map control to place item in
property
var
geoArea
:
undefined
///< GeoArea derived class.
property
var
_depotVisual
:
undefined
property
var
_depotDrag
:
undefined
property
bool
_showDepot
:
geoArea
.
interactive
opacity
:
0.3
signal
clicked
(
int
sequenceNumber
)
on_ShowDepotChanged
:
{
if
(
_showDepot
){
_addDepotVisual
()
_addDepotDrag
()
}
else
{
_destroyDepotVisual
()
_destroyDepotDrag
()
}
}
Component.onCompleted
:
{
if
(
_showDepot
){
_addDepotVisual
()
_addDepotDrag
()
}
console
.
assert
(
map
!==
undefined
,
"
please set the map property
"
)
console
.
assert
(
geoArea
!==
undefined
,
"
please set the geoArea property
"
)
}
Component.onDestruction
:
{
_destroyDepotVisual
()
}
// Area polygon
QGCMapPolygonVisuals
{
...
...
@@ -65,78 +42,61 @@ Item {
borderColor
:
"
blue
"
interiorColor
:
"
blue
"
altColor
:
QGroundControl
.
globalPalette
.
surveyPolygonTerrainCollision
interiorOpacity
:
_root
.
opacity
z
:
QGroundControl
.
zOrderMapItems
-
1
interiorOpacity
:
0.3
}
Loader
{
id
:
depotLoader
sourceComponent
:
depotComponent
}
// Depot Point.
Component
{
id
:
depotPointComponent
id
:
depotComponent
Item
{
id
:
depotMapItem
MapQuickItem
{
id
:
mapItem
coordinate
:
_root
.
geoArea
.
depot
anchorPoint.x
:
sourceItem
.
anchorPointX
anchorPoint.y
:
sourceItem
.
anchorPointY
visible
:
true
z
:
QGroundControl
.
zOrderMapItems
Component.onCompleted
:
{
coordinate
=
Qt
.
binding
(
function
(){
return
_root
.
geoArea
.
depot
})
}
sourceItem
:
MissionItemIndexLabel
{
checked
:
geoArea
.
interactiv
e
label
:
qsTr
(
"
Launch
"
)
checked
:
tru
e
label
:
qsTr
(
"
Depot
"
)
highlightSelected
:
true
onClicked
:
_root
.
clicked
(
0
)
visible
:
true
}
}
}
Component
{
id
:
depotDragComponent
MissionItemIndicatorDrag
{
mapControl
:
_root
.
map
itemIndicator
:
_depot
itemCoordinate
:
geoArea
.
depot
visible
:
geoArea
.
interactive
property
var
depot
:
geoArea
.
depot
onItemCoordinateChanged
:
{
if
(
itemCoordinate
.
latitude
!==
depot
.
latitude
||
itemCoordinate
.
longitude
!==
depot
.
longitude
){
if
(
_root
.
areaItem
.
containsCoordinate
(
itemCoordinate
)){
_root
.
areaItem
.
depot
=
itemCoordinate
}
}
itemCoordinate
=
Qt
.
binding
(
function
(){
return
_root
.
geoArea
.
depot
})
}
visible
:
mapItem
.
visible
z
:
mapItem
.
z
}
}
function
_addDepotVisual
()
{
if
(
!
_depotVisual
){
_depotVisual
=
depotPointComponent
.
createObject
(
_root
)
map
.
addMapItem
(
_depotVisual
)
}
}
ItemDragger
{
anchor
:
mapItem
z
:
QGroundControl
.
zOrderMapItems
+
1
draggable
:
_root
.
geoArea
.
interactive
function
_destroyDepotVisual
()
{
if
(
_depotVisual
){
map
.
removeMapItem
(
_depotVisual
)
_depotVisual
.
destroy
()
_depotVisual
=
undefined
onDragStop
:{
_root
.
geoArea
.
depot
=
mapItem
.
coordinate
mapItem
.
coordinate
=
Qt
.
binding
(
function
(){
return
_root
.
geoArea
.
depot
})
}
}
function
_addDepotDrag
()
{
if
(
!
_depotDrag
){
_depotDrag
=
depotDragComponent
.
createObject
(
_root
)
}
Component.onCompleted
:
{
_root
.
map
.
addMapItem
(
mapItem
)
}
function
_destroyDepotDrag
()
{
if
(
_depotDrag
){
_depotDrag
.
destroy
()
_depotDrag
=
undefined
}
}
}
src/MissionManager/QGCMapPolygon.h
View file @
8da5e19a
...
...
@@ -10,64 +10,71 @@
#ifndef QGCMapPolygon_H
#define QGCMapPolygon_H
#include <QObject>
#include <QGeoCoordinate>
#include <Q
VariantLis
t>
#include <Q
Objec
t>
#include <QPolygon>
#include <QVariantList>
#include "QmlObjectListModel.h"
#include "KMLDomDocument.h"
#include "QmlObjectListModel.h"
/// The QGCMapPolygon class provides a polygon which can be displayed on a map
using a map visuals control.
///
It maintains a representation of the polygon on QVariantList and QmlObjectListModel format.
class
QGCMapPolygon
:
public
QObject
{
/// The QGCMapPolygon class provides a polygon which can be displayed on a map
///
using a map visuals control. It maintains a representation of the polygon on
/// QVariantList and QmlObjectListModel format.
class
QGCMapPolygon
:
public
QObject
{
Q_OBJECT
public:
QGCMapPolygon
(
QObject
*
parent
=
nullptr
);
QGCMapPolygon
(
const
QGCMapPolygon
&
other
,
QObject
*
parent
=
nullptr
);
QGCMapPolygon
(
QObject
*
parent
=
nullptr
);
QGCMapPolygon
(
const
QGCMapPolygon
&
other
,
QObject
*
parent
=
nullptr
);
const
QGCMapPolygon
&
operator
=
(
const
QGCMapPolygon
&
other
);
const
QGCMapPolygon
&
operator
=
(
const
QGCMapPolygon
&
other
);
Q_PROPERTY
(
int
count
READ
count
NOTIFY
countChanged
)
Q_PROPERTY
(
QVariantList
path
READ
path
NOTIFY
pathChanged
)
Q_PROPERTY
(
double
area
READ
area
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
(
QGeoCoordinate
center
READ
center
WRITE
setCenter
NOTIFY
centerChanged
)
Q_PROPERTY
(
bool
centerDrag
READ
centerDrag
WRITE
setCenterDrag
NOTIFY
centerDragChanged
)
Q_PROPERTY
(
bool
interactive
READ
interactive
WRITE
setInteractive
NOTIFY
interactiveChanged
)
Q_PROPERTY
(
QGeoCoordinate
center
READ
center
WRITE
setCenter
NOTIFY
centerChanged
)
Q_PROPERTY
(
bool
centerDrag
READ
centerDrag
WRITE
setCenterDrag
NOTIFY
centerDragChanged
)
Q_PROPERTY
(
bool
interactive
READ
interactive
WRITE
setInteractive
NOTIFY
interactiveChanged
)
Q_PROPERTY
(
bool
isValid
READ
isValid
NOTIFY
isValidChanged
)
Q_PROPERTY
(
bool
empty
READ
empty
NOTIFY
isEmptyChanged
)
Q_PROPERTY
(
bool
traceMode
READ
traceMode
WRITE
setTraceMode
NOTIFY
traceModeChanged
)
Q_PROPERTY
(
bool
showAltColor
READ
showAltColor
WRITE
setShowAltColor
NOTIFY
showAltColorChanged
)
Q_PROPERTY
(
int
selectedVertex
READ
selectedVertex
WRITE
selectVertex
NOTIFY
selectedVertexChanged
)
Q_PROPERTY
(
bool
traceMode
READ
traceMode
WRITE
setTraceMode
NOTIFY
traceModeChanged
)
Q_PROPERTY
(
bool
showAltColor
READ
showAltColor
WRITE
setShowAltColor
NOTIFY
showAltColorChanged
)
Q_PROPERTY
(
int
selectedVertex
READ
selectedVertex
WRITE
selectVertex
NOTIFY
selectedVertexChanged
)
Q_INVOKABLE
void
clear
(
void
);
Q_INVOKABLE
void
appendVertex
(
const
QGeoCoordinate
&
coordinate
);
Q_INVOKABLE
void
appendVertex
(
const
QGeoCoordinate
&
coordinate
);
Q_INVOKABLE
void
removeVertex
(
int
vertexIndex
);
Q_INVOKABLE
void
appendVertices
(
const
QVariantList
&
varCoords
);
Q_INVOKABLE
void
appendVertices
(
const
QVariantList
&
varCoords
);
void
appendVertices
(
const
QList
<
QGeoCoordinate
>&
coordinates
);
void
appendVertices
(
const
QList
<
QGeoCoordinate
>
&
coordinates
);
/// Adjust the value for the specified coordinate
/// @param vertexIndex Polygon point index to modify (0-based)
/// @param coordinate New coordinate for point
Q_INVOKABLE
void
adjustVertex
(
int
vertexIndex
,
const
QGeoCoordinate
coordinate
);
Q_INVOKABLE
void
adjustVertex
(
int
vertexIndex
,
const
QGeoCoordinate
coordinate
);
/// Splits the segment comprised of vertextIndex -> vertexIndex + 1
Q_INVOKABLE
void
splitPolygonSegment
(
int
vertexIndex
);
/// 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
;
/// Offsets the current polygon edges by the specified distance in meters
Q_INVOKABLE
void
offset
(
double
distance
);
/// Loads a polygon from a KML/SH{ file
/// @return true: success
Q_INVOKABLE
bool
loadKMLOrSHPFile
(
const
QString
&
file
);
Q_INVOKABLE
bool
loadKMLOrSHPFile
(
const
QString
&
file
);
/// Returns the path in a list of QGeoCoordinate's format
QList
<
QGeoCoordinate
>
coordinateList
(
void
)
const
;
...
...
@@ -78,19 +85,20 @@ public:
/// Adjust polygon winding order to be clockwise (if needed)
Q_INVOKABLE
void
verifyClockwiseWinding
(
void
);
Q_INVOKABLE
void
beginReset
(
void
);
Q_INVOKABLE
void
endReset
(
void
);
Q_INVOKABLE
void
beginReset
(
void
);
Q_INVOKABLE
void
endReset
(
void
);
/// Saves the polygon to the json object.
/// @param json Json object to save to
void
saveToJson
(
QJsonObject
&
json
);
void
saveToJson
(
QJsonObject
&
json
);
/// 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)
bool
loadFromJson
(
const
QJsonObject
&
json
,
bool
required
,
QString
&
errorString
);
bool
loadFromJson
(
const
QJsonObject
&
json
,
bool
required
,
QString
&
errorString
);
/// Convert polygon to NED and return (D is ignored)
QList
<
QPointF
>
nedPolygon
(
void
)
const
;
...
...
@@ -98,48 +106,48 @@ public:
/// Returns the area of the polygon in meters squared
double
area
(
void
)
const
;
QDomElement
kmlPolygonElement
(
KMLDomDocument
&
domDocument
);
QDomElement
kmlPolygonElement
(
KMLDomDocument
&
domDocument
);
// Property methods
int
count
(
void
)
const
{
return
_polygonPath
.
count
();
}
bool
dirty
(
void
)
const
{
return
_dirty
;
}
void
setDirty
(
bool
dirty
);
QGeoCoordinate
center
(
void
)
const
{
return
_center
;
}
bool
centerDrag
(
void
)
const
{
return
_centerDrag
;
}
bool
interactive
(
void
)
const
{
return
_interactive
;
}
bool
isValid
(
void
)
const
{
return
_polygonModel
.
count
()
>=
3
;
}
bool
empty
(
void
)
const
{
return
_polygonModel
.
count
()
==
0
;
}
bool
traceMode
(
void
)
const
{
return
_traceMode
;
}
int
count
(
void
)
const
{
return
_polygonPath
.
count
();
}
bool
dirty
(
void
)
const
{
return
_dirty
;
}
void
setDirty
(
bool
dirty
);
QGeoCoordinate
center
(
void
)
const
{
return
_center
;
}
bool
centerDrag
(
void
)
const
{
return
_centerDrag
;
}
bool
interactive
(
void
)
const
{
return
_interactive
;
}
bool
isValid
(
void
)
const
{
return
_polygonModel
.
count
()
>=
3
;
}
bool
empty
(
void
)
const
{
return
_polygonModel
.
count
()
==
0
;
}
bool
traceMode
(
void
)
const
{
return
_traceMode
;
}
bool
showAltColor
(
void
)
const
{
return
_showAltColor
;
}
int
selectedVertex
()
const
{
return
_selectedVertexIndex
;
}
QVariantList
path
(
void
)
const
{
return
_polygonPath
;
}
QmlObjectListModel
*
qmlPathModel
(
void
)
{
return
&
_polygonModel
;
}
QmlObjectListModel
&
pathModel
(
void
)
{
return
_polygonModel
;
}
QVariantList
path
(
void
)
const
{
return
_polygonPath
;
}
QmlObjectListModel
*
qmlPathModel
(
void
)
{
return
&
_polygonModel
;
}
QmlObjectListModel
&
pathModel
(
void
)
{
return
_polygonModel
;
}
void
setPath
(
const
QList
<
QGeoCoordinate
>&
path
);
void
setPath
(
const
QVariantList
&
path
);
void
setCenter
(
QGeoCoordinate
newCenter
);
void
setCenterDrag
(
bool
centerDrag
);
void
setInteractive
(
bool
interactive
);
void
setTraceMode
(
bool
traceMode
);
void
setPath
(
const
QList
<
QGeoCoordinate
>
&
path
);
void
setPath
(
const
QVariantList
&
path
);
void
setCenter
(
QGeoCoordinate
newCenter
);
void
setCenterDrag
(
bool
centerDrag
);
void
setInteractive
(
bool
interactive
);
void
setTraceMode
(
bool
traceMode
);
void
setShowAltColor
(
bool
showAltColor
);
void
selectVertex
(
int
index
);
void
selectVertex
(
int
index
);
static
const
char
*
jsonPolygonKey
;
static
const
char
*
jsonPolygonKey
;
signals:
void
countChanged
(
int
count
);
void
pathChanged
(
void
);
void
dirtyChanged
(
bool
dirty
);
void
cleared
(
void
);
void
centerChanged
(
QGeoCoordinate
center
);
void
centerDragChanged
(
bool
centerDrag
);
void
interactiveChanged
(
bool
interactive
);
bool
isValidChanged
(
void
);
bool
isEmptyChanged
(
void
);
void
traceModeChanged
(
bool
traceMode
);
void
countChanged
(
int
count
);
void
pathChanged
(
void
);
void
dirtyChanged
(
bool
dirty
);
void
cleared
(
void
);
void
centerChanged
(
QGeoCoordinate
center
);
void
centerDragChanged
(
bool
centerDrag
);
void
interactiveChanged
(
bool
interactive
);
bool
isValidChanged
(
void
);
bool
isEmptyChanged
(
void
);
void
traceModeChanged
(
bool
traceMode
);
void
showAltColorChanged
(
bool
showAltColor
);
void
selectedVertexChanged
(
int
index
);
...
...
@@ -149,12 +157,12 @@ private slots:
void
_updateCenter
(
void
);
private:
void
_init
(
void
);
QPolygonF
_toPolygonF
(
void
)
const
;
QGeoCoordinate
_coordFromPointF
(
const
QPointF
&
point
)
const
;
QPointF
_pointFFromCoord
(
const
QGeoCoordinate
&
coordinate
)
const
;
void
_beginResetIfNotActive
(
void
);
void
_endResetIfNotActive
(
void
);
void
_init
(
void
);
QPolygonF
_toPolygonF
(
void
)
const
;
QGeoCoordinate
_coordFromPointF
(
const
QPointF
&
point
)
const
;
QPointF
_pointFFromCoord
(
const
QGeoCoordinate
&
coordinate
)
const
;
void
_beginResetIfNotActive
(
void
);
void
_endResetIfNotActive
(
void
);
QVariantList
_polygonPath
;
QmlObjectListModel
_polygonModel
;
...
...
src/MissionManager/QGCMapPolygonVisuals.qml
View file @
8da5e19a
...
...
@@ -34,6 +34,10 @@ Item {
property
int
borderWidth
:
0
property
color
borderColor
:
"
black
"
readonly
property
bool
editing
:
_editing
property
bool
_editing
:
false
property
bool
_circleMode
:
false
property
real
_circleRadius
property
bool
_circleRadiusDrag
:
false
...
...
@@ -50,6 +54,7 @@ Item {
readonly
property
string
_polygonToolsText
:
qsTr
(
"
Polygon Tools
"
)
readonly
property
string
_traceText
:
qsTr
(
"
Click in the map to add vertices. Click 'Done Tracing' when finished.
"
)
function
addCommonVisuals
()
{
if
(
_objMgrCommonVisuals
.
empty
)
{
_objMgrCommonVisuals
.
createObject
(
polygonComponent
,
mapControl
,
true
)
...
...
@@ -301,7 +306,13 @@ Item {
sourceItem
:
SplitIndicator
{
z
:
_zorderSplitHandle
onClicked
:
if
(
_root
.
interactive
)
mapPolygon
.
splitPolygonSegment
(
mapQuickItem
.
vertexIndex
)
onClicked
:
{
if
(
_root
.
interactive
){
mapPolygon
.
splitPolygonSegment
(
mapQuickItem
.
vertexIndex
)
_root
.
split
()
}
}
}
}
}
...
...
@@ -351,7 +362,6 @@ Item {
mapControl
:
_root
.
mapControl
z
:
_zorderDragHandle
visible
:
!
_circleMode
onDragStop
:
mapPolygon
.
verifyClockwiseWinding
()
property
int
polygonVertex
...
...
@@ -366,6 +376,15 @@ Item {
}
}
onDragStart
:{
_root
.
_editing
=
true
}
onDragStop
:{
mapPolygon
.
verifyClockwiseWinding
()
_root
.
_editing
=
false
}
onClicked
:
if
(
_root
.
interactive
)
menu
.
popupVertex
(
polygonVertex
)
}
}
...
...
@@ -487,9 +506,17 @@ Item {
MissionItemIndicatorDrag
{
mapControl
:
_root
.
mapControl
z
:
_zorderCenterHandle
onItemCoordinateChanged
:
mapPolygon
.
center
=
itemCoordinate
onDragStart
:
mapPolygon
.
centerDrag
=
true
onDragStop
:
mapPolygon
.
centerDrag
=
false
onDragStart
:
{
mapPolygon
.
centerDrag
=
true
_root
.
_editing
=
true
}
onDragStop
:{
mapPolygon
.
centerDrag
=
false
_root
.
_editing
=
false
}
}
}
...
...
@@ -620,6 +647,14 @@ Item {
_lastRadius
=
radius
}
}
onDragStart
:
{
_root
.
_editing
=
true
}
onDragStop
:
{
_root
.
_editing
=
false
}
}
}
...
...
src/QmlControls/QGroundControl/Controls/qmldir
View file @
8da5e19a
...
...
@@ -113,6 +113,4 @@ MAVLinkChart 1.0 MAVLinkChart.qml
MeasurementItemMapVisual 1.0 MeasurementItemMapVisual.qml
CircularGeneratorMapVisual 1.0 CircularGeneratorMapVisual.qml
GeoAreaVisualLoader 1.0 GeoAreaVisualLoader.qml
DragCoordinate 1.0 DragCoordinate.qml
CoordinateIndicator 1.0 CoordinateIndicator.qml
CoordinateIndicatorDrag 1.0 CoordinateIndicatorDrag.qml
ItemDragger 1.0 ItemDragger.qml
src/QmlControls/QmlObjectListModel.h
View file @
8da5e19a
...
...
@@ -7,80 +7,84 @@
*
****************************************************************************/
#ifndef QmlObjectListModel_H
#define QmlObjectListModel_H
#include <QAbstractListModel>
class
QmlObjectListModel
:
public
QAbstractListModel
{
class
QmlObjectListModel
:
public
QAbstractListModel
{
Q_OBJECT
public:
QmlObjectListModel
(
QObject
*
parent
=
nullptr
);
QmlObjectListModel
(
QObject
*
parent
=
nullptr
);
~
QmlObjectListModel
()
override
;
Q_PROPERTY
(
int
count
READ
count
NOTIFY
countChanged
)
/// Returns true if any of the items in the list are dirty. Requires each object to have
///
a dirty property and dirtyChanged signal.
/// Returns true if any of the items in the list are dirty. Requires each
/// object to have
a dirty property and dirtyChanged signal.
Q_PROPERTY
(
bool
dirty
READ
dirty
WRITE
setDirty
NOTIFY
dirtyChanged
)
Q_INVOKABLE
QObject
*
get
(
int
index
);
Q_INVOKABLE
QObject
*
get
(
int
index
);
// Property accessors
int
count
()
const
;
bool
dirty
()
const
{
return
_dirty
;
}
void
setDirty
(
bool
dirty
);
void
append
(
QObject
*
object
);
void
append
(
QList
<
QObject
*>
objects
);
QObjectList
swapObjectList
(
const
QObjectList
&
newlist
);
void
clear
();
QObject
*
removeAt
(
int
i
);
QObject
*
removeOne
(
QObject
*
object
)
{
return
removeAt
(
indexOf
(
object
));
}
void
insert
(
int
i
,
QObject
*
object
);
void
insert
(
int
i
,
QList
<
QObject
*>
objects
);
bool
contains
(
QObject
*
object
)
{
return
_objectList
.
indexOf
(
object
)
!=
-
1
;
}
int
indexOf
(
QObject
*
object
)
{
return
_objectList
.
indexOf
(
object
);
}
int
count
()
const
;
bool
dirty
()
const
{
return
_dirty
;
}
void
setDirty
(
bool
dirty
);
void
append
(
QObject
*
object
);
void
append
(
QList
<
QObject
*>
objects
);
QObjectList
swapObjectList
(
const
QObjectList
&
newlist
);
void
clear
();
QObject
*
removeAt
(
int
i
);
QObject
*
removeOne
(
QObject
*
object
)
{
return
removeAt
(
indexOf
(
object
));
}
void
insert
(
int
i
,
QObject
*
object
);
void
insert
(
int
i
,
QList
<
QObject
*>
objects
);
bool
contains
(
QObject
*
object
)
{
return
_objectList
.
indexOf
(
object
)
!=
-
1
;
}
int
indexOf
(
QObject
*
object
)
{
return
_objectList
.
indexOf
(
object
);
}
/// Moves an item to a new position
void
move
(
int
from
,
int
to
);
QObject
*
operator
[]
(
int
i
);
const
QObject
*
operator
[]
(
int
i
)
const
;
template
<
class
T
>
T
value
(
int
index
)
{
return
qobject_cast
<
T
>
(
_objectList
[
index
]);
}
QList
<
QObject
*>*
objectList
()
{
return
&
_objectList
;
}
QObject
*
operator
[](
int
i
);
const
QObject
*
operator
[](
int
i
)
const
;
template
<
class
T
>
T
value
(
int
index
)
{
return
qobject_cast
<
T
>
(
_objectList
[
index
]);
}
QList
<
QObject
*>
*
objectList
()
{
return
&
_objectList
;
}
/// Calls deleteLater on all items and this itself.
void
deleteListAndContents
();
void
deleteListAndContents
();
/// Clears the list and calls deleteLater on each entry
void
clearAndDeleteContents
();
void
clearAndDeleteContents
();
void
beginReset
();
void
endReset
();
void
beginReset
();
void
endReset
();
signals:
void
countChanged
(
int
count
);
void
dirtyChanged
(
bool
dirtyChanged
);
void
countChanged
(
int
count
);
void
dirtyChanged
(
bool
dirtyChanged
);
private
slots
:
void
_childDirtyChanged
(
bool
dirty
);
void
_childDirtyChanged
(
bool
dirty
);
private:
// Overrides from QAbstractListModel
int
rowCount
(
const
QModelIndex
&
parent
=
QModelIndex
())
const
override
;
QVariant
data
(
const
QModelIndex
&
index
,
int
role
=
Qt
::
DisplayRole
)
const
override
;
bool
insertRows
(
int
position
,
int
rows
,
const
QModelIndex
&
index
=
QModelIndex
())
override
;
bool
removeRows
(
int
position
,
int
rows
,
const
QModelIndex
&
index
=
QModelIndex
())
override
;
bool
setData
(
const
QModelIndex
&
index
,
const
QVariant
&
value
,
int
role
=
Qt
::
EditRole
)
override
;
int
rowCount
(
const
QModelIndex
&
parent
=
QModelIndex
())
const
override
;
QVariant
data
(
const
QModelIndex
&
index
,
int
role
=
Qt
::
DisplayRole
)
const
override
;
bool
insertRows
(
int
position
,
int
rows
,
const
QModelIndex
&
index
=
QModelIndex
())
override
;
bool
removeRows
(
int
position
,
int
rows
,
const
QModelIndex
&
index
=
QModelIndex
())
override
;
bool
setData
(
const
QModelIndex
&
index
,
const
QVariant
&
value
,
int
role
=
Qt
::
EditRole
)
override
;
QHash
<
int
,
QByteArray
>
roleNames
(
void
)
const
override
;
private:
QList
<
QObject
*>
_objectList
;
QList
<
QObject
*>
_objectList
;
bool
_dirty
;
bool
_skipDirtyFirstItem
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment