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
1b05f323
Commit
1b05f323
authored
Dec 16, 2020
by
Valentin Platzgummer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MeasurementItemEditor improved
parent
31d4efc3
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
653 additions
and
319 deletions
+653
-319
qgroundcontrol.pro
qgroundcontrol.pro
+2
-3
AreaData.cc
src/MeasurementComplexItem/AreaData.cc
+37
-40
AreaData.h
src/MeasurementComplexItem/AreaData.h
+7
-12
CircularGenerator.cpp
src/MeasurementComplexItem/CircularGenerator.cpp
+1
-6
GeneratorBase.cc
src/MeasurementComplexItem/GeneratorBase.cc
+1
-0
MeasurementComplexItem.cc
src/MeasurementComplexItem/MeasurementComplexItem.cc
+172
-107
MeasurementComplexItem.h
src/MeasurementComplexItem/MeasurementComplexItem.h
+48
-10
GeoArea.cc
src/MeasurementComplexItem/geometry/GeoArea.cc
+3
-3
GeoArea.h
src/MeasurementComplexItem/geometry/GeoArea.h
+3
-2
MeasurementArea.cc
src/MeasurementComplexItem/geometry/MeasurementArea.cc
+152
-8
MeasurementArea.h
src/MeasurementComplexItem/geometry/MeasurementArea.h
+4
-1
SafeArea.cc
src/MeasurementComplexItem/geometry/SafeArea.cc
+3
-3
SafeArea.h
src/MeasurementComplexItem/geometry/SafeArea.h
+1
-1
MeasurementComplexItem.SettingsGroup.json
...omplexItem/json/MeasurementComplexItem.SettingsGroup.json
+3
-3
AreaDataEditor.qml
src/MeasurementComplexItem/qml/AreaDataEditor.qml
+112
-34
CircularGeneratorEditor.qml
src/MeasurementComplexItem/qml/CircularGeneratorEditor.qml
+1
-1
MeasurementItemEditor.qml
src/MeasurementComplexItem/qml/MeasurementItemEditor.qml
+101
-85
ParameterEditor.qml
src/MeasurementComplexItem/qml/ParameterEditor.qml
+2
-0
No files found.
qgroundcontrol.pro
View file @
1b05f323
...
...
@@ -34,14 +34,13 @@ DebugBuild {
DEFINES
+=
DEBUG
#
DEFINES
+=
SNAKE_SHOW_TIME
#
DEFINES
+=
SNAKE_DEBUG
DEFINES
+=
SNAKE_SHOW_TIME
DEFINES
+=
DEBUG_CIRCULAR_SURVEY
#
DEFINES
+=
SNAKE_SHOW_TIME
DEFINES
+=
ROS_BRIDGE_DEBUG
}
else
{
DESTDIR
=
$$
{
OUT_PWD
}
/
release
#
DEFINES
+=
ROS_BRIDGE_DEBUG
DEFINES
+=
SNAKE_SHOW_TIME
#
DEFINES
+=
SNAKE_SHOW_TIME
#
DEFINES
+=
SNAKE_DEBUG
DEFINES
+=
NDEBUG
}
...
...
src/MeasurementComplexItem/AreaData.cc
View file @
1b05f323
...
...
@@ -18,8 +18,7 @@ AreaData::AreaData(QObject *parent) : QObject(parent) {}
AreaData
::~
AreaData
()
{}
AreaData
::
AreaData
(
const
AreaData
&
other
,
QObject
*
parent
)
:
QObject
(
parent
),
_showErrorMessages
(
true
)
{
AreaData
::
AreaData
(
const
AreaData
&
other
,
QObject
*
parent
)
:
QObject
(
parent
)
{
*
this
=
other
;
}
...
...
@@ -93,21 +92,21 @@ const QmlObjectListModel *AreaData::areaList() const { return &_areaList; }
QGeoCoordinate
AreaData
::
origin
()
const
{
return
_origin
;
}
bool
AreaData
::
isCorrect
()
{
bool
AreaData
::
isCorrect
(
bool
showError
)
{
if
(
!
initialized
())
{
qCWarning
(
AreaDataLog
)
<<
"isCorrect(): not initialized"
;
return
false
;
}
// Check if areas are correct
if
(
!
_areasCorrect
())
{
if
(
!
_areasCorrect
(
showError
))
{
return
false
;
}
// Check if areas where added.
MeasurementArea
*
measurementArea
=
nullptr
;
SafeArea
*
safeArea
=
nullptr
;
if
(
!
_getAreas
(
&
measurementArea
,
&
safeArea
))
{
if
(
!
_getAreas
(
&
measurementArea
,
&
safeArea
,
showError
))
{
return
false
;
}
...
...
@@ -128,7 +127,8 @@ bool AreaData::isCorrect() {
// qDebug() << ss.str().c_str();
if
(
!
bg
::
covered_by
(
measurementAreaENU
,
safeAreaENU
))
{
_processError
(
tr
(
"Measurement Area not inside Safe Area. Please adjust "
"the Measurement Area.
\n
"
));
"the Measurement Area.
\n
"
),
showError
);
return
false
;
}
...
...
@@ -209,11 +209,11 @@ bool AreaData::initialized() {
measurementArea
->
count
()
>=
3
&&
safeArea
->
count
()
>=
3
;
}
void
AreaData
::
intersection
()
{
if
(
initialized
()
&&
_areasCorrect
())
{
void
AreaData
::
intersection
(
bool
showError
)
{
if
(
initialized
()
&&
_areasCorrect
(
showError
))
{
MeasurementArea
*
measurementArea
=
nullptr
;
SafeArea
*
safeArea
=
nullptr
;
if
(
_getAreas
(
&
measurementArea
,
&
safeArea
))
{
if
(
_getAreas
(
&
measurementArea
,
&
safeArea
,
showError
))
{
// convert to ENU
const
auto
origin
=
this
->
origin
();
...
...
@@ -230,7 +230,8 @@ void AreaData::intersection() {
if
(
outputENU
.
size
()
<
1
||
outputENU
[
0
].
outer
().
size
()
<
4
)
{
_processError
(
"Intersection did't deliver any result. Measurement Area and "
"Safe Area must touch each other."
);
"Safe Area must touch each other."
,
showError
);
return
;
}
...
...
@@ -238,7 +239,8 @@ void AreaData::intersection() {
_processError
(
"Hint: Only simple polygons can be displayed. If Intersection"
"produces polygons with holes or multi polygons, only "
"partial information can be displayed."
);
"partial information can be displayed."
,
showError
);
}
// Shrink the result if safeAreaENU doesn't cover it.
...
...
@@ -247,16 +249,18 @@ void AreaData::intersection() {
while
(
!
bg
::
covered_by
(
large
,
safeAreaENU
))
{
snake
::
offsetPolygon
(
large
,
small
,
-
0.1
);
large
=
std
::
move
(
small
);
qDebug
()
<<
"intersection(): shrink"
;
}
// Convert.
measurementArea
->
clear
();
for
(
auto
it
=
large
.
outer
().
begin
();
it
!=
large
.
outer
().
end
()
-
1
;
++
it
)
{
QGeoCoordinate
c
;
snake
::
fromENU
(
origin
,
*
it
,
c
);
measurementArea
->
appendVertex
(
c
);
// Check if result is different from input.
if
(
!
bg
::
equals
(
large
,
measurementAreaENU
))
{
// Convert.
measurementArea
->
clear
();
for
(
auto
it
=
large
.
outer
().
begin
();
it
!=
large
.
outer
().
end
()
-
1
;
++
it
)
{
QGeoCoordinate
c
;
snake
::
fromENU
(
origin
,
*
it
,
c
);
measurementArea
->
appendVertex
(
c
);
}
}
}
}
...
...
@@ -302,7 +306,7 @@ bool AreaData::load(const QJsonObject &obj, QString &errorString) {
// load MeasurementArea
if
(
jsonArea
[
GeoArea
::
areaTypeKey
].
toString
()
==
MeasurementArea
::
name
)
{
MeasurementArea
::
name
String
)
{
auto
area
=
getGeoArea
<
MeasurementArea
*>
(
_areaList
);
...
...
@@ -325,7 +329,8 @@ bool AreaData::load(const QJsonObject &obj, QString &errorString) {
}
}
// load SafeArea
else
if
(
jsonArea
[
GeoArea
::
areaTypeKey
].
toString
()
==
SafeArea
::
name
)
{
else
if
(
jsonArea
[
GeoArea
::
areaTypeKey
].
toString
()
==
SafeArea
::
nameString
)
{
auto
area
=
getGeoArea
<
SafeArea
*>
(
_areaList
);
if
(
area
==
nullptr
)
{
...
...
@@ -394,7 +399,6 @@ bool AreaData::save(QJsonObject &obj) {
}
else
{
qDebug
(
AreaDataLog
)
<<
"save(): not able to save area: "
<<
area
->
objectName
();
_processError
(
tr
(
"Not able to save area: "
)
+
area
->
objectName
());
return
false
;
}
}
...
...
@@ -411,21 +415,21 @@ void AreaData::_setOrigin(const QGeoCoordinate &origin) {
}
}
void
AreaData
::
_processError
(
const
QString
&
str
)
{
void
AreaData
::
_processError
(
const
QString
&
str
,
bool
showError
)
{
this
->
_errorString
=
str
;
emit
error
();
if
(
_showErrorMessages
)
{
if
(
showError
)
{
qgcApp
()
->
informationMessageBoxOnMainThread
(
tr
(
"Area Editor"
),
this
->
errorString
());
}
}
bool
AreaData
::
_areasCorrect
()
{
bool
AreaData
::
_areasCorrect
(
bool
showError
)
{
// Check if areas are correct.
for
(
int
i
=
0
;
i
<
_areaList
.
count
();
++
i
)
{
auto
*
area
=
_areaList
.
value
<
GeoArea
*>
(
0
);
auto
*
area
=
_areaList
.
value
<
GeoArea
*>
(
i
);
if
(
!
area
->
isCorrect
())
{
_processError
(
area
->
errorString
());
_processError
(
area
->
errorString
()
,
showError
);
return
false
;
}
}
...
...
@@ -433,30 +437,25 @@ bool AreaData::_areasCorrect() {
return
true
;
}
bool
AreaData
::
_getAreas
(
MeasurementArea
**
measurementArea
,
SafeArea
**
safeArea
)
{
bool
AreaData
::
_getAreas
(
MeasurementArea
**
measurementArea
,
SafeArea
**
safeArea
,
bool
showError
)
{
*
measurementArea
=
getGeoArea
<
MeasurementArea
*>
(
_areaList
);
if
(
*
measurementArea
==
nullptr
)
{
_processError
(
tr
(
"Measurement Area missing. Please define a measurement area."
));
tr
(
"Measurement Area missing. Please define a measurement area."
),
showError
);
return
false
;
}
*
safeArea
=
getGeoArea
<
SafeArea
*>
(
_areaList
);
if
(
*
safeArea
==
nullptr
)
{
_processError
(
tr
(
"Safe Area missing. Please define a safe area."
));
_processError
(
tr
(
"Safe Area missing. Please define a safe area."
),
showError
);
return
false
;
}
return
true
;
}
void
AreaData
::
setShowErrorMessages
(
bool
showErrorMessages
)
{
if
(
showErrorMessages
!=
_showErrorMessages
)
{
_showErrorMessages
=
showErrorMessages
;
emit
showErrorMessagesChanged
();
}
}
void
AreaData
::
_updateOrigin
()
{
auto
*
measurementArea
=
getGeoArea
<
MeasurementArea
*>
(
_areaList
);
if
(
measurementArea
!=
nullptr
)
{
...
...
@@ -464,6 +463,4 @@ void AreaData::_updateOrigin() {
}
}
bool
AreaData
::
showErrorMessages
()
const
{
return
_showErrorMessages
;
}
QString
AreaData
::
errorString
()
const
{
return
_errorString
;
}
src/MeasurementComplexItem/AreaData.h
View file @
1b05f323
...
...
@@ -20,8 +20,7 @@ public:
AreaData
&
operator
=
(
const
AreaData
&
other
);
Q_PROPERTY
(
QmlObjectListModel
*
areaList
READ
areaList
NOTIFY
areaListChanged
)
Q_PROPERTY
(
bool
showErrorMessages
READ
showErrorMessages
WRITE
setShowErrorMessages
NOTIFY
showErrorMessagesChanged
)
Q_PROPERTY
(
QString
errorString
READ
errorString
NOTIFY
error
)
// Member Methodes
//!
...
...
@@ -51,7 +50,7 @@ public:
//! \note Origin might change if the list of areas changes.
QGeoCoordinate
origin
()
const
;
Q_INVOKABLE
bool
isCorrect
();
Q_INVOKABLE
bool
isCorrect
(
bool
showError
=
true
);
//!
//! \brief initialize Initializes the areas in a valid way, such that they
//! area inside the bounding box. \param bottomLeft bottom left corner of the
...
...
@@ -69,7 +68,7 @@ public:
//! either.
//!
Q_INVOKABLE
bool
initialized
();
Q_INVOKABLE
void
intersection
();
Q_INVOKABLE
void
intersection
(
bool
showError
=
true
);
Q_INVOKABLE
MeasurementArea
*
measurementArea
();
Q_INVOKABLE
SafeArea
*
safeArea
();
...
...
@@ -82,25 +81,21 @@ public:
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
);
void
_processError
(
const
QString
&
str
);
bool
_areasCorrect
();
bool
_getAreas
(
MeasurementArea
**
measurementArea
,
SafeArea
**
safeArea
);
void
_processError
(
const
QString
&
str
,
bool
showError
);
bool
_areasCorrect
(
bool
showError
);
bool
_getAreas
(
MeasurementArea
**
measurementArea
,
SafeArea
**
safeArea
,
bool
showError
);
QGeoCoordinate
_origin
;
QmlObjectListModel
_areaList
;
QString
_errorString
;
bool
_showErrorMessages
;
};
src/MeasurementComplexItem/CircularGenerator.cpp
View file @
1b05f323
...
...
@@ -406,6 +406,7 @@ void CircularGenerator::setMeasurementArea(MeasurementArea *area) {
&
CircularGenerator
::
resetReferenceIfInvalid
);
connect
(
_measurementArea
,
&
MeasurementArea
::
pathChanged
,
this
,
&
GeneratorBase
::
generatorChanged
);
resetReferenceIfInvalid
();
}
emit
generatorChanged
();
...
...
@@ -438,16 +439,13 @@ bool circularTransects(const snake::FPoint &reference,
distances
.
reserve
(
polygon
.
outer
().
size
());
std
::
vector
<
snake
::
Angle
>
angles
;
angles
.
reserve
(
polygon
.
outer
().
size
());
//#ifdef DEBUG_CIRCULAR_SURVEY
// qCDebug(CircularGeneratorLog) << "circularTransects():";
//#endif
for
(
const
auto
&
p
:
polygon
.
outer
())
{
snake
::
Length
distance
=
bg
::
distance
(
reference
,
p
)
*
si
::
meter
;
distances
.
push_back
(
distance
);
snake
::
Angle
alpha
=
(
std
::
atan2
(
p
.
get
<
1
>
(),
p
.
get
<
0
>
()))
*
si
::
radian
;
alpha
=
alpha
<
0
*
si
::
radian
?
alpha
+
2
*
M_PI
*
si
::
radian
:
alpha
;
angles
.
push_back
(
alpha
);
//#ifdef DEBUG_CIRCULAR_SURVEY
// qCDebug(CircularGeneratorLog) << "distances, angles,
// coordinates:"; qCDebug(CircularGeneratorLog) <<
// to_string(distance).c_str(); qCDebug(CircularGeneratorLog)
...
...
@@ -455,7 +453,6 @@ bool circularTransects(const snake::FPoint &reference,
// qCDebug(CircularGeneratorLog) << "x = " << p.get<0>() << "y
// = "
// << p.get<1>();
//#endif
}
auto
rMin
=
deltaR
;
// minimal circle radius
...
...
@@ -484,7 +481,6 @@ bool circularTransects(const snake::FPoint &reference,
vector
<
ClipperLib
::
Path
>
sectors
(
nTran
,
ClipperLib
::
Path
());
const
auto
nSectors
=
long
(
std
::
round
(((
alpha2
-
alpha1
)
/
deltaAlpha
).
value
()));
//#ifdef DEBUG_CIRCULAR_SURVEY
// qCDebug(CircularGeneratorLog) << "circularTransects(): sector
// parameres:"; qCDebug(CircularGeneratorLog) << "alpha1: " <<
// to_string(snake::Degree(alpha1)).c_str();
...
...
@@ -499,7 +495,6 @@ bool circularTransects(const snake::FPoint &reference,
// qCDebug(CircularGeneratorLog)
// << "rMax: " << to_string(rMax).c_str();
// qCDebug(CircularGeneratorLog) << "nTran: " << nTran;
//#endif
using
ClipperCircle
=
GenericCircle
<
ClipperLib
::
cInt
,
ClipperLib
::
IntPoint
>
;
for
(
auto
&
sector
:
sectors
)
{
...
...
src/MeasurementComplexItem/GeneratorBase.cc
View file @
1b05f323
...
...
@@ -67,6 +67,7 @@ bool GeneratorFactory::registerGenerator(const QString &type,
GeneratorFactory
::
Creator
creator
)
{
const
auto
pair
=
_creatorMap
.
insert
(
std
::
make_pair
(
type
,
creator
));
auto
success
=
pair
.
second
;
Q_ASSERT
(
success
);
return
success
;
}
...
...
src/MeasurementComplexItem/MeasurementComplexItem.cc
View file @
1b05f323
This diff is collapsed.
Click to expand it.
src/MeasurementComplexItem/MeasurementComplexItem.h
View file @
1b05f323
...
...
@@ -34,12 +34,12 @@ public:
const
QString
&
kmlOrShpFile
,
QObject
*
parent
);
~
MeasurementComplexItem
();
Q_PROPERTY
(
Fact
*
variant
READ
variant
CONSTANT
)
Q_PROPERTY
(
Fact
*
altitude
READ
variant
CONSTANT
)
Q_PROPERTY
(
Fact
*
variant
Index
READ
variantIndex
CONSTANT
)
Q_PROPERTY
(
Fact
*
altitude
READ
altitude
CONSTANT
)
Q_PROPERTY
(
QStringList
variantNames
READ
variantNames
NOTIFY
variantNamesChanged
)
Q_PROPERTY
(
QStringList
generatorNameList
READ
generatorNameList
NOTIFY
generator
Name
ListChanged
)
generatorListChanged
)
Q_PROPERTY
(
bool
calculating
READ
calculating
NOTIFY
calculatingChanged
)
Q_PROPERTY
(
bool
editing
READ
editing
NOTIFY
editingChanged
)
Q_PROPERTY
(
bool
idle
READ
idle
NOTIFY
idleChanged
)
...
...
@@ -95,18 +95,56 @@ public:
virtual
QString
abbreviation
(
void
)
const
override
final
;
// Generator
bool
addGenerator
(
const
QString
&
name
,
routing
::
GeneratorBase
*
g
);
//!
//! \brief addGenerator Adds a generator.
//!
//! Adds a generator. The generator will be added to the generatorList() and
//! it's name to the generatorNameList(). Generators are identified by index
//! or name(), hence their name must be unique. A generator can not be added
//! if name() is already inside generatorNameList(). \param g Pointer to a
//! generator. \return Returns true if the generator was addes successfully,
//! false either.
//!
bool
addGenerator
(
routing
::
GeneratorBase
*
g
);
//!
//! \brief removeGenerator Removes the generator.
//! \param name The name of the generator to be removed.
//! \return Returns true if the generator was removed successfully.
//! \note The generator will be deleted if this or nullptr is it's parent.
bool
removeGenerator
(
const
QString
&
name
);
//!
//! \brief removeGenerator Removes the generator.
//! \param index The index of the generator to be removed
//! \return Returns true if the generator was removed successfully.
//! \note See above.
bool
removeGenerator
(
int
index
);
Q_INVOKABLE
bool
switchToGenerator
(
const
QString
&
name
);
Q_INVOKABLE
bool
switchToGenerator
(
int
index
);
//!
//! \brief resetGenerators Resets the generators as they where after creation
//! of this object.
//!
Q_INVOKABLE
void
resetGenerators
();
QList
<
PtrGenerator
>
generatorList
()
const
;
QStringList
generatorNameList
()
const
;
routing
::
GeneratorBase
*
generator
();
const
routing
::
GeneratorBase
*
generator
()
const
;
routing
::
GeneratorBase
*
generator
(
int
index
);
const
routing
::
GeneratorBase
*
generator
(
int
index
)
const
;
//!
//! \brief generatorIndex
//! \return Returns the index of the current generator.
int
generatorIndex
()
const
;
//!
//! \brief generatorIndex
//! \param name
//! \return Returns the index of the generator with the name \p name, or -1 if
//! the generator is unknown.
//!
int
generatorIndex
(
const
QString
&
name
);
// Editing.
//!
...
...
@@ -142,9 +180,9 @@ public:
AreaData
*
areaData
();
QVariantList
route
();
Fact
*
variant
();
Fact
*
altitude
();
Fact
*
variantIndex
();
QStringList
variantNames
()
const
;
Fact
*
altitude
();
bool
calculating
()
const
;
bool
editing
()
const
;
// set to true on creation
...
...
@@ -158,7 +196,7 @@ public:
signals:
void
variantNamesChanged
();
void
generator
Name
ListChanged
();
void
generatorListChanged
();
void
generatorChanged
();
void
calculatingChanged
();
...
...
@@ -173,7 +211,7 @@ private slots:
// Worker functions.
void
_storeRoutingData
(
PtrRoutingData
pRoute
);
void
_updateRoute
();
void
_changeVariant
();
void
_changeVariant
Index
();
void
_reverseRoute
();
private:
...
...
@@ -184,6 +222,7 @@ private:
static
bool
_editing
(
STATE
state
);
static
bool
_idle
(
STATE
state
);
void
_updateFlightpathSegments
();
void
_onAltitudeChanged
();
// Hirarcical stuff.
int
_sequenceNumber
;
...
...
@@ -195,7 +234,7 @@ private:
// Facts
QMap
<
QString
,
FactMetaData
*>
_metaDataMap
;
SettingsFact
_altitude
;
SettingsFact
_variant
;
SettingsFact
_variant
Index
;
QStringList
_variantNames
;
// Area data
...
...
@@ -205,7 +244,6 @@ private:
// Generators
QList
<
PtrGenerator
>
_generatorList
;
QStringList
_generatorNameList
;
PtrGenerator
_pGenerator
;
// Routing.
...
...
src/MeasurementComplexItem/geometry/GeoArea.cc
View file @
1b05f323
...
...
@@ -9,7 +9,7 @@
QGC_LOGGING_CATEGORY
(
GeoAreaLog
,
"GeoAreaLog"
)
const
char
*
GeoArea
::
name
=
"GeoArea"
;
const
char
*
GeoArea
::
name
String
=
"GeoArea"
;
const
char
*
GeoArea
::
areaTypeKey
=
"AreaType"
;
const
char
*
GeoArea
::
settingsGroup
=
"GeoArea"
;
...
...
@@ -59,7 +59,7 @@ bool GeoArea::isCorrect() {
std
::
stringstream
ss
;
ss
<<
bg
::
wkt
(
polygonENU
);
qCWarning
(
GeoAreaLog
)
<<
"polygonENU: "
<<
ss
.
str
().
c_str
();
setErrorString
(
t
r
(
"Area invalid. Area
must be a simple polygon."
));
setErrorString
(
t
his
->
objectName
()
+
tr
(
"
must be a simple polygon."
));
}
}
return
false
;
...
...
@@ -81,7 +81,7 @@ bool GeoArea::covers(const QGeoCoordinate &c) {
}
void
GeoArea
::
init
()
{
this
->
setObjectName
(
name
);
this
->
setObjectName
(
name
String
);
// connect(this, &GeoArea::pathChanged, [this] {
// if (this->objectName() != "Tile") {
// qDebug() << this->objectName() << " path: " << this->path() << "\n";
...
...
src/MeasurementComplexItem/geometry/GeoArea.h
View file @
1b05f323
...
...
@@ -30,12 +30,13 @@ public:
//!
//! \brief covers Checks if GeoArea covers c.
//! \param c
//! \return Returns true if c is inside, or on the border of GeoArea.
//! \return Returns true if c is inside, or on the border of GeoArea, false
//! either.
//!
Q_INVOKABLE
bool
covers
(
const
QGeoCoordinate
&
c
);
// static Members
static
const
char
*
name
;
static
const
char
*
name
String
;
static
const
char
*
areaTypeKey
;
static
const
char
*
settingsGroup
;
...
...
src/MeasurementComplexItem/geometry/MeasurementArea.cc
View file @
1b05f323
...
...
@@ -5,14 +5,22 @@
#include <boost/units/systems/si.hpp>
#include "JsonHelper.h"
#include "QGCLoggingCategory.h"
#include <QJsonArray>
#ifndef SNAKE_MAX_TILES
#define SNAKE_MAX_TILES 1000
#endif
QGC_LOGGING_CATEGORY
(
MeasurementAreaLog
,
"MeasurementAreaLog"
)
namespace
{
const
char
*
tileCenterPointsKey
=
"TileCenterPoints"
;
const
char
*
tileArrayKey
=
"TileArray"
;
}
// namespace
TileData
::
TileData
()
:
tiles
(
this
)
{}
TileData
::~
TileData
()
{
tiles
.
clearAndDeleteContents
();
}
...
...
@@ -50,6 +58,82 @@ bool TileData::operator!=(const TileData &other) const {
return
!
this
->
operator
==
(
other
);
}
void
TileData
::
saveToJson
(
QJsonObject
&
json
)
{
// save center points
QJsonValue
jsonCenterPoints
;
JsonHelper
::
saveGeoCoordinateArray
(
tileCenterPoints
,
false
,
jsonCenterPoints
);
json
[
tileCenterPointsKey
]
=
std
::
move
(
jsonCenterPoints
);
// save tiles
QJsonArray
jsonTiles
;
for
(
int
i
=
0
;
i
<
tiles
.
count
();
++
i
)
{
auto
tile
=
tiles
.
value
<
SnakeTile
*>
(
i
);
if
(
tile
!=
nullptr
)
{
QJsonObject
jsonTile
;
tile
->
saveToJson
(
jsonTile
);
jsonTiles
.
append
(
jsonTile
);
}
else
{
qCritical
()
<<
"TileData::saveToJson(): Object other than SnakeTile "
"inside tiles (QmlObjectListModel))"
;
Q_ASSERT
(
tile
!=
nullptr
);
}
}
json
[
tileArrayKey
]
=
std
::
move
(
jsonTiles
);
}
bool
TileData
::
loadFromJson
(
const
QJsonObject
&
json
,
QString
&
errorString
)
{
clear
();
// load tiles
if
(
json
.
contains
(
tileArrayKey
)
&&
json
[
tileArrayKey
].
isArray
())
{
QString
e
;
for
(
const
auto
&
jsonTile
:
json
[
tileArrayKey
].
toArray
())
{
auto
tile
=
new
SnakeTile
(
this
);
if
(
tile
->
loadFromJson
(
jsonTile
.
toObject
(),
e
))
{
tiles
.
append
(
tile
);
}
else
{
tile
->
deleteLater
();
errorString
.
append
(
e
);
return
false
;
}
}
}
else
{
errorString
.
append
(
tr
(
"Not able to load tiles.
\n
"
));
qCWarning
(
MeasurementAreaLog
)
<<
"Not able to load tiles. tileArrayKey missing or wrong type."
;
if
(
json
.
contains
(
tileArrayKey
))
{
qCWarning
(
MeasurementAreaLog
)
<<
"tile array type: "
<<
json
[
tileArrayKey
].
type
();
}
return
false
;
}
// load center points
if
(
json
.
contains
(
tileCenterPointsKey
)
&&
json
[
tileCenterPointsKey
].
isArray
())
{
QString
e
;
if
(
!
JsonHelper
::
loadGeoCoordinateArray
(
json
[
tileCenterPointsKey
],
false
,
tileCenterPoints
,
e
))
{
errorString
.
append
(
e
);
errorString
.
append
(
"
\n
"
);
return
false
;
}
}
else
{
errorString
.
append
(
tr
(
"Not able to load center points.
\n
"
));
qCWarning
(
MeasurementAreaLog
)
<<
"Not able to load center points. tileCenterPointsKey missing or "
"wrong type."
;
if
(
json
.
contains
(
tileCenterPointsKey
))
{
qCWarning
(
MeasurementAreaLog
)
<<
"center points type: "
<<
json
[
tileCenterPointsKey
].
type
();
}
return
false
;
}
return
true
;
}
void
TileData
::
clear
()
{
this
->
tiles
.
clearAndDeleteContents
();
this
->
tileCenterPoints
.
clear
();
...
...
@@ -68,7 +152,9 @@ const char *tileHeightKey = "TileHeight";
const
char
*
tileWidthName
=
"TileWidth"
;
const
char
*
minTileAreaKey
=
"MinTileAreaPercent"
;
const
char
*
showTilesKey
=
"ShowTiles"
;
const
char
*
MeasurementArea
::
name
=
"Measurement Area"
;
const
char
*
progressKey
=
"Progress"
;
const
char
*
tileKey
=
"Tiles"
;
const
char
*
MeasurementArea
::
nameString
=
"Measurement Area"
;
MeasurementArea
::
MeasurementArea
(
QObject
*
parent
)
:
GeoArea
(
parent
),
...
...
@@ -193,7 +279,20 @@ bool MeasurementArea::saveToJson(QJsonObject &json) {
json
[
tileWidthName
]
=
_tileWidth
.
rawValue
().
toDouble
();
json
[
minTileAreaKey
]
=
_minTileAreaPercent
.
rawValue
().
toDouble
();
json
[
showTilesKey
]
=
_showTiles
.
rawValue
().
toBool
();
json
[
areaTypeKey
]
=
name
;
json
[
areaTypeKey
]
=
nameString
;
// save progess
QJsonArray
jsonProgess
;
for
(
const
auto
&
p
:
_progress
)
{
jsonProgess
.
append
(
p
);
}
json
[
progressKey
]
=
std
::
move
(
jsonProgess
);
// save tiles
QJsonObject
jsonTiles
;
_tileData
.
saveToJson
(
jsonTiles
);
json
[
tileKey
]
=
std
::
move
(
jsonTiles
);
return
true
;
}
else
{
qCDebug
(
MeasurementAreaLog
)
...
...
@@ -211,6 +310,7 @@ bool MeasurementArea::loadFromJson(const QJsonObject &json,
disableUpdate
();
bool
retVal
=
true
;
// load parameters necessary for tile calculation.
if
(
!
json
.
contains
(
tileHeightKey
)
||
!
json
[
tileHeightKey
].
isDouble
())
{
errorString
.
append
(
tr
(
"Could not load tile height!
\n
"
));
retVal
=
false
;
...
...
@@ -232,15 +332,59 @@ bool MeasurementArea::loadFromJson(const QJsonObject &json,
_minTileAreaPercent
.
setRawValue
(
json
[
minTileAreaKey
].
toDouble
());
}
if
(
!
json
.
contains
(
showTilesKey
)
||
!
json
[
showTilesKey
].
isBool
())
{
errorString
.
append
(
tr
(
"Could not load show tiles !
\n
"
));
retVal
=
false
;
}
else
{
// load less important parameters
if
(
json
.
contains
(
showTilesKey
)
||
!
json
[
showTilesKey
].
isBool
())
{
_showTiles
.
setRawValue
(
json
[
showTilesKey
].
toBool
());
}
// load tiles and progress
bool
tileError
=
false
;
if
(
json
.
contains
(
tileKey
)
&&
json
[
tileKey
].
isObject
())
{
QString
e
;
if
(
!
_tileData
.
loadFromJson
(
json
[
tileKey
].
toObject
(),
e
))
{
qCWarning
(
MeasurementAreaLog
)
<<
"TileData::loadFromJson(): "
<<
e
;
tileError
=
true
;
}
else
{
progressChanged
();
}
}
else
{
tileError
=
true
;
}
bool
progressError
=
false
;
QVector
<
int
>
prog
;
if
(
json
.
contains
(
progressKey
)
&&
json
[
progressKey
].
isArray
())
{
for
(
const
auto
&
p
:
json
[
progressKey
].
toArray
())
{
if
(
p
.
isDouble
())
{
prog
.
append
(
p
.
toDouble
());
}
else
{
progressError
=
true
;
break
;
}
}
// check if entries are in range
if
(
!
progressError
)
{
for
(
const
auto
&
p
:
prog
)
{
if
(
p
<
0
||
p
>
100
)
{
progressError
=
true
;
break
;
}
}
}
}
else
{
progressError
=
true
;
}
if
(
!
progressError
)
{
_progress
.
swap
(
prog
);
progressChanged
();
}
// do update if error occurred.
enableUpdate
();
doUpdate
();
if
(
progressError
||
tileError
)
{
doUpdate
();
}
return
retVal
;
}
else
{
...
...
@@ -408,7 +552,7 @@ void MeasurementArea::enableUpdate() {
}
void
MeasurementArea
::
init
()
{