/** ****************************************************************************** * * @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 #include #include "waypointitem.h" #include "QDir" #include #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")); /* QTranslator * translator = NULL; translator->load(QCoreApplication::applicationDirPath() + "\\MAP_zh_CN.qm"); QCoreApplication::installTranslator(translator); */ 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); 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(); NoOperationTimer = new QTimer(this); connect(NoOperationTimer,SIGNAL(timeout()), this,SLOT(NOPTimeout())); NoOperationTimer->start(20000);//20s不操作 } 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(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(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(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) { foreach(QGraphicsItem * i, map->childItems()) { UAVItem *u = qgraphicsitem_cast(i); if (u) { if(u->SysID() == sysid) { u->SetUAVHeading(Heading); //qDebug() << Heading; } } } } int OPMapWidget::getUAVCurrent(void) { int num = -1; foreach(QGraphicsItem * i, map->childItems()) { UAVItem *u = qgraphicsitem_cast(i); if (u) { if(u->Select()) { num = u->SysID(); } } } return num; } void OPMapWidget::DeleteTrail(void) { foreach(QGraphicsItem * i, map->childItems()) { UAVItem *u = qgraphicsitem_cast(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::WPLineDelete(WayPointItem *from, WayPointItem *to) { do { WayPointLine *line = WPLineFind(from,to); if(line) { delete line; } else { break; } }while(1); } WayPointLine *OPMapWidget::WPLineFind(WayPointItem *from, WayPointItem *to) { foreach(QGraphicsItem * i, map->childItems()) { WayPointLine *w = qgraphicsitem_cast(i); if (w) { if (w->WPLineFrom() == from) { return w; } } } 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::SampleBuffers))); } else { setupViewport(new QWidget()); } update(); } internals::PointLatLng OPMapWidget::currentMousePosition() { return currentmouseposition; } void OPMapWidget::mouseMoveEvent(QMouseEvent *event) { QGraphicsView::mouseMoveEvent(event); QPointF p = event->pos(); //qDebug() << "mouseMoveEvent"; p = map->mapFromParent(p); currentmouseposition = map->FromLocalToLatLng(p.x(), p.y()); isLNOP = false; emit EmitCurrentMousePosition(currentmouseposition); } void OPMapWidget::mousePressEvent(QMouseEvent *event) { QGraphicsView::mousePressEvent(event); //qDebug() << "mousePressEvent"; isLNOP = false; emit MousePressEvent(event); } void OPMapWidget::mouseReleaseEvent(QMouseEvent *event) { isLNOP = false; QGraphicsView::mouseReleaseEvent(event); emit MouseReleaseEvent(event); } void OPMapWidget::mouseDoubleClickEvent(QMouseEvent *event) { QGraphicsView::mouseDoubleClickEvent(event); 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); WPLineCreate(WPFind(Item->Number() - 1),Item,Qt::green,false,2); qDebug() << "WPCreate Point" << QThread::currentThreadId(); } } emit MouseDoubleClickEvent(event); } ////////////////WAYPOINT//////////////////////// WayPointItem *OPMapWidget::WPCreate() { WayPointItem *item = new WayPointItem(this->CurrentPosition(), 0, map); ConnectWP(item); item->setParentItem(map); int position = item->Number(); emit WPCreated(position, item); return item; } WayPointItem *OPMapWidget::magicWPCreate() { WayPointItem *item = new WayPointItem(map, true); item->SetShowNumber(false); item->setParentItem(map); return item; } void OPMapWidget::WPCreate(WayPointItem *item) { ConnectWP(item); item->setParentItem(map); int position = item->Number(); emit WPCreated(position, item); setOverlayOpacity(overlayOpacity); } WayPointItem *OPMapWidget::WPCreate(internals::PointLatLng const & coord, int const & altitude) { WayPointItem *item = new WayPointItem(coord, altitude, map); ConnectWP(item); item->setParentItem(map); int position = item->Number(); emit WPCreated(position, item); setOverlayOpacity(overlayOpacity); return item; } WayPointItem *OPMapWidget::WPCreate(internals::PointLatLng const & coord, int const & altitude, QString const & description) { WayPointItem *item = new WayPointItem(coord, altitude, description, map); ConnectWP(item); item->setParentItem(map); int position = item->Number(); emit WPCreated(position, item); setOverlayOpacity(overlayOpacity); return item; } WayPointItem *OPMapWidget::WPCreate(const distBearingAltitude &relativeCoord, const QString &description) { WayPointItem *item = new WayPointItem(relativeCoord, description, map); ConnectWP(item); item->setParentItem(map); int position = item->Number(); emit WPCreated(position, item); setOverlayOpacity(overlayOpacity); return item; } void OPMapWidget::WPInsert(const int &position) { internals::PointLatLng latlng; WayPointItem *item_old0 = WPFind(position-1); WayPointItem *item_old1 = WPFind(position); WayPointItem *item_old2 = WPFind(position+1); //删除连线 if((item_old1)&&(item_old2)) { WPLineDelete(item_old1,item_old2); //WPLineDelete(item_old1,item_old2); //WPLineDelete(item_old1,item_old2); } //删除连线 if((item_old1)&&(item_old0)) { WPLineDelete(item_old0,item_old1); //WPLineDelete(item_old0,item_old1); //WPLineDelete(item_old0,item_old1); 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(), map); ConnectWP(item); item->SetNumber(position); item->setParentItem(map); setOverlayOpacity(overlayOpacity); setSelectedWP(item); item->emitWPProperty();//这个没有执行 foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) { if(w != item) { if(w->Number() >= item->Number()) { w->SetNumber(w->Number()+1); } } } } WayPointItem *w_next = WPFind(item->Number() + 1); if(w_next) { WPLineCreate(item,w_next,Qt::green,false,2); WayPointItem *w_next_1 = WPFind(w_next->Number() + 1); if(w_next_1) { WPLineCreate(w_next,w_next_1,Qt::green,false,2); } } /* WayPointItem *w_last = WPFind(item->Number() - 1); if(w_last) { WPLineCreate(w_last,item,Qt::green,false,2); WayPointItem *w_last2 = WPFind(item->Number() - 2); if(w_last2) { WPLineCreate(w_last2,w_last,Qt::green,false,2); } } */ } foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) { //qDebug() << "all number" << w->Number() << w->snumber; WPFollowPrevious(w->FollowPrevious(),w); } } } void OPMapWidget::WPInsert(WayPointItem *item, const int &position) { item->SetNumber(position); ConnectWP(item); item->setParentItem(map); 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, map); item->SetNumber(position); ConnectWP(item); item->setParentItem(map); 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, description, map); item->SetNumber(position); ConnectWP(item); item->setParentItem(map); 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, description, map); item->SetNumber(position); ConnectWP(item); item->setParentItem(map); emit WPInserted(position, item); setOverlayOpacity(overlayOpacity); return item; } void OPMapWidget::WPDelete(WayPointItem *item) { int number = item->Number(); emit WPDeleted(number, item); delete item; //当前选中为上一点 WayPointItem *w = WPFind(number -1); if(w) { setSelectedWP(w); w->emitWPProperty(); WayPointItem *w_next = WPFind(w->Number() + 1); if(w_next) { WPLineCreate(w,w_next,Qt::green,false,2); } } else { WayPointItem *ww = WPFind(number); if(ww) { setSelectedWP(ww); ww->emitWPProperty(); } } } void OPMapWidget::WPDelete(int number) { WayPointItem *w = WPFind(number); if (w) { qDebug() << "delete" <Number(); emit WPDeleted(w->Number(), w); delete w; } //当前选中为上一点 WayPointItem *item = WPFind(number -1); if(item) { setSelectedWP(item); item->emitWPProperty(); WayPointItem *item_next = WPFind(item->Number() + 1); if(item_next) { WPLineCreate(item,item_next,Qt::green,false,2); } else { qDebug() << "can not find next fine"; } } else { WayPointItem *ww = WPFind(number); if(ww) { setSelectedWP(ww); ww->emitWPProperty(); } } foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) { WPFollowPrevious(w->FollowPrevious(),w); } } } WayPointItem *OPMapWidget::WPFind(int number) { foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) { if (w->Number() == number) { return w; } } } return nullptr; } void OPMapWidget::WPSetVisibleAll(bool value) { foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) { if (w->Number() != -1) { w->setVisible(value); } } } } void OPMapWidget::WPDeleteAll() { foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) { if (w->Number() != -1) { emit WPDeleted(w->Number(), w); delete w; } } } } bool OPMapWidget::WPPresent() { foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) { if (w->Number() != -1) { return true; } } } return false; } void OPMapWidget::deleteAllOverlays() { foreach(QGraphicsItem * i, map->childItems()) { WayPointLine *w = qgraphicsitem_cast(i); if (w) { w->deleteLater(); } else { WayPointCircle *ww = qgraphicsitem_cast(i); if (ww) { ww->deleteLater(); } } } } QList OPMapWidget::WPSelected() { QList list; foreach(QGraphicsItem * i, mscene.selectedItems()) { WayPointItem *w = qgraphicsitem_cast(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); //生成后立即选中,并且把信息发给ui界面 setSelectedWP(item); item->emitWPProperty(); } 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(QListlist) { 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(number); 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 list; QList wplist; list = this->scene()->selectedItems(); foreach(QGraphicsItem * item, list) { WayPointItem *wp = qgraphicsitem_cast(item); qDebug() << "selete item" << wp->Number(); if (wp) { wplist.append(wp); } } if (wplist.length() > 0) { emit selectedWPChanged(wplist); } } void OPMapWidget::WPotherPoint(int number) { WayPointItem *wp = WPFind(number); if(wp) { setSelectedWP(number); 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(i); if (w) { qDebug() << "set Edit" <WPSetEdit(isEdit); } } foreach(QGraphicsItem * i, map->childItems()) { UAVItem *uav = qgraphicsitem_cast(i); if (uav) { uav->setEdit(isEdit); } } foreach(QGraphicsItem * i, map->childItems()) { WayPointLine *l = qgraphicsitem_cast(i); if (l) { l->setEdit(isEdit); } } } void OPMapWidget::WPSetCurrent(int seq) { foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) { if(w->Number() == seq) { w->WPSetCurrent(true); //qDebug() << "map WPSetCurrent" << seq; } else { w->WPSetCurrent(false); } } } } void OPMapWidget::WPsearchall(void) { //重新排序一下 //QList list; QMap list; foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) { list.insert(w->Number(),w->Command()); } } for (QMap::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(altitudeitem) { if(value) { altitudeitem->show(); } else { altitudeitem->hide(); } } } void OPMapWidget::WPLocalChanged(QPointF p, WayPointItem *w) { WayPointItem *item = WPFind(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) { if(flag) { WayPointItem *item = WPFind(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(front_seq--); if(front_item) { if(front_item->FollowPrevious() == false) { qDebug() << "front_item" << front_item->Number(); break; } else { continue; } } else { break; } }while(1); WayPointItem *next_item; int next_seq = w->Number(); do{ next_item = WPFind(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(1); 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(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(1); WayPointItem *next_item; int next_seq = w->Number()+1; do{ next_item = WPFind(next_seq++); if(next_item) { if(next_item->FollowPrevious() == false) { qDebug() << "next_item" << next_item->Number(); break; } else { continue; } } else { break; } }while(1); 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 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 uint8_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); if(command > MAV_CMD::MAV_CMD_NAV_LAST) { } else { //WPLineCreate(WPFind(Item->Number() - 1),Item,Qt::green,false,2); } //Item->setParent(map); qDebug() << "autocontinue" << autocontinue; emit setWPProperty(param1,param2,param3,param4, x,y,z, seq, 0, command, 0, 0, frame, 0, autocontinue, mission_type); Item->emitWPProperty(); } } 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节点写入 { QJsonArray circles; QJsonArray polygons; geoFence.insert("circles",circles); geoFence.insert("polygons",polygons); geoFence.insert("version",2); } //mission节点写入 { QJsonArray items; QJsonArray plannedHomePosition; foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); 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; item.insert("AMSLAltAboveTerrain",0); item.insert("Altitude",w->Alt()); item.insert("AltitudeMode",1); 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","SimpleItem"); //这里有问题 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",2); mission.insert("hoverSpeed",2); mission.insert("items",items); mission.insert("plannedHomePosition",plannedHomePosition); mission.insert("vehicleType",20); 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(i); if (u) { if(u->Select() == true) { sysid = u->SysID(); compid = u->CompID(); emit signal_WPDownload(sysid,compid); } } } } void OPMapWidget::WPUpload(void) { //发送第一个 QList list; //先发送一个清空指令 foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) { list.append(w); w->emitWPProperty(); w->setVisible(false); } } foreach(QGraphicsItem * i, map->childItems()) { WayPointLine *l = qgraphicsitem_cast(i); if (l) { l->setVisible(false); } } qDebug() << "WPUpload" << list.size(); //选择当前ID号 int sysid = 0; int compid = 0; foreach(QGraphicsItem * i, map->childItems()) { UAVItem *u = qgraphicsitem_cast(i); if (u) { if(u->Select() == true) { sysid = u->SysID(); compid = u->CompID(); //如果有选中,那么就发送,选中几个就发几个 emit signal_WPUpload(sysid,compid,list.size());//直接发送全部航点到 } } } } void OPMapWidget::WPSendItemOK(uint16_t seq, bool flag) { if(flag == true) { foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) { if(w->Number() == (seq)) { w->setVisible(true); foreach(QGraphicsItem * i, map->childItems()) { WayPointLine *l = qgraphicsitem_cast(i); if (l) { if(l->WPLineTo() == w) l->setVisible(true); } } } } } } else { foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) w->setVisible(true); } foreach(QGraphicsItem * i, map->childItems()) { WayPointLine *l = qgraphicsitem_cast(i); if (l) l->setVisible(true); } } } //这个有可能是其他线程运行,导致生成的航点不对,下载得到 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"; // << QThread::currentThreadId(); //qDebug() << "receivers Point" << x * 10e-8 << y * 10e-8 << 10e-8; internals::PointLatLng LatLng; LatLng.SetLat(x * 10e-8); LatLng.SetLng(y * 10e-8); WayPointItem *Item = WPCreate(LatLng,z); Item->SetNumber(seq+1); if(command > MAV_CMD::MAV_CMD_NAV_LAST) { } else { //WPLineCreate(WPFind(Item->Number() - 1),Item,Qt::green,false,2); } //Item->setParent(map); emit setWPProperty(param1,param2,param3,param4, x,y,z, seq+1, group, command, target_system, target_component, frame, current, autocontinue, mission_type); Item->emitWPProperty(); } 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 Info; foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(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 Info; foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(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(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() { int number = 0; foreach(QGraphicsItem * i, map->childItems()) { WayPointItem *w = qgraphicsitem_cast(i); if (w) { if(w->Number() >= number) { number = w->Number(); } } } qDebug() << "PointNumber" << number +1; emit PointNumber(number + 1); } }