Unverified Commit 03ce13ab authored by Don Gagne's avatar Don Gagne Committed by GitHub

Merge pull request #8612 from DonLakeFlyer/PlanKML

Much better conversion of Mission to KML for use as 3d validation
parents 984d5392 bb35cc17
......@@ -10,6 +10,8 @@ Note: This file only contains high level features or important fixes.
### 4.0.6 - Not yet released
* Plan: Much better conversion of missions to KML for 3d visualization/verification of missions
### 4.0.5 - Stable
* Solo: Fix mission upload failures
......
......@@ -587,7 +587,7 @@ HEADERS += \
src/MissionManager/FixedWingLandingComplexItem.h \
src/MissionManager/GeoFenceController.h \
src/MissionManager/GeoFenceManager.h \
src/MissionManager/KML.h \
src/MissionManager/KMLPlanDomDocument.h \
src/MissionManager/MissionCommandList.h \
src/MissionManager/MissionCommandTree.h \
src/MissionManager/MissionCommandUIInfo.h \
......@@ -795,7 +795,7 @@ SOURCES += \
src/MissionManager/FixedWingLandingComplexItem.cc \
src/MissionManager/GeoFenceController.cc \
src/MissionManager/GeoFenceManager.cc \
src/MissionManager/KML.cc \
src/MissionManager/KMLPlanDomDocument.cc \
src/MissionManager/MissionCommandList.cc \
src/MissionManager/MissionCommandTree.cc \
src/MissionManager/MissionCommandUIInfo.cc \
......
......@@ -7,7 +7,6 @@
*
****************************************************************************/
import QtQuick 2.3
import QtLocation 5.3
import QtPositioning 5.3
......@@ -20,7 +19,7 @@ MapItemView {
property bool showSpecialVisual: false
delegate: MapPolyline {
line.width: 3
line.color: object && showSpecialVisual && object.specialVisual ? "green" : "#be781c" // Hack, can't get palette to work in here
line.color: object && showSpecialVisual && object.specialVisual ? "green" : QGroundControl.globalPalette.mapMissionTrajectory
z: QGroundControl.zOrderWaypointLines
path: object && object.coordinate1.isValid && object.coordinate2.isValid ? [ object.coordinate1, object.coordinate2 ] : []
}
......
......@@ -11,12 +11,12 @@
#include "JsonHelper.h"
#include "MissionController.h"
#include "QGCGeo.h"
#include "QGroundControlQmlGlobal.h"
#include "QGCQGeoCoordinate.h"
#include "SettingsManager.h"
#include "AppSettings.h"
#include "QGCQGeoCoordinate.h"
#include "PlanMasterController.h"
#include "QGCApplication.h"
#include <QPolygonF>
......
......@@ -11,7 +11,6 @@
#include "JsonHelper.h"
#include "MissionController.h"
#include "QGCGeo.h"
#include "QGroundControlQmlGlobal.h"
#include "SimpleMissionItem.h"
#include "PlanMasterController.h"
......
/****************************************************************************
*
* (c) 2009-2020 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 "KML.h"
#include <QDomDocument>
#include <QStringList>
const QString Kml::_version("version=\"1.0\"");
const QString Kml::_encoding("encoding=\"UTF-8\"");
const QString Kml::_opengis("http://www.opengis.net/kml/2.2");
const QString Kml::_qgckml("QGC KML");
Kml::Kml()
{
//create header
createHeader();
//name
createTextElement(_docEle, "name", _qgckml);
//open
createTextElement(_docEle, "open", "1");
//create style
createStyles();
}
void Kml::points(const QStringList& points)
{
//create placemark
QDomElement placemark = _domDocument.createElement("Placemark");
_docEle.appendChild(placemark);
createTextElement(placemark, "styleUrl", "yellowLineGreenPoly");
createTextElement(placemark, "name", "Absolute");
createTextElement(placemark, "visibility", "0");
createTextElement(placemark, "description", "Transparent purple line");
QStringList latLonAlt = points[0].split(",");
QStringList lookAtList({latLonAlt[0], latLonAlt[1], "0" \
, "-100", "45", "2500"});
createLookAt(placemark, lookAtList);
//Add linestring
QDomElement lineString = _domDocument.createElement("LineString");
placemark.appendChild(lineString);
//extruder
createTextElement(lineString, "extruder", "1");
createTextElement(lineString, "tessellate", "1");
createTextElement(lineString, "altitudeMode", "absolute");
QString coordinates;
for(const auto& point : points) {
coordinates += point + "\n";
}
createTextElement(lineString, "coordinates", coordinates);
}
void Kml::save(QDomDocument& document)
{
document = _domDocument;
}
void Kml::createHeader()
{
QDomProcessingInstruction header = _domDocument.createProcessingInstruction("xml", _version + " " + _encoding);
_domDocument.appendChild(header);
QDomElement kml = _domDocument.createElement("kml");
kml.setAttribute("xmlns", _opengis);
_docEle = _domDocument.createElement("Document");
kml.appendChild(_docEle);
_domDocument.appendChild(kml);
}
void Kml::createStyles()
{
QDomElement style = _domDocument.createElement("Style");
style.setAttribute("id", "yellowLineGreenPoly");
createStyleLine(style, "7f00ffff", "4", "7f00ff00");
_docEle.appendChild(style);
}
void Kml::createLookAt(QDomElement& placemark, const QStringList &lookAtList)
{
QDomElement lookAt = _domDocument.createElement("LookAt");
placemark.appendChild(lookAt);
createTextElement(lookAt, "longitude", lookAtList[0]);
createTextElement(lookAt, "latitude", lookAtList[1]);
createTextElement(lookAt, "altitude", lookAtList[2]);
createTextElement(lookAt, "heading", lookAtList[3]);
createTextElement(lookAt, "tilt", lookAtList[4]);
createTextElement(lookAt, "range", lookAtList[5]);
}
void Kml::createTextElement(QDomElement& domEle, const QString& elementName, const QString& textElement)
{
// <elementName>textElement</elementName>
auto element = _domDocument.createElement(elementName);
element.appendChild(_domDocument.createTextNode(textElement));
domEle.appendChild(element);
}
void Kml::createStyleLine(QDomElement& domEle, const QString& lineColor, const QString& lineWidth, const QString& polyColor)
{
/*
<LineStyle>
<color>7f00ffff</color>
<width>4</width>
</LineStyle>
<PolyStyle>
<color>7f00ff00</color>
</PolyStyle>
*/
auto lineStyle = _domDocument.createElement("LineStyle");
auto polyStyle = _domDocument.createElement("PolyStyle");
domEle.appendChild(lineStyle);
domEle.appendChild(polyStyle);
createTextElement(lineStyle, "color", lineColor);
createTextElement(lineStyle, "width", lineWidth);
createTextElement(polyStyle, "color", polyColor);
}
Kml::~Kml()
{
}
/****************************************************************************
*
* (c) 2009-2020 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 "KMLPlanDomDocument.h"
#include "QGCPalette.h"
#include "QGCApplication.h"
#include "MissionCommandTree.h"
#include "MissionCommandUIInfo.h"
#include "FactMetaData.h"
#include <QDomDocument>
#include <QStringList>
const char* KMLPlanDomDocument::_missionLineStyleName = "MissionLineStyle";
const char* KMLPlanDomDocument::_ballonStyleName = "BalloonStyle";
KMLPlanDomDocument::KMLPlanDomDocument()
{
QDomProcessingInstruction header = createProcessingInstruction(QStringLiteral("xml"), QStringLiteral("version=\"1.0\" encoding=\"UTF-8\""));
appendChild(header);
QDomElement kmlElement = createElement(QStringLiteral("kml"));
kmlElement.setAttribute(QStringLiteral("xmlns"), "http://www.opengis.net/kml/2.2");
_documentElement = createElement(QStringLiteral("Document"));
kmlElement.appendChild(_documentElement);
appendChild(kmlElement);
_addTextElement(_documentElement, "name", QStringLiteral("%1 Plan KML").arg(qgcApp()->applicationName()));
_addTextElement(_documentElement, "open", "1");
_addStyles();
}
QString KMLPlanDomDocument::_kmlCoordString(const QGeoCoordinate& coord)
{
return QStringLiteral("%1,%2,%3").arg(QString::number(coord.longitude(), 'f', 7)).arg(QString::number(coord.latitude(), 'f', 7)).arg(QString::number(coord.altitude(), 'f', 2));
}
void KMLPlanDomDocument::addMissionItems(Vehicle* vehicle, QList<MissionItem*> rgMissionItems)
{
if (rgMissionItems.count() == 0) {
return;
}
QDomElement itemFolderElement = createElement("Folder");
_documentElement.appendChild(itemFolderElement);
_addTextElement(itemFolderElement, "name", "Items");
QDomElement flightPathElement = createElement("Placemark");
_documentElement.appendChild(flightPathElement);
_addTextElement(flightPathElement, "styleUrl", QStringLiteral("#%1").arg(_missionLineStyleName));
_addTextElement(flightPathElement, "name", "Flight Path");
_addTextElement(flightPathElement, "visibility", "1");
_addLookAt(flightPathElement, rgMissionItems[0]->coordinate());
// Build up the mission trajectory line coords
QList<QGeoCoordinate> rgFlightCoords;
QGeoCoordinate homeCoord = rgMissionItems[0]->coordinate();
for (const MissionItem* item : rgMissionItems) {
const MissionCommandUIInfo* uiInfo = qgcApp()->toolbox()->missionCommandTree()->getUIInfo(vehicle, item->command());
if (uiInfo) {
double altAdjustment = item->frame() == MAV_FRAME_GLOBAL ? 0 : homeCoord.altitude(); // Used to convert to amsl
if (uiInfo->isTakeoffCommand() && !vehicle->fixedWing()) {
// These takeoff items go straight up from home position to specified altitude
QGeoCoordinate coord = homeCoord;
coord.setAltitude(item->param7() + altAdjustment);
rgFlightCoords += coord;
}
if (uiInfo->specifiesCoordinate()) {
QGeoCoordinate coord = item->coordinate();
coord.setAltitude(coord.altitude() + altAdjustment); // convert to amsl
if (!uiInfo->isStandaloneCoordinate()) {
// Flight path goes through this item
rgFlightCoords += coord;
}
// Add a place mark for each WP
QDomElement wpPlacemarkElement = createElement("Placemark");
_addTextElement(wpPlacemarkElement, "name", QStringLiteral("%1 %2").arg(QString::number(item->sequenceNumber())).arg(item->command() == MAV_CMD_NAV_WAYPOINT ? "" : uiInfo->friendlyName()));
_addTextElement(wpPlacemarkElement, "styleUrl", QStringLiteral("#%1").arg(_ballonStyleName));
QDomElement wpPointElement = createElement("Point");
_addTextElement(wpPointElement, "altitudeMode", "absolute");
_addTextElement(wpPointElement, "coordinates", _kmlCoordString(coord));
_addTextElement(wpPointElement, "extrude", "1");
QDomElement descriptionElement = createElement("description");
QString htmlString;
htmlString += QStringLiteral("Index: %1\n").arg(item->sequenceNumber());
htmlString += uiInfo->friendlyName() + "\n";
htmlString += QStringLiteral("Alt AMSL: %1 %2\n").arg(QString::number(FactMetaData::metersToAppSettingsDistanceUnits(coord.altitude()).toDouble(), 'f', 2)).arg(FactMetaData::appSettingsDistanceUnitsString());
htmlString += QStringLiteral("Alt Rel: %1 %2\n").arg(QString::number(FactMetaData::metersToAppSettingsDistanceUnits(coord.altitude() - homeCoord.altitude()).toDouble(), 'f', 2)).arg(FactMetaData::appSettingsDistanceUnitsString());
htmlString += QStringLiteral("Lat: %1\n").arg(QString::number(coord.latitude(), 'f', 7));
htmlString += QStringLiteral("Lon: %1\n").arg(QString::number(coord.longitude(), 'f', 7));
QDomCDATASection cdataSection = createCDATASection(htmlString);
descriptionElement.appendChild(cdataSection);
wpPlacemarkElement.appendChild(descriptionElement);
wpPlacemarkElement.appendChild(wpPointElement);
itemFolderElement.appendChild(wpPlacemarkElement);
}
}
}
// Create a LineString element from the coords
QDomElement lineStringElement = createElement("LineString");
flightPathElement.appendChild(lineStringElement);
_addTextElement(lineStringElement, "extruder", "1");
_addTextElement(lineStringElement, "tessellate", "1");
_addTextElement(lineStringElement, "altitudeMode", "absolute");
QString coordString;
for (const QGeoCoordinate& coord : rgFlightCoords) {
coordString += QStringLiteral("%1\n").arg(_kmlCoordString(coord));
}
_addTextElement(lineStringElement, "coordinates", coordString);
}
QString KMLPlanDomDocument::_kmlColorString (const QColor& color)
{
return QStringLiteral("ff%1%2%3").arg(color.blue(), 2, 16, QChar('0')).arg(color.green(), 2, 16, QChar('0')).arg(color.red(), 2, 16, QChar('0'));
}
void KMLPlanDomDocument::_addStyles(void)
{
QGCPalette palette;
QDomElement styleElement1 = createElement("Style");
styleElement1.setAttribute("id", _missionLineStyleName);
QDomElement lineStyleElement = createElement("LineStyle");
_addTextElement(lineStyleElement, "color", _kmlColorString(palette.mapMissionTrajectory()));
_addTextElement(lineStyleElement, "width", "4");
styleElement1.appendChild(lineStyleElement);
QDomElement styleElement2 = createElement("Style");
styleElement2.setAttribute("id", _ballonStyleName);
QDomElement balloonStyleElement = createElement("BalloonStyle");
_addTextElement(balloonStyleElement, "text", "$[description]");
styleElement2.appendChild(balloonStyleElement);
_documentElement.appendChild(styleElement1);
_documentElement.appendChild(styleElement2);
}
void KMLPlanDomDocument::_addTextElement(QDomElement &element, const QString &name, const QString &value)
{
QDomElement textElement = createElement(name);
textElement.appendChild(createTextNode(value));
element.appendChild(textElement);
}
void KMLPlanDomDocument::_addLookAt(QDomElement& element, const QGeoCoordinate& coord)
{
QDomElement lookAtElement = createElement("LookAt");
_addTextElement(lookAtElement, "latitude", QString::number(coord.latitude(), 'f', 7));
_addTextElement(lookAtElement, "longitude", QString::number(coord.longitude(), 'f', 7));
_addTextElement(lookAtElement, "altitude", QString::number(coord.longitude(), 'f', 2));
_addTextElement(lookAtElement, "heading", "-100");
_addTextElement(lookAtElement, "tilt", "45");
_addTextElement(lookAtElement, "range", "2500");
element.appendChild(lookAtElement);
}
......@@ -7,36 +7,33 @@
*
****************************************************************************/
#ifndef KML_H
#define KML_H
#pragma once
#include <QDomDocument>
#include <QDomElement>
#include <QGeoCoordinate>
class Kml
class MissionItem;
class Vehicle;
/// Used to convert a Plan to a KML document
class KMLPlanDomDocument : public QDomDocument
{
public:
Kml();
~Kml();
KMLPlanDomDocument();
void points(const QStringList& points);
void polygon(const QStringList& points);
void save(QDomDocument& document);
void addMissionItems(Vehicle* vehicle, QList<MissionItem*> rgMissionItems);
private:
void createHeader();
void createLookAt(QDomElement& placemark, const QStringList &lookAtList);
void createStyles();
void createStyleLine(QDomElement& domEle, const QString& lineColor, const QString& lineWidth, const QString& polyColor);
void createTextElement(QDomElement& domEle, const QString& elementName, const QString& textElement);
QDomDocument _domDocument;
QDomElement _docEle;
static const QString _encoding;
static const QString _opengis;
static const QString _qgckml;
static const QString _version;
};
void _addStyles (void);
QString _kmlColorString (const QColor& color);
void _addTextElement (QDomElement& element, const QString& name, const QString& value);
QString _kmlCoordString (const QGeoCoordinate& coord);
void _addLookAt(QDomElement& element, const QGeoCoordinate& coord);
#endif
QDomElement _documentElement;
static const char* _missionLineStyleName;
static const char* _ballonStyleName;
};
......@@ -172,6 +172,7 @@
"friendlyName": "Takeoff",
"description": "Launch from the ground and travel towards the specified takeoff position.",
"specifiesCoordinate": true,
"isTakeoffCommand": true,
"friendlyEdit": true,
"category": "Basic",
"param1": {
......@@ -290,6 +291,7 @@
"friendlyName": "VTOL takeoff",
"description": "Hover straight up to specified altitude, transition to fixed-wing and fly to the specified takeoff location.",
"specifiesCoordinate": true,
"isTakeoffCommand": true,
"friendlyEdit": true,
"category": "Basic",
"param4": {
......
......@@ -12,7 +12,6 @@
#include "Vehicle.h"
#include "FirmwarePluginManager.h"
#include "QGCApplication.h"
#include "QGroundControlQmlGlobal.h"
#include "JsonHelper.h"
#include "MissionCommandUIInfo.h"
......
......@@ -14,7 +14,6 @@
#include "Vehicle.h"
#include "FirmwarePluginManager.h"
#include "QGCApplication.h"
#include "QGroundControlQmlGlobal.h"
#include "MissionCommandUIInfo.h"
#include "MissionCommandList.h"
#include "SettingsManager.h"
......
......@@ -38,6 +38,7 @@ const char* MissionCommandUIInfo::_standaloneCoordinateJsonKey = "standaloneCoo
const char* MissionCommandUIInfo::_specifiesCoordinateJsonKey = "specifiesCoordinate";
const char* MissionCommandUIInfo::_specifiesAltitudeOnlyJsonKey = "specifiesAltitudeOnly";
const char* MissionCommandUIInfo::_isLandCommandJsonKey = "isLandCommand";
const char* MissionCommandUIInfo::_isTakeoffCommandJsonKey = "isTakeoffCommand";
const char* MissionCommandUIInfo::_unitsJsonKey = "units";
const char* MissionCommandUIInfo::_commentJsonKey = "comment";
const char* MissionCommandUIInfo::_advancedCategory = "Advanced";
......@@ -174,6 +175,15 @@ bool MissionCommandUIInfo::isLandCommand(void) const
}
}
bool MissionCommandUIInfo::isTakeoffCommand(void) const
{
if (_infoMap.contains(_isTakeoffCommandJsonKey)) {
return _infoMap[_isTakeoffCommandJsonKey].toBool();
} else {
return false;
}
}
void MissionCommandUIInfo::_overrideInfo(MissionCommandUIInfo* uiInfo)
{
// Override info values
......@@ -209,7 +219,7 @@ bool MissionCommandUIInfo::loadJsonInfo(const QJsonObject& jsonObject, bool requ
QStringList allKeys;
allKeys << _idJsonKey << _rawNameJsonKey << _friendlyNameJsonKey << _descriptionJsonKey << _standaloneCoordinateJsonKey << _specifiesCoordinateJsonKey
<<_friendlyEditJsonKey << _param1JsonKey << _param2JsonKey << _param3JsonKey << _param4JsonKey << _param5JsonKey << _param6JsonKey << _param7JsonKey
<< _paramRemoveJsonKey << _categoryJsonKey << _specifiesAltitudeOnlyJsonKey << _isLandCommandJsonKey;
<< _paramRemoveJsonKey << _categoryJsonKey << _specifiesAltitudeOnlyJsonKey << _isLandCommandJsonKey << _isTakeoffCommandJsonKey;
// Look for unknown keys in top level object
for (const QString& key: jsonObject.keys()) {
......@@ -275,6 +285,9 @@ bool MissionCommandUIInfo::loadJsonInfo(const QJsonObject& jsonObject, bool requ
if (jsonObject.contains(_isLandCommandJsonKey)) {
_infoMap[_isLandCommandJsonKey] = jsonObject.value(_isLandCommandJsonKey).toBool();
}
if (jsonObject.contains(_isTakeoffCommandJsonKey)) {
_infoMap[_isTakeoffCommandJsonKey] = jsonObject.value(_isTakeoffCommandJsonKey).toBool();
}
if (jsonObject.contains(_friendlyEditJsonKey)) {
_infoMap[_friendlyEditJsonKey] = jsonObject.value(_friendlyEditJsonKey).toVariant();
}
......@@ -305,6 +318,9 @@ bool MissionCommandUIInfo::loadJsonInfo(const QJsonObject& jsonObject, bool requ
if (!_infoAvailable(_isLandCommandJsonKey)) {
_setInfoValue(_isLandCommandJsonKey, false);
}
if (!_infoAvailable(_isTakeoffCommandJsonKey)) {
_setInfoValue(_isTakeoffCommandJsonKey, false);
}
if (!_infoAvailable(_friendlyEditJsonKey)) {
_setInfoValue(_friendlyEditJsonKey, false);
}
......
......@@ -96,6 +96,7 @@ private:
/// specifiesCoordinate bool false true: Command specifies a lat/lon/alt coordinate
/// specifiesAltitudeOnly bool false true: Command specifies an altitude only (no coordinate)
/// standaloneCoordinate bool false true: Vehicle does not fly through coordinate associated with command (exampl: ROI)
/// isTakeoffCommand bool false true: Command specifies a takeoff command (TAEKOFF, VTOL_TAKEOFF, ...)
/// isLandCommand bool false true: Command specifies a land command (LAND, VTOL_LAND, ...)
/// friendlyEdit bool false true: Command supports friendly editing dialog, false: Command supports 'Show all values" style editing only
/// category string Advanced Category which this command belongs to
......@@ -120,6 +121,7 @@ public:
Q_PROPERTY(bool specifiesCoordinate READ specifiesCoordinate CONSTANT)
Q_PROPERTY(bool specifiesAltitudeOnly READ specifiesAltitudeOnly CONSTANT)
Q_PROPERTY(bool isLandCommand READ isLandCommand CONSTANT)
Q_PROPERTY(bool isTakeoffCommand READ isTakeoffCommand CONSTANT)
Q_PROPERTY(int command READ intCommand CONSTANT)
MAV_CMD command(void) const { return _command; }
......@@ -134,6 +136,7 @@ public:
bool specifiesCoordinate (void) const;
bool specifiesAltitudeOnly (void) const;
bool isLandCommand (void) const;
bool isTakeoffCommand (void) const;
/// Load the data in the object from the specified json
/// @param jsonObject Json object to load from
......@@ -194,6 +197,7 @@ private:
static const char* _specifiesCoordinateJsonKey;
static const char* _specifiesAltitudeOnlyJsonKey;
static const char* _isLandCommandJsonKey;
static const char* _isTakeoffCommandJsonKey;
static const char* _unitsJsonKey;
static const char* _commentJsonKey;
static const char* _advancedCategory;
......
......@@ -28,7 +28,7 @@
#include "MissionSettingsItem.h"
#include "QGCQGeoCoordinate.h"
#include "PlanMasterController.h"
#include "KML.h"
#include "KMLPlanDomDocument.h"
#include "QGCCorePlugin.h"
#include "TakeoffMissionItem.h"
#include "PlanViewSettings.h"
......@@ -273,46 +273,14 @@ bool MissionController::_convertToMissionItems(QmlObjectListModel* visualMission
return endActionSet;
}
void MissionController::convertToKMLDocument(QDomDocument& document)
void MissionController::addMissionToKML(KMLPlanDomDocument& planKML)
{
QObject* deleteParent = new QObject();
QList<MissionItem*> rgMissionItems;
_convertToMissionItems(_visualItems, rgMissionItems, deleteParent);
if (rgMissionItems.count() == 0) {
return;
}
const double homePositionAltitude = _settingsItem->coordinate().altitude();
QString coord;
QStringList coords;
// Drop home position
bool dropPoint = true;
for(const auto& item : rgMissionItems) {
if(dropPoint) {
dropPoint = false;
continue;
}
const MissionCommandUIInfo* uiInfo = \
qgcApp()->toolbox()->missionCommandTree()->getUIInfo(_controllerVehicle, item->command());
if (uiInfo && uiInfo->specifiesCoordinate() && !uiInfo->isStandaloneCoordinate()) {
double amslAltitude = item->param7() + (item->frame() == MAV_FRAME_GLOBAL ? 0 : homePositionAltitude);
coord = QString::number(item->param6(),'f',7) \
+ "," \
+ QString::number(item->param5(),'f',7) \
+ "," \
+ QString::number(amslAltitude,'f',2);
coords.append(coord);
}
}
planKML.addMissionItems(_controllerVehicle, rgMissionItems);
deleteParent->deleteLater();
Kml kml;
kml.points(coords);
kml.save(document);
}
void MissionController::sendItemsToVehicle(Vehicle* vehicle, QmlObjectListModel* visualMissionItems)
......
......@@ -13,7 +13,7 @@
#include "QmlObjectListModel.h"
#include "Vehicle.h"
#include "QGCLoggingCategory.h"
#include "KMLPlanDomDocument.h"
#include "QGCGeoBoundingCube.h"
#include <QHash>
......@@ -195,7 +195,7 @@ public:
bool showPlanFromManagerVehicle (void) final;
// Create KML file
void convertToKMLDocument(QDomDocument& document);
void addMissionToKML(KMLPlanDomDocument& planKML);
// Property accessors
......
......@@ -11,7 +11,6 @@
#include "JsonHelper.h"
#include "MissionController.h"
#include "QGCGeo.h"
#include "QGroundControlQmlGlobal.h"
#include "SimpleMissionItem.h"
#include "SettingsManager.h"
#include "AppSettings.h"
......
......@@ -9,7 +9,6 @@
#include "MissionSettingsTest.h"
#include "QGCApplication.h"
#include "QGroundControlQmlGlobal.h"
#include "SettingsManager.h"
MissionSettingsTest::MissionSettingsTest(void)
......
......@@ -15,7 +15,7 @@
#include "AppSettings.h"
#include "JsonHelper.h"
#include "MissionManager.h"
#include "KML.h"
#include "KMLPlanDomDocument.h"
#include "SurveyPlanCreator.h"
#include "StructureScanPlanCreator.h"
#include "CorridorScanPlanCreator.h"
......@@ -492,10 +492,10 @@ void PlanMasterController::saveToKml(const QString& filename)
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qgcApp()->showMessage(tr("KML save error %1 : %2").arg(filename).arg(file.errorString()));
} else {
QDomDocument domDocument;
_missionController.convertToKMLDocument(domDocument);
KMLPlanDomDocument planKML;
_missionController.addMissionToKML(planKML);
QTextStream stream(&file);
stream << domDocument.toString();
stream << planKML.toString();
file.close();
}
}
......
......@@ -7,10 +7,6 @@
*
****************************************************************************/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "RallyPointController.h"
#include "RallyPoint.h"
#include "Vehicle.h"
......@@ -20,7 +16,6 @@
#include "ParameterManager.h"
#include "JsonHelper.h"
#include "SimpleMissionItem.h"
#include "QGroundControlQmlGlobal.h"
#include "SettingsManager.h"
#include "AppSettings.h"
#include "PlanMasterController.h"
......
......@@ -12,11 +12,11 @@
#include "JsonHelper.h"
#include "MissionController.h"
#include "QGCGeo.h"
#include "QGroundControlQmlGlobal.h"
#include "QGCQGeoCoordinate.h"
#include "SettingsManager.h"
#include "AppSettings.h"
#include "PlanMasterController.h"
#include "QGCApplication.h"
#include <QPolygonF>
......
......@@ -116,7 +116,9 @@ void TakeoffMissionItem::setCoordinate(const QGeoCoordinate& coordinate)
bool TakeoffMissionItem::isTakeoffCommand(MAV_CMD command)
{
return command == MAV_CMD_NAV_TAKEOFF || command == MAV_CMD_NAV_VTOL_TAKEOFF;
const MissionCommandUIInfo* uiInfo = qgcApp()->toolbox()->missionCommandTree()->getUIInfo(qgcApp()->toolbox()->multiVehicleManager()->offlineEditingVehicle(), command);
return uiInfo ? uiInfo->isTakeoffCommand() : false;
}
void TakeoffMissionItem::_initLaunchTakeoffAtSameLocation(void)
......
......@@ -11,11 +11,11 @@
#include "JsonHelper.h"
#include "MissionController.h"
#include "QGCGeo.h"
#include "QGroundControlQmlGlobal.h"
#include "QGCQGeoCoordinate.h"
#include "SettingsManager.h"
#include "AppSettings.h"
#include "QGCQGeoCoordinate.h"
#include "QGCApplication.h"
#include <QPolygonF>
......
......@@ -68,7 +68,7 @@ public:
Q_PROPERTY(bool specifiesAltitudeOnly READ specifiesAltitudeOnly NOTIFY specifiesAltitudeOnlyChanged) ///< true: Item has altitude only, no full coordinate
Q_PROPERTY(bool isSimpleItem READ isSimpleItem NOTIFY isSimpleItemChanged) ///< Simple or Complex MissionItem
Q_PROPERTY(bool isTakeoffItem READ isTakeoffItem NOTIFY isTakeoffItemChanged) ///< true: Takeoff item special case
Q_PROPERTY(bool isLandCommand READ isLandCommand NOTIFY isLandCommandChanged) ///< true: Takeoff item special case
Q_PROPERTY(bool isLandCommand READ isLandCommand NOTIFY isLandCommandChanged)
Q_PROPERTY(QString editorQml MEMBER _editorQml CONSTANT) ///< Qml code for editing this item
Q_PROPERTY(QString mapVisualQML READ mapVisualQML CONSTANT) ///< QMl code for map visuals
Q_PROPERTY(double specifiedFlightSpeed READ specifiedFlightSpeed NOTIFY specifiedFlightSpeedChanged) ///< NaN for not specified
......
......@@ -81,11 +81,15 @@ void QGCPalette::_buildMap()
DECLARE_QGC_COLOR(statusPassedText, "#9d9d9d", "#000000", "#707070", "#ffffff")
DECLARE_QGC_COLOR(statusPendingText, "#9d9d9d", "#000000", "#707070", "#ffffff")
// Colors are not affecting by theming
DECLARE_QGC_COLOR(mapWidgetBorderLight, "#ffffff", "#ffffff", "#ffffff", "#ffffff")
DECLARE_QGC_COLOR(mapWidgetBorderDark, "#000000", "#000000", "#000000", "#000000")
DECLARE_QGC_COLOR(brandingPurple, "#4A2C6D", "#4A2C6D", "#4A2C6D", "#4A2C6D")
DECLARE_QGC_COLOR(brandingBlue, "#48D6FF", "#6045c5", "#48D6FF", "#6045c5")
// Colors not affecting by theming
// Disabled Enabled
DECLARE_QGC_NONTHEMED_COLOR(brandingPurple, "#4A2C6D", "#4A2C6D")
DECLARE_QGC_NONTHEMED_COLOR(brandingBlue, "#48D6FF", "#6045c5")
// Colors not affecting by theming or enable/disable
DECLARE_QGC_SINGLE_COLOR(mapWidgetBorderLight, "#ffffff")
DECLARE_QGC_SINGLE_COLOR(mapWidgetBorderDark, "#000000")
DECLARE_QGC_SINGLE_COLOR(mapMissionTrajectory, "#be781c")
}
void QGCPalette::setColorGroupEnabled(bool enabled)
......
......@@ -28,6 +28,34 @@
_colors << #name; \
}
#define DECLARE_QGC_NONTHEMED_COLOR(name, disabledColor, enabledColor) \
{ \
PaletteColorInfo_t colorInfo = { \
{ QColor(disabledColor), QColor(enabledColor) }, \
{ QColor(disabledColor), QColor(enabledColor) } \
}; \
qgcApp()->toolbox()->corePlugin()->paletteOverride(#name, colorInfo); \
_colorInfoMap[Light][ColorGroupEnabled][QStringLiteral(#name)] = colorInfo[Light][ColorGroupEnabled]; \
_colorInfoMap[Light][ColorGroupDisabled][QStringLiteral(#name)] = colorInfo[Light][ColorGroupDisabled]; \
_colorInfoMap[Dark][ColorGroupEnabled][QStringLiteral(#name)] = colorInfo[Dark][ColorGroupEnabled]; \
_colorInfoMap[Dark][ColorGroupDisabled][QStringLiteral(#name)] = colorInfo[Dark][ColorGroupDisabled]; \
_colors << #name; \
}
#define DECLARE_QGC_SINGLE_COLOR(name, color) \
{ \
PaletteColorInfo_t colorInfo = { \
{ QColor(color), QColor(color) }, \
{ QColor(color), QColor(color) } \
}; \
qgcApp()->toolbox()->corePlugin()->paletteOverride(#name, colorInfo); \
_colorInfoMap[Light][ColorGroupEnabled][QStringLiteral(#name)] = colorInfo[Light][ColorGroupEnabled]; \
_colorInfoMap[Light][ColorGroupDisabled][QStringLiteral(#name)] = colorInfo[Light][ColorGroupDisabled]; \
_colorInfoMap[Dark][ColorGroupEnabled][QStringLiteral(#name)] = colorInfo[Dark][ColorGroupEnabled]; \
_colorInfoMap[Dark][ColorGroupDisabled][QStringLiteral(#name)] = colorInfo[Dark][ColorGroupDisabled]; \
_colors << #name; \
}
#define DEFINE_QGC_COLOR(NAME, SETNAME) \
Q_PROPERTY(QColor NAME READ NAME WRITE SETNAME NOTIFY paletteChanged) \
Q_PROPERTY(QStringList NAME ## Colors READ NAME ## Colors NOTIFY paletteChanged) \
......@@ -103,6 +131,7 @@ public:
DEFINE_QGC_COLOR(mapIndicatorChild, setMapIndicatorChild)
DEFINE_QGC_COLOR(mapWidgetBorderLight, setMapWidgetBorderLight)
DEFINE_QGC_COLOR(mapWidgetBorderDark, setMapWidgetBorderDark)
DEFINE_QGC_COLOR(mapMissionTrajectory, setMapMissionTrajectory)
DEFINE_QGC_COLOR(brandingPurple, setBrandingPurple)
DEFINE_QGC_COLOR(brandingBlue, setBrandingBlue)
DEFINE_QGC_COLOR(colorGreen, setColorGreen)
......
......@@ -67,6 +67,7 @@ void QGroundControlQmlGlobal::setToolbox(QGCToolbox* toolbox)
_gpsRtkFactGroup = qgcApp()->gpsRtkFactGroup();
_airspaceManager = toolbox->airspaceManager();
_adsbVehicleManager = toolbox->adsbVehicleManager();
_globalPalette = new QGCPalette(this);
#if defined(QGC_ENABLE_PAIRING)
_pairingManager = toolbox->pairingManager();
#endif
......
......@@ -24,6 +24,7 @@
#include "AppSettings.h"
#include "AirspaceManager.h"
#include "ADSBVehicleManager.h"
#include "QGCPalette.h"
#if defined(QGC_ENABLE_PAIRING)
#include "PairingManager.h"
#endif
......@@ -81,6 +82,7 @@ public:
Q_PROPERTY(MicrohardManager* microhardManager READ microhardManager CONSTANT)
Q_PROPERTY(bool microhardSupported READ microhardSupported CONSTANT)
Q_PROPERTY(bool supportsPairing READ supportsPairing CONSTANT)
Q_PROPERTY(QGCPalette* globalPalette MEMBER _globalPalette CONSTANT) // This palette will always return enabled colors
#if defined(QGC_ENABLE_PAIRING)
Q_PROPERTY(PairingManager* pairingManager READ pairingManager CONSTANT)
#endif
......@@ -280,6 +282,7 @@ private:
TaisyncManager* _taisyncManager = nullptr;
MicrohardManager* _microhardManager = nullptr;
ADSBVehicleManager* _adsbVehicleManager = nullptr;
QGCPalette* _globalPalette = nullptr;
#if defined(QGC_ENABLE_PAIRING)
PairingManager* _pairingManager = nullptr;
#endif
......
......@@ -13,7 +13,6 @@
#include "UAS.h"
#include "QGCApplication.h"
#include "FollowMe.h"
#include "QGroundControlQmlGlobal.h"
#include "ParameterManager.h"
#include "SettingsManager.h"
#include "QGCCorePlugin.h"
......
......@@ -31,7 +31,6 @@
#include "QGCApplication.h"
#include "QGCImageProvider.h"
#include "MissionCommandTree.h"
#include "QGroundControlQmlGlobal.h"
#include "SettingsManager.h"
#include "QGCQGeoCoordinate.h"
#include "QGCCorePlugin.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment