Files
gcs-nf/opmap/mapwidget/opmapwidget.cpp
T

2562 lines
70 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
******************************************************************************
*
* @file opmapwidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @brief The Map Widget, this is the part exposed to the user
* @see The GNU Public License (GPL) Version 3
* @defgroup OPMapWidget
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "opmapwidget.h"
#include <QtGui>
#include <QMetaObject>
#include "waypointitem.h"
#include "QDir"
#include <QGraphicsSceneMouseEvent>
#include "QTextCodec"
namespace mapcontrol {
OPMapWidget::OPMapWidget(QWidget *parent, Configuration *config) : QGraphicsView(parent), configuration(config), UAV(0), GPS(0), Home(0)
, followmouse(true), compass(0), showuav(false), showhome(false), diagTimer(0), diagGraphItem(0), showDiag(false), overlayOpacity(1),isWPCreate(false)
{
//QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB2312"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf8"));
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
core = new internals::Core;
QDir *MapDir = new QDir;
if(!MapDir->exists("./maps"))
MapDir->mkdir("./maps");//如果文件夹不存在就新建
config->SetCacheLocation(QDir::currentPath() + QDir::separator() + "maps" + QDir::separator());
map = new MapGraphicItem(core, config);
//map->setAcceptDrops(true);
mscene.addItem(map);//添加图层
this->setScene(&mscene);
Home = new HomeItem(map, this);
Home->setParentItem(map);
Home->setZValue(-1);
this->adjustSize();
connect(map, SIGNAL(zoomChanged(double, double, double)), this, SIGNAL(zoomChanged(double, double, double)));
connect(map->core, SIGNAL(OnCurrentPositionChanged(internals::PointLatLng)), this, SIGNAL(OnCurrentPositionChanged(internals::PointLatLng)));
connect(map->core, SIGNAL(OnEmptyTileError(int, core::Point)), this, SIGNAL(OnEmptyTileError(int, core::Point)));
connect(map->core, SIGNAL(OnMapDrag()), this, SIGNAL(OnMapDrag()));
connect(map->core, SIGNAL(OnMapTypeChanged(MapType::Types)), this, SIGNAL(OnMapTypeChanged(MapType::Types)));
connect(map->core, SIGNAL(OnMapZoomChanged()), this, SIGNAL(OnMapZoomChanged()));
connect(map->core, SIGNAL(OnTileLoadComplete()), this, SIGNAL(OnTileLoadComplete()));
connect(map->core, SIGNAL(OnTileLoadStart()), this, SIGNAL(OnTileLoadStart()));
connect(map->core, SIGNAL(OnTilesStillToLoad(int)), this, SIGNAL(OnTilesStillToLoad(int)));
connect(map, SIGNAL(wpdoubleclicked(WayPointItem *)), this, SIGNAL(OnWayPointDoubleClicked(WayPointItem *)));
connect(&mscene, SIGNAL(selectionChanged()), this, SLOT(OnSelectionChanged()));
SetShowDiagnostics(showDiag);
this->setMouseTracking(followmouse);
SetShowCompass(false);
QPixmapCache::setCacheLimit(1024 * 1024);//set 1M byte
setOverlayOpacity(overlayOpacity);
altitudeitem = new AltitudeItem(map,Qt::red);
altitudeitem->setParentItem(map);
altitudeitem->setPos(0,(this->height() - altitudeitem->boundingRect().height())/2);
altitudeitem->hide();
waypointsetting = new WayPointSetting(map,QColor("#a39d9c"));
mscene.addItem(waypointsetting);
waypointsetting->hide();
// WPnearPoint
connect(waypointsetting,SIGNAL(WPnearPoint(int)),
this,SLOT(WPnearPoint(int)));
connect(waypointsetting,SIGNAL(WPotherPoint(int)),
this,SLOT(WPotherPoint(int)));
connect(waypointsetting,SIGNAL(WPDelete()),
this,SLOT(WPDelete()));
connect(waypointsetting,SIGNAL(WPInsert()),
this,SLOT(WPInsert()));
connect(waypointsetting,SIGNAL(WPUpload()),
this,SLOT(WPUpload()));
connect(waypointsetting,SIGNAL(WPDownload()),
this,SLOT(WPDownload()));
connect(waypointsetting,SIGNAL(WPSave(QString)),
this,SLOT(WPSave(QString)));
connect(waypointsetting,SIGNAL(WPLoad(QString)),
this,SLOT(WPLoad(QString)));
/*
connect(this,SIGNAL(allPoint(QMap<int,int>)),
waypointsetting,SLOT(setallPoint(QMap<int,int>)));
*/
connect(waypointsetting,SIGNAL(searchall()),
this,SLOT(WPsearchall()));
connect(waypointsetting,SIGNAL(WPRuler()),
this,SLOT(ruler_clicked()));
connect(waypointsetting,SIGNAL(WPTable()),
this,SLOT(table_clicked()));
//missiontable = new MissionDialog();
//missiontable->hide();
point_begin.SetLat(0);
point_begin.SetLng(0);
point_end.SetLat(0);
point_end.SetLng(0);
measureline = new MeasureLine(point_begin, point_end, map, QColor("#FFFF00"));
mscene.addItem(measureline);
measureline->hide();
NoOperationTimer = new QTimer(this);
connect(NoOperationTimer,SIGNAL(timeout()),
this,SLOT(NOPTimeout()));
NoOperationTimer->start(20000);//20s不操作
currentGroup = 3;
}
void OPMapWidget::dragEnterEvent(QDragEnterEvent *event)
{
QString suffix = event->mimeData()->urls()[0].fileName().right(5);
if(!suffix.compare(tr(".plan")))
{
event->acceptProposedAction();
}
else
{
event->ignore();
}
}
void OPMapWidget::dropEvent(QDropEvent *event)
{
const QMimeData *qm = event->mimeData();
QString fileName = qm->urls()[0].toLocalFile();
if(fileName.right(5) == ".plan")
{
WPLoad(fileName);
}
}
void OPMapWidget::ruler_clicked(void)
{
if(isMeasure)
{
isMeasure = false;
this->setCursor(Qt::ArrowCursor);
}
else
{
isMeasure = true;
measurenumber = 1;//开始记录
if(measureline)
{
measureline->show();
}
QPixmap pix(":/markers/images/ruler.png");
this->setCursor(QCursor(pix.scaled(QSize(50,50), Qt::KeepAspectRatio)));
}
}
void OPMapWidget::table_clicked(void)
{
/*
if(missiontable)
{
if(missiontable->isHidden())
{
missiontable->show();
}
else
{
missiontable->hide();
}
}
*/
}
void OPMapWidget::SetShowDiagnostics(bool const & value)
{
showDiag = value;
}
void OPMapWidget::SetUavPic(QString UAVPic)
{
if (UAV != 0) {
UAV->SetUavPic(UAVPic);
}
if (GPS != 0) {
GPS->SetUavPic(UAVPic);
}
}
void OPMapWidget::SetShowUAV(const bool &value)
{
if (value && UAV == 0) {
UAV = new UAVItem(map, this);
UAV->setParentItem(map);
connect(this, SIGNAL(UAVLeftSafetyBouble(internals::PointLatLng)), UAV, SIGNAL(UAVLeftSafetyBouble(internals::PointLatLng)));
connect(this, SIGNAL(UAVReachedWayPoint(int, WayPointItem *)), UAV, SIGNAL(UAVReachedWayPoint(int, WayPointItem *)));
connect(UAV,SIGNAL(selected(int,int)),
this,SIGNAL(uav_selected(int,int)));
UAV->setOpacity(overlayOpacity);
} else if (!value) {
if (UAV != 0) {
delete UAV;
UAV = NULL;
}
}
}
void OPMapWidget::addUAV(int sysid,int compid)
{
UAVItem *uavItem = new UAVItem(map, this);
uavItem->setParentItem(map);
uavItem->SetUavPic("Fixwing.png");
uavItem->setID(sysid,compid);
connect(this, SIGNAL(UAVLeftSafetyBouble(internals::PointLatLng)),
uavItem, SIGNAL(UAVLeftSafetyBouble(internals::PointLatLng)));
connect(this, SIGNAL(UAVReachedWayPoint(int, WayPointItem *)),
uavItem, SIGNAL(UAVReachedWayPoint(int, WayPointItem *)));
connect(uavItem,SIGNAL(selected(int,int)),
this,SIGNAL(uav_selected(int,int)));
uavItem->setOpacity(overlayOpacity);
//检测,如果只有一个飞机,那么就选中
uint32_t uavCount = 0;
foreach(QGraphicsItem * i, map->childItems()) {
UAVItem *u = qgraphicsitem_cast<UAVItem *>(i);
if (u) {
uavCount ++;
}
}
if(uavCount <= 1)
{
uavItem->setSelect(true);
}
else
{
uavItem->setSelect(false);
}
this->SetCurrentPosition();
}
void OPMapWidget::NOPTimeout()
{
//qDebug() << "NOPTimeout";
//这个超限
if(isWPCreate == false)
{
isLNOP = true;
}
}
void OPMapWidget::SetCurrentPosition()
{
foreach(QGraphicsItem * i, map->childItems()) {
UAVItem *u = qgraphicsitem_cast<UAVItem *>(i);
if (u) {
if(u->Select())//当前选中,那么检查如果超出了屏幕范围,就将位置拉回中点
{
map->core->SetCurrentPosition(u->UAVPos());//缓慢拉回来
}
}
}
}
void OPMapWidget::SetCurrentPosition(internals::PointLatLng const & value)
{
map->core->SetCurrentPosition(value);
}
void OPMapWidget::setUAVPos(int sysid,int compid,double x,double y,double z)
{
//qDebug() << sysid << compid;
foreach(QGraphicsItem * i, map->childItems()) {
UAVItem *u = qgraphicsitem_cast<UAVItem *>(i);
if (u) {
if(u->SysID() == sysid)
{
internals::PointLatLng LatLng;
LatLng.SetLat(x);
LatLng.SetLng(y);
u->SetUAVPos(LatLng,z);
/*
//==========================
编辑界面不拉回
飞行界面 20s不操作才会拉回一次
//===========================*/
if(isWPCreate == false)
{
if(u->Select())//当前选中,那么检查如果超出了屏幕范围,就将位置拉回中点
{
if(((u->pos().x() <= 0)||
(u->pos().x() >= this->size().width())||
(u->pos().y() < 0)||
(u->pos().y() >= this->size().height()))&&(isLNOP == true))
{
this->SetCurrentPosition(LatLng);//缓慢拉回来
}
}
}
}
}
}
}
void OPMapWidget::setUAVHeading(int sysid,int compid,float Heading)
{
Q_UNUSED(compid)
foreach(QGraphicsItem * i, map->childItems()) {
UAVItem *u = qgraphicsitem_cast<UAVItem *>(i);
if (u) {
if(u->SysID() == sysid)
{
u->SetUAVHeading(Heading);
}
}
}
}
int OPMapWidget::getUAVCurrent(void)
{
int num = -1;
foreach(QGraphicsItem * i, map->childItems()) {
UAVItem *u = qgraphicsitem_cast<UAVItem *>(i);
if (u) {
if(u->Select())
{
num = u->SysID();
}
}
}
return num;
}
void OPMapWidget::DeleteTrail(void)
{
foreach(QGraphicsItem * i, map->childItems()) {
UAVItem *u = qgraphicsitem_cast<UAVItem *>(i);
if (u) {
if(u->Select())
{
u->DeleteTrail();
}
}
}
}
WayPointLine *OPMapWidget::WPLineCreate(WayPointItem *from, WayPointItem *to, QColor color, bool dashed, int width)
{
if (!from | !to) {
return NULL;
}
WayPointLine *ret = new WayPointLine(from, to, map, color, dashed, width);
ret->setOpacity(overlayOpacity);
return ret;
}
WayPointLine *OPMapWidget::WPLineCreate(HomeItem *from, WayPointItem *to, QColor color, bool dashed, int width)
{
if (!from | !to) {
return NULL;
}
WayPointLine *ret = new WayPointLine(from, to, map, color, dashed, width);
ret->setOpacity(overlayOpacity);
return ret;
}
void OPMapWidget::WPLineUpdate(int group)//调用这个,刷新连接线
{
}
void OPMapWidget::WPLineDelete(WayPointItem *from, WayPointItem *to)
{
do
{
WayPointLine *line = WPLineFind(from,to);
if(line)
{
delete line;
}
else
{
break;
}
}while(0);
}
WayPointLine *OPMapWidget::WPLineFind(WayPointItem *from, WayPointItem *to)
{
foreach(QGraphicsItem * i, map->childItems()) {
WayPointLine *l = qgraphicsitem_cast<WayPointLine *>(i);
if (l) {
if ((l->WPLineFrom() == from) && (l->WPLineTo() == to) )
{
return l;
}
}
}
return NULL;
}
WayPointCircle *OPMapWidget::WPCircleCreate(WayPointItem *center, double radius, bool clockwise, QColor color, bool dashed, int width)
{
if (!center | !radius) {
return NULL;
}
WayPointCircle *ret = new WayPointCircle(center, radius, clockwise, map, color, dashed, width);
ret->setOpacity(overlayOpacity);
return ret;
}
WayPointCircle *OPMapWidget::WPCircleCreate(HomeItem *center, double radius, bool clockwise, QColor color, bool dashed, int width)
{
if (!center | !radius) {
return NULL;
}
WayPointCircle *ret = new WayPointCircle(center, radius, clockwise, map, color, dashed, width);
ret->setOpacity(overlayOpacity);
return ret;
}
void OPMapWidget::SetShowHome(const bool &value)
{
Home->setVisible(value);
}
void OPMapWidget::resizeEvent(QResizeEvent *event)
{
if (scene()) {
scene()->setSceneRect(
QRect(QPoint(0,0), event->size()));
}
QGraphicsView::resizeEvent(event);
if (compass) {
compass->setScale(0.1 + 0.05 * (qreal)(event->size().width()) / 1000 * (qreal)(event->size().height()) / 600);
}
}
QSize OPMapWidget::sizeHint() const
{
return map->sizeHint();
}
void OPMapWidget::showEvent(QShowEvent *event)
{
connect(&mscene, SIGNAL(sceneRectChanged(QRectF)), map, SLOT(resize(QRectF)));
map->start();
QGraphicsView::showEvent(event);
}
OPMapWidget::~OPMapWidget()
{
if (UAV) {
delete UAV;
}
if (Home) {
delete Home;
}
if (map) {
delete map;
}
if (core) {
delete core;
}
if (configuration) {
delete configuration;
}
foreach(QGraphicsItem * i, this->items()) {
if (i) {
delete i;
}
}
}
void OPMapWidget::closeEvent(QCloseEvent *event)
{
core->OnMapClose();
event->accept();
}
void OPMapWidget::SetUseOpenGL(const bool &value)
{
useOpenGL = value;
if (useOpenGL) {
setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer)));
} else {
setupViewport(new QWidget());
}
update();
}
internals::PointLatLng OPMapWidget::currentMousePosition()
{
return currentmouseposition;
}
void OPMapWidget::mouseMoveEvent(QMouseEvent *event)
{
QGraphicsView::mouseMoveEvent(event);
if(altitudeitem)
{
if((event->pos().x() > altitudeitem->x())&&(event->pos().x() < (altitudeitem->boundingRect().width() + altitudeitem->x())) &&
(event->pos().y() > altitudeitem->y())&&(event->pos().y() < (altitudeitem->boundingRect().height() + altitudeitem->y())))//在高度区域禁止生成航点
{
return;
}
}
//一个区域内禁止生成
/*
if(waypointsetting)
{
if((event->pos().x() > waypointsetting->x())&&(event->pos().x() < (waypointsetting->boundingRect().width() + waypointsetting->x())) &&
(event->pos().y() > waypointsetting->y())&&(event->pos().y() < (waypointsetting->boundingRect().height() + waypointsetting->y())))//在按键区域禁止生成航点
{
return;
}
}
*/
QPointF p = event->pos();
//qDebug() << "mouseMoveEvent";
p = map->mapFromParent(p);
currentmouseposition = map->FromLocalToLatLng(p.x(), p.y());
isLNOP = false;
if(isMeasure)
{
QPointF p = event->pos();
p = map->mapFromParent(p);
point_end = map->FromLocalToLatLng(p.x(), p.y());
//measurenumber = 1;
if(measureline)
{
if(measurenumber == 2)//取了第一个点后
{
measureline->setTo(point_end);
}
}
}
emit EmitCurrentMousePosition(currentmouseposition);
if(isMeasure)
{
QPixmap pix(":/markers/images/ruler.png");
this->setCursor(QCursor(pix.scaled(QSize(50,50), Qt::KeepAspectRatio)));
}
}
void OPMapWidget::mousePressEvent(QMouseEvent *event)
{
QGraphicsView::mousePressEvent(event);
if(altitudeitem)
{
if((event->pos().x() > altitudeitem->x())&&(event->pos().x() < (altitudeitem->boundingRect().width() + altitudeitem->x())) &&
(event->pos().y() > altitudeitem->y())&&(event->pos().y() < (altitudeitem->boundingRect().height() + altitudeitem->y())))//在高度区域禁止生成航点
{
return;
}
}
//一个区域内禁止生成
/*
if(waypointsetting)
{
if((event->pos().x() > waypointsetting->x())&&(event->pos().x() < (waypointsetting->boundingRect().width() + waypointsetting->x())) &&
(event->pos().y() > waypointsetting->y())&&(event->pos().y() < (waypointsetting->boundingRect().height() + waypointsetting->y())))//在按键区域禁止生成航点
{
return;
}
}
*/
if(event->button() == Qt::LeftButton)
{
if(isMeasure)
{
if(measurenumber == 1)
{
QPointF p = event->pos();
p = map->mapFromParent(p);
point_begin = map->FromLocalToLatLng(p.x(), p.y());
measurenumber ++;
if(measureline)
{
measureline->setFrom(point_begin);
}
}
else
{
QPointF p = event->pos();
p = map->mapFromParent(p);
point_end = map->FromLocalToLatLng(p.x(), p.y());
measurenumber = 1;
if(measureline)
{
measureline->setTo(point_end);
}
}
}
}
isLNOP = false;
emit MousePressEvent(event);
if(isMeasure)
{
QPixmap pix(":/markers/images/ruler.png");
this->setCursor(QCursor(pix.scaled(QSize(50,50), Qt::KeepAspectRatio)));
}
}
void OPMapWidget::mouseReleaseEvent(QMouseEvent *event)
{
isLNOP = false;
QGraphicsView::mouseReleaseEvent(event);
emit MouseReleaseEvent(event);
if(isMeasure)
{
QPixmap pix(":/markers/images/ruler.png");
this->setCursor(QCursor(pix.scaled(QSize(50,50), Qt::KeepAspectRatio)));
}
//qDebug() << "relea";
}
void OPMapWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
QGraphicsView::mouseDoubleClickEvent(event);
if(isMeasure)
{
QPixmap pix(":/markers/images/ruler.png");
this->setCursor(QCursor(pix.scaled(QSize(50,50), Qt::KeepAspectRatio)));
}
if(isMeasure)
{
return;
}
if(altitudeitem)
{
if((event->pos().x() > altitudeitem->x())&&(event->pos().x() < (altitudeitem->boundingRect().width() + altitudeitem->x())) &&
(event->pos().y() > altitudeitem->y())&&(event->pos().y() < (altitudeitem->boundingRect().height() + altitudeitem->y())))//在高度区域禁止生成航点
{
return;
}
}
//一个区域内禁止生成
/*
if(waypointsetting)
{
if((event->pos().x() > waypointsetting->x())&&(event->pos().x() < (waypointsetting->boundingRect().width() + waypointsetting->x())) &&
(event->pos().y() > waypointsetting->y())&&(event->pos().y() < (waypointsetting->boundingRect().height() + waypointsetting->y())))//在按键区域禁止生成航点
{
return;
}
}
*/
isLNOP = false;
//生成一个列表
//如果是点击生成,那么就获取当前的编辑组,使用当前编辑组的编号
if(isWPCreate == true)
{
if(event->button() == Qt::LeftButton)
{
QPointF p = event->pos();
p = map->mapFromParent(p);
internals::PointLatLng LatLng;
LatLng = map->FromLocalToLatLng(p.x(), p.y());
WayPointItem *Item = WPCreate(LatLng,50);
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if (w->MissionType() == Item->MissionType()) {
if(w->Number() == (Item->Number() - 1))
{
WPLineCreate(w,Item,Qt::green,false,2);
}
}
}
}
}
}
emit MouseDoubleClickEvent(event);
}
////////////////WAYPOINT////////////////////////
WayPointItem *OPMapWidget::WPCreate()
{
//获取当前组下面的seq最大值
int seq = getWaypointSize(currentGroup) + 1;
WayPointItem *item = new WayPointItem(this->CurrentPosition(), 0,seq,currentGroup, map);
ConnectWP(item);
item->setParentItem(map);
item->SetMissionType(currentGroup);
int position = item->Number();
emit WPCreated(position, item);
setSelectedWP(item);
item->emitWPProperty();
return item;
}
WayPointItem *OPMapWidget::magicWPCreate()
{
//获取当前组下面的seq最大值
int seq = getWaypointSize(currentGroup) + 1;
WayPointItem *item = new WayPointItem(seq,currentGroup,map, true);
item->SetShowNumber(false);
item->setParentItem(map);
item->SetMissionType(currentGroup);
setSelectedWP(item);
item->emitWPProperty();
return item;
}
void OPMapWidget::WPCreate(WayPointItem *item)
{
ConnectWP(item);
item->setParentItem(map);
item->SetMissionType(currentGroup);
int position = item->Number();
emit WPCreated(position, item);
setOverlayOpacity(overlayOpacity);
setSelectedWP(item);
item->emitWPProperty();
}
WayPointItem *OPMapWidget::WPCreate(internals::PointLatLng const & coord, int const & altitude)
{
//获取当前组下面的seq最大值
int seq = getWaypointSize(currentGroup) + 1;
WayPointItem *item = new WayPointItem(coord, altitude,seq,currentGroup, map);
ConnectWP(item);
item->setParentItem(map);
item->SetMissionType(currentGroup);
int position = item->Number();
emit WPCreated(position, item);
setOverlayOpacity(overlayOpacity);
setSelectedWP(item);
item->emitWPProperty();
return item;
}
WayPointItem *OPMapWidget::WPCreate(internals::PointLatLng const & coord, int const & altitude, QString const & description)
{
//获取当前组下面的seq最大值
int seq = getWaypointSize(currentGroup) + 1;
WayPointItem *item = new WayPointItem(coord, altitude,seq,currentGroup, description, map);
ConnectWP(item);
item->setParentItem(map);
item->SetMissionType(currentGroup);
int position = item->Number();
emit WPCreated(position, item);
setOverlayOpacity(overlayOpacity);
setSelectedWP(item);
item->emitWPProperty();
return item;
}
WayPointItem *OPMapWidget::WPCreate(const distBearingAltitude &relativeCoord, const QString &description)
{
//获取当前组下面的seq最大值
int seq = getWaypointSize(currentGroup) + 1;
WayPointItem *item = new WayPointItem(relativeCoord,seq,currentGroup, description, map);
ConnectWP(item);
item->setParentItem(map);
item->SetMissionType(currentGroup);
int position = item->Number();
emit WPCreated(position, item);
setOverlayOpacity(overlayOpacity);
setSelectedWP(item);
item->emitWPProperty();
return item;
}
int OPMapWidget::getWaypointSize(int group)
{
QList<WayPointItem *> list;
list.clear();
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if (w->MissionType() == group) {
list.append(w);
}
}
}
return list.size();
}
void OPMapWidget::WPInsert()
{
bool isExist = false;
//获取位置和组号
int position = 0;
int group = 3;
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if (w->isSelected()) {
if(currentGroup == w->MissionType())
{
position = w->Number();
group = w->MissionType();
isExist = true;
break;
}
}
}
}
if(isExist == false)//没有选中的点
{
return;
}
//刷新全部连线,目前连线很乱
internals::PointLatLng latlng;
WayPointItem *item_old0 = WPFind(group,position-1);
WayPointItem *item_old1 = WPFind(group,position);//当前选中的点
WayPointItem *item_old2 = WPFind(group,position+1);
//删除连线
if((item_old1)&&(item_old0))
{
WPLineDelete(item_old0,item_old1);
WPLineDelete(item_old1,item_old0);
internals::PointLatLng latlng1 = item_old0->Coord();
internals::PointLatLng latlng2 = item_old1->Coord();
latlng.SetLat((latlng1.Lat() + latlng2.Lat())/2);
latlng.SetLng((latlng1.Lng() + latlng2.Lng())/2);
}
else
{
if(item_old1)
{
latlng = item_old1->Coord();
}
}
//如果指定的点存在,那么就可以在这之前(编号比现在小)插入一个点
if(item_old1)
{
WayPointItem *item = new WayPointItem(latlng, item_old1->Altitude(), position,group,map);
ConnectWP(item);
item->SetNumber(position);
item->setParentItem(map);
item->SetMissionType(group);
setOverlayOpacity(overlayOpacity);
setSelectedWP(item);
item->emitWPProperty();//这个没有执行
//调整编号
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if(w->MissionType() == group)
{
if(w != item)
{
if(w->Number() >= item->Number())
{
w->SetNumber(w->Number()+1);
}
}
}
}
}
WayPointItem *w_last = WPFind(group,item->Number() - 1);
if(w_last)
{
WPLineCreate(w_last,item,Qt::green,false,2);
}
WayPointItem *w_next = WPFind(group,item->Number() + 1);
if(w_next)
{
WPLineCreate(item,w_next,Qt::green,false,2);
}
}
//设置跟随
/*
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
WPFollowPrevious(w->FollowPrevious(),w);
}
}
*/
}
void OPMapWidget::WPInsert(WayPointItem *item, const int &position)
{
item->SetNumber(position);
ConnectWP(item);
item->setParentItem(map);
item->SetMissionType(currentGroup);
emit WPInserted(position, item);
setOverlayOpacity(overlayOpacity);
}
WayPointItem *OPMapWidget::WPInsert(internals::PointLatLng const & coord, int const & altitude, const int &position)
{
WayPointItem *item = new WayPointItem(coord, altitude,position,currentGroup, map);
item->SetNumber(position);
ConnectWP(item);
item->setParentItem(map);
item->SetMissionType(currentGroup);
emit WPInserted(position, item);
setOverlayOpacity(overlayOpacity);
return item;
}
WayPointItem *OPMapWidget::WPInsert(internals::PointLatLng const & coord, int const & altitude, QString const & description, const int &position)
{
internals::PointLatLng mcoord;
bool reloc = false;
if (mcoord == internals::PointLatLng(0, 0)) {
mcoord = CurrentPosition();
reloc = true;
} else {
mcoord = coord;
}
WayPointItem *item = new WayPointItem(mcoord, altitude,position,currentGroup, description, map);
item->SetNumber(position);
ConnectWP(item);
item->setParentItem(map);
item->SetMissionType(currentGroup);
emit WPInserted(position, item);
if (reloc) {
emit WPValuesChanged(item);
}
setOverlayOpacity(overlayOpacity);
return item;
}
WayPointItem *OPMapWidget::WPInsert(distBearingAltitude const & relative, QString const & description, const int &position)
{
WayPointItem *item = new WayPointItem(relative,position,currentGroup, description, map);
item->SetNumber(position);
ConnectWP(item);
item->setParentItem(map);
item->SetMissionType(currentGroup);
emit WPInserted(position, item);
setOverlayOpacity(overlayOpacity);
return item;
}
void OPMapWidget::WPDelete(WayPointItem *item)
{
int number = item->Number();
int group = item->MissionType();
emit WPDeleted(number, item);
delete item;
//当前选中为上一点
WayPointItem *w = WPFind(group,number -1);
if(w)
{
setSelectedWP(w);
w->emitWPProperty();
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w_next = qgraphicsitem_cast<WayPointItem *>(i);
if (w_next) {
if (w->MissionType() == w_next->MissionType()) {
if(w->Number() == (w_next->Number() + 1))
{
WPLineCreate(w,w_next,Qt::green,false,2);
}
}
}
}
}
else
{
WayPointItem *ww = WPFind(group,number);
if(ww)
{
setSelectedWP(ww);
ww->emitWPProperty();
}
}
}
void OPMapWidget::WPDelete(void)
{
int number = 0;
int group = 3;
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if (w->isSelected()) {
number = w->Number();
group = w->MissionType();
emit WPDeleted(w->Number(), w);//这个会修改编号
delete w;
}
}
}
//当前选中为上一点
WayPointItem *item = WPFind(group,number -1);
if(item)
{
setSelectedWP(item);
item->emitWPProperty();
WayPointItem *item_next = WPFind(group,number);
if (item_next) {
WPLineCreate(item,item_next,Qt::green,false,2);
}
}
else
{
WayPointItem *ww = WPFind(group,number);
if(ww)
{
setSelectedWP(ww);
ww->emitWPProperty();
}
}
}
WayPointItem *OPMapWidget::WPFind(int group,int number)
{
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if(w->MissionType() == group)
{
if (w->Number() == number) {
return w;
}
}
}
}
return nullptr;
}
void OPMapWidget::WPSetVisibleAll(bool value)
{
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if(w->MissionType() == currentGroup)
{
if (w->Number() != -1) {
w->setVisible(value);
}
}
}
}
}
void OPMapWidget::WPAdd(void)
{
internals::PointLatLng LatLng;
LatLng.SetLat(0);
LatLng.SetLng(0);
WayPointItem *Item = WPCreate(LatLng,50);
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if (w->MissionType() == Item->MissionType()) {
if(w->Number() == (Item->Number() - 1))
{
WPLineCreate(w,Item,Qt::green,false,2);
}
}
}
}
}
//清除当前航线才能下载
void OPMapWidget::WPDeleteAll()
{
//删除一个组
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if(w->MissionType() == currentGroup)
{
emit WPDeleted(w->Number(), w);
delete w;
}
}
}
}
bool OPMapWidget::WPPresent()
{
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if (w->Number() != -1) {
return true;
}
}
}
return false;
}
void OPMapWidget::deleteAllOverlays()
{
foreach(QGraphicsItem * i, map->childItems()) {
WayPointLine *w = qgraphicsitem_cast<WayPointLine *>(i);
if (w) {
w->deleteLater();
} else {
WayPointCircle *ww = qgraphicsitem_cast<WayPointCircle *>(i);
if (ww) {
ww->deleteLater();
}
}
}
}
QList<WayPointItem *> OPMapWidget::WPSelected()
{
QList<WayPointItem *> list;
foreach(QGraphicsItem * i, mscene.selectedItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
list.append(w);
}
}
return list;
}
void OPMapWidget::WPRenumber(WayPointItem *item, const int &newnumber)
{
item->SetNumber(newnumber);
}
void OPMapWidget::ConnectWP(WayPointItem *item)
{
connect(item, SIGNAL(WPNumberChanged(int, int, WayPointItem *)), this, SIGNAL(WPNumberChanged(int, int, WayPointItem *)), Qt::DirectConnection);
connect(item, SIGNAL(WPValuesChanged(WayPointItem *)), this, SIGNAL(WPValuesChanged(WayPointItem *)), Qt::DirectConnection);
connect(item, SIGNAL(localPositionChanged(QPointF, WayPointItem *)), this, SIGNAL(WPLocalPositionChanged(QPointF, WayPointItem *)), Qt::DirectConnection);
connect(item, SIGNAL(manualCoordChange(WayPointItem *)), this, SIGNAL(WPManualCoordChange(WayPointItem *)), Qt::DirectConnection);
connect(this, SIGNAL(WPInserted(int, WayPointItem *)), item, SLOT(WPInserted(int, WayPointItem *)), Qt::DirectConnection);
connect(this, SIGNAL(WPNumberChanged(int, int, WayPointItem *)), item, SLOT(WPRenumbered(int, int, WayPointItem *)), Qt::DirectConnection);
connect(this, SIGNAL(WPDeleted(int, WayPointItem *)), item, SLOT(WPDeleted(int, WayPointItem *)), Qt::DirectConnection);
connect(item,SIGNAL(WPChanged(int,double,double)),this,SIGNAL(WPChanged(int,double,double)));
connect(item, SIGNAL(WPProperty(float,float,float,float,int32_t,int32_t,float,uint16_t,uint16_t,uint16_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t)),
this, SIGNAL(WPProperty(float,float,float,float,int32_t,int32_t,float,uint16_t,uint16_t,uint16_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t)),Qt::DirectConnection);
connect(this, SIGNAL(setWPProperty(float,float,float,float,int32_t,int32_t,float,uint16_t,uint16_t,uint16_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t)),
item, SLOT(setWPProperty(float,float,float,float,int32_t,int32_t,float,uint16_t,uint16_t,uint16_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t)),Qt::DirectConnection);
connect(item, SIGNAL(WPProperty(float,float,float,float,int32_t,int32_t,float,uint16_t,uint16_t,uint16_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t)),
this, SLOT(find_PointNumber()),Qt::DirectConnection);
/*
connect(item, SIGNAL(WPFollowPrevious(bool,WayPointItem*)),
this, SLOT(WPFollowPrevious(bool,WayPointItem*)),Qt::DirectConnection);
*/
connect(item, SIGNAL(localPositionChanged(QPointF, WayPointItem *)),
this, SLOT(WPLocalChanged(QPointF, WayPointItem *)), Qt::DirectConnection);
connect(item,SIGNAL(SetCurrent(int)),
this,SIGNAL(setCurrent(int)), Qt::DirectConnection);
connect(item,SIGNAL(ElevationChanged(int,double)),
this,SLOT(ElevationChanged(int,double)), Qt::DirectConnection);
connect(item,SIGNAL(AltitudeChanged(int,double)),
this,SLOT(AltitudeChanged(int,double)), Qt::DirectConnection);
connect(item,SIGNAL(setCurrentPoint(int)),
this,SLOT(setCurrentPoint(int)), Qt::DirectConnection);
connect(item,SIGNAL(currentMissiontype(int)),
this,SLOT(WPGroup(int)), Qt::DirectConnection);
//生成后立即选中,并且把信息发给ui界面
item->emitWPProperty();
setSelectedWP(item);
}
void OPMapWidget::diagRefresh()
{
if (showDiag) {
if (diagGraphItem == 0) {
diagGraphItem = new QGraphicsTextItem();
mscene.addItem(diagGraphItem);
diagGraphItem->setPos(10, 100);
diagGraphItem->setZValue(3);
diagGraphItem->setFlag(QGraphicsItem::ItemIsMovable, true);
diagGraphItem->setDefaultTextColor(Qt::yellow);
}
diagGraphItem->setPlainText(core->GetDiagnostics().toString());
} else if (diagGraphItem != 0) {
delete diagGraphItem;
diagGraphItem = 0;
}
}
//////////////////////////////////////////////
void OPMapWidget::SetShowCompass(const bool &value)
{
if (value && !compass) {
compass = new QGraphicsSvgItem(QString::fromUtf8(":/markers/images/compas.svg"));
compass->setScale(0.1 + 0.05 * (qreal)(this->size().width()) / 1000 * (qreal)(this->size().height()) / 600);
// compass->setTransformOriginPoint(compass->boundingRect().width(),compass->boundingRect().height());
compass->setFlag(QGraphicsItem::ItemIsMovable, true);
compass->setFlag(QGraphicsItem::ItemIsSelectable, true);
mscene.addItem(compass);
compass->setTransformOriginPoint(compass->boundingRect().width() / 2, compass->boundingRect().height() / 2);
compass->setPos(55 - compass->boundingRect().width() / 2, 55 - compass->boundingRect().height() / 2);
compass->setZValue(3);
compass->setOpacity(0.7);
}
if (!value && compass) {
delete compass;
compass = 0;
}
}
void OPMapWidget::setOverlayOpacity(qreal value)
{
map->setOverlayOpacity(value);
overlayOpacity = value;
}
void OPMapWidget::SetRotate(qreal const & value)
{
map->mapRotate(value);
if (compass && (compass->rotation() != value)) {
compass->setRotation(value);
}
}
void OPMapWidget::RipMap()
{
new MapRipper(core, map->SelectedArea());
}
void OPMapWidget::setSelectedWP(QList<WayPointItem * >list)
{
this->scene()->clearSelection();
foreach(WayPointItem * wp, list) {
wp->setSelected(true);
if(altitudeitem)
{
if(!wp->FollowPrevious())
altitudeitem->setCurrentPoint(wp->Number());
}
}
}
void OPMapWidget::setSelectedWP(int number)
{
this->scene()->clearSelection();
WayPointItem *wp = WPFind(currentGroup,number);
if(wp)
{
wp->setSelected(true);
if(altitudeitem)
{
if(!wp->FollowPrevious())
altitudeitem->setCurrentPoint(wp->Number());
}
}
}
void OPMapWidget::setSelectedWP(WayPointItem *item)
{
this->scene()->clearSelection();
item->setSelected(true);
if(altitudeitem)
{
if(!item->FollowPrevious())
altitudeitem->setCurrentPoint(item->Number());
}
}
void OPMapWidget::OnSelectionChanged()
{
QList<QGraphicsItem *> list;
QList<WayPointItem *> wplist;
list = this->scene()->selectedItems();
foreach(QGraphicsItem * item, list) {
WayPointItem *wp = qgraphicsitem_cast<WayPointItem *>(item);
qDebug() << "selete item" << wp->Number();
if (wp) {
wplist.append(wp);
}
}
if (wplist.length() > 0) {
emit selectedWPChanged(wplist);
}
}
void OPMapWidget::WPnearPoint(int number)
{
int position = 0;
int group = 3;
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if (w->isSelected()) {
position = w->Number() + number;
group = w->MissionType();
}
}
}
WayPointItem *wp = WPFind(group,position);
if(wp)
{
setSelectedWP(position);
wp->emitWPProperty();
}
}
void OPMapWidget::WPotherPoint(int number)
{
int position = 0;
int group = 3;
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if (w->isSelected()) {
group = w->MissionType();
}
}
}
position = number;
WayPointItem *wp = WPFind(group,position);
if(wp)
{
setSelectedWP(position);
wp->emitWPProperty();
}
}
void OPMapWidget::setWPLock(bool const & lock)
{
bool isEdit = false;
if(lock == true)
{
isEdit = false;
}
else
{
isEdit = true;
}
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
qDebug() << "set Edit" <<isEdit;
w->WPSetEdit(isEdit);
}
}
foreach(QGraphicsItem * i, map->childItems()) {
UAVItem *uav = qgraphicsitem_cast<UAVItem *>(i);
if (uav) {
uav->setEdit(isEdit);
}
}
foreach(QGraphicsItem * i, map->childItems()) {
WayPointLine *l = qgraphicsitem_cast<WayPointLine *>(i);
if (l) {
l->setEdit(isEdit);
}
}
}
void OPMapWidget::WPSetCurrent(int seq)
{
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if(w->Number() == seq)
{
w->WPSetCurrent(true);
//qDebug() << "map WPSetCurrent" << seq;
}
else
{
w->WPSetCurrent(false);
}
}
}
}
void OPMapWidget::WPsearchall(void)
{
//重新排序一下
//QList<mapcontrol::WayPointItem *> list;
QMap<int,int> list;
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
list.insert(w->Number(),w->Command());
}
}
for (QMap<int,int>::iterator i = list.begin();i != list.end(); ++i)
{
qDebug() << i.key() << i.value();
}
if(list.size() != 0)
{
emit allPoint(list);
}
}
void OPMapWidget::setWPCreate(bool const & value)
{
isWPCreate = value;
if(map)
{
if(value)
{
map->setAcceptDrops(true);
}
else
{
map->setAcceptDrops(false);
}
}
if(altitudeitem)
{
if(value)
{
altitudeitem->show();
}
else
{
altitudeitem->hide();
}
}
if(waypointsetting)
{
if(value)
{
//waypointsetting->show();
}
else
{
waypointsetting->hide();
}
}
}
void OPMapWidget::WPLocalChanged(QPointF p, WayPointItem *w)
{
WayPointItem *item = WPFind(w->MissionType(),w->Number() + 1);
if(item)
{
if(item->FollowPrevious() == true)
{
QPointF pos = p;
pos.setX(pos.x() + w->boundingRect().width());
item->setPosition(pos);
}
}
}
void OPMapWidget::WPFollowPrevious(bool flag,WayPointItem *w)
{
int Point_Count = 0;
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {//逐渐往下增加
Point_Count++;
}
}
if(flag)
{
WayPointItem *item = WPFind(w->MissionType(),w->Number() - 1);
if(item)
{
WPLineDelete(item,w);
//跟随上一点的位置
QPointF pos = item->pos();
pos.setX(pos.x() + w->boundingRect().width());
w->setPosition(pos);
//找到前后两个不是跟随的点,将他们连接起来
WayPointItem *front_item;
int front_seq = w->Number();
do{
front_item = WPFind(w->MissionType(),front_seq--);
if(front_item)
{
if(front_item->FollowPrevious() == false)
{
qDebug() << "front_item" << front_item->Number();
break;
}
else {
continue;
}
}
else
{
break;
}
}while(front_seq > 0);
WayPointItem *next_item;
int next_seq = w->Number();
do{
next_item = WPFind(w->MissionType(),next_seq++);
if(next_item)
{
WPLineDelete(w,next_item);
if(next_item->FollowPrevious() == false)
{
qDebug() << "next_item" << next_item->Number();
break;
}
else {
continue;
}
}
else
{
break;
}
}while(next_seq <= Point_Count);
if(next_item)
{
WPLineDelete(w,next_item);
}
if((front_item)&&(next_item))
{
WPLineCreate(front_item,next_item,Qt::green,false,2);
}
}
}
else
{
//找到前后两个不是跟随的点,将他们连接起来
WayPointItem *front_item;
int front_seq = w->Number()-1;
do{
front_item = WPFind(w->MissionType(),front_seq--);
if(front_item)
{
if(front_item->FollowPrevious() == false)
{
qDebug() << "front_item" << front_item->Number();
break;
}
else {
//如果上一点存在,那么就删除掉线
qDebug() << "Delete front" << front_item->Number();
WPLineDelete(front_item,w);
continue;
}
}
else
{
break;
}
}while(front_seq > 0);
WayPointItem *next_item;
int next_seq = w->Number()+1;
do{
next_item = WPFind(w->MissionType(),next_seq++);
if(next_item)
{
if(next_item->FollowPrevious() == false)
{
qDebug() << "next_item" << next_item->Number();
break;
}
else {
continue;
}
}
else
{
break;
}
}while(next_seq <= Point_Count);
if((front_item)&&(next_item))
{
WPLineDelete(front_item,next_item);
}
if(front_item)
{
WPLineCreate(front_item,w,Qt::green,false,2);
}
if(next_item)
{
WPLineCreate(w,next_item,Qt::green,false,2);
}
}
}
//先清除再读取
void OPMapWidget::WPLoad(QString path)//带文件目录参数
{
//清除所有
WPDeleteAll();//清除当前航线
qDebug() << "WPLoad" << path;
//读取
QFile jsonFile(path);
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Unable to open file" << path << jsonFile.errorString();
return;
}
QByteArray bytes = jsonFile.readAll();
jsonFile.close();
QJsonParseError jsonParseError;
QJsonDocument doc = QJsonDocument::fromJson(bytes, &jsonParseError);
if (jsonParseError.error != QJsonParseError::NoError) {
qWarning() << path << "Unable to open json document" << jsonParseError.errorString();
return;
}
QJsonObject json = doc.object();
//安全区解码
QJsonArray circlesArray = json.value("geoFence").toObject().value("circles").toArray().at(0).toObject().value("circles").toArray();
for(QJsonValue item: circlesArray) {
}
QJsonArray polygonsArray = json.value("geoFence").toObject().value("polygons").toArray().at(0).toObject().value("polygon").toArray();
for(QJsonValue item: polygonsArray) {
//获得边界
qDebug() << "polygons" << item.toArray().at(0).toDouble() << item.toArray().at(1).toDouble();
}
//任务解码
QJsonArray itemsArray = json.value("mission").toObject().value("items").toArray();
for(QJsonValue item: itemsArray) {
if (!item.isObject()) {
return;
}
uint8_t AMSLAltAboveTerrain = item.toObject().find("AMSLAltAboveTerrain").value().toInt();
uint8_t Altitude = item.toObject().find("Altitude").value().toDouble();
uint8_t AltitudeMode = item.toObject().find("AltitudeMode").value().toInt();
uint8_t autocontinue = item.toObject().find("autoContinue").value().toBool()?(1):(0);//bool
uint16_t command = item.toObject().find("command").value().toInt();
uint16_t seq = item.toObject().find("doJumpId").value().toInt();
uint8_t frame = item.toObject().find("frame").value().toInt();
QJsonArray params = item.toObject().find("params").value().toArray();//array
uint8_t mission_type = item.toObject().find("type").value().toInt();
float param1 = params.at(0).toDouble();
float param2 = params.at(1).toDouble();
float param3 = params.at(2).toDouble();
float param4 = params.at(3).toDouble();
int32_t x = params.at(4).toDouble() * 10e6;
int32_t y = params.at(5).toDouble() * 10e6;
float z = params.at(6).toDouble();
internals::PointLatLng LatLng;
LatLng.SetLat(x * 10e-8);
LatLng.SetLng(y * 10e-8);
qDebug() << "LatLng" << LatLng.Lat() << LatLng.Lng();
WayPointItem *Item = WPCreate(LatLng,z);
Item->SetNumber(seq);
emit setWPProperty(param1,param2,param3,param4,
x,y,z,
seq,
mission_type,//当前组
command,
0,
0,
frame,
0,
autocontinue,
mission_type);
Item->emitWPProperty();
WayPointItem *w_last = WPFind(Item->MissionType(),Item->Number() - 1);
if(w_last)
{
WPLineCreate(w_last,Item,Qt::green,false,2);
}
}
}
void OPMapWidget::WPSave(QString path)//带文件目录参数
{
qDebug() << "WPSave" << path;
//保存到文件 *.plan,使用qgc的协议 json读写
QJsonDocument *doc = new QJsonDocument();
QJsonObject root= doc->object();
QJsonObject geoFence;
QJsonObject mission;
QJsonObject rallyPoints;
//geoFence节点写入 mission type == 1,2
//判断围栏数量大于0时写入,否则不写
QJsonArray circles;
QJsonArray polygons;
{
QJsonArray polygon;
QJsonObject polygonObj;
polygonObj["inclusion"] = true;
polygonObj["polygon"] = polygon;
polygonObj["version"] = 1;
polygons.append(polygonObj);
}
geoFence.insert("circles",circles);
geoFence.insert("polygons",polygons);
geoFence.insert("version",2);
//mission节点写入 (mission type == 3...)
{
QJsonArray items;
QJsonArray plannedHomePosition;
QMap<int,WayPointItem *> wlist;
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {//逐渐往下增加
wlist.insert(w->Number(),w);
}
}
for (QMap<int,WayPointItem *>::iterator i = wlist.begin(); i != wlist.end(); ++i) {
WayPointItem *w = i.value();
if (w) {//逐渐往下增加
if(w->Number()>0)
{
//存到items
QJsonArray params;
params.append(w->Param1());
params.append(w->Param2());
params.append(w->Param3());
params.append(w->Param4());
params.append(w->Coord().Lat());
params.append(w->Coord().Lng());
params.append(w->Alt());
//可能有点问题
QJsonObject item;
//如果这个点是指令,那么不会有高度信息
if(w->Command() < MAV_CMD::MAV_CMD_NAV_LAST) {
item.insert("AMSLAltAboveTerrain",w->Alt());
item.insert("Altitude",w->Alt());
item.insert("AltitudeMode",2);
}
item.insert("autoContinue",w->AutoContinue()?true:false);
item.insert("command",w->Command());
item.insert("doJumpId",w->Number());
item.insert("frame",w->Frame());
item.insert("params",params);
item.insert("type",w->MissionType());
items.append(item);
}
if(w->Number() == 1)
{
plannedHomePosition.append(w->Coord().Lat());
plannedHomePosition.append(w->Coord().Lng());
plannedHomePosition.append(w->Alt());
}
}
}
mission.insert("cruiseSpeed",2);
mission.insert("firmwareType",0);
mission.insert("hoverSpeed",2);
mission.insert("items",items);
mission.insert("plannedHomePosition",plannedHomePosition);
mission.insert("vehicleType",1);
mission.insert("version",2);
}
//rallyPoints节点写入
{
QJsonArray points;
rallyPoints.insert("points",points);
rallyPoints.insert("version",2);
}
//根节点写入
root.insert("fileType","Plan");
root.insert("geoFence",geoFence);
root.insert("groundStation","GCS_nf");
root.insert("mission", mission);
root.insert("rallyPoints", rallyPoints);
root.insert("version", 1);
//设置文档
doc->setObject(root);
//如果没有后缀名,那就追加
if(path.right(5) != ".plan")
{
path.append(".plan");
}
QFile file(path);
if(!file.open(QIODevice::ReadWrite|QFile::Truncate)) {
qDebug() << "File open error";
}
file.write(doc->toJson());
file.close();
}
void OPMapWidget::WPDownload(void)
{
//请求读取航点
qDebug() << "WPDownload";
WPDeleteAll();
int sysid = 0;
int compid = 0;
foreach(QGraphicsItem * i, map->childItems()) {
UAVItem *u = qgraphicsitem_cast<UAVItem *>(i);
if (u) {
if(u->Select() == true)
{
sysid = u->SysID();
compid = u->CompID();
emit signal_WPDownload(sysid,compid,currentGroup);
}
}
}
}
void OPMapWidget::WPUpload(void)
{
//发送第一个
QList<mapcontrol::WayPointItem *> list;
//先发送一个清空指令
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
//上传当前选中的航线
if(w->MissionType() == currentGroup)
{
list.append(w);
w->emitWPProperty();
//w->setVisible(false);
}
}
}
if(list.size() <= 0)
{
emit showMessage("请先载入任务航线");
return;
}
emit showMessage(tr("开始上传航点,总数%1").arg(list.size()));
//选择当前ID号
int sysid = 0;
int compid = 0;
foreach(QGraphicsItem * i, map->childItems()) {
UAVItem *u = qgraphicsitem_cast<UAVItem *>(i);
if (u) {
if(u->Select() == true)
{
sysid = u->SysID();
compid = u->CompID();
//如果有选中,那么就发送,选中几个就发几个
emit signal_WPUpload(sysid,compid,list.size(),currentGroup);//直接发送全部航点到
}
}
}
}
//飞行界面收到的当前航点的消息
void OPMapWidget::groupchanged(int value)
{
currentMissionType = value;
//如果当前是在飞行界面,那么就下载,否则不动
if(isWPCreate == true)//编辑界面
{
}
else//飞行界面
{
qDebug() << "show current group" << currentMissionType;
//将不是当前的全部变成灰色,当前的显示
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
qDebug() << "missiontype" << w->MissionType();
if(w->MissionType() == currentMissionType)
{
w->setisActive(true);
}
else
{
w->setisActive(false);
}
}
}
//将不是当前的先全部变成灰色,当前的显示
foreach(QGraphicsItem * i, map->childItems()) {
WayPointLine *l = qgraphicsitem_cast<WayPointLine *>(i);
if (l) {
WayPointItem *from = qgraphicsitem_cast<WayPointItem *>(l->WPLineFrom());
WayPointItem *to = qgraphicsitem_cast<WayPointItem *>(l->WPLineTo());
if((from)||(to))
{
if(from)
{
if(from->MissionType() == currentMissionType)
{
l->setisActive(true);
}
else
{
l->setisActive(false);
}
}
else if(to)
{
if(from->MissionType() == currentMissionType)
{
l->setisActive(true);
}
else
{
l->setisActive(false);
}
}
else//不知道这句对不对
{
l->setisActive(false);
}
}
}
}
}
update();
}
//编辑界面收到的组切换的消息
void OPMapWidget::WPGroup(int value)
{
currentGroup = value;
qDebug() << "group checkout" << value;
//切换当前航线,其他都隐藏,或者高亮当前
//将不是当前的全部变成灰色,当前的显示
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
qDebug() << "missiontype" << w->MissionType();
if(w->MissionType() == currentGroup)
{
w->setisActive(true);
}
else
{
w->setisActive(false);
}
}
}
//将不是当前的先全部变成灰色,当前的显示
foreach(QGraphicsItem * i, map->childItems()) {
WayPointLine *l = qgraphicsitem_cast<WayPointLine *>(i);
if (l) {
WayPointItem *from = qgraphicsitem_cast<WayPointItem *>(l->WPLineFrom());
WayPointItem *to = qgraphicsitem_cast<WayPointItem *>(l->WPLineTo());
if((from)||(to))
{
if(from)
{
if(from->MissionType() == currentGroup)
{
l->setisActive(true);
}
else
{
l->setisActive(false);
}
}
else if(to)
{
if(from->MissionType() == currentGroup)
{
l->setisActive(true);
}
else
{
l->setisActive(false);
}
}
else//不知道这句对不对
{
l->setisActive(false);
}
}
}
}
update();
}
void OPMapWidget::WPSendItemOK(uint16_t seq, bool flag)
{
if(flag == true)
{
QString str;
str.append("上传航点");
str.append(QString::number(seq));
emit showMessage(str);
}
else
{
QString str;
str.append(tr("上传失败%1").arg(seq));
emit showMessage(str);
}
}
//这个有可能是其他线程运行,导致生成的航点不对,下载得到
void OPMapWidget::receivedPoint(float param1,float param2,float param3,float param4,
int32_t x,int32_t y,float z,
uint16_t seq,
uint16_t group,
uint16_t command,
uint8_t target_system,
uint8_t target_component,
uint8_t frame,
uint8_t current,
uint8_t autocontinue,
uint8_t mission_type)
{
qDebug() << "receivers Point";
//emit showMessage(tr("recieve way point %1").arg(seq + 1));
emit showMessage(tr("recieve way point group:%1 seq:%2").arg(mission_type).arg(seq + 1));
//qDebug() << "receivers Point" << x * 10e-8 << y * 10e-8 << 10e-8;
bool isExist = false;
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w) {
if(w->MissionType() == mission_type)//如果组别一样,那么就赋值
{
if(w->Number() == (seq+1))
{
qDebug() << "waypoint exist:" << w->Number() << seq+1;
isExist = true;
internals::PointLatLng LatLng;
LatLng.SetLat(x * 10e-8);
LatLng.SetLng(y * 10e-8);
w->SetLat(LatLng.Lat());
LatLng.SetLng(LatLng.Lng());
w->SetNumber(seq+1);
emit setWPProperty(param1,param2,param3,param4,
x,y,z,
seq+1,
group,
command,
target_system,
target_component,
frame,
current,
autocontinue,
mission_type);
w->emitWPProperty();
}
}
}
}
if(!isExist)
{
internals::PointLatLng LatLng;
LatLng.SetLat(x * 10e-8);
LatLng.SetLng(y * 10e-8);
//获取当前组下面的seq最大值
WayPointItem *Item = new WayPointItem(LatLng, z,seq+1,mission_type, map);
ConnectWP(Item);
Item->setParentItem(map);
Item->SetMissionType(mission_type);
int position = Item->Number();
emit WPCreated(position, Item);
setOverlayOpacity(overlayOpacity);
emit setWPProperty(param1,param2,param3,param4,
x,y,z,
seq+1,
group,
command,
target_system,
target_component,
frame,
current,
autocontinue,
mission_type);
Item->emitWPProperty();
qDebug() << "waypoint not exist:" << Item->Number() << seq+1 <<currentGroup << mission_type;
//===========连线
WayPointItem *w_last = WPFind(Item->MissionType(),Item->Number() - 1);
if(w_last)
{
WPLineCreate(w_last,Item,Qt::green,false,2);
}
}
qDebug() << "Exist" << isExist;
}
void OPMapWidget::getMapTypes(void)
{
emit MapTypes(Helper::MapTypes());
}
void OPMapWidget::setMapTypes(QVariant value)
{
this->SetMapType(Helper::MapTypeFromString(value.toString()));
}
void OPMapWidget::ElevationChanged(int seq,double value)
{
QMap<int,float> Info;
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w)
{
if(!w->FollowPrevious())
Info.insert(w->Number(),w->getElevation());
}
}
if(altitudeitem)
{
altitudeitem->setElevation(Info);
}
}
void OPMapWidget::AltitudeChanged(int seq,double value)
{
QMap<int,float> Info;
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w)
{
if(!w->FollowPrevious())
Info.insert(w->Number(),w->Alt());
}
}
if(altitudeitem)
{
altitudeitem->setAltitude(Info);
}
updateMessage();
}
void OPMapWidget::setCurrentPoint(int value)
{
if(altitudeitem)
{
altitudeitem->setCurrentPoint(value);
}
}
void OPMapWidget::updateMessage(void)
{
totalDistance = 0;
WayPointItem *Last = nullptr;
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w)
{
if(Last != nullptr)
{
totalDistance += internals::PureProjection::DistanceBetweenLatLng(Last->Coord(),w->Coord()) * 10e2;
}
Last = w;
}
}
Last = nullptr;
delete Last;
emit TotalDistanceUpdate(totalDistance);
}
void OPMapWidget::find_PointNumber()
{
QList<int> nums;
nums.clear();
int number = 0;
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w)
{
number = w->Number();
if(w->Command() < MAV_CMD::MAV_CMD_NAV_LAST)
{
nums.append(number);
}
}
}
qDebug() << "nums" << nums;
emit PointNumber(nums);
}
void OPMapWidget::getAllPoints(int group)
{
QMap<int,WayPointItem *> points;
points.clear();
foreach(QGraphicsItem * i, map->childItems()) {
WayPointItem *w = qgraphicsitem_cast<WayPointItem *>(i);
if (w)
{
if(w->MissionType() == group)
{
points.insert(w->Number(),w);
}
}
}
QMapIterator<int,WayPointItem *> iter(points);
while (iter.hasNext()) {
iter.next();
WayPointItem *Item = iter.value();
Item->emitWPProperty();
}
}
}