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
a22db7f4
Commit
a22db7f4
authored
Sep 17, 2020
by
Valentin Platzgummer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tiles added to WimaMeasurementArea
parent
a0c951cb
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
162 additions
and
34 deletions
+162
-34
WimaMeasurementArea.cc
src/Wima/Geometry/WimaMeasurementArea.cc
+103
-31
WimaMeasurementArea.h
src/Wima/Geometry/WimaMeasurementArea.h
+15
-2
WimaMeasurementAreaEditor.qml
src/WimaView/WimaMeasurementAreaEditor.qml
+6
-0
WimaMeasurementAreaMapVisual.qml
src/WimaView/WimaMeasurementAreaMapVisual.qml
+38
-1
No files found.
src/Wima/Geometry/WimaMeasurementArea.cc
View file @
a22db7f4
#include "WimaMeasurementArea.h"
#include "QtConcurrentRun"
#include "SnakeTile.h"
#include "snake.h"
#include <boost/units/systems/si.hpp>
#ifndef SNAKE_MAX_TILES
#define SNAKE_MAX_TILES 1000
#endif
const
char
*
WimaMeasurementArea
::
settingsGroup
=
"MeasurementArea"
;
const
char
*
WimaMeasurementArea
::
tileHeightName
=
"TileHeight"
;
const
char
*
WimaMeasurementArea
::
tileWidthName
=
"TileWidth"
;
...
...
@@ -13,6 +18,8 @@ const char *WimaMeasurementArea::minTransectLengthName = "MinTransectLength";
const
char
*
WimaMeasurementArea
::
showTilesName
=
"ShowTiles"
;
const
char
*
WimaMeasurementArea
::
WimaMeasurementAreaName
=
"Measurement Area"
;
void
tileDeleter
(
QmlObjectListModel
*
tiles
)
{
tiles
->
clearAndDeleteContents
();
}
WimaMeasurementArea
::
WimaMeasurementArea
(
QObject
*
parent
)
:
WimaArea
(
parent
),
_metaDataMap
(
FactMetaData
::
createMapFromJsonFile
(
...
...
@@ -32,7 +39,8 @@ WimaMeasurementArea::WimaMeasurementArea(QObject *parent)
this
/* QObject parent */
)),
_showTiles
(
SettingsFact
(
settingsGroup
,
_metaDataMap
[
showTilesName
],
this
/* QObject parent */
)),
_calculating
(
false
)
{
_pTiles
(
new
QmlObjectListModel
(),
&
tileDeleter
),
_calculating
(
false
),
_polygonValid
(
false
)
{
init
();
}
...
...
@@ -56,7 +64,8 @@ WimaMeasurementArea::WimaMeasurementArea(const WimaMeasurementArea &other,
this
/* QObject parent */
)),
_showTiles
(
SettingsFact
(
settingsGroup
,
_metaDataMap
[
showTilesName
],
this
/* QObject parent */
)),
_calculating
(
false
)
{
_pTiles
(
new
QmlObjectListModel
(),
&
tileDeleter
),
_calculating
(
false
),
_polygonValid
(
false
)
{
init
();
}
...
...
@@ -73,7 +82,7 @@ operator=(const WimaMeasurementArea &other) {
}
WimaMeasurementArea
::~
WimaMeasurementArea
()
{
this
->
_
tiles
.
clearAndDeleteContents
();
this
->
_
pTiles
->
clearAndDeleteContents
();
}
QString
WimaMeasurementArea
::
mapVisualQML
()
const
{
...
...
@@ -96,6 +105,12 @@ Fact *WimaMeasurementArea::minTransectLength() { return &_minTransectLength; }
Fact
*
WimaMeasurementArea
::
showTiles
()
{
return
&
_showTiles
;
}
QmlObjectListModel
*
WimaMeasurementArea
::
tiles
()
{
return
this
->
_pTiles
.
get
();
}
int
WimaMeasurementArea
::
maxTiles
()
{
return
SNAKE_MAX_TILES
;
}
bool
WimaMeasurementArea
::
ready
()
{
return
!
_calculating
;
}
void
WimaMeasurementArea
::
saveToJson
(
QJsonObject
&
json
)
{
this
->
WimaArea
::
saveToJson
(
json
);
json
[
tileHeightName
]
=
_tileHeight
.
rawValue
().
toDouble
();
...
...
@@ -160,41 +175,72 @@ bool WimaMeasurementArea::loadFromJson(const QJsonObject &json,
return
false
;
}
}
//!
//! \brief WimaMeasurementArea::doUpdate
//! \pre WimaMeasurementArea::deferUpdate must be called first, don't call this
//! function directly!
void
WimaMeasurementArea
::
doUpdate
()
{
using
namespace
snake
;
using
namespace
boost
::
units
;
#ifdef SNAKE_SHOW_TIME
auto
start
=
std
::
chrono
::
high_resolution_clock
::
now
();
#endif
auto
polygon
=
this
->
coordinateList
();
for
(
auto
&
v
:
polygon
)
{
v
.
setAltitude
(
0
);
}
if
(
polygon
.
size
()
>
3
)
{
QGeoCoordinate
origin
=
polygon
.
first
();
BoostPolygon
polygonENU
;
areaToEnu
(
origin
,
polygon
,
polygonENU
);
Length
height
=
this
->
_tileHeight
.
rawValue
().
toDouble
()
*
si
::
meter
;
Length
width
=
this
->
_tileWidth
.
rawValue
().
toDouble
()
*
si
::
meter
;
Area
minArea
=
const
auto
height
=
this
->
_tileHeight
.
rawValue
().
toDouble
()
*
si
::
meter
;
const
auto
width
=
this
->
_tileWidth
.
rawValue
().
toDouble
()
*
si
::
meter
;
const
auto
tileArea
=
width
*
height
;
const
auto
totalArea
=
this
->
area
()
*
si
::
meter
*
si
::
meter
;
const
auto
estNumTiles
=
totalArea
/
tileArea
;
if
(
!
this
->
_calculating
&&
long
(
std
::
ceil
(
estNumTiles
.
value
()))
<=
SNAKE_MAX_TILES
&&
this
->
count
()
>=
3
&&
this
->
isSimplePolygon
())
{
this
->
_calculating
=
true
;
if
(
!
this
->
_polygonValid
)
{
this
->
_polygon
=
this
->
coordinateList
();
for
(
auto
&
v
:
this
->
_polygon
)
{
v
.
setAltitude
(
0
);
}
this
->
_polygonValid
=
true
;
}
const
auto
&
polygon
=
this
->
_polygon
;
const
auto
minArea
=
this
->
_minTileArea
.
rawValue
().
toDouble
()
*
si
::
meter
*
si
::
meter
;
std
::
vector
<
BoostPolygon
>
tilesENU
;
BoundingBox
bbox
;
std
::
string
errorString
;
if
(
snake
::
tiles
(
polygonENU
,
height
,
width
,
minArea
,
tilesENU
,
bbox
,
errorString
))
{
this
->
_tiles
.
clearAndDeleteContents
();
for
(
const
auto
&
t
:
tilesENU
)
{
auto
geoTile
=
new
SnakeTile
(
&
this
->
_tiles
);
for
(
const
auto
&
v
:
t
.
outer
())
{
QGeoCoordinate
geoVertex
;
fromENU
(
origin
,
v
,
geoVertex
);
geoTile
->
push_back
(
geoVertex
);
auto
*
th
=
this
->
thread
();
auto
future
=
QtConcurrent
::
run
([
polygon
,
th
,
height
,
width
,
minArea
]
{
#ifdef SNAKE_SHOW_TIME
auto
start
=
std
::
chrono
::
high_resolution_clock
::
now
();
#endif
TilesPtr
pTiles
(
new
QmlObjectListModel
(),
&
tileDeleter
);
QGeoCoordinate
origin
=
polygon
.
first
();
BoostPolygon
polygonENU
;
areaToEnu
(
origin
,
polygon
,
polygonENU
);
std
::
vector
<
BoostPolygon
>
tilesENU
;
BoundingBox
bbox
;
std
::
string
errorString
;
if
(
snake
::
tiles
(
polygonENU
,
height
,
width
,
minArea
,
tilesENU
,
bbox
,
errorString
))
{
for
(
const
auto
&
t
:
tilesENU
)
{
auto
geoTile
=
new
SnakeTile
(
pTiles
.
get
());
for
(
const
auto
&
v
:
t
.
outer
())
{
QGeoCoordinate
geoVertex
;
fromENU
(
origin
,
v
,
geoVertex
);
geoTile
->
push_back
(
geoVertex
);
}
pTiles
->
append
(
geoTile
);
}
this
->
_tiles
.
append
(
geoTile
);
}
}
pTiles
->
moveToThread
(
th
);
#ifdef SNAKE_SHOW_TIME
qDebug
()
<<
"WimaMeasurementArea::doUpdate concurrent update execution time: "
<<
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
std
::
chrono
::
high_resolution_clock
::
now
()
-
start
)
.
count
()
<<
" ms"
;
#endif
return
pTiles
;
});
// QtConcurrent::run()
this
->
_watcher
.
setFuture
(
future
);
}
#ifdef SNAKE_SHOW_TIME
qDebug
()
<<
"WimaMeasurementArea::doUpdate execution time: "
...
...
@@ -209,9 +255,30 @@ void WimaMeasurementArea::deferUpdate() {
if
(
this
->
_timer
.
isActive
())
{
this
->
_timer
.
stop
();
}
if
(
this
->
_pTiles
->
count
()
>
0
)
{
this
->
_pTiles
->
clearAndDeleteContents
();
emit
this
->
tilesChanged
();
}
this
->
_timer
.
start
(
100
);
}
void
WimaMeasurementArea
::
storeTiles
()
{
#ifdef SNAKE_SHOW_TIME
auto
start
=
std
::
chrono
::
high_resolution_clock
::
now
();
#endif
this
->
_pTiles
=
this
->
_watcher
.
result
();
this
->
_calculating
=
false
;
emit
this
->
tilesChanged
();
// This is expensive. Drawing tiles is expensive too.
#ifdef SNAKE_SHOW_TIME
qDebug
()
<<
"WimaMeasurementArea::storeTiles() execution time: "
<<
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
std
::
chrono
::
high_resolution_clock
::
now
()
-
start
)
.
count
()
<<
" ms"
;
#endif
}
void
WimaMeasurementArea
::
init
()
{
this
->
setObjectName
(
WimaMeasurementAreaName
);
connect
(
&
this
->
_tileHeight
,
&
Fact
::
rawValueChanged
,
this
,
...
...
@@ -222,15 +289,20 @@ void WimaMeasurementArea::init() {
&
WimaMeasurementArea
::
deferUpdate
);
connect
(
this
,
&
WimaArea
::
pathChanged
,
this
,
&
WimaMeasurementArea
::
deferUpdate
);
connect
(
this
,
&
WimaArea
::
pathChanged
,
[
this
]
{
this
->
_polygonValid
=
false
;
});
this
->
_timer
.
setSingleShot
(
true
);
connect
(
&
this
->
_timer
,
&
QTimer
::
timeout
,
this
,
&
WimaMeasurementArea
::
doUpdate
);
connect
(
&
this
->
_watcher
,
&
QFutureWatcher
<
std
::
unique_ptr
<
QmlObjectListModel
>>::
finished
,
this
,
&
WimaMeasurementArea
::
storeTiles
);
}
/*!
* \class WimaMeasurementArea
* \brief Class defining the area inside which the actual drone measurements
are
* performed.
* \brief Class defining the area inside which the actual drone measurements
*
are
performed.
*
* \sa WimaArea, WimaController, WimaPlaner
*/
src/Wima/Geometry/WimaMeasurementArea.h
View file @
a22db7f4
#pragma once
#include <QFutureWatcher>
#include <QObject>
#include <QTimer>
...
...
@@ -22,6 +23,8 @@ public:
Q_PROPERTY
(
Fact
*
transectDistance
READ
transectDistance
CONSTANT
)
Q_PROPERTY
(
Fact
*
minTransectLength
READ
minTransectLength
CONSTANT
)
Q_PROPERTY
(
Fact
*
showTiles
READ
showTiles
CONSTANT
)
Q_PROPERTY
(
QmlObjectListModel
*
tiles
READ
tiles
NOTIFY
tilesChanged
)
Q_PROPERTY
(
int
maxTiles
READ
maxTiles
NOTIFY
maxTilesChanged
)
// Overrides from WimaPolygon
QString
mapVisualQML
(
void
)
const
;
...
...
@@ -33,6 +36,9 @@ public:
Fact
*
transectDistance
();
Fact
*
minTransectLength
();
Fact
*
showTiles
();
QmlObjectListModel
*
tiles
();
int
maxTiles
();
bool
ready
();
// Member Methodes
void
saveToJson
(
QJsonObject
&
json
);
...
...
@@ -53,12 +59,15 @@ public:
static
const
char
*
WimaMeasurementAreaName
;
signals:
void
tilesChanged
();
void
maxTilesChanged
();
public
slots
:
private
slots
:
void
doUpdate
();
void
deferUpdate
();
void
storeTiles
();
private:
// Member Methodes
...
...
@@ -76,6 +85,10 @@ private:
// Tile stuff.
QTimer
_timer
;
std
::
atomic_bool
_calculating
;
QmlObjectListModel
_tiles
;
using
TilesPtr
=
std
::
shared_ptr
<
QmlObjectListModel
>
;
TilesPtr
_pTiles
;
QList
<
QGeoCoordinate
>
_polygon
;
QFutureWatcher
<
TilesPtr
>
_watcher
;
bool
_calculating
;
bool
_polygonValid
;
};
src/WimaView/WimaMeasurementAreaEditor.qml
View file @
a22db7f4
...
...
@@ -178,6 +178,12 @@ Rectangle {
QGCLabel
{
text
:
qsTr
(
"
Nodes
"
)
}
QGCLabel
{
text
:
areaItem
.
count
}
QGCLabel
{
text
:
qsTr
(
"
Tiles
"
)
}
QGCLabel
{
text
:
areaItem
.
tiles
.
count
}
QGCLabel
{
text
:
qsTr
(
"
Max. Tiles
"
)
}
QGCLabel
{
text
:
areaItem
.
maxTiles
}
}
}
// Column
}
// Rectangle
src/WimaView/WimaMeasurementAreaMapVisual.qml
View file @
a22db7f4
...
...
@@ -85,7 +85,7 @@ Item {
Component.onDestruction
:
{
}
// Polygon
WimaMapPolygonVisuals
{
qgcView
:
_root
.
qgcView
mapControl
:
map
...
...
@@ -96,6 +96,7 @@ Item {
interiorOpacity
:
0.25
}
// Border Polygon
WimaMapPolygonVisuals
{
qgcView
:
_root
.
qgcView
mapControl
:
map
...
...
@@ -106,4 +107,40 @@ Item {
interiorOpacity
:
1
}
// Add Snake tiles to the map
Component
{
id
:
tileComponent
MapPolygon
{
color
:
"
transparent
"
opacity
:
1
border.color
:
"
black
"
border.width
:
1
path
:
[]
}
}
Repeater
{
property
bool
enable
:
areaItem
.
showTiles
.
value
model
:
enable
?
areaItem
.
tiles
:
0
Item
{
property
var
_tileComponent
function
addVisuals
()
{
_tileComponent
=
tileComponent
.
createObject
(
map
)
map
.
addMapItem
(
_tileComponent
)
_tileComponent
.
path
=
object
.
path
}
function
removeVisuals
()
{
_tileComponent
.
destroy
()
}
Component.onCompleted
:
{
addVisuals
()
}
Component.onDestruction
:
{
removeVisuals
()
}
}
}
}
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