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
130e12cf
Commit
130e12cf
authored
Oct 01, 2018
by
Thomas Gubler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SurveyComplexItem] wire up to splitConcavePolygons setting (lots of code duplication)
parent
6f2a9953
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
230 additions
and
3 deletions
+230
-3
SurveyComplexItem.cc
src/MissionManager/SurveyComplexItem.cc
+228
-3
SurveyComplexItem.h
src/MissionManager/SurveyComplexItem.h
+2
-0
No files found.
src/MissionManager/SurveyComplexItem.cc
View file @
130e12cf
...
...
@@ -1061,13 +1061,238 @@ bool SurveyComplexItem::_hoverAndCaptureEnabled(void) const
void
SurveyComplexItem
::
_rebuildTransectsPhase1
(
void
)
{
_rebuildTransectsPhase1Worker
(
false
/* refly */
);
bool
split
=
qgcApp
()
->
toolbox
()
->
settingsManager
()
->
appSettings
()
->
splitConcavePolygons
()
->
rawValue
().
toBool
();
if
(
split
)
{
_rebuildTransectsPhase1WorkerSplitPolygons
(
false
/* refly */
);
}
else
{
_rebuildTransectsPhase1WorkerSinglePolygon
(
false
/* refly */
);
}
if
(
_refly90DegreesFact
.
rawValue
().
toBool
())
{
_rebuildTransectsPhase1Worker
(
true
/* refly */
);
if
(
split
)
{
_rebuildTransectsPhase1WorkerSplitPolygons
(
true
/* refly */
);
}
else
{
_rebuildTransectsPhase1WorkerSinglePolygon
(
true
/* refly */
);
}
}
}
void
SurveyComplexItem
::
_rebuildTransectsPhase1Worker
(
bool
refly
)
void
SurveyComplexItem
::
_rebuildTransectsPhase1WorkerSinglePolygon
(
bool
refly
)
{
if
(
_ignoreRecalc
)
{
return
;
}
// If the transects are getting rebuilt then any previously loaded mission items are now invalid
if
(
_loadedMissionItemsParent
)
{
_loadedMissionItems
.
clear
();
_loadedMissionItemsParent
->
deleteLater
();
_loadedMissionItemsParent
=
NULL
;
}
// First pass will clear old transect data, refly will append to existing data
if
(
!
refly
)
{
_transects
.
clear
();
_transectsPathHeightInfo
.
clear
();
}
if
(
_surveyAreaPolygon
.
count
()
<
3
)
{
return
;
}
// Convert polygon to NED
QList
<
QPointF
>
polygonPoints
;
QGeoCoordinate
tangentOrigin
=
_surveyAreaPolygon
.
pathModel
().
value
<
QGCQGeoCoordinate
*>
(
0
)
->
coordinate
();
qCDebug
(
SurveyComplexItemLog
)
<<
"_rebuildTransectsPhase1 Convert polygon to NED - _surveyAreaPolygon.count():tangentOrigin"
<<
_surveyAreaPolygon
.
count
()
<<
tangentOrigin
;
for
(
int
i
=
0
;
i
<
_surveyAreaPolygon
.
count
();
i
++
)
{
double
y
,
x
,
down
;
QGeoCoordinate
vertex
=
_surveyAreaPolygon
.
pathModel
().
value
<
QGCQGeoCoordinate
*>
(
i
)
->
coordinate
();
if
(
i
==
0
)
{
// This avoids a nan calculation that comes out of convertGeoToNed
x
=
y
=
0
;
}
else
{
convertGeoToNed
(
vertex
,
tangentOrigin
,
&
y
,
&
x
,
&
down
);
}
polygonPoints
+=
QPointF
(
x
,
y
);
qCDebug
(
SurveyComplexItemLog
)
<<
"_rebuildTransectsPhase1 vertex:x:y"
<<
vertex
<<
polygonPoints
.
last
().
x
()
<<
polygonPoints
.
last
().
y
();
}
// Generate transects
double
gridAngle
=
_gridAngleFact
.
rawValue
().
toDouble
();
double
gridSpacing
=
_cameraCalc
.
adjustedFootprintSide
()
->
rawValue
().
toDouble
();
gridAngle
=
_clampGridAngle90
(
gridAngle
);
gridAngle
+=
refly
?
90
:
0
;
qCDebug
(
SurveyComplexItemLog
)
<<
"_rebuildTransectsPhase1 Clamped grid angle"
<<
gridAngle
;
qCDebug
(
SurveyComplexItemLog
)
<<
"_rebuildTransectsPhase1 gridSpacing:gridAngle:refly"
<<
gridSpacing
<<
gridAngle
<<
refly
;
// Convert polygon to bounding rect
qCDebug
(
SurveyComplexItemLog
)
<<
"_rebuildTransectsPhase1 Polygon"
;
QPolygonF
polygon
;
for
(
int
i
=
0
;
i
<
polygonPoints
.
count
();
i
++
)
{
qCDebug
(
SurveyComplexItemLog
)
<<
"Vertex"
<<
polygonPoints
[
i
];
polygon
<<
polygonPoints
[
i
];
}
polygon
<<
polygonPoints
[
0
];
QRectF
boundingRect
=
polygon
.
boundingRect
();
QPointF
boundingCenter
=
boundingRect
.
center
();
qCDebug
(
SurveyComplexItemLog
)
<<
"Bounding rect"
<<
boundingRect
.
topLeft
().
x
()
<<
boundingRect
.
topLeft
().
y
()
<<
boundingRect
.
bottomRight
().
x
()
<<
boundingRect
.
bottomRight
().
y
();
// Create set of rotated parallel lines within the expanded bounding rect. Make the lines larger than the
// bounding box to guarantee intersection.
QList
<
QLineF
>
lineList
;
// Transects are generated to be as long as the largest width/height of the bounding rect plus some fudge factor.
// This way they will always be guaranteed to intersect with a polygon edge no matter what angle they are rotated to.
// They are initially generated with the transects flowing from west to east and then points within the transect north to south.
double
maxWidth
=
qMax
(
boundingRect
.
width
(),
boundingRect
.
height
())
+
2000.0
;
double
halfWidth
=
maxWidth
/
2.0
;
double
transectX
=
boundingCenter
.
x
()
-
halfWidth
;
double
transectXMax
=
transectX
+
maxWidth
;
while
(
transectX
<
transectXMax
)
{
double
transectYTop
=
boundingCenter
.
y
()
-
halfWidth
;
double
transectYBottom
=
boundingCenter
.
y
()
+
halfWidth
;
lineList
+=
QLineF
(
_rotatePoint
(
QPointF
(
transectX
,
transectYTop
),
boundingCenter
,
gridAngle
),
_rotatePoint
(
QPointF
(
transectX
,
transectYBottom
),
boundingCenter
,
gridAngle
));
transectX
+=
gridSpacing
;
}
// Now intersect the lines with the polygon
QList
<
QLineF
>
intersectLines
;
#if 1
_intersectLinesWithPolygon
(
lineList
,
polygon
,
intersectLines
);
#else
// This is handy for debugging grid problems, not for release
intersectLines
=
lineList
;
#endif
// Less than two transects intersected with the polygon:
// Create a single transect which goes through the center of the polygon
// Intersect it with the polygon
if
(
intersectLines
.
count
()
<
2
)
{
_surveyAreaPolygon
.
center
();
QLineF
firstLine
=
lineList
.
first
();
QPointF
lineCenter
=
firstLine
.
pointAt
(
0.5
);
QPointF
centerOffset
=
boundingCenter
-
lineCenter
;
firstLine
.
translate
(
centerOffset
);
lineList
.
clear
();
lineList
.
append
(
firstLine
);
intersectLines
=
lineList
;
_intersectLinesWithPolygon
(
lineList
,
polygon
,
intersectLines
);
}
// Make sure all lines are going the same direction. Polygon intersection leads to lines which
// can be in varied directions depending on the order of the intesecting sides.
QList
<
QLineF
>
resultLines
;
_adjustLineDirection
(
intersectLines
,
resultLines
);
// Convert from NED to Geo
QList
<
QList
<
QGeoCoordinate
>>
transects
;
foreach
(
const
QLineF
&
line
,
resultLines
)
{
QGeoCoordinate
coord
;
QList
<
QGeoCoordinate
>
transect
;
convertNedToGeo
(
line
.
p1
().
y
(),
line
.
p1
().
x
(),
0
,
tangentOrigin
,
&
coord
);
transect
.
append
(
coord
);
convertNedToGeo
(
line
.
p2
().
y
(),
line
.
p2
().
x
(),
0
,
tangentOrigin
,
&
coord
);
transect
.
append
(
coord
);
transects
.
append
(
transect
);
}
_adjustTransectsToEntryPointLocation
(
transects
);
if
(
refly
)
{
_optimizeTransectsForShortestDistance
(
_transects
.
last
().
last
().
coord
,
transects
);
}
if
(
_flyAlternateTransectsFact
.
rawValue
().
toBool
())
{
QList
<
QList
<
QGeoCoordinate
>>
alternatingTransects
;
for
(
int
i
=
0
;
i
<
transects
.
count
();
i
++
)
{
if
(
!
(
i
&
1
))
{
alternatingTransects
.
append
(
transects
[
i
]);
}
}
for
(
int
i
=
transects
.
count
()
-
1
;
i
>
0
;
i
--
)
{
if
(
i
&
1
)
{
alternatingTransects
.
append
(
transects
[
i
]);
}
}
transects
=
alternatingTransects
;
}
// Adjust to lawnmower pattern
bool
reverseVertices
=
false
;
for
(
int
i
=
0
;
i
<
transects
.
count
();
i
++
)
{
// We must reverse the vertices for every other transect in order to make a lawnmower pattern
QList
<
QGeoCoordinate
>
transectVertices
=
transects
[
i
];
if
(
reverseVertices
)
{
reverseVertices
=
false
;
QList
<
QGeoCoordinate
>
reversedVertices
;
for
(
int
j
=
transectVertices
.
count
()
-
1
;
j
>=
0
;
j
--
)
{
reversedVertices
.
append
(
transectVertices
[
j
]);
}
transectVertices
=
reversedVertices
;
}
else
{
reverseVertices
=
true
;
}
transects
[
i
]
=
transectVertices
;
}
// Convert to CoordInfo transects and append to _transects
foreach
(
const
QList
<
QGeoCoordinate
>&
transect
,
transects
)
{
QGeoCoordinate
coord
;
QList
<
TransectStyleComplexItem
::
CoordInfo_t
>
coordInfoTransect
;
TransectStyleComplexItem
::
CoordInfo_t
coordInfo
;
coordInfo
=
{
transect
[
0
],
CoordTypeSurveyEdge
};
coordInfoTransect
.
append
(
coordInfo
);
coordInfo
=
{
transect
[
1
],
CoordTypeSurveyEdge
};
coordInfoTransect
.
append
(
coordInfo
);
// For hover and capture we need points for each camera location within the transect
if
(
triggerCamera
()
&&
hoverAndCaptureEnabled
())
{
double
transectLength
=
transect
[
0
].
distanceTo
(
transect
[
1
]);
double
transectAzimuth
=
transect
[
0
].
azimuthTo
(
transect
[
1
]);
if
(
triggerDistance
()
<
transectLength
)
{
int
cInnerHoverPoints
=
floor
(
transectLength
/
triggerDistance
());
qCDebug
(
SurveyComplexItemLog
)
<<
"cInnerHoverPoints"
<<
cInnerHoverPoints
;
for
(
int
i
=
0
;
i
<
cInnerHoverPoints
;
i
++
)
{
QGeoCoordinate
hoverCoord
=
transect
[
0
].
atDistanceAndAzimuth
(
triggerDistance
()
*
(
i
+
1
),
transectAzimuth
);
TransectStyleComplexItem
::
CoordInfo_t
coordInfo
=
{
hoverCoord
,
CoordTypeInteriorHoverTrigger
};
coordInfoTransect
.
insert
(
1
+
i
,
coordInfo
);
}
}
}
// Extend the transect ends for turnaround
if
(
_hasTurnaround
())
{
QGeoCoordinate
turnaroundCoord
;
double
turnAroundDistance
=
_turnAroundDistanceFact
.
rawValue
().
toDouble
();
double
azimuth
=
transect
[
0
].
azimuthTo
(
transect
[
1
]);
turnaroundCoord
=
transect
[
0
].
atDistanceAndAzimuth
(
-
turnAroundDistance
,
azimuth
);
turnaroundCoord
.
setAltitude
(
qQNaN
());
TransectStyleComplexItem
::
CoordInfo_t
coordInfo
=
{
turnaroundCoord
,
CoordTypeTurnaround
};
coordInfoTransect
.
prepend
(
coordInfo
);
azimuth
=
transect
.
last
().
azimuthTo
(
transect
[
transect
.
count
()
-
2
]);
turnaroundCoord
=
transect
.
last
().
atDistanceAndAzimuth
(
-
turnAroundDistance
,
azimuth
);
turnaroundCoord
.
setAltitude
(
qQNaN
());
coordInfo
=
{
turnaroundCoord
,
CoordTypeTurnaround
};
coordInfoTransect
.
append
(
coordInfo
);
}
_transects
.
append
(
coordInfoTransect
);
}
}
void
SurveyComplexItem
::
_rebuildTransectsPhase1WorkerSplitPolygons
(
bool
refly
)
{
if
(
_ignoreRecalc
)
{
return
;
...
...
src/MissionManager/SurveyComplexItem.h
View file @
130e12cf
...
...
@@ -111,6 +111,8 @@ private:
bool
_loadV3
(
const
QJsonObject
&
complexObject
,
int
sequenceNumber
,
QString
&
errorString
);
bool
_loadV4
(
const
QJsonObject
&
complexObject
,
int
sequenceNumber
,
QString
&
errorString
);
void
_rebuildTransectsPhase1Worker
(
bool
refly
);
void
_rebuildTransectsPhase1WorkerSinglePolygon
(
bool
refly
);
void
_rebuildTransectsPhase1WorkerSplitPolygons
(
bool
refly
);
/// Adds to the _transects array from one polygon
void
_rebuildTranscetsFromPolygon
(
bool
refly
,
const
QPolygonF
&
polygon
,
const
QGeoCoordinate
&
tangentOrigin
,
const
QPointF
*
const
transitionPoint
);
// Decompose polygon into list of convex sub polygons
...
...
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