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
03d3d538
Commit
03d3d538
authored
Jun 01, 2018
by
DonLakeFlyer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support for Sync - Load KML
parent
4b3b4769
Changes
22
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
454 additions
and
158 deletions
+454
-158
qgroundcontrol.pro
qgroundcontrol.pro
+2
-0
KMLFileHelper.cc
src/KMLFileHelper.cc
+176
-0
KMLFileHelper.h
src/KMLFileHelper.h
+37
-0
CorridorScanComplexItem.cc
src/MissionManager/CorridorScanComplexItem.cc
+7
-1
CorridorScanComplexItem.h
src/MissionManager/CorridorScanComplexItem.h
+4
-1
CorridorScanComplexItemTest.cc
src/MissionManager/CorridorScanComplexItemTest.cc
+1
-1
MissionController.cc
src/MissionManager/MissionController.cc
+42
-15
MissionController.h
src/MissionManager/MissionController.h
+22
-7
PlanMasterController.cc
src/MissionManager/PlanMasterController.cc
+1
-1
PlanMasterController.h
src/MissionManager/PlanMasterController.h
+2
-2
QGCMapPolygon.cc
src/MissionManager/QGCMapPolygon.cc
+5
-64
QGCMapPolyline.cc
src/MissionManager/QGCMapPolyline.cc
+5
-45
SectionTest.cc
src/MissionManager/SectionTest.cc
+1
-1
StructureScanComplexItem.cc
src/MissionManager/StructureScanComplexItem.cc
+8
-1
StructureScanComplexItem.h
src/MissionManager/StructureScanComplexItem.h
+4
-1
StructureScanComplexItemTest.cc
src/MissionManager/StructureScanComplexItemTest.cc
+2
-2
SurveyComplexItem.cc
src/MissionManager/SurveyComplexItem.cc
+7
-1
SurveyComplexItem.h
src/MissionManager/SurveyComplexItem.h
+4
-1
SurveyComplexItemTest.cc
src/MissionManager/SurveyComplexItemTest.cc
+1
-1
TransectStyleComplexItem.cc
src/MissionManager/TransectStyleComplexItem.cc
+2
-0
PlanView.qml
src/PlanView/PlanView.qml
+114
-13
QGCApplication.cc
src/QGCApplication.cc
+7
-0
No files found.
qgroundcontrol.pro
View file @
03d3d538
...
...
@@ -515,6 +515,7 @@ HEADERS += \
src
/
Joystick
/
Joystick
.
h
\
src
/
Joystick
/
JoystickManager
.
h
\
src
/
JsonHelper
.
h
\
src
/
KMLFileHelper
.
h
\
src
/
LogCompressor
.
h
\
src
/
MG
.
h
\
src
/
MissionManager
/
CameraCalc
.
h
\
...
...
@@ -711,6 +712,7 @@ SOURCES += \
src
/
Joystick
/
Joystick
.
cc
\
src
/
Joystick
/
JoystickManager
.
cc
\
src
/
JsonHelper
.
cc
\
src
/
KMLFileHelper
.
cc
\
src
/
LogCompressor
.
cc
\
src
/
MissionManager
/
CameraCalc
.
cc
\
src
/
MissionManager
/
CameraSection
.
cc
\
...
...
src/KMLFileHelper.cc
0 → 100644
View file @
03d3d538
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "KMLFileHelper.h"
#include <QFile>
QDomDocument
KMLFileHelper
::
loadFile
(
const
QString
&
kmlFile
,
QString
&
errorString
)
{
QFile
file
(
kmlFile
);
errorString
.
clear
();
if
(
!
file
.
exists
())
{
errorString
=
tr
(
"File not found: %1"
).
arg
(
kmlFile
);
return
QDomDocument
();
}
if
(
!
file
.
open
(
QIODevice
::
ReadOnly
))
{
errorString
=
tr
(
"Unable to open file: %1 error: $%2"
).
arg
(
kmlFile
).
arg
(
file
.
errorString
());
return
QDomDocument
();
}
QDomDocument
doc
;
QString
errorMessage
;
int
errorLine
;
if
(
!
doc
.
setContent
(
&
file
,
&
errorMessage
,
&
errorLine
))
{
errorString
=
tr
(
"Unable to parse KML file: %1 error: %2 line: %3"
).
arg
(
kmlFile
).
arg
(
errorMessage
).
arg
(
errorLine
);
return
QDomDocument
();
}
return
doc
;
}
QVariantList
KMLFileHelper
::
determineFileContents
(
const
QString
&
kmlFile
)
{
QString
errorString
;
KMLFileContents
fileContents
=
determineFileContents
(
kmlFile
,
errorString
);
QVariantList
varList
;
varList
.
append
(
QVariant
::
fromValue
(
fileContents
));
varList
.
append
(
QVariant
::
fromValue
(
errorString
));
return
varList
;
}
KMLFileHelper
::
KMLFileContents
KMLFileHelper
::
determineFileContents
(
const
QString
&
kmlFile
,
QString
&
errorString
)
{
QDomDocument
domDocument
=
KMLFileHelper
::
loadFile
(
kmlFile
,
errorString
);
if
(
!
errorString
.
isEmpty
())
{
return
Error
;
}
QDomNodeList
rgNodes
=
domDocument
.
elementsByTagName
(
"Polygon"
);
if
(
rgNodes
.
count
())
{
return
Polygon
;
}
rgNodes
=
domDocument
.
elementsByTagName
(
"LineString"
);
if
(
rgNodes
.
count
())
{
return
Polyline
;
}
errorString
=
tr
(
"No known type found in KML file."
);
return
Error
;
}
bool
KMLFileHelper
::
loadPolygonFromFile
(
const
QString
&
kmlFile
,
QList
<
QGeoCoordinate
>&
vertices
,
QString
&
errorString
)
{
errorString
.
clear
();
vertices
.
clear
();
QDomDocument
domDocument
=
KMLFileHelper
::
loadFile
(
kmlFile
,
errorString
);
if
(
!
errorString
.
isEmpty
())
{
return
false
;
}
QDomNodeList
rgNodes
=
domDocument
.
elementsByTagName
(
"Polygon"
);
if
(
rgNodes
.
count
()
==
0
)
{
errorString
=
tr
(
"Unable to find Polygon node in KML"
);
return
false
;
}
QDomNode
coordinatesNode
=
rgNodes
.
item
(
0
).
namedItem
(
"outerBoundaryIs"
).
namedItem
(
"LinearRing"
).
namedItem
(
"coordinates"
);
if
(
coordinatesNode
.
isNull
())
{
errorString
=
tr
(
"Internal error: Unable to find coordinates node in KML"
);
return
false
;
}
QString
coordinatesString
=
coordinatesNode
.
toElement
().
text
().
simplified
();
QStringList
rgCoordinateStrings
=
coordinatesString
.
split
(
" "
);
QList
<
QGeoCoordinate
>
rgCoords
;
for
(
int
i
=
0
;
i
<
rgCoordinateStrings
.
count
()
-
1
;
i
++
)
{
QString
coordinateString
=
rgCoordinateStrings
[
i
];
QStringList
rgValueStrings
=
coordinateString
.
split
(
","
);
QGeoCoordinate
coord
;
coord
.
setLongitude
(
rgValueStrings
[
0
].
toDouble
());
coord
.
setLatitude
(
rgValueStrings
[
1
].
toDouble
());
rgCoords
.
append
(
coord
);
}
// Determine winding, reverse if needed
double
sum
=
0
;
for
(
int
i
=
0
;
i
<
rgCoords
.
count
();
i
++
)
{
QGeoCoordinate
coord1
=
rgCoords
[
i
];
QGeoCoordinate
coord2
=
(
i
==
rgCoords
.
count
()
-
1
)
?
rgCoords
[
0
]
:
rgCoords
[
i
+
1
];
sum
+=
(
coord2
.
longitude
()
-
coord1
.
longitude
())
*
(
coord2
.
latitude
()
+
coord1
.
latitude
());
}
bool
reverse
=
sum
<
0.0
;
if
(
reverse
)
{
QList
<
QGeoCoordinate
>
rgReversed
;
for
(
int
i
=
0
;
i
<
rgCoords
.
count
();
i
++
)
{
rgReversed
.
prepend
(
rgCoords
[
i
]);
}
rgCoords
=
rgReversed
;
}
vertices
=
rgCoords
;
return
true
;
}
bool
KMLFileHelper
::
loadPolylineFromFile
(
const
QString
&
kmlFile
,
QList
<
QGeoCoordinate
>&
coords
,
QString
&
errorString
)
{
errorString
.
clear
();
coords
.
clear
();
QDomDocument
domDocument
=
KMLFileHelper
::
loadFile
(
kmlFile
,
errorString
);
if
(
!
errorString
.
isEmpty
())
{
return
false
;
}
QDomNodeList
rgNodes
=
domDocument
.
elementsByTagName
(
"LineString"
);
if
(
rgNodes
.
count
()
==
0
)
{
errorString
=
tr
(
"Unable to find LineString node in KML"
);
return
false
;
}
QDomNode
coordinatesNode
=
rgNodes
.
item
(
0
).
namedItem
(
"coordinates"
);
if
(
coordinatesNode
.
isNull
())
{
errorString
=
tr
(
"Internal error: Unable to find coordinates node in KML"
);
return
false
;
}
QString
coordinatesString
=
coordinatesNode
.
toElement
().
text
().
simplified
();
QStringList
rgCoordinateStrings
=
coordinatesString
.
split
(
" "
);
QList
<
QGeoCoordinate
>
rgCoords
;
for
(
int
i
=
0
;
i
<
rgCoordinateStrings
.
count
()
-
1
;
i
++
)
{
QString
coordinateString
=
rgCoordinateStrings
[
i
];
QStringList
rgValueStrings
=
coordinateString
.
split
(
","
);
QGeoCoordinate
coord
;
coord
.
setLongitude
(
rgValueStrings
[
0
].
toDouble
());
coord
.
setLatitude
(
rgValueStrings
[
1
].
toDouble
());
rgCoords
.
append
(
coord
);
}
coords
=
rgCoords
;
return
true
;
}
src/KMLFileHelper.h
0 → 100644
View file @
03d3d538
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#pragma once
#include <QObject>
#include <QDomDocument>
#include <QList>
#include <QGeoCoordinate>
/// 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
KMLFileHelper
:
public
QObject
{
Q_OBJECT
public:
enum
KMLFileContents
{
Polygon
,
Polyline
,
Error
};
Q_ENUM
(
KMLFileContents
)
Q_INVOKABLE
static
QVariantList
determineFileContents
(
const
QString
&
kmlFile
);
static
KMLFileContents
determineFileContents
(
const
QString
&
kmlFile
,
QString
&
errorString
);
static
QDomDocument
loadFile
(
const
QString
&
kmlFile
,
QString
&
errorString
);
static
bool
loadPolygonFromFile
(
const
QString
&
kmlFile
,
QList
<
QGeoCoordinate
>&
vertices
,
QString
&
errorString
);
static
bool
loadPolylineFromFile
(
const
QString
&
kmlFile
,
QList
<
QGeoCoordinate
>&
coords
,
QString
&
errorString
);
};
src/MissionManager/CorridorScanComplexItem.cc
View file @
03d3d538
...
...
@@ -27,7 +27,7 @@ const char* CorridorScanComplexItem::_jsonEntryPointKey = "EntryPoint";
const
char
*
CorridorScanComplexItem
::
jsonComplexItemTypeValue
=
"CorridorScan"
;
CorridorScanComplexItem
::
CorridorScanComplexItem
(
Vehicle
*
vehicle
,
bool
flyView
,
QObject
*
parent
)
CorridorScanComplexItem
::
CorridorScanComplexItem
(
Vehicle
*
vehicle
,
bool
flyView
,
const
QString
&
kmlFile
,
QObject
*
parent
)
:
TransectStyleComplexItem
(
vehicle
,
flyView
,
settingsGroup
,
parent
)
,
_entryPoint
(
0
)
,
_metaDataMap
(
FactMetaData
::
createMapFromJsonFile
(
QStringLiteral
(
":/json/CorridorScan.SettingsGroup.json"
),
this
))
...
...
@@ -50,6 +50,12 @@ CorridorScanComplexItem::CorridorScanComplexItem(Vehicle* vehicle, bool flyView,
connect
(
&
_corridorPolyline
,
&
QGCMapPolyline
::
pathChanged
,
this
,
&
CorridorScanComplexItem
::
_rebuildCorridorPolygon
);
connect
(
&
_corridorWidthFact
,
&
Fact
::
valueChanged
,
this
,
&
CorridorScanComplexItem
::
_rebuildCorridorPolygon
);
if
(
!
kmlFile
.
isEmpty
())
{
_corridorPolyline
.
loadKMLFile
(
kmlFile
);
_corridorPolyline
.
setDirty
(
false
);
}
setDirty
(
false
);
}
void
CorridorScanComplexItem
::
save
(
QJsonArray
&
planItems
)
...
...
src/MissionManager/CorridorScanComplexItem.h
View file @
03d3d538
...
...
@@ -23,7 +23,10 @@ class CorridorScanComplexItem : public TransectStyleComplexItem
Q_OBJECT
public:
CorridorScanComplexItem
(
Vehicle
*
vehicle
,
bool
flyView
,
QObject
*
parent
);
/// @param vehicle Vehicle which this is being contructed for
/// @param flyView true: Created for use in the Fly View, false: Created for use in the Plan View
/// @param kmlFile Polyline comes from this file, empty for default polyline
CorridorScanComplexItem
(
Vehicle
*
vehicle
,
bool
flyView
,
const
QString
&
kmlFile
,
QObject
*
parent
);
Q_PROPERTY
(
QGCMapPolyline
*
corridorPolyline
READ
corridorPolyline
CONSTANT
)
Q_PROPERTY
(
Fact
*
corridorWidth
READ
corridorWidth
CONSTANT
)
...
...
src/MissionManager/CorridorScanComplexItemTest.cc
View file @
03d3d538
...
...
@@ -23,7 +23,7 @@ void CorridorScanComplexItemTest::init(void)
UnitTest
::
init
();
_offlineVehicle
=
new
Vehicle
(
MAV_AUTOPILOT_PX4
,
MAV_TYPE_QUADROTOR
,
qgcApp
()
->
toolbox
()
->
firmwarePluginManager
(),
this
);
_corridorItem
=
new
CorridorScanComplexItem
(
_offlineVehicle
,
false
/* flyView */
,
this
);
_corridorItem
=
new
CorridorScanComplexItem
(
_offlineVehicle
,
false
/* flyView */
,
QString
()
/* kmlFile */
,
this
/* parent */
);
// vehicleSpeed need for terrain calcs
MissionController
::
MissionFlightStatus_t
missionFlightStatus
;
...
...
src/MissionManager/MissionController.cc
View file @
03d3d538
...
...
@@ -389,25 +389,48 @@ int MissionController::insertROIMissionItem(QGeoCoordinate coordinate, int i)
int
MissionController
::
insertComplexMissionItem
(
QString
itemName
,
QGeoCoordinate
mapCenterCoordinate
,
int
i
)
{
ComplexMissionItem
*
newItem
;
bool
surveyStyleItem
=
false
;
int
sequenceNumber
=
_nextSequenceNumber
();
if
(
itemName
==
_surveyMissionItemName
)
{
newItem
=
new
SurveyComplexItem
(
_controllerVehicle
,
_flyView
,
_visualItems
);
newItem
=
new
SurveyComplexItem
(
_controllerVehicle
,
_flyView
,
QString
()
/* kmlFile */
,
_visualItems
/* parent */
);
newItem
->
setCoordinate
(
mapCenterCoordinate
);
surveyStyleItem
=
true
;
}
else
if
(
itemName
==
_fwLandingMissionItemName
)
{
newItem
=
new
FixedWingLandingComplexItem
(
_controllerVehicle
,
_flyView
,
_visualItems
);
newItem
=
new
FixedWingLandingComplexItem
(
_controllerVehicle
,
_flyView
,
_visualItems
/* parent */
);
}
else
if
(
itemName
==
_structureScanMissionItemName
)
{
newItem
=
new
StructureScanComplexItem
(
_controllerVehicle
,
_flyView
,
_visualItems
);
newItem
=
new
StructureScanComplexItem
(
_controllerVehicle
,
_flyView
,
QString
()
/* kmlFile */
,
_visualItems
/* parent */
);
}
else
if
(
itemName
==
_corridorScanMissionItemName
)
{
newItem
=
new
CorridorScanComplexItem
(
_controllerVehicle
,
_flyView
,
_visualItems
);
surveyStyleItem
=
true
;
newItem
=
new
CorridorScanComplexItem
(
_controllerVehicle
,
_flyView
,
QString
()
/* kmlFile */
,
_visualItems
/* parent */
);
}
else
{
qWarning
()
<<
"Internal error: Unknown complex item:"
<<
itemName
;
return
sequenceNumber
;
}
return
_insertComplexMissionItemWorker
(
newItem
,
i
);
}
int
MissionController
::
insertComplexMissionItemFromKML
(
QString
itemName
,
QString
kmlFile
,
int
i
)
{
ComplexMissionItem
*
newItem
;
if
(
itemName
==
_surveyMissionItemName
)
{
newItem
=
new
SurveyComplexItem
(
_controllerVehicle
,
_flyView
,
kmlFile
,
_visualItems
);
}
else
if
(
itemName
==
_structureScanMissionItemName
)
{
newItem
=
new
StructureScanComplexItem
(
_controllerVehicle
,
_flyView
,
kmlFile
,
_visualItems
);
}
else
if
(
itemName
==
_corridorScanMissionItemName
)
{
newItem
=
new
CorridorScanComplexItem
(
_controllerVehicle
,
_flyView
,
kmlFile
,
_visualItems
);
}
else
{
qWarning
()
<<
"Internal error: Unknown complex item:"
<<
itemName
;
return
_nextSequenceNumber
();
}
return
_insertComplexMissionItemWorker
(
newItem
,
i
);
}
int
MissionController
::
_insertComplexMissionItemWorker
(
ComplexMissionItem
*
complexItem
,
int
i
)
{
int
sequenceNumber
=
_nextSequenceNumber
();
bool
surveyStyleItem
=
qobject_cast
<
SurveyComplexItem
*>
(
complexItem
)
||
qobject_cast
<
CorridorScanComplexItem
*>
(
complexItem
);
if
(
surveyStyleItem
)
{
bool
rollSupported
=
false
;
bool
pitchSupported
=
false
;
...
...
@@ -434,14 +457,18 @@ int MissionController::insertComplexMissionItem(QString itemName, QGeoCoordinate
}
}
new
Item
->
setSequenceNumber
(
sequenceNumber
);
_initVisualItem
(
new
Item
);
complex
Item
->
setSequenceNumber
(
sequenceNumber
);
_initVisualItem
(
complex
Item
);
_visualItems
->
insert
(
i
,
newItem
);
if
(
i
==
-
1
)
{
_visualItems
->
append
(
complexItem
);
}
else
{
_visualItems
->
insert
(
i
,
complexItem
);
}
_recalcAll
();
return
new
Item
->
sequenceNumber
();
return
complex
Item
->
sequenceNumber
();
}
void
MissionController
::
removeMissionItem
(
int
index
)
...
...
@@ -529,7 +556,7 @@ bool MissionController::_loadJsonMissionFileV1(const QJsonObject& json, QmlObjec
return
false
;
}
SurveyComplexItem
*
item
=
new
SurveyComplexItem
(
_controllerVehicle
,
_flyView
,
visualItems
);
SurveyComplexItem
*
item
=
new
SurveyComplexItem
(
_controllerVehicle
,
_flyView
,
QString
()
/* kmlFile */
,
visualItems
/* parent */
);
const
QJsonObject
itemObject
=
itemValue
.
toObject
();
if
(
item
->
load
(
itemObject
,
itemObject
[
"id"
].
toInt
(),
errorString
))
{
surveyItems
.
append
(
item
);
...
...
@@ -687,7 +714,7 @@ bool MissionController::_loadJsonMissionFileV2(const QJsonObject& json, QmlObjec
if
(
complexItemType
==
SurveyComplexItem
::
jsonComplexItemTypeValue
)
{
qCDebug
(
MissionControllerLog
)
<<
"Loading Survey: nextSequenceNumber"
<<
nextSequenceNumber
;
SurveyComplexItem
*
surveyItem
=
new
SurveyComplexItem
(
_controllerVehicle
,
_flyView
,
visualItems
);
SurveyComplexItem
*
surveyItem
=
new
SurveyComplexItem
(
_controllerVehicle
,
_flyView
,
QString
()
/* kmlFile */
,
visualItems
);
if
(
!
surveyItem
->
load
(
itemObject
,
nextSequenceNumber
++
,
errorString
))
{
return
false
;
}
...
...
@@ -705,7 +732,7 @@ bool MissionController::_loadJsonMissionFileV2(const QJsonObject& json, QmlObjec
visualItems
->
append
(
landingItem
);
}
else
if
(
complexItemType
==
StructureScanComplexItem
::
jsonComplexItemTypeValue
)
{
qCDebug
(
MissionControllerLog
)
<<
"Loading Structure Scan: nextSequenceNumber"
<<
nextSequenceNumber
;
StructureScanComplexItem
*
structureItem
=
new
StructureScanComplexItem
(
_controllerVehicle
,
_flyView
,
visualItems
);
StructureScanComplexItem
*
structureItem
=
new
StructureScanComplexItem
(
_controllerVehicle
,
_flyView
,
QString
()
/* kmlFile */
,
visualItems
);
if
(
!
structureItem
->
load
(
itemObject
,
nextSequenceNumber
++
,
errorString
))
{
return
false
;
}
...
...
@@ -714,7 +741,7 @@ bool MissionController::_loadJsonMissionFileV2(const QJsonObject& json, QmlObjec
visualItems
->
append
(
structureItem
);
}
else
if
(
complexItemType
==
CorridorScanComplexItem
::
jsonComplexItemTypeValue
)
{
qCDebug
(
MissionControllerLog
)
<<
"Loading Corridor Scan: nextSequenceNumber"
<<
nextSequenceNumber
;
CorridorScanComplexItem
*
corridorItem
=
new
CorridorScanComplexItem
(
_controllerVehicle
,
_flyView
,
visualItems
);
CorridorScanComplexItem
*
corridorItem
=
new
CorridorScanComplexItem
(
_controllerVehicle
,
_flyView
,
QString
()
/* kmlFile */
,
visualItems
);
if
(
!
corridorItem
->
load
(
itemObject
,
nextSequenceNumber
++
,
errorString
))
{
return
false
;
}
...
...
src/MissionManager/MissionController.h
View file @
03d3d538
...
...
@@ -25,6 +25,7 @@ class MissionSettingsItem;
class
AppSettings
;
class
MissionManager
;
class
SimpleMissionItem
;
class
ComplexMissionItem
;
class
QDomDocument
;
Q_DECLARE_LOGGING_CATEGORY
(
MissionControllerLog
)
...
...
@@ -89,6 +90,10 @@ public:
Q_PROPERTY
(
int
batteryChangePoint
READ
batteryChangePoint
NOTIFY
batteryChangePointChanged
)
Q_PROPERTY
(
int
batteriesRequired
READ
batteriesRequired
NOTIFY
batteriesRequiredChanged
)
Q_PROPERTY
(
QString
surveyComplexItemName
READ
surveyComplexItemName
CONSTANT
)
Q_PROPERTY
(
QString
corridorScanComplexItemName
READ
corridorScanComplexItemName
CONSTANT
)
Q_PROPERTY
(
QString
structureScanComplexItemName
READ
structureScanComplexItemName
CONSTANT
)
Q_INVOKABLE
void
removeMissionItem
(
int
index
);
/// Add a new simple mission item to the list
...
...
@@ -108,6 +113,12 @@ public:
/// @return Sequence number for new item
Q_INVOKABLE
int
insertComplexMissionItem
(
QString
itemName
,
QGeoCoordinate
mapCenterCoordinate
,
int
i
);
/// Add a new complex mission item to the list
/// @param itemName: Name of complex item to create (from complexMissionItemNames)
/// @param i: index to insert at, -1 for end
/// @return Sequence number for new item
Q_INVOKABLE
int
insertComplexMissionItemFromKML
(
QString
itemName
,
QString
kmlFile
,
int
i
);
Q_INVOKABLE
void
resumeMission
(
int
resumeIndex
);
/// Updates the altitudes of the items in the current mission to the new default altitude
...
...
@@ -155,6 +166,9 @@ public:
QGeoCoordinate
plannedHomePosition
(
void
)
const
;
VisualMissionItem
*
currentPlanViewItem
(
void
)
const
;
double
progressPct
(
void
)
const
{
return
_progressPct
;
}
QString
surveyComplexItemName
(
void
)
const
{
return
_surveyMissionItemName
;
}
QString
corridorScanComplexItemName
(
void
)
const
{
return
_corridorScanMissionItemName
;
}
QString
structureScanComplexItemName
(
void
)
const
{
return
_structureScanMissionItemName
;
}
int
currentMissionIndex
(
void
)
const
;
int
resumeMissionIndex
(
void
)
const
;
...
...
@@ -242,6 +256,7 @@ private:
void
_addWaypointLineSegment
(
CoordVectHashTable
&
prevItemPairHashTable
,
VisualItemPair
&
pair
);
void
_addCommandTimeDelay
(
SimpleMissionItem
*
simpleItem
,
bool
vtolInHover
);
void
_addTimeDistance
(
bool
vtolInHover
,
double
hoverTime
,
double
cruiseTime
,
double
extraTime
,
double
distance
,
int
seqNum
);
int
_insertComplexMissionItemWorker
(
ComplexMissionItem
*
complexItem
,
int
i
);
private:
MissionManager
*
_missionManager
;
...
...
src/MissionManager/PlanMasterController.cc
View file @
03d3d538
...
...
@@ -484,7 +484,7 @@ QStringList PlanMasterController::saveNameFilters(void) const
return
filters
;
}
QStringList
PlanMasterController
::
sav
eKmlFilters
(
void
)
const
QStringList
PlanMasterController
::
fil
eKmlFilters
(
void
)
const
{
QStringList
filters
;
...
...
src/MissionManager/PlanMasterController.h
View file @
03d3d538
...
...
@@ -43,7 +43,7 @@ public:
///< kml file extension for missions
Q_PROPERTY
(
QStringList
loadNameFilters
READ
loadNameFilters
CONSTANT
)
///< File filter list loading plan files
Q_PROPERTY
(
QStringList
saveNameFilters
READ
saveNameFilters
CONSTANT
)
///< File filter list saving plan files
Q_PROPERTY
(
QStringList
saveKmlFilters
READ
saveKmlFilters
CONSTANT
)
///< File filter list saving
KML files
Q_PROPERTY
(
QStringList
fileKmlFilters
READ
fileKmlFilters
CONSTANT
)
///< File filter list for load/save
KML files
/// Should be called immediately upon Component.onCompleted.
Q_INVOKABLE
void
start
(
bool
flyView
);
...
...
@@ -81,7 +81,7 @@ public:
QString
kmlFileExtension
(
void
)
const
;
QStringList
loadNameFilters
(
void
)
const
;
QStringList
saveNameFilters
(
void
)
const
;
QStringList
sav
eKmlFilters
(
void
)
const
;
QStringList
fil
eKmlFilters
(
void
)
const
;
QJsonDocument
saveToJson
();
...
...
src/MissionManager/QGCMapPolygon.cc
View file @
03d3d538
...
...
@@ -12,6 +12,7 @@
#include "JsonHelper.h"
#include "QGCQGeoCoordinate.h"
#include "QGCApplication.h"
#include "KMLFileHelper.h"
#include <QGeoRectangle>
#include <QDebug>
...
...
@@ -453,71 +454,11 @@ void QGCMapPolygon::offset(double distance)
bool
QGCMapPolygon
::
loadKMLFile
(
const
QString
&
kmlFile
)
{
QFile
file
(
kmlFile
);
if
(
!
file
.
exists
())
{
qgcApp
()
->
showMessage
(
tr
(
"File not found: %1"
).
arg
(
kmlFile
));
return
false
;
}
if
(
!
file
.
open
(
QIODevice
::
ReadOnly
))
{
qgcApp
()
->
showMessage
(
tr
(
"Unable to open file: %1 error: $%2"
).
arg
(
kmlFile
).
arg
(
file
.
errorString
()));
return
false
;
}
QDomDocument
doc
;
QString
errorMessage
;
int
errorLine
;
if
(
!
doc
.
setContent
(
&
file
,
&
errorMessage
,
&
errorLine
))
{
qgcApp
()
->
showMessage
(
tr
(
"Unable to parse KML file: %1 error: %2 line: %3"
).
arg
(
kmlFile
).
arg
(
errorMessage
).
arg
(
errorLine
));
return
false
;
}
QDomNodeList
rgNodes
=
doc
.
elementsByTagName
(
"Polygon"
);
if
(
rgNodes
.
count
()
==
0
)
{
qgcApp
()
->
showMessage
(
tr
(
"Unable to find Polygon node in KML"
));
return
false
;
}
QDomNode
coordinatesNode
=
rgNodes
.
item
(
0
).
namedItem
(
"outerBoundaryIs"
).
namedItem
(
"LinearRing"
).
namedItem
(
"coordinates"
);
if
(
coordinatesNode
.
isNull
())
{
qgcApp
()
->
showMessage
(
tr
(
"Internal error: Unable to find coordinates node in KML"
));
return
false
;
}
QString
coordinatesString
=
coordinatesNode
.
toElement
().
text
().
simplified
();
QStringList
rgCoordinateStrings
=
coordinatesString
.
split
(
" "
);
QString
errorString
;
QList
<
QGeoCoordinate
>
rgCoords
;
for
(
int
i
=
0
;
i
<
rgCoordinateStrings
.
count
()
-
1
;
i
++
)
{
QString
coordinateString
=
rgCoordinateStrings
[
i
];
QStringList
rgValueStrings
=
coordinateString
.
split
(
","
);
QGeoCoordinate
coord
;
coord
.
setLongitude
(
rgValueStrings
[
0
].
toDouble
());
coord
.
setLatitude
(
rgValueStrings
[
1
].
toDouble
());
rgCoords
.
append
(
coord
);
}
// Determine winding, reverse if needed
double
sum
=
0
;
for
(
int
i
=
0
;
i
<
rgCoords
.
count
();
i
++
)
{
QGeoCoordinate
coord1
=
rgCoords
[
i
];
QGeoCoordinate
coord2
=
(
i
==
rgCoords
.
count
()
-
1
)
?
rgCoords
[
0
]
:
rgCoords
[
i
+
1
];
sum
+=
(
coord2
.
longitude
()
-
coord1
.
longitude
())
*
(
coord2
.
latitude
()
+
coord1
.
latitude
());
}
bool
reverse
=
sum
<
0.0
;
if
(
reverse
)
{
QList
<
QGeoCoordinate
>
rgReversed
;
for
(
int
i
=
0
;
i
<
rgCoords
.
count
();
i
++
)
{
rgReversed
.
prepend
(
rgCoords
[
i
]);
}
rgCoords
=
rgReversed
;
if
(
!
KMLFileHelper
::
loadPolygonFromFile
(
kmlFile
,
rgCoords
,
errorString
))
{
qgcApp
()
->
showMessage
(
errorString
);
return
false
;
}
clear
();
...
...
src/MissionManager/QGCMapPolyline.cc
View file @
03d3d538
...
...
@@ -12,6 +12,7 @@
#include "JsonHelper.h"
#include "QGCQGeoCoordinate.h"
#include "QGCApplication.h"
#include "KMLFileHelper.h"
#include <QGeoRectangle>
#include <QDebug>
...
...
@@ -338,52 +339,11 @@ QList<QGeoCoordinate> QGCMapPolyline::offsetPolyline(double distance)
bool
QGCMapPolyline
::
loadKMLFile
(
const
QString
&
kmlFile
)
{
QFile
file
(
kmlFile
);
if
(
!
file
.
exists
())
{
qgcApp
()
->
showMessage
(
tr
(
"File not found: %1"
).
arg
(
kmlFile
));
return
false
;
}
if
(
!
file
.
open
(
QIODevice
::
ReadOnly
))
{
qgcApp
()
->
showMessage
(
tr
(
"Unable to open file: %1 error: $%2"
).
arg
(
kmlFile
).
arg
(
file
.
errorString
()));
return
false
;
}
QDomDocument
doc
;
QString
errorMessage
;
int
errorLine
;
if
(
!
doc
.
setContent
(
&
file
,
&
errorMessage
,
&
errorLine
))
{
qgcApp
()
->
showMessage
(
tr
(
"Unable to parse KML file: %1 error: %2 line: %3"
).
arg
(
kmlFile
).
arg
(
errorMessage
).
arg
(
errorLine
));
return
false
;
}
QDomNodeList
rgNodes
=
doc
.
elementsByTagName
(
"LineString"
);
if
(
rgNodes
.
count
()
==
0
)
{
qgcApp
()
->
showMessage
(
tr
(
"Unable to find LineString node in KML"
));
return
false
;
}
QDomNode
coordinatesNode
=
rgNodes
.
item
(
0
).
namedItem
(
"coordinates"
);
if
(
coordinatesNode
.
isNull
())
{
qgcApp
()
->
showMessage
(
tr
(
"Internal error: Unable to find coordinates node in KML"
));
return
false
;
}
QString
coordinatesString
=
coordinatesNode
.
toElement
().
text
().
simplified
();
QStringList
rgCoordinateStrings
=
coordinatesString
.
split
(
" "
);
QString
errorString
;
QList
<
QGeoCoordinate
>
rgCoords
;
for
(
int
i
=
0
;
i
<
rgCoordinateStrings
.
count
()
-
1
;
i
++
)
{
QString
coordinateString
=
rgCoordinateStrings
[
i
];
QStringList
rgValueStrings
=
coordinateString
.
split
(
","
);
QGeoCoordinate
coord
;
coord
.
setLongitude
(
rgValueStrings
[
0
].
toDouble
());
coord
.
setLatitude
(
rgValueStrings
[
1
].
toDouble
());
rgCoords
.
append
(
coord
);
if
(
!
KMLFileHelper
::
loadPolylineFromFile
(
kmlFile
,
rgCoords
,
errorString
))
{
qgcApp
()
->
showMessage
(
errorString
);
return
false
;
}
clear
();
...
...
src/MissionManager/SectionTest.cc
View file @
03d3d538
...
...
@@ -83,7 +83,7 @@ void SectionTest::_commonScanTest(Section* section)
waypointVisualItems
.
append
(
&
simpleItem
);
QmlObjectListModel
complexVisualItems
;
SurveyComplexItem
surveyItem
(
_offlineVehicle
,
false
/* fly View */
,
this
);
SurveyComplexItem
surveyItem
(
_offlineVehicle
,
false
/* fly View */
,
QString
()
/* kmlFile */
,
this
/* parent */
);
complexVisualItems
.
append
(
&
surveyItem
);
// This tests the common cases which should not lead to scan succeess
...
...
src/MissionManager/StructureScanComplexItem.cc
View file @
03d3d538
...
...
@@ -30,7 +30,7 @@ const char* StructureScanComplexItem::jsonComplexItemTypeValue = "StructureSc
const
char
*
StructureScanComplexItem
::
_jsonCameraCalcKey
=
"CameraCalc"
;
const
char
*
StructureScanComplexItem
::
_jsonAltitudeRelativeKey
=
"altitudeRelative"
;
StructureScanComplexItem
::
StructureScanComplexItem
(
Vehicle
*
vehicle
,
bool
flyView
,
QObject
*
parent
)
StructureScanComplexItem
::
StructureScanComplexItem
(
Vehicle
*
vehicle
,
bool
flyView
,
const
QString
&
kmlFile
,
QObject
*
parent
)
:
ComplexMissionItem
(
vehicle
,
flyView
,
parent
)
,
_metaDataMap
(
FactMetaData
::
createMapFromJsonFile
(
QStringLiteral
(
":/json/StructureScan.SettingsGroup.json"
),
this
/* QObject parent */
))
,
_sequenceNumber
(
0
)
...
...
@@ -75,6 +75,13 @@ StructureScanComplexItem::StructureScanComplexItem(Vehicle* vehicle, bool flyVie
connect
(
&
_layersFact
,
&
Fact
::
valueChanged
,
this
,
&
StructureScanComplexItem
::
_recalcCameraShots
);
_recalcLayerInfo
();
if
(
!
kmlFile
.
isEmpty
())
{
_structurePolygon
.
loadKMLFile
(
kmlFile
);
_structurePolygon
.
setDirty
(
false
);
}
setDirty
(
false
);
}
void
StructureScanComplexItem
::
_setScanDistance
(
double
scanDistance
)
...
...
src/MissionManager/StructureScanComplexItem.h
View file @
03d3d538
...
...
@@ -25,7 +25,10 @@ class StructureScanComplexItem : public ComplexMissionItem
Q_OBJECT
public:
StructureScanComplexItem
(
Vehicle
*
vehicle
,
bool
flyView
,
QObject
*
parent
);
/// @param vehicle Vehicle which this is being contructed for
/// @param flyView true: Created for use in the Fly View, false: Created for use in the Plan View
/// @param kmlFile Polygon comes from this file, empty for default polygon
StructureScanComplexItem
(
Vehicle
*
vehicle
,
bool
flyView
,
const
QString
&
kmlFile
,
QObject
*
parent
);
Q_PROPERTY
(
CameraCalc
*
cameraCalc
READ
cameraCalc
CONSTANT
)
Q_PROPERTY
(
Fact
*
altitude
READ
altitude
CONSTANT
)
...
...
src/MissionManager/StructureScanComplexItemTest.cc
View file @
03d3d538
...
...
@@ -24,7 +24,7 @@ void StructureScanComplexItemTest::init(void)
_rgSignals
[
dirtyChangedIndex
]
=
SIGNAL
(
dirtyChanged
(
bool
));
_offlineVehicle
=
new
Vehicle
(
MAV_AUTOPILOT_PX4
,
MAV_TYPE_QUADROTOR
,
qgcApp
()
->
toolbox
()
->
firmwarePluginManager
(),
this
);
_structureScanItem
=
new
StructureScanComplexItem
(
_offlineVehicle
,
false
/* flyView */
,
this
);
_structureScanItem
=
new
StructureScanComplexItem
(
_offlineVehicle
,
false
/* flyView */
,
QString
()
/* kmlFile */
,
this
/* parent */
);
_structureScanItem
->
setDirty
(
false
);
_multiSpy
=
new
MultiSignalSpy
();
...
...
@@ -121,7 +121,7 @@ void StructureScanComplexItemTest::_testSaveLoad(void)
_structureScanItem
->
save
(
items
);
QString
errorString
;
StructureScanComplexItem
*
newItem
=
new
StructureScanComplexItem
(
_offlineVehicle
,
false
/* flyView */
,
this
);
StructureScanComplexItem
*
newItem
=
new
StructureScanComplexItem
(
_offlineVehicle
,
false
/* flyView */
,
QString
()
/* kmlFile */
,
this
/* parent */
);
QVERIFY
(
newItem
->
load
(
items
[
0
].
toObject
(),
10
,
errorString
));
QVERIFY
(
errorString
.
isEmpty
());
_validateItem
(
newItem
);
...
...
src/MissionManager/SurveyComplexItem.cc
View file @
03d3d538
...
...
@@ -59,7 +59,7 @@ const char* SurveyComplexItem::_jsonV3FixedValueIsAltitudeKey = "fixedVa
const
char
*
SurveyComplexItem
::
_jsonV3Refly90DegreesKey
=
"refly90Degrees"
;
const
char
*
SurveyComplexItem
::
_jsonFlyAlternateTransectsKey
=
"flyAlternateTransects"
;
SurveyComplexItem
::
SurveyComplexItem
(
Vehicle
*
vehicle
,
bool
flyView
,
QObject
*
parent
)
SurveyComplexItem
::
SurveyComplexItem
(
Vehicle
*
vehicle
,
bool
flyView
,
const
QString
&
kmlFile
,
QObject
*
parent
)
:
TransectStyleComplexItem
(
vehicle
,
flyView
,
settingsGroup
,
parent
)
,
_metaDataMap
(
FactMetaData
::
createMapFromJsonFile
(
QStringLiteral
(
":/json/Survey.SettingsGroup.json"
),
this
))
,
_gridAngleFact
(
settingsGroup
,
_metaDataMap
[
gridAngleName
])
...
...
@@ -91,6 +91,12 @@ SurveyComplexItem::SurveyComplexItem(Vehicle* vehicle, bool flyView, QObject* pa
// FIXME: Shouldn't these be in TransectStyleComplexItem? They are also in CorridorScanComplexItem constructur
connect
(
&
_cameraCalc
,
&
CameraCalc
::
distanceToSurfaceRelativeChanged
,
this
,
&
SurveyComplexItem
::
coordinateHasRelativeAltitudeChanged
);
connect
(
&
_cameraCalc
,
&
CameraCalc
::
distanceToSurfaceRelativeChanged
,
this
,
&
SurveyComplexItem
::
exitCoordinateHasRelativeAltitudeChanged
);
if
(
!
kmlFile
.
isEmpty
())
{
_surveyAreaPolygon
.
loadKMLFile
(
kmlFile
);
_surveyAreaPolygon
.
setDirty
(
false
);
}
setDirty
(
false
);
}
void
SurveyComplexItem
::
save
(
QJsonArray
&
planItems
)
...
...
src/MissionManager/SurveyComplexItem.h
View file @
03d3d538
...
...
@@ -21,7 +21,10 @@ class SurveyComplexItem : public TransectStyleComplexItem
Q_OBJECT
public:
SurveyComplexItem
(
Vehicle
*
vehicle
,
bool
flyView
,
QObject
*
parent
);
/// @param vehicle Vehicle which this is being contructed for
/// @param flyView true: Created for use in the Fly View, false: Created for use in the Plan View
/// @param kmlFile Polygon comes from this file, empty for default polygon
SurveyComplexItem
(
Vehicle
*
vehicle
,
bool
flyView
,
const
QString
&
kmlFile
,
QObject
*
parent
);
Q_PROPERTY
(
Fact
*
gridAngle
READ
gridAngle
CONSTANT
)
Q_PROPERTY
(
Fact
*
flyAlternateTransects
READ
flyAlternateTransects
CONSTANT
)
...
...
src/MissionManager/SurveyComplexItemTest.cc
View file @
03d3d538
...
...
@@ -29,7 +29,7 @@ void SurveyComplexItemTest::init(void)
_rgSurveySignals
[
surveyDirtyChangedIndex
]
=
SIGNAL
(
dirtyChanged
(
bool
));
_offlineVehicle
=
new
Vehicle
(
MAV_AUTOPILOT_PX4
,
MAV_TYPE_QUADROTOR
,
qgcApp
()
->
toolbox
()
->
firmwarePluginManager
(),
this
);
_surveyItem
=
new
SurveyComplexItem
(
_offlineVehicle
,
false
/* flyView */
,
this
);
_surveyItem
=
new
SurveyComplexItem
(
_offlineVehicle
,
false
/* flyView */
,
QString
()
/* kmlFile */
,
this
/* parent */
);
_surveyItem
->
turnAroundDistance
()
->
setRawValue
(
0
);
// Unit test written for no turnaround distance
_surveyItem
->
setDirty
(
false
);
_mapPolygon
=
_surveyItem
->
surveyAreaPolygon
();
...
...
src/MissionManager/TransectStyleComplexItem.cc
View file @
03d3d538
...
...
@@ -106,6 +106,8 @@ TransectStyleComplexItem::TransectStyleComplexItem(Vehicle* vehicle, bool flyVie
connect
(
this
,
&
TransectStyleComplexItem
::
visualTransectPointsChanged
,
this
,
&
TransectStyleComplexItem
::
greatestDistanceToChanged
);
connect
(
this
,
&
TransectStyleComplexItem
::
followTerrainChanged
,
this
,
&
TransectStyleComplexItem
::
_followTerrainChanged
);
setDirty
(
false
);
}
void
TransectStyleComplexItem
::
_setCameraShots
(
int
cameraShots
)
...
...
src/PlanView/PlanView.qml
View file @
03d3d538
...
...
@@ -24,6 +24,7 @@ import QGroundControl.FactSystem 1.0
import
QGroundControl
.
FactControls
1.0
import
QGroundControl
.
Palette
1.0
import
QGroundControl
.
Controllers
1.0
import
QGroundControl
.
KMLFileHelper
1.0
/// Mission Editor
...
...
@@ -77,6 +78,11 @@ QGCView {
_missionController
.
setCurrentPlanViewIndex
(
sequenceNumber
,
true
)
}
function
insertComplexMissionItemFromKML
(
complexItemName
,
kmlFile
,
index
)
{
var
sequenceNumber
=
_missionController
.
insertComplexMissionItemFromKML
(
complexItemName
,
kmlFile
,
index
)
_missionController
.
setCurrentPlanViewIndex
(
sequenceNumber
,
true
)
}
property
bool
_firstMissionLoadComplete
:
false
property
bool
_firstFenceLoadComplete
:
false
property
bool
_firstRallyLoadComplete
:
false
...
...
@@ -192,7 +198,7 @@ QGCView {
return
}
fileDialog
.
title
=
qsTr
(
"
Save Plan
"
)
fileDialog
.
plan
=
true
fileDialog
.
plan
Files
=
true
fileDialog
.
selectExisting
=
false
fileDialog
.
nameFilters
=
masterController
.
saveNameFilters
fileDialog
.
fileExtension
=
QGroundControl
.
settingsManager
.
appSettings
.
planFileExtension
...
...
@@ -204,15 +210,25 @@ QGCView {
mapFitFunctions
.
fitMapViewportToMissionItems
()
}
function
loadKmlFromSelectedFile
()
{
fileDialog
.
title
=
qsTr
(
"
Load KML
"
)
fileDialog
.
planFiles
=
false
fileDialog
.
selectExisting
=
true
fileDialog
.
nameFilters
=
masterController
.
fileKmlFilters
fileDialog
.
fileExtension
=
QGroundControl
.
settingsManager
.
appSettings
.
kmlFileExtension
fileDialog
.
fileExtension2
=
""
fileDialog
.
openForLoad
()
}
function
saveKmlToSelectedFile
()
{
if
(
!
readyForSaveSend
())
{
waitingOnDataMessage
()
return
}
fileDialog
.
title
=
qsTr
(
"
Save KML
"
)
fileDialog
.
plan
=
false
fileDialog
.
plan
Files
=
false
fileDialog
.
selectExisting
=
false
fileDialog
.
nameFilters
=
masterController
.
sav
eKmlFilters
fileDialog
.
nameFilters
=
masterController
.
fil
eKmlFilters
fileDialog
.
fileExtension
=
QGroundControl
.
settingsManager
.
appSettings
.
kmlFileExtension
fileDialog
.
fileExtension2
=
""
fileDialog
.
openForSave
()
...
...
@@ -259,22 +275,96 @@ QGCView {
QGCFileDialog
{
id
:
fileDialog
qgcView
:
_qgcView
property
bool
plan
:
true
folder
:
QGroundControl
.
settingsManager
.
appSettings
.
missionSavePath
property
bool
planFiles
:
true
///< true: working with plan files, false: working with kml file
onAcceptedForSave
:
{
plan
?
masterController
.
saveToFile
(
file
)
:
masterController
.
saveToKml
(
file
)
if
(
planFiles
)
{
masterController
.
saveToFile
(
file
)
}
else
{
masterController
.
saveToKml
(
file
)
}
close
()
}
onAcceptedForLoad
:
{
if
(
planFiles
)
{
masterController
.
loadFromFile
(
file
)
masterController
.
fitViewportToItems
()
_missionController
.
setCurrentPlanViewIndex
(
0
,
true
)
}
else
{
var
retList
=
KMLFileHelper
.
determineFileContents
(
file
)
if
(
retList
[
0
]
==
KMLFileHelper
.
Error
)
{
_qgcView
.
showMessage
(
"
Error
"
,
retList
[
1
],
StandardButton
.
Ok
)
}
else
if
(
retList
[
0
]
==
KMLFileHelper
.
Polygon
)
{
kmlPolygonSelectDialogKMLFile
=
file
_qgcView
.
showDialog
(
kmlPolygonSelectDialog
,
fileDialog
.
title
,
_qgcView
.
showDialogDefaultWidth
,
StandardButton
.
Ok
|
StandardButton
.
Cancel
)
}
else
if
(
retList
[
0
]
==
KMLFileHelper
.
Polyline
)
{
insertComplexMissionItemFromKML
(
_missionController
.
corridorScanComplexItemName
,
file
,
-
1
)
}
}
close
()
}
}
property
string
kmlPolygonSelectDialogKMLFile
Component
{
id
:
kmlPolygonSelectDialog
QGCViewDialog
{
property
var
editVehicle
:
_activeVehicle
?
_activeVehicle
:
QGroundControl
.
multiVehicleManager
.
offlineEditingVehicle
function
accept
()
{
var
complexItemName
if
(
surveyRadio
.
checked
)
{
complexItemName
=
_missionController
.
surveyComplexItemName
}
else
{
complexItemName
=
_missionController
.
structureScanComplexItemName
}
insertComplexMissionItemFromKML
(
complexItemName
,
kmlPolygonSelectDialogKMLFile
,
-
1
)
hideDialog
()
}
Component.onCompleted
:
{
if
(
editVehicle
.
fixedWing
)
{
// Only Survey available
accept
()
}
}
ExclusiveGroup
{
id
:
radioGroup
}
Column
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
spacing
:
ScreenTools
.
defaultFontPixelHeight
QGCLabel
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
wrapMode
:
Text
.
WordWrap
text
:
qsTr
(
"
What would you like to create from the polygon specified by the KML file?
"
)
}
QGCRadioButton
{
id
:
surveyRadio
text
:
qsTr
(
"
Survey
"
)
checked
:
true
exclusiveGroup
:
radioGroup
}
QGCRadioButton
{
text
:
qsTr
(
"
Structure Scan
"
)
exclusiveGroup
:
radioGroup
visible
:
!
editVehicle
.
fixedWing
}
}
}
}
Component
{
id
:
moveDialog
...
...
@@ -808,7 +898,7 @@ QGCView {
}
QGCButton
{
text
:
qsTr
(
"
Save
To File
...
"
)
text
:
qsTr
(
"
Save
Plan
...
"
)
Layout.fillWidth
:
true
enabled
:
!
masterController
.
syncInProgress
onClicked
:
{
...
...
@@ -818,7 +908,7 @@ QGCView {
}
QGCButton
{
text
:
qsTr
(
"
Load
From File
...
"
)
text
:
qsTr
(
"
Load
Plan
...
"
)
Layout.fillWidth
:
true
enabled
:
!
masterController
.
syncInProgress
onClicked
:
{
...
...
@@ -832,14 +922,16 @@ QGCView {
}
QGCButton
{
text
:
qsTr
(
"
Remove All
"
)
text
:
qsTr
(
"
Load KML...
"
)
Layout.fillWidth
:
true
enabled
:
!
masterController
.
syncInProgress
onClicked
:
{
dropPanel
.
hide
()
_qgcView
.
showDialog
(
removeAllPromptDialog
,
qsTr
(
"
Remove all
"
),
_qgcView
.
showDialogDefaultWidth
,
StandardButton
.
Yes
|
StandardButton
.
No
)
masterController
.
loadKmlFromSelectedFile
(
)
}
}
QGCButton
{
text
:
qsTr
(
"
Save KML...
"
)
Layout.fillWidth
:
true
...
...
@@ -854,6 +946,15 @@ QGCView {
masterController
.
saveKmlToSelectedFile
()
}
}
QGCButton
{
text
:
qsTr
(
"
Remove All
"
)
Layout.fillWidth
:
true
onClicked
:
{
dropPanel
.
hide
()
_qgcView
.
showDialog
(
removeAllPromptDialog
,
qsTr
(
"
Remove all
"
),
_qgcView
.
showDialogDefaultWidth
,
StandardButton
.
Yes
|
StandardButton
.
No
)
}
}
}
}
}
...
...
src/QGCApplication.cc
View file @
03d3d538
...
...
@@ -84,6 +84,7 @@
#include "VisualMissionItem.h"
#include "EditPositionDialogController.h"
#include "FactValueSliderListModel.h"
#include "KMLFileHelper.h"
#ifndef NO_SERIAL_LINK
#include "SerialLink.h"
...
...
@@ -139,6 +140,11 @@ static QObject* qgroundcontrolQmlGlobalSingletonFactory(QQmlEngine*, QJSEngine*)
return
qmlGlobal
;
}
static
QObject
*
kmlFileHelperSingletonFactory
(
QQmlEngine
*
,
QJSEngine
*
)
{
return
new
KMLFileHelper
;
}
QGCApplication
::
QGCApplication
(
int
&
argc
,
char
*
argv
[],
bool
unitTesting
)
#ifdef __mobile__
:
QGuiApplication
(
argc
,
argv
)
...
...
@@ -394,6 +400,7 @@ void QGCApplication::_initCommon(void)
// Register Qml Singletons
qmlRegisterSingletonType
<
QGroundControlQmlGlobal
>
(
"QGroundControl"
,
1
,
0
,
"QGroundControl"
,
qgroundcontrolQmlGlobalSingletonFactory
);
qmlRegisterSingletonType
<
ScreenToolsController
>
(
"QGroundControl.ScreenToolsController"
,
1
,
0
,
"ScreenToolsController"
,
screenToolsControllerSingletonFactory
);
qmlRegisterSingletonType
<
KMLFileHelper
>
(
"QGroundControl.KMLFileHelper"
,
1
,
0
,
"KMLFileHelper"
,
kmlFileHelperSingletonFactory
);
}
bool
QGCApplication
::
_initForNormalAppBoot
(
void
)
...
...
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