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
4948045b
Commit
4948045b
authored
Dec 31, 2020
by
Valentin Platzgummer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MeasurementArea prepared for new NemoInterface
parent
0e658bb3
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
474 additions
and
375 deletions
+474
-375
QGCExternalLibs.pri
QGCExternalLibs.pri
+0
-5
qgroundcontrol.pro
qgroundcontrol.pro
+8
-2
CircularGenerator.cpp
src/MeasurementComplexItem/CircularGenerator.cpp
+13
-22
HashFunctions.cpp
src/MeasurementComplexItem/HashFunctions.cpp
+1
-0
HashFunctions.h
src/MeasurementComplexItem/HashFunctions.h
+32
-0
LinearGenerator.cpp
src/MeasurementComplexItem/LinearGenerator.cpp
+12
-20
MeasurementComplexItem.cc
src/MeasurementComplexItem/MeasurementComplexItem.cc
+1
-1
NemoInterface.cpp
src/MeasurementComplexItem/NemoInterface.cpp
+3
-3
MeasurementArea.cc
src/MeasurementComplexItem/geometry/MeasurementArea.cc
+190
-225
MeasurementArea.h
src/MeasurementComplexItem/geometry/MeasurementArea.h
+16
-20
ProgressArray.h
src/MeasurementComplexItem/geometry/ProgressArray.h
+10
-0
TileDiff.h
src/MeasurementComplexItem/geometry/TileDiff.h
+11
-0
geometry.h
src/MeasurementComplexItem/geometry/geometry.h
+3
-2
MeasurementTile.cpp
...MeasurementComplexItem/nemo_interface/MeasurementTile.cpp
+52
-0
MeasurementTile.h
src/MeasurementComplexItem/nemo_interface/MeasurementTile.h
+39
-0
SnakeTile.cpp
src/MeasurementComplexItem/nemo_interface/SnakeTile.cpp
+0
-22
SnakeTile.h
src/MeasurementComplexItem/nemo_interface/SnakeTile.h
+0
-22
SnakeTiles.h
src/MeasurementComplexItem/nemo_interface/SnakeTiles.h
+2
-2
MeasurementAreaMapVisual.qml
src/MeasurementComplexItem/qml/MeasurementAreaMapVisual.qml
+28
-29
QmlObjectListHelper.cpp
src/comm/QmlObjectListHelper.cpp
+1
-0
QmlObjectListHelper.h
src/comm/QmlObjectListHelper.h
+52
-0
No files found.
QGCExternalLibs.pri
View file @
4948045b
...
...
@@ -226,11 +226,6 @@ contains (DEFINES, DISABLE_AIRMAP) {
}
}
# GeograpicLib (TODO: add Windows support!)
LinuxBuild {
LIBS += -L$$PWD/libs/libGeographic -lGeographic # libGeograpic.so.17
}
# google or-tools (TODO: add Windows support!)
LinuxBuild {
OR_TOOLS_PATH = $$PWD/libs/or-tools-src-ubuntu
...
...
qgroundcontrol.pro
View file @
4948045b
...
...
@@ -445,7 +445,11 @@ contains (DEFINES, QGC_ENABLE_PAIRING) {
#
HEADERS
+=
\
src
/
MeasurementComplexItem
/
geometry
/
ProgressArray
.
h
\
src
/
MeasurementComplexItem
/
geometry
/
TileDiff
.
h
\
src
/
MeasurementComplexItem
/
geometry
/
geometry
.
h
\
src
/
MeasurementComplexItem
/
HashFunctions
.
h
\
src
/
MeasurementComplexItem
/
nemo_interface
/
MeasurementTile
.
h
\
src
/
QmlControls
/
QmlUnitsConversion
.
h
\
src
/
MeasurementComplexItem
/
geometry
/
GeoArea
.
h
\
src
/
MeasurementComplexItem
/
geometry
/
MeasurementArea
.
h
\
...
...
@@ -487,7 +491,6 @@ HEADERS += \
src
/
MeasurementComplexItem
/
nemo_interface
/
QNemoHeartbeat
.
h
\
src
/
MeasurementComplexItem
/
nemo_interface
/
QNemoProgress
.
h
\
src
/
MeasurementComplexItem
/
nemo_interface
/
QNemoProgress
.
h
\
src
/
MeasurementComplexItem
/
nemo_interface
/
SnakeTile
.
h
\
src
/
MeasurementComplexItem
/
nemo_interface
/
SnakeTileLocal
.
h
\
src
/
MeasurementComplexItem
/
nemo_interface
/
SnakeTiles
.
h
\
src
/
MeasurementComplexItem
/
nemo_interface
/
SnakeTilesLocal
.
h
\
...
...
@@ -498,6 +501,7 @@ HEADERS += \
src
/
api
/
QmlComponentInfo
.
h
\
src
/
GPS
/
Drivers
/
src
/
base_station
.
h
\
src
/
Settings
/
WimaSettings
.
h
\
src
/
comm
/
QmlObjectListHelper
.
h
\
src
/
comm
/
ros_bridge
/
include
/
RosBridgeClient
.
h
\
src
/
comm
/
ros_bridge
/
include
/
com_private
.
h
\
src
/
comm
/
ros_bridge
/
include
/
message_traits
.
h
\
...
...
@@ -525,6 +529,8 @@ SOURCES += \
src
/
MeasurementComplexItem
/
geometry
/
MeasurementArea
.
cc
\
src
/
MeasurementComplexItem
/
geometry
/
SafeArea
.
cc
\
src
/
MeasurementComplexItem
/
geometry
/
geometry
.
cpp
\
src
/
MeasurementComplexItem
/
HashFunctions
.
cpp
\
src
/
MeasurementComplexItem
/
nemo_interface
/
MeasurementTile
.
cpp
\
src
/
Vehicle
/
VehicleEscStatusFactGroup
.
cc
\
src
/
MeasurementComplexItem
/
AreaData
.
cc
\
src
/
api
/
QGCCorePlugin
.
cc
\
...
...
@@ -541,7 +547,7 @@ SOURCES += \
src
/
MeasurementComplexItem
/
geometry
/
GeoPoint3D
.
cpp
\
src
/
MeasurementComplexItem
/
NemoInterface
.
cpp
\
src
/
MeasurementComplexItem
/
nemo_interface
/
QNemoProgress
.
cc
\
src
/
MeasurementComplexItem
/
nemo_interface
/
SnakeTile
.
cpp
\
src
/
comm
/
QmlObjectListHelper
.
cpp
\
src
/
comm
/
ros_bridge
/
include
/
RosBridgeClient
.
cpp
\
src
/
comm
/
ros_bridge
/
include
/
com_private
.
cpp
\
src
/
comm
/
ros_bridge
/
include
/
messages
/
geographic_msgs
/
geopoint
.
cpp
\
...
...
src/MeasurementComplexItem/CircularGenerator.cpp
View file @
4948045b
...
...
@@ -10,7 +10,7 @@
#include "geometry/MeasurementArea.h"
#include "geometry/SafeArea.h"
#include "geometry/clipper/clipper.hpp"
#include "nemo_interface/
Snake
Tile.h"
#include "nemo_interface/
Measurement
Tile.h"
QGC_LOGGING_CATEGORY
(
CircularGeneratorLog
,
"CircularGeneratorLog"
)
...
...
@@ -118,31 +118,22 @@ bool CircularGenerator::get(Work &work) {
auto
pPolygon
=
std
::
make_shared
<
geometry
::
FPolygon
>
();
geometry
::
areaToEnu
(
origin
,
geoPolygon
,
*
pPolygon
);
// Progress and tiles.
const
auto
&
progress
=
measurementArea
->
progress
();
// Collect tiles with progress == 100 %.
const
auto
*
tiles
=
measurementArea
->
tiles
();
auto
pTiles
=
std
::
make_shared
<
std
::
vector
<
geometry
::
FPolygon
>>
();
if
(
progress
.
size
()
==
tiles
->
count
())
{
for
(
int
i
=
0
;
i
<
tiles
->
count
();
++
i
)
{
if
(
progress
[
i
]
==
100
)
{
const
auto
*
obj
=
(
*
tiles
)[
int
(
i
)];
const
auto
*
tile
=
qobject_cast
<
const
SnakeTile
*>
(
obj
);
if
(
tile
!=
nullptr
)
{
geometry
::
FPolygon
tileENU
;
geometry
::
areaToEnu
(
origin
,
tile
->
coordinateList
(),
tileENU
);
pTiles
->
push_back
(
std
::
move
(
tileENU
));
}
else
{
qCDebug
(
CircularGeneratorLog
)
<<
"get(): progress.size() != tiles->count()."
;
return
false
;
}
for
(
int
i
=
0
;
i
<
tiles
->
count
();
++
i
)
{
const
auto
tile
=
qobject_cast
<
const
MeasurementTile
*>
(
tiles
->
operator
[](
i
));
if
(
tile
!=
nullptr
)
{
if
(
qFuzzyCompare
(
tile
->
progress
(),
100
))
{
geometry
::
FPolygon
tileENU
;
geometry
::
areaToEnu
(
origin
,
tile
->
coordinateList
(),
tileENU
);
pTiles
->
push_back
(
std
::
move
(
tileENU
));
}
}
else
{
qCDebug
(
CircularGeneratorLog
)
<<
"get(): tile == nullptr."
;
return
false
;
}
}
else
{
qCDebug
(
CircularGeneratorLog
)
<<
"get(): progress.size() != tiles->count()."
;
return
false
;
}
auto
serviceArea
=
getGeoArea
<
const
SafeArea
*>
(
*
this
->
_d
->
areaList
());
...
...
src/MeasurementComplexItem/HashFunctions.cpp
0 → 100644
View file @
4948045b
#include "HashFunctions.h"
src/MeasurementComplexItem/HashFunctions.h
0 → 100644
View file @
4948045b
#ifndef HASHFUNCTIONS_H
#define HASHFUNCTIONS_H
#include <QGeoCoordinate>
#include <functional>
#include <QmlObjectListModel.h>
namespace
std
{
template
<>
struct
hash
<
QGeoCoordinate
>
{
std
::
size_t
operator
()(
const
QGeoCoordinate
&
c
)
{
hash
<
double
>
h
;
return
h
(
c
.
latitude
())
^
h
(
c
.
longitude
())
^
h
(
c
.
altitude
());
}
};
template
<
template
<
class
>
class
Container
,
class
EntryType
>
struct
hash
<
Container
<
EntryType
>>
{
std
::
size_t
operator
()(
const
Container
<
EntryType
>
&
list
)
{
std
::
size_t
value
=
0
;
hash
<
EntryType
>
h
;
for
(
const
auto
it
=
std
::
begin
(
list
);
it
!=
std
::
end
(
list
);
++
it
)
{
value
^=
h
(
*
it
);
}
return
value
;
}
};
}
// namespace std
#endif // HASHFUNCTIONS_H
src/MeasurementComplexItem/LinearGenerator.cpp
View file @
4948045b
...
...
@@ -9,7 +9,7 @@
#include "geometry/clipper/clipper.hpp"
#include "RoutingThread.h"
#include "nemo_interface/
Snake
Tile.h"
#include "nemo_interface/
Measurement
Tile.h"
namespace
routing
{
...
...
@@ -100,29 +100,21 @@ bool LinearGenerator::get(Work &generator) {
geometry
::
areaToEnu
(
origin
,
geoPolygon
,
*
pPolygon
);
// Progress and tiles.
const
auto
&
progress
=
measurementArea
->
progress
();
const
auto
*
tiles
=
measurementArea
->
tiles
();
auto
pTiles
=
std
::
make_shared
<
std
::
vector
<
geometry
::
FPolygon
>>
();
if
(
progress
.
size
()
==
tiles
->
count
())
{
for
(
int
i
=
0
;
i
<
tiles
->
count
();
++
i
)
{
if
(
progress
[
i
]
==
100
)
{
const
QObject
*
obj
=
(
*
tiles
)[
int
(
i
)];
const
auto
*
tile
=
qobject_cast
<
const
SnakeTile
*>
(
obj
);
if
(
tile
!=
nullptr
)
{
geometry
::
FPolygon
tileENU
;
geometry
::
areaToEnu
(
origin
,
tile
->
coordinateList
(),
tileENU
);
pTiles
->
push_back
(
std
::
move
(
tileENU
));
}
else
{
qCDebug
(
LinearGeneratorLog
)
<<
"get(): tile == nullptr"
;
return
false
;
}
for
(
int
i
=
0
;
i
<
tiles
->
count
();
++
i
)
{
const
auto
tile
=
qobject_cast
<
const
MeasurementTile
*>
(
tiles
->
operator
[](
i
));
if
(
qFuzzyCompare
(
tile
->
progress
(),
100
))
{
if
(
tile
!=
nullptr
)
{
geometry
::
FPolygon
tileENU
;
geometry
::
areaToEnu
(
origin
,
tile
->
coordinateList
(),
tileENU
);
pTiles
->
push_back
(
std
::
move
(
tileENU
));
}
else
{
qCDebug
(
LinearGeneratorLog
)
<<
"get(): tile == nullptr"
;
return
false
;
}
}
}
else
{
qCDebug
(
LinearGeneratorLog
)
<<
"get(): progress.size() != tiles->count()."
;
return
false
;
}
auto
serviceArea
=
getGeoArea
<
const
SafeArea
*>
(
*
this
->
_d
->
areaList
());
...
...
src/MeasurementComplexItem/MeasurementComplexItem.cc
View file @
4948045b
...
...
@@ -8,7 +8,7 @@
#include "geometry/SafeArea.h"
#include "geometry/clipper/clipper.hpp"
#include "geometry/geometry.h"
#include "nemo_interface/
Snake
Tile.h"
#include "nemo_interface/
Measurement
Tile.h"
// QGC
#include "JsonHelper.h"
...
...
src/MeasurementComplexItem/NemoInterface.cpp
View file @
4948045b
...
...
@@ -17,7 +17,7 @@
#include "geometry/geometry.h"
#include "nemo_interface/QNemoHeartbeat.h"
#include "nemo_interface/QNemoProgress.h"
#include "nemo_interface/
Snake
Tile.h"
#include "nemo_interface/
Measurement
Tile.h"
#include "ros_bridge/include/messages/geographic_msgs/geopoint.h"
#include "ros_bridge/include/messages/jsk_recognition_msgs/polygon_array.h"
...
...
@@ -158,7 +158,7 @@ void NemoInterface::Impl::setTileData(const TileData &tileData) {
UniqueLock
lk2
(
this
->
tilesENUMutex
,
std
::
adopt_lock
);
const
auto
*
obj
=
tileData
.
tiles
[
0
];
const
auto
*
tile
=
qobject_cast
<
const
Snake
Tile
*>
(
obj
);
const
auto
*
tile
=
qobject_cast
<
const
Measurement
Tile
*>
(
obj
);
if
(
tile
!=
nullptr
)
{
if
(
tile
->
coordinateList
().
size
()
>
0
)
{
if
(
tile
->
coordinateList
().
first
().
isValid
())
{
...
...
@@ -167,7 +167,7 @@ void NemoInterface::Impl::setTileData(const TileData &tileData) {
this
->
tilesENU
.
polygons
().
clear
();
for
(
int
i
=
0
;
i
<
tileData
.
tiles
.
count
();
++
i
)
{
obj
=
tileData
.
tiles
[
i
];
tile
=
qobject_cast
<
const
Snake
Tile
*>
(
obj
);
tile
=
qobject_cast
<
const
Measurement
Tile
*>
(
obj
);
if
(
tile
!=
nullptr
)
{
SnakeTileLocal
tileENU
;
geometry
::
areaToEnu
(
origin
,
tile
->
coordinateList
(),
tileENU
.
path
());
...
...
src/MeasurementComplexItem/geometry/MeasurementArea.cc
View file @
4948045b
#include "MeasurementArea.h"
#include "
QtConcurrentRun
"
#include "
HashFunctions.h
"
#include "geometry.h"
#include "nemo_interface/SnakeTile.h"
#include "nemo_interface/MeasurementTile.h"
#include <ctime>
#include "QtConcurrentRun"
#include <QJsonArray>
#include <QQmlEngine>
#include <boost/units/systems/si.hpp>
#include "JsonHelper.h"
#include "QGCLoggingCategory.h"
#include "QmlObjectListHelper.h"
#include <QJsonArray>
#ifndef SNAKE_MAX_TILES
#define SNAKE_MAX_TILES 1000
#ifndef MAX_TILES
#define MAX_TILES 1000
#endif
using
namespace
geometry
;
...
...
@@ -26,142 +30,31 @@ bool getTiles(const FPolygon &area, Length tileHeight, Length tileWidth,
QGC_LOGGING_CATEGORY
(
MeasurementAreaLog
,
"MeasurementAreaLog"
)
namespace
{
const
char
*
tileCenterPointsKey
=
"TileCenterPoints"
;
const
char
*
tileArrayKey
=
"TileArray"
;
}
// namespace
TileData
::
TileData
()
:
tiles
(
this
)
{}
TileData
::~
TileData
()
{
tiles
.
clearAndDeleteContents
();
}
TileData
&
TileData
::
operator
=
(
const
TileData
&
other
)
{
this
->
tiles
.
clearAndDeleteContents
();
for
(
std
::
size_t
i
=
0
;
i
<
std
::
size_t
(
other
.
tiles
.
count
());
++
i
)
{
const
auto
*
obj
=
other
.
tiles
[
i
];
const
auto
*
tile
=
qobject_cast
<
const
SnakeTile
*>
(
obj
);
if
(
tile
!=
nullptr
)
{
this
->
tiles
.
append
(
tile
->
clone
(
this
));
}
else
{
qCWarning
(
MeasurementAreaLog
)
<<
"TileData::operator=: nullptr"
;
}
}
this
->
tileCenterPoints
=
other
.
tileCenterPoints
;
return
*
this
;
}
bool
TileData
::
operator
==
(
const
TileData
&
other
)
const
{
if
(
this
->
tileCenterPoints
==
other
.
tileCenterPoints
&&
this
->
tiles
.
count
()
==
other
.
tiles
.
count
())
{
for
(
int
i
=
0
;
i
<
other
.
tiles
.
count
();
++
i
)
{
if
(
this
->
tiles
[
i
]
!=
other
.
tiles
[
i
])
{
return
false
;
}
}
return
true
;
}
else
{
return
false
;
}
}
TileData
::
TileData
()
{}
TileData
::~
TileData
()
{}
TileData
&
TileData
::
operator
=
(
const
TileData
&
other
)
{
return
*
this
;
}
bool
TileData
::
operator
==
(
const
TileData
&
other
)
const
{
return
false
;
}
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
);
return
operator
==
(
other
);
}
void
TileData
::
saveToJson
(
QJsonObject
&
json
)
{}
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
();
return
false
;
}
size_t
TileData
::
size
()
const
{
if
(
tiles
.
count
()
==
tileCenterPoints
.
size
())
{
return
tiles
.
count
();
}
else
{
return
0
;
}
}
void
TileData
::
clear
()
{}
std
::
size_t
TileData
::
size
()
const
{
return
0
;
}
const
char
*
MeasurementArea
::
settingsGroup
=
"MeasurementArea"
;
const
char
*
tileHeightKey
=
"TileHeight"
;
const
char
*
tileWidthName
=
"TileWidth"
;
const
char
*
minTileAreaKey
=
"MinTileAreaPercent"
;
const
char
*
showTilesKey
=
"ShowTiles"
;
const
char
*
progressKey
=
"Progress"
;
const
char
*
tileKey
=
"Tiles"
;
const
char
*
MeasurementArea
::
nameString
=
"Measurement Area"
;
...
...
@@ -179,7 +72,8 @@ MeasurementArea::MeasurementArea(QObject *parent)
this
/* QObject parent */
)),
_showTiles
(
SettingsFact
(
settingsGroup
,
_metaDataMap
[
showTilesKey
],
this
/* QObject parent */
)),
_holdProgress
(
false
),
_state
(
STATE
::
IDLE
)
{
_tiles
(
new
QmlObjectListModel
()),
_holdProgress
(
false
),
_state
(
STATE
::
IDLE
)
{
init
();
}
...
...
@@ -197,7 +91,8 @@ MeasurementArea::MeasurementArea(const MeasurementArea &other, QObject *parent)
this
/* QObject parent */
)),
_showTiles
(
SettingsFact
(
settingsGroup
,
_metaDataMap
[
showTilesKey
],
this
/* QObject parent */
)),
_holdProgress
(
false
),
_state
(
STATE
::
IDLE
)
{
_tiles
(
new
QmlObjectListModel
()),
_holdProgress
(
false
),
_state
(
STATE
::
IDLE
)
{
init
();
disableUpdate
();
...
...
@@ -207,8 +102,12 @@ MeasurementArea::MeasurementArea(const MeasurementArea &other, QObject *parent)
_showTiles
=
other
.
_showTiles
;
if
(
other
.
ready
())
{
_progress
=
other
.
_progress
;
_tileData
=
other
.
_tileData
;
for
(
int
i
=
0
;
i
<
other
.
_tiles
->
count
();
++
i
)
{
_tiles
->
append
(
qobject_cast
<
const
MeasurementTile
*>
(
other
.
_tiles
->
operator
[](
i
))
->
clone
(
_tiles
.
get
()));
}
_tileMap
=
other
.
_tileMap
;
enableUpdate
();
}
else
{
enableUpdate
();
...
...
@@ -226,8 +125,13 @@ MeasurementArea &MeasurementArea::operator=(const MeasurementArea &other) {
_showTiles
=
other
.
_showTiles
;
if
(
other
.
ready
())
{
_progress
=
other
.
_progress
;
_tileData
=
other
.
_tileData
;
_tiles
->
clearAndDeleteContents
();
for
(
int
i
=
0
;
i
<
other
.
_tiles
->
count
();
++
i
)
{
_tiles
->
append
(
qobject_cast
<
const
MeasurementTile
*>
(
other
.
_tiles
->
operator
[](
i
))
->
clone
(
_tiles
.
get
()));
}
_tileMap
=
other
.
_tileMap
;
enableUpdate
();
}
else
{
enableUpdate
();
...
...
@@ -236,7 +140,7 @@ MeasurementArea &MeasurementArea::operator=(const MeasurementArea &other) {
return
*
this
;
}
MeasurementArea
::~
MeasurementArea
()
{}
MeasurementArea
::~
MeasurementArea
()
{
_tiles
->
clearAndDeleteContents
();
}
QString
MeasurementArea
::
mapVisualQML
()
const
{
return
QStringLiteral
(
"MeasurementAreaMapVisual.qml"
);
...
...
@@ -259,32 +163,21 @@ Fact *MeasurementArea::minTileArea() { return &_minTileAreaPercent; }
Fact
*
MeasurementArea
::
showTiles
()
{
return
&
_showTiles
;
}
QmlObjectListModel
*
MeasurementArea
::
tiles
()
{
return
&
this
->
_tileData
.
tiles
;
}
const
QVector
<
int
>
&
MeasurementArea
::
progress
()
const
{
return
this
->
_progress
;
}
QVector
<
int
>
MeasurementArea
::
progressQml
()
const
{
return
this
->
_progress
;
}
QmlObjectListModel
*
MeasurementArea
::
tiles
()
{
return
_tiles
.
get
();
}
const
QmlObjectListModel
*
MeasurementArea
::
tiles
()
const
{
return
&
this
->
_tileData
.
tiles
;
return
_tiles
.
get
()
;
}
const
QVariantList
&
MeasurementArea
::
tileCenterPoints
()
const
{
return
this
->
_tileData
.
tileCenterPoints
;
}
const
TileData
&
MeasurementArea
::
tileData
()
const
{
return
this
->
_tileData
;
}
int
MeasurementArea
::
maxTiles
()
const
{
return
SNAKE_MAX_TILES
;
}
int
MeasurementArea
::
maxTiles
()
const
{
return
MAX_TILES
;
}
bool
MeasurementArea
::
ready
()
const
{
return
this
->
_state
==
STATE
::
IDLE
;
}
bool
MeasurementArea
::
measurementCompleted
()
const
{
if
(
ready
())
{
for
(
const
auto
&
p
:
_progress
)
{
if
(
p
!=
100
)
{
for
(
int
i
=
0
;
i
<
_tiles
->
count
();
++
i
)
{
const
auto
tile
=
qobject_cast
<
const
MeasurementTile
*>
(
_tiles
->
get
(
i
));
if
(
!
qFuzzyCompare
(
tile
->
progress
(),
100
))
{
return
false
;
}
}
...
...
@@ -303,17 +196,15 @@ bool MeasurementArea::saveToJson(QJsonObject &json) {
json
[
showTilesKey
]
=
_showTiles
.
rawValue
().
toBool
();
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
);
QJsonArray
jsonTileArray
;
for
(
int
i
=
0
;
i
<
_tiles
->
count
();
++
i
)
{
auto
tile
=
qobject_cast
<
MeasurementTile
*>
(
_tiles
->
get
(
i
));
QJsonObject
jsonTile
;
tile
->
saveToJson
(
jsonTile
);
jsonTileArray
.
append
(
jsonTile
);
}
json
[
tileArrayKey
]
=
std
::
move
(
jsonTileArray
);
return
true
;
}
else
{
...
...
@@ -359,52 +250,39 @@ bool MeasurementArea::loadFromJson(const QJsonObject &json,
_showTiles
.
setRawValue
(
json
[
showTilesKey
].
toBool
());
}
// load tiles
and progress
// load tiles
bool
tileError
=
false
;
if
(
json
.
contains
(
tileKey
)
&&
json
[
tileKey
].
isObject
())
{
if
(
json
.
contains
(
tileArrayKey
)
&&
json
[
tileArrayKey
].
isArray
())
{
QString
e
;
if
(
!
_tileData
.
loadFromJson
(
json
[
tileKey
].
toObject
(),
e
))
{
qCWarning
(
MeasurementAreaLog
)
<<
"TileData::loadFromJson(): "
<<
e
;
tileError
=
true
;
}
else
{
progressChanged
();
}
}
else
{
tileError
=
true
;
}
_tiles
->
clearAndDeleteContents
();
for
(
auto
&&
jsonTile
:
json
[
tileArrayKey
].
toArray
())
{
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
());
auto
tile
=
new
MeasurementTile
(
this
);
if
(
tile
->
loadFromJson
(
jsonTile
.
toObject
(),
e
))
{
_tiles
->
append
(
tile
);
}
else
{
progressError
=
true
;
tile
->
deleteLater
();
qCWarning
(
MeasurementAreaLog
)
<<
e
;
tileError
=
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
);
emit
progressChanged
();
qCWarning
(
MeasurementAreaLog
)
<<
"Not able to load tiles. tileArrayKey missing or wrong type."
;
if
(
json
.
contains
(
tileArrayKey
))
{
qCWarning
(
MeasurementAreaLog
)
<<
"tile array type: "
<<
json
[
tileArrayKey
].
type
();
}
tileError
=
true
;
}
// do update if error occurred.
enableUpdate
();
if
(
progressError
||
tileError
)
{
if
(
tileError
)
{
doUpdate
();
}
...
...
@@ -426,28 +304,44 @@ bool MeasurementArea::isCorrect() {
return
false
;
}
bool
MeasurementArea
::
setProgress
(
const
QVector
<
int
>
&
p
)
{
if
(
ready
())
{
if
(
!
_holdProgress
&&
p
.
size
()
==
this
->
tiles
()
->
count
()
&&
this
->
_progress
!=
p
)
{
this
->
_progress
=
p
;
void
MeasurementArea
::
updateProgress
(
const
ProgressArray
&
array
)
{
if
(
ready
()
&&
!
_holdProgress
&&
array
.
size
()
>
0
)
{
bool
anyChanges
=
false
;
for
(
const
auto
&
pair
:
array
)
{
const
auto
&
id
=
pair
.
first
;
const
auto
&
progress
=
pair
.
second
;
auto
it
=
_tileMap
.
find
(
id
);
if
(
it
!=
_tileMap
.
end
())
{
if
(
!
qFuzzyCompare
(
progress
,
it
->
second
->
progress
()))
{
it
->
second
->
setProgress
(
progress
);
anyChanges
=
true
;
}
}
}
if
(
anyChanges
)
{
emit
progressChanged
();
emit
progressAccepted
();
return
true
;
}
}
emit
progressNotAccepted
();
return
false
;
}
void
MeasurementArea
::
randomProgress
()
{
if
(
ready
())
{
std
::
srand
(
std
::
time
(
nullptr
));
for
(
auto
&
p
:
_progress
)
{
for
(
int
i
=
0
;
i
<
_tiles
->
count
();
++
i
)
{
auto
tile
=
_tiles
->
value
<
MeasurementTile
*>
(
i
);
Q_ASSERT
(
tile
!=
nullptr
);
auto
p
=
tile
->
progress
();
p
+=
std
::
rand
()
%
125
;
if
(
p
>
100
)
{
p
=
100
;
}
tile
->
setProgress
(
p
);
}
emit
progressChanged
();
...
...
@@ -456,13 +350,25 @@ void MeasurementArea::randomProgress() {
void
MeasurementArea
::
resetProgress
()
{
if
(
ready
())
{
for
(
auto
&
p
:
_progress
)
{
p
=
0
;
bool
anyChanges
=
false
;
for
(
int
i
=
0
;
i
<
_tiles
->
count
();
++
i
)
{
auto
tile
=
_tiles
->
value
<
MeasurementTile
*>
(
i
);
Q_ASSERT
(
tile
!=
nullptr
);
if
(
!
qFuzzyCompare
(
tile
->
progress
(),
0
))
{
tile
->
setProgress
(
0
);
anyChanges
=
true
;
}
}
emit
progressChanged
();
if
(
anyChanges
)
{
emit
progressChanged
();
}
}
}
//!
//! \brief MeasurementArea::doUpdate
//! \pre MeasurementArea::deferUpdate must be called first, don't call
...
...
@@ -480,7 +386,7 @@ void MeasurementArea::doUpdate() {
const
auto
totalArea
=
this
->
area
()
*
si
::
meter
*
si
::
meter
;
const
auto
estNumTiles
=
totalArea
/
tileArea
;