MapWidget.cc 23.7 KB
Newer Older
1
/*==================================================================
pixhawk's avatar
pixhawk committed
2 3 4 5
======================================================================*/

/**
 * @file
lm's avatar
lm committed
6
 *   @brief Implementation of MapWidget
pixhawk's avatar
pixhawk committed
7 8
 *
 *   @author Lorenz Meier <mavteam@student.ethz.ch>
lm's avatar
lm committed
9
 *   @author Mariano Lizarraga
pixhawk's avatar
pixhawk committed
10 11 12
 *
 */

lm's avatar
lm committed
13 14
#include <QComboBox>
#include <QGridLayout>
15
#include <QDir>
16

pixhawk's avatar
pixhawk committed
17 18
#include "MapWidget.h"
#include "ui_MapWidget.h"
lm's avatar
lm committed
19 20
#include "UASInterface.h"
#include "UASManager.h"
21 22
#include "MAV2DIcon.h"
#include "Waypoint2DIcon.h"
pixhawk's avatar
pixhawk committed
23

pixhawk's avatar
pixhawk committed
24 25
#include "MG.h"

26

pixhawk's avatar
pixhawk committed
27 28 29
MapWidget::MapWidget(QWidget *parent) :
        QWidget(parent),
        zoomLevel(0),
30 31
        uasIcons(),
        uasTrails(),
32
        mav(NULL),
pixhawk's avatar
pixhawk committed
33 34 35
        m_ui(new Ui::MapWidget)
{
    m_ui->setupUi(this);
pixhawk's avatar
pixhawk committed
36

37
    waypointIsDrag = false;
pixhawk's avatar
pixhawk committed
38

pixhawk's avatar
pixhawk committed
39 40
    // Accept focus by clicking or keyboard
    this->setFocusPolicy(Qt::StrongFocus);
pixhawk's avatar
pixhawk committed
41

pixhawk's avatar
pixhawk committed
42
    // create MapControl
43
    mc = new qmapcontrol::MapControl(QSize(320, 240));
pixhawk's avatar
pixhawk committed
44
    mc->showScale(true);
45
    mc->showCoord(true);
46
    mc->enablePersistentCache();
47
    mc->setMouseTracking(true); // required to update the mouse position for diplay and capture
pixhawk's avatar
pixhawk committed
48

pixhawk's avatar
pixhawk committed
49
    // create MapAdapter to get maps from
lm's avatar
lm committed
50
    //TileMapAdapter* osmAdapter = new TileMapAdapter("tile.openstreetmap.org", "/%1/%2/%3.png", 256, 0, 17);
pixhawk's avatar
pixhawk committed
51

52
    qmapcontrol::MapAdapter* mapadapter_overlay = new qmapcontrol::YahooMapAdapter("us.maps3.yimg.com", "/aerial.maps.yimg.com/png?v=2.2&t=h&s=256&x=%2&y=%3&z=%1");
pixhawk's avatar
pixhawk committed
53

lm's avatar
lm committed
54
    // MAP BACKGROUND
55 56
    mapadapter = new qmapcontrol::GoogleSatMapAdapter();
    l = new qmapcontrol::MapLayer("Google Satellite", mapadapter);
lm's avatar
lm committed
57
    mc->addLayer(l);
pixhawk's avatar
pixhawk committed
58

lm's avatar
lm committed
59
    // STREET OVERLAY
60
    overlay = new qmapcontrol::MapLayer("Overlay", mapadapter_overlay);
lm's avatar
lm committed
61 62
    overlay->setVisible(false);
    mc->addLayer(overlay);
pixhawk's avatar
pixhawk committed
63

lm's avatar
lm committed
64 65
    // WAYPOINT LAYER
    // create a layer with the mapadapter and type GeometryLayer (for waypoints)
66
    geomLayer = new qmapcontrol::GeometryLayer("Waypoints", mapadapter);
67
    mc->addLayer(geomLayer);
pixhawk's avatar
pixhawk committed
68 69 70



71 72 73
    //
    //    Layer* gsatLayer = new Layer("Google Satellite", gsat, Layer::MapLayer);
    //    mc->addLayer(gsatLayer);
pixhawk's avatar
pixhawk committed
74

lm's avatar
lm committed
75 76 77 78
    // SET INITIAL POSITION AND ZOOM
    // Set default zoom level
    mc->setZoom(16);
    // Zurich, ETH
79
    mc->setView(QPointF(8.548056,47.376389));
pixhawk's avatar
pixhawk committed
80

81 82
    // Veracruz Mexico
    //mc->setView(QPointF(-96.105208,19.138955));
pixhawk's avatar
pixhawk committed
83

lm's avatar
lm committed
84 85 86
    // Add controls to select map provider
    /////////////////////////////////////////////////
    QActionGroup* mapproviderGroup = new QActionGroup(this);
87 88 89 90 91
    osmAction = new QAction(QIcon(":/images/mapproviders/openstreetmap.png"), tr("OpenStreetMap"), mapproviderGroup);
    yahooActionMap = new QAction(QIcon(":/images/mapproviders/yahoo.png"), tr("Yahoo: Map"), mapproviderGroup);
    yahooActionSatellite = new QAction(QIcon(":/images/mapproviders/yahoo.png"), tr("Yahoo: Satellite"), mapproviderGroup);
    googleActionMap = new QAction(QIcon(":/images/mapproviders/google.png"), tr("Google: Map"), mapproviderGroup);
    googleSatAction = new QAction(QIcon(":/images/mapproviders/google.png"), tr("Google: Sat"), mapproviderGroup);
lm's avatar
lm committed
92 93 94 95 96 97 98 99
    osmAction->setCheckable(true);
    yahooActionMap->setCheckable(true);
    yahooActionSatellite->setCheckable(true);
    googleActionMap->setCheckable(true);
    googleSatAction->setCheckable(true);
    googleSatAction->setChecked(true);
    connect(mapproviderGroup, SIGNAL(triggered(QAction*)),
            this, SLOT(mapproviderSelected(QAction*)));
pixhawk's avatar
pixhawk committed
100

lm's avatar
lm committed
101
    // Overlay seems currently broken
102 103 104 105 106
    //    yahooActionOverlay = new QAction(tr("Yahoo: street overlay"), this);
    //    yahooActionOverlay->setCheckable(true);
    //    yahooActionOverlay->setChecked(overlay->isVisible());
    //    connect(yahooActionOverlay, SIGNAL(toggled(bool)),
    //            overlay, SLOT(setVisible(bool)));
pixhawk's avatar
pixhawk committed
107

108 109 110 111 112 113
    //    mapproviderGroup->addAction(googleSatAction);
    //    mapproviderGroup->addAction(osmAction);
    //    mapproviderGroup->addAction(yahooActionOverlay);
    //    mapproviderGroup->addAction(googleActionMap);
    //    mapproviderGroup->addAction(yahooActionMap);
    //    mapproviderGroup->addAction(yahooActionSatellite);
pixhawk's avatar
pixhawk committed
114

lm's avatar
lm committed
115 116 117 118
    // Create map provider selection menu
    mapMenu = new QMenu(this);
    mapMenu->addActions(mapproviderGroup->actions());
    mapMenu->addSeparator();
119
    //    mapMenu->addAction(yahooActionOverlay);
pixhawk's avatar
pixhawk committed
120

lm's avatar
lm committed
121 122 123
    mapButton = new QPushButton(this);
    mapButton->setText("Map Source");
    mapButton->setMenu(mapMenu);
pixhawk's avatar
pixhawk committed
124

pixhawk's avatar
pixhawk committed
125
    // display the MapControl in the application
lm's avatar
lm committed
126
    QGridLayout* layout = new QGridLayout(this);
pixhawk's avatar
pixhawk committed
127
    layout->setMargin(0);
lm's avatar
lm committed
128 129 130 131 132 133 134 135
    layout->setSpacing(2);
    layout->addWidget(mc, 0, 0, 1, 2);
    layout->addWidget(mapButton, 1, 0);
    layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 1, 1);
    layout->setRowStretch(0, 100);
    layout->setRowStretch(1, 1);
    layout->setColumnStretch(0, 1);
    layout->setColumnStretch(1, 50);
pixhawk's avatar
pixhawk committed
136
    setLayout(layout);
pixhawk's avatar
pixhawk committed
137

138
    // create buttons to control the map (zoom, GPS tracking and WP capture)
pixhawk's avatar
pixhawk committed
139 140
    QPushButton* zoomin = new QPushButton(QIcon(":/images/actions/list-add.svg"), "", this);
    QPushButton* zoomout = new QPushButton(QIcon(":/images/actions/list-remove.svg"), "", this);
141
    createPath = new QPushButton(QIcon(":/images/actions/go-bottom.svg"), "", this);
pixhawk's avatar
pixhawk committed
142
    followgps = new QPushButton(QIcon(":/images/actions/system-lock-screen.svg"), "", this);
pixhawk's avatar
pixhawk committed
143

pixhawk's avatar
pixhawk committed
144 145
    zoomin->setMaximumWidth(50);
    zoomout->setMaximumWidth(50);
146
    createPath->setMaximumWidth(50);
pixhawk's avatar
pixhawk committed
147
    followgps->setMaximumWidth(50);
pixhawk's avatar
pixhawk committed
148

149 150 151 152 153
    // Set checkable buttons
    // TODO: Currently checked buttons are are very difficult to distinguish when checked.
    //       create a style and the slots to change the background so it is easier to distinguish
    followgps->setCheckable(true);
    createPath->setCheckable(true);
pixhawk's avatar
pixhawk committed
154

155
    // add buttons to control the map (zoom, GPS tracking and WP capture)
lm's avatar
lm committed
156 157 158 159 160 161 162 163 164 165 166 167
    QGridLayout* innerlayout = new QGridLayout(mc);
    innerlayout->setMargin(5);
    innerlayout->setSpacing(5);
    innerlayout->addWidget(zoomin, 0, 0);
    innerlayout->addWidget(zoomout, 1, 0);
    innerlayout->addWidget(followgps, 2, 0);
    innerlayout->addWidget(createPath, 3, 0);
    // Add spacers to compress buttons on the top left
    innerlayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 4, 0);
    innerlayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 0, 1, 0, 5);
    innerlayout->setRowStretch(0, 1);
    innerlayout->setRowStretch(1, 100);
pixhawk's avatar
pixhawk committed
168
    mc->setLayout(innerlayout);
pixhawk's avatar
pixhawk committed
169 170


171
    // Connect the required signals-slots
172 173
    connect(zoomin, SIGNAL(clicked(bool)),
            mc, SLOT(zoomIn()));
pixhawk's avatar
pixhawk committed
174

175 176
    connect(zoomout, SIGNAL(clicked(bool)),
            mc, SLOT(zoomOut()));
pixhawk's avatar
pixhawk committed
177 178 179 180 181 182 183

    QList<UASInterface*> systems = UASManager::instance()->getUASList();
    foreach(UASInterface* system, systems)
    {
        addUAS(system);
    }

184 185
    connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)),
            this, SLOT(addUAS(UASInterface*)));
pixhawk's avatar
pixhawk committed
186 187

    activeUASSet(UASManager::instance()->getActiveUAS());
188
    connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(activeUASSet(UASInterface*)));
pixhawk's avatar
pixhawk committed
189

190 191
    connect(mc, SIGNAL(mouseEventCoordinate(const QMouseEvent*, const QPointF)),
            this, SLOT(captureMapClick(const QMouseEvent*, const QPointF)));
pixhawk's avatar
pixhawk committed
192

193
    connect(createPath, SIGNAL(clicked(bool)),
194
            this, SLOT(createPathButtonClicked(bool)));
pixhawk's avatar
pixhawk committed
195 196


197 198
    connect(geomLayer, SIGNAL(geometryClicked(Geometry*,QPoint)),
            this, SLOT(captureGeometryClick(Geometry*, QPoint)));
pixhawk's avatar
pixhawk committed
199

200 201
    connect(geomLayer, SIGNAL(geometryDragged(Geometry*, QPointF)),
            this, SLOT(captureGeometryDrag(Geometry*, QPointF)));
pixhawk's avatar
pixhawk committed
202

203 204
    connect(geomLayer, SIGNAL(geometryEndDrag(Geometry*, QPointF)),
            this, SLOT(captureGeometryEndDrag(Geometry*, QPointF)));
pixhawk's avatar
pixhawk committed
205

206 207 208
    // Configure the WP Path's pen
    pointPen = new QPen(QColor(0, 255,0));
    pointPen->setWidth(3);
pixhawk's avatar
pixhawk committed
209

210
    path = new qmapcontrol::LineString (wps, "UAV Path", pointPen);
lm's avatar
lm committed
211
    mc->layer("Waypoints")->addGeometry(path);
pixhawk's avatar
pixhawk committed
212

213 214 215 216 217
    //Camera Control
    // CAMERA INDICATOR LAYER
    // create a layer with the mapadapter and type GeometryLayer (for camera indicator)
    camLayer = new qmapcontrol::GeometryLayer("Camera", mapadapter);
    mc->addLayer(camLayer);
pixhawk's avatar
pixhawk committed
218

219
    //camLine = new qmapcontrol::LineString(camPoints,"Camera Eje", camBorderPen);
pixhawk's avatar
pixhawk committed
220

221 222
    drawCamBorder = false;
    radioCamera = 10;
lm's avatar
lm committed
223 224
}

225

lm's avatar
lm committed
226 227 228 229 230 231 232 233
void MapWidget::mapproviderSelected(QAction* action)
{
    //delete mapadapter;
    mapButton->setText(action->text());
    if (action == osmAction)
    {
        int zoom = mapadapter->adaptedZoom();
        mc->setZoom(0);
pixhawk's avatar
pixhawk committed
234

235
        mapadapter = new qmapcontrol::OSMMapAdapter();
lm's avatar
lm committed
236 237
        l->setMapAdapter(mapadapter);
        geomLayer->setMapAdapter(mapadapter);
pixhawk's avatar
pixhawk committed
238

lm's avatar
lm committed
239 240
        mc->updateRequestNew();
        mc->setZoom(zoom);
241
        //        yahooActionOverlay->setEnabled(false);
lm's avatar
lm committed
242
        overlay->setVisible(false);
243
        //        yahooActionOverlay->setChecked(false);
pixhawk's avatar
pixhawk committed
244

lm's avatar
lm committed
245 246 247 248 249
    }
    else if (action == yahooActionMap)
    {
        int zoom = mapadapter->adaptedZoom();
        mc->setZoom(0);
pixhawk's avatar
pixhawk committed
250

251
        mapadapter = new qmapcontrol::YahooMapAdapter();
lm's avatar
lm committed
252 253
        l->setMapAdapter(mapadapter);
        geomLayer->setMapAdapter(mapadapter);
pixhawk's avatar
pixhawk committed
254

lm's avatar
lm committed
255 256
        mc->updateRequestNew();
        mc->setZoom(zoom);
257
        //        yahooActionOverlay->setEnabled(false);
lm's avatar
lm committed
258
        overlay->setVisible(false);
259
        //        yahooActionOverlay->setChecked(false);
lm's avatar
lm committed
260 261 262 263 264 265
    }
    else if (action == yahooActionSatellite)
    {
        int zoom = mapadapter->adaptedZoom();
        QPointF a = mc->currentCoordinate();
        mc->setZoom(0);
pixhawk's avatar
pixhawk committed
266

267
        mapadapter = new qmapcontrol::YahooMapAdapter("us.maps3.yimg.com", "/aerial.maps.yimg.com/png?v=1.7&t=a&s=256&x=%2&y=%3&z=%1");
lm's avatar
lm committed
268
        l->setMapAdapter(mapadapter);
pixhawk's avatar
pixhawk committed
269

lm's avatar
lm committed
270 271
        mc->updateRequestNew();
        mc->setZoom(zoom);
272
        //        yahooActionOverlay->setEnabled(true);
lm's avatar
lm committed
273 274 275 276 277
    }
    else if (action == googleActionMap)
    {
        int zoom = mapadapter->adaptedZoom();
        mc->setZoom(0);
278
        mapadapter = new qmapcontrol::GoogleMapAdapter();
lm's avatar
lm committed
279 280
        l->setMapAdapter(mapadapter);
        geomLayer->setMapAdapter(mapadapter);
pixhawk's avatar
pixhawk committed
281

lm's avatar
lm committed
282 283
        mc->updateRequestNew();
        mc->setZoom(zoom);
284
        //        yahooActionOverlay->setEnabled(false);
lm's avatar
lm committed
285
        overlay->setVisible(false);
286
        //        yahooActionOverlay->setChecked(false);
lm's avatar
lm committed
287 288 289 290 291
    }
    else if (action == googleSatAction)
    {
        int zoom = mapadapter->adaptedZoom();
        mc->setZoom(0);
292
        mapadapter = new qmapcontrol::GoogleSatMapAdapter();
lm's avatar
lm committed
293 294
        l->setMapAdapter(mapadapter);
        geomLayer->setMapAdapter(mapadapter); 
pixhawk's avatar
pixhawk committed
295

lm's avatar
lm committed
296 297
        mc->updateRequestNew();
        mc->setZoom(zoom);
298
        //        yahooActionOverlay->setEnabled(false);
lm's avatar
lm committed
299
        overlay->setVisible(false);
300
        //        yahooActionOverlay->setChecked(false);
lm's avatar
lm committed
301 302 303 304 305
    }
    else
    {
        mapButton->setText("Select..");
    }
306
}
lm's avatar
lm committed
307

lm's avatar
lm committed
308

309
void MapWidget::createPathButtonClicked(bool checked)
lm's avatar
lm committed
310
{
311
    Q_UNUSED(checked);
pixhawk's avatar
pixhawk committed
312 313 314



lm's avatar
lm committed
315 316 317 318
    if (createPath->isChecked())
    {
        // change the cursor shape
        this->setCursor(Qt::PointingHandCursor);
319
        mc->setMouseMode(qmapcontrol::MapControl::None);
pixhawk's avatar
pixhawk committed
320 321


322
        // emit signal start to create a Waypoint global
323
        emit createGlobalWP(true, mc->currentCoordinate());
pixhawk's avatar
pixhawk committed
324

325 326 327 328 329 330 331
        //        // Clear the previous WP track
        //        // TODO: Move this to an actual clear track button and add a warning dialog
        //        mc->layer("Waypoints")->clearGeometries();
        //        wps.clear();
        //        path->setPoints(wps);
        //        mc->layer("Waypoints")->addGeometry(path);
        //        wpIndex.clear();
pixhawk's avatar
pixhawk committed
332 333


lm's avatar
lm committed
334
    } else {
pixhawk's avatar
pixhawk committed
335

lm's avatar
lm committed
336
        this->setCursor(Qt::ArrowCursor);
337
        mc->setMouseMode(qmapcontrol::MapControl::Panning);
pixhawk's avatar
pixhawk committed
338 339


lm's avatar
lm committed
340
    }
pixhawk's avatar
pixhawk committed
341

342
}
343

344 345 346 347 348 349 350
/**
 * Captures a click on the map and if in create WP path mode, it adds the WP on MouseButtonRelease
 *
 * @param event The mouse event
 * @param coordinate The coordinate in which it occured the mouse event
 * @note  This slot is connected to the mouseEventCoordinate of the QMapControl object
 */
351

352 353
void MapWidget::captureMapClick(const QMouseEvent* event, const QPointF coordinate)
{
pixhawk's avatar
pixhawk committed
354

355
    qDebug() << mc->mouseMode();
pixhawk's avatar
pixhawk committed
356

357
    if (QEvent::MouseButtonRelease == event->type() && createPath->isChecked())
358
    {
359 360
        // Create waypoint name
        QString str;
pixhawk's avatar
pixhawk committed
361

362
        str = QString("%1").arg(path->numberOfPoints());
pixhawk's avatar
pixhawk committed
363

364 365
        // create the WP and set everything in the LineString to display the path
        Waypoint2DIcon* tempCirclePoint;
pixhawk's avatar
pixhawk committed
366

367 368 369 370 371 372 373 374 375
        if (mav)
        {
            tempCirclePoint = new Waypoint2DIcon(coordinate.x(), coordinate.y(), 20, str, qmapcontrol::Point::Middle, new QPen(mav->getColor()));
        }
        else
        {
            tempCirclePoint = new Waypoint2DIcon(coordinate.x(), coordinate.y(), 20, str, qmapcontrol::Point::Middle);
        }
        mc->layer("Waypoints")->addGeometry(tempCirclePoint);
pixhawk's avatar
pixhawk committed
376

377 378 379
        qmapcontrol::Point* tempPoint = new qmapcontrol::Point(coordinate.x(), coordinate.y(),str);
        wps.append(tempPoint);
        path->addPoint(tempPoint);
pixhawk's avatar
pixhawk committed
380

381
        wpIndex.insert(str,tempPoint);
pixhawk's avatar
pixhawk committed
382

383 384
        // Refresh the screen
        mc->updateRequestNew();
pixhawk's avatar
pixhawk committed
385

386 387
        // emit signal mouse was clicked
        emit captureMapCoordinateClick(coordinate);
pixhawk's avatar
pixhawk committed
388

389
    }
pixhawk's avatar
pixhawk committed
390 391
}

392 393
void MapWidget::createWaypointGraphAtMap(const QPointF coordinate)
{
394 395 396
    if (!wpExists(coordinate)){
        // Create waypoint name
        QString str;
pixhawk's avatar
pixhawk committed
397 398


399
        str = QString("%1").arg(path->numberOfPoints());
pixhawk's avatar
pixhawk committed
400

401 402 403
        // create the WP and set everything in the LineString to display the path
        //CirclePoint* tempCirclePoint = new CirclePoint(coordinate.x(), coordinate.y(), 10, str);
        Waypoint2DIcon* tempCirclePoint;
pixhawk's avatar
pixhawk committed
404

405 406 407 408 409 410 411 412
        if (mav)
        {
            tempCirclePoint = new Waypoint2DIcon(coordinate.x(), coordinate.y(), 20, str, qmapcontrol::Point::Middle, new QPen(mav->getColor()));
        }
        else
        {
            tempCirclePoint = new Waypoint2DIcon(coordinate.x(), coordinate.y(), 20, str, qmapcontrol::Point::Middle);
        }
pixhawk's avatar
pixhawk committed
413 414


415
        mc->layer("Waypoints")->addGeometry(tempCirclePoint);
pixhawk's avatar
pixhawk committed
416

417 418 419
        Point* tempPoint = new Point(coordinate.x(), coordinate.y(),str);
        wps.append(tempPoint);
        path->addPoint(tempPoint);
pixhawk's avatar
pixhawk committed
420

421
        wpIndex.insert(str,tempPoint);
tecnosapiens's avatar
tecnosapiens committed
422
        qDebug()<<"Funcion createWaypointGraphAtMap WP= "<<str<<" -> x= "<<tempPoint->latitude()<<" y= "<<tempPoint->longitude();
pixhawk's avatar
pixhawk committed
423

tecnosapiens's avatar
tecnosapiens committed
424
        // Refresh the screen
425 426
        mc->updateRequestNew();
    }
pixhawk's avatar
pixhawk committed
427

428 429
    ////    // emit signal mouse was clicked
    //    emit captureMapCoordinateClick(coordinate);
430 431
}

432
int MapWidget::wpExists(const QPointF coordinate){
433 434 435 436 437
    for (int i = 0; i < wps.size(); i++){
        if (wps.at(i)->latitude() == coordinate.y() &&
            wps.at(i)->longitude()== coordinate.x()){
            return 1;
        }
438
    }
439
    return 0;
440 441
}

442

443 444
void MapWidget::captureGeometryClick(Geometry* geom, QPoint point)
{
445 446
    Q_UNUSED(geom);
    Q_UNUSED(point);
pixhawk's avatar
pixhawk committed
447

448
    mc->setMouseMode(qmapcontrol::MapControl::None);
pixhawk's avatar
pixhawk committed
449

450 451
}

452 453
void MapWidget::captureGeometryDrag(Geometry* geom, QPointF coordinate)
{
pixhawk's avatar
pixhawk committed
454 455


456
    waypointIsDrag = true;
pixhawk's avatar
pixhawk committed
457

458 459
    // Refresh the screen
    mc->updateRequestNew();
pixhawk's avatar
pixhawk committed
460

461 462 463
    int temp = 0;
    qmapcontrol::Point* point2Find;
    point2Find = wpIndex[geom->name()];
pixhawk's avatar
pixhawk committed
464

465 466 467
    if (point2Find)
    {
        point2Find->setCoordinate(coordinate);
pixhawk's avatar
pixhawk committed
468

469 470 471 472
        point2Find = dynamic_cast <qmapcontrol::Point*> (geom);
        if (point2Find)
        {
            point2Find->setCoordinate(coordinate);
pixhawk's avatar
pixhawk committed
473

474 475 476 477 478 479
            // qDebug() << geom->name();
            temp = geom->get_myIndex();
            //qDebug() << temp;
            emit sendGeometryEndDrag(coordinate,temp);
        }
    }
pixhawk's avatar
pixhawk committed
480

481 482
}

483
void MapWidget::captureGeometryEndDrag(Geometry* geom, QPointF coordinate)
484
{
485 486 487
    Q_UNUSED(geom);
    Q_UNUSED(coordinate);
    // TODO: Investigate why when creating the waypoint path this slot is being called
pixhawk's avatar
pixhawk committed
488

489 490 491 492 493 494
    // Only change the mouse mode back to panning when not creating a WP path
    if (!createPath->isChecked())
    {
        waypointIsDrag = false;
        mc->setMouseMode(qmapcontrol::MapControl::Panning);
    }
pixhawk's avatar
pixhawk committed
495

496 497
}

pixhawk's avatar
pixhawk committed
498 499 500 501
MapWidget::~MapWidget()
{
    delete m_ui;
}
lm's avatar
lm committed
502 503 504 505 506 507
/**
 *
 * @param uas the UAS/MAV to monitor/display with the HUD
 */
void MapWidget::addUAS(UASInterface* uas)
{
pixhawk's avatar
pixhawk committed
508 509 510 511
    if(mav != NULL)
    {
        disconnect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64)));
    }
512
    connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64)));
lm's avatar
lm committed
513 514
}

515 516 517 518 519 520 521 522 523
void MapWidget::activeUASSet(UASInterface* uas)
{
    if (uas)
    {
        mav = uas;
        path->setPen(new QPen(mav->getColor()));
    }
}

lm's avatar
lm committed
524 525 526 527 528 529 530 531 532
/**
 * Updates the global position of one MAV and append the last movement to the trail
 *
 * @param uas The unmanned air system
 * @param lat Latitude in WGS84 ellipsoid
 * @param lon Longitutde in WGS84 ellipsoid
 * @param alt Altitude over mean sea level
 * @param usec Timestamp of the position message in milliseconds FIXME will move to microseconds
 */
lm's avatar
lm committed
533 534 535
void MapWidget::updateGlobalPosition(UASInterface* uas, double lat, double lon, double alt, quint64 usec)
{
    Q_UNUSED(usec);
536
    Q_UNUSED(alt); // FIXME Use altitude
pixhawk's avatar
pixhawk committed
537
    quint64 currTime = MG::TIME::getGroundTimeNow();
538
    if (currTime - lastUpdate > 90)
pixhawk's avatar
pixhawk committed
539 540
    {
        lastUpdate = currTime;
541 542 543 544 545 546
        // create a LineString
        //QList<Point*> points;
        // Points with a circle
        // A QPen can be used to customize the
        //pointpen->setWidth(3);
        //points.append(new CirclePoint(lat, lon, 10, uas->getUASName(), Point::Middle, pointpen));
pixhawk's avatar
pixhawk committed
547

548 549 550 551
        if (!uasIcons.contains(uas->getUASID()))
        {
            // Get the UAS color
            QColor uasColor = uas->getColor();
pixhawk's avatar
pixhawk committed
552

553 554
            // Icon
            QPen* pointpen = new QPen(uasColor);
555
            qDebug() << uas->getUASName();
556
            MAV2DIcon* p = new MAV2DIcon(lat, lon, 20, uas->getUASName(), qmapcontrol::Point::Middle, pointpen);
557
            uasIcons.insert(uas->getUASID(), p);
lm's avatar
lm committed
558
            geomLayer->addGeometry(p);
pixhawk's avatar
pixhawk committed
559

560 561
            // Line
            // A QPen also can use transparency
pixhawk's avatar
pixhawk committed
562

563
            QList<qmapcontrol::Point*> points;
pixhawk's avatar
pixhawk committed
564
            points.append(new qmapcontrol::Point(lat, lon, ""));
565 566 567
            QPen* linepen = new QPen(uasColor.darker());
            linepen->setWidth(2);
            // Add the Points and the QPen to a LineString
568
            qmapcontrol::LineString* ls = new qmapcontrol::LineString(points, uas->getUASName(), linepen);
569
            uasTrails.insert(uas->getUASID(), ls);
pixhawk's avatar
pixhawk committed
570

571
            // Add the LineString to the layer
lm's avatar
lm committed
572
            geomLayer->addGeometry(ls);
573 574 575
        }
        else
        {
576 577 578 579 580 581
            MAV2DIcon* p = dynamic_cast<MAV2DIcon*>(uasIcons.value(uas->getUASID()));
            if (p)
            {
                p->setCoordinate(QPointF(lat, lon));
                p->setYaw(uas->getYaw());
            }
582
            // Extend trail
pixhawk's avatar
pixhawk committed
583
            uasTrails.value(uas->getUASID())->addPoint(new qmapcontrol::Point(lat, lon, ""));
584
        }
pixhawk's avatar
pixhawk committed
585 586


587
        // Connect click events of the layer to this object
588
        // connect(osmLayer, SIGNAL(geometryClicked(Geometry*, QPoint)),
589
        //                  this, SLOT(geometryClicked(Geometry*, QPoint)));
pixhawk's avatar
pixhawk committed
590

591 592
        // Sets the view to the interesting area
        updatePosition(0, lat, lon);
pixhawk's avatar
pixhawk committed
593 594
    }
}
pixhawk's avatar
pixhawk committed
595

lm's avatar
lm committed
596 597 598
/**
 * Center the view on this position
 */
lm's avatar
lm committed
599
void MapWidget::updatePosition(float time, double lat, double lon)
pixhawk's avatar
pixhawk committed
600
{
lm's avatar
lm committed
601
    Q_UNUSED(time);
602
    //gpsposition->setText(QString::number(time) + " / " + QString::number(lat) + " / " + QString::number(lon));
603
    if (followgps->isChecked() && isVisible())
pixhawk's avatar
pixhawk committed
604
    {
lm's avatar
lm committed
605
        mc->setView(QPointF(lat, lon));
pixhawk's avatar
pixhawk committed
606 607 608 609 610 611 612 613 614 615 616 617 618 619
    }
}

void MapWidget::wheelEvent(QWheelEvent *event)
{
    int numDegrees = event->delta() / 8;
    int numSteps = numDegrees / 15;
    // Calculate new zoom level
    int newZoom = mc->currentZoom()+numSteps;
    // Set new zoom level, level is bounded by map control
    mc->setZoom(newZoom);
    // Detail zoom level is the number of steps zoomed in further
    // after the bounding has taken effect
    detailZoom = qAbs(qMin(0, mc->currentZoom()-newZoom));
pixhawk's avatar
pixhawk committed
620

621
    // visual field of camera
622
    updateCameraPosition(20*newZoom,0,"no");
pixhawk's avatar
pixhawk committed
623

pixhawk's avatar
pixhawk committed
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
}

void MapWidget::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_Plus:
        mc->zoomIn();
        break;
    case Qt::Key_Minus:
        mc->zoomOut();
        break;
    case Qt::Key_Left:
        mc->scrollLeft(this->width()/scrollStep);
        break;
    case Qt::Key_Right:
        mc->scrollRight(this->width()/scrollStep);
        break;
    case Qt::Key_Down:
        mc->scrollDown(this->width()/scrollStep);
        break;
    case Qt::Key_Up:
        mc->scrollUp(this->width()/scrollStep);
        break;
    default:
        QWidget::keyPressEvent(event);
    }
}

652
void MapWidget::resizeEvent(QResizeEvent* event )
pixhawk's avatar
pixhawk committed
653
{
654 655
    Q_UNUSED(event);
    mc->resize(this->size());
pixhawk's avatar
pixhawk committed
656 657
}

658 659 660 661 662 663 664 665 666 667
void MapWidget::showEvent(QShowEvent* event)
{
    Q_UNUSED(event);
}

void MapWidget::hideEvent(QHideEvent* event)
{
    Q_UNUSED(event);
}

pixhawk's avatar
pixhawk committed
668 669 670 671 672 673 674 675 676 677 678 679

void MapWidget::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
680 681 682
void MapWidget::clearPath()
{
    // Clear the previous WP track
pixhawk's avatar
pixhawk committed
683

684 685 686 687 688 689
    mc->layer("Waypoints")->clearGeometries();
    wps.clear();
    path->setPoints(wps);
    mc->layer("Waypoints")->addGeometry(path);
    wpIndex.clear();
    mc->updateRequestNew();
pixhawk's avatar
pixhawk committed
690 691


692 693 694 695
    if(createPath->isChecked())
    {
        createPath->click();
    }
pixhawk's avatar
pixhawk committed
696

697
}
698 699 700 701 702 703

void MapWidget::changeGlobalWaypointPositionBySpinBox(int index, float lat, float lon)
{
    if(!waypointIsDrag)
    {
        qDebug() <<"indice WP= "<<index <<"\n";
pixhawk's avatar
pixhawk committed
704

705 706 707
        QPointF coordinate;
        coordinate.setX(lon);
        coordinate.setY(lat);
pixhawk's avatar
pixhawk committed
708

709 710 711
        Point* point2Find;
        point2Find = wpIndex[QString::number(index)];
        point2Find->setCoordinate(coordinate);
pixhawk's avatar
pixhawk committed
712

713 714
        point2Find = dynamic_cast <Point*> (mc->layer("Waypoints")->get_Geometry(index));
        point2Find->setCoordinate(coordinate);
pixhawk's avatar
pixhawk committed
715

716 717
        // Refresh the screen
        mc->updateRequestNew();
718
    }
pixhawk's avatar
pixhawk committed
719 720


721 722
}

723 724
void MapWidget::updateCameraPosition(double radio, double bearing, QString dir)
{
pixhawk's avatar
pixhawk committed
725
    // FIXME Mariano
726 727
    //camPoints.clear();
    QPointF currentPos = mc->currentCoordinate();
728
    //    QPointF actualPos = getPointxBearing_Range(currentPos.y(),currentPos.x(),bearing,distance);
pixhawk's avatar
pixhawk committed
729

730 731
    //    qmapcontrol::Point* tempPoint1 = new qmapcontrol::Point(currentPos.x(), currentPos.y(),"inicial",qmapcontrol::Point::Middle);
    //    qmapcontrol::Point* tempPoint2 = new qmapcontrol::Point(actualPos.x(), actualPos.y(),"final",qmapcontrol::Point::Middle);
pixhawk's avatar
pixhawk committed
732

733 734
    //    camPoints.append(tempPoint1);
    //    camPoints.append(tempPoint2);
pixhawk's avatar
pixhawk committed
735

736
    //    camLine->setPoints(camPoints);
pixhawk's avatar
pixhawk committed
737

738
    QPen* camBorderPen = new QPen(QColor(255,0,0));
739
    camBorderPen->setWidth(2);
pixhawk's avatar
pixhawk committed
740

741
    //radio = mc->currentZoom()
pixhawk's avatar
pixhawk committed
742

743 744 745 746
    if(drawCamBorder)
    {
        //clear camera borders
        mc->layer("Camera")->clearGeometries();
pixhawk's avatar
pixhawk committed
747

748 749
        //create a camera borders
        qmapcontrol::CirclePoint* camBorder = new qmapcontrol::CirclePoint(currentPos.x(), currentPos.y(), radio, "camBorder", qmapcontrol::Point::Middle, camBorderPen);
pixhawk's avatar
pixhawk committed
750

751
        //camBorder->setCoordinate(currentPos);
pixhawk's avatar
pixhawk committed
752

753
        mc->layer("Camera")->addGeometry(camBorder);
754
        // mc->layer("Camera")->addGeometry(camLine);
755
        mc->updateRequestNew();
pixhawk's avatar
pixhawk committed
756

757
    }
758 759 760 761 762
    else
    {
        //clear camera borders
        mc->layer("Camera")->clearGeometries();
        mc->updateRequestNew();
pixhawk's avatar
pixhawk committed
763

764
    }
pixhawk's avatar
pixhawk committed
765 766


767 768 769 770 771 772
}

void MapWidget::drawBorderCamAtMap(bool status)
{
    drawCamBorder = status;
    updateCameraPosition(20,0,"no");
pixhawk's avatar
pixhawk committed
773

774 775 776 777 778
}

QPointF MapWidget::getPointxBearing_Range(double lat1, double lon1, double bearing, double distance)
{
    QPointF temp;
pixhawk's avatar
pixhawk committed
779

780
    double rad = M_PI/180;
pixhawk's avatar
pixhawk committed
781

782 783 784
    bearing = bearing*rad;
    temp.setX((lon1 + ((distance/60) * (sin(bearing)))));
    temp.setY((lat1 + ((distance/60) * (cos(bearing)))));
pixhawk's avatar
pixhawk committed
785

786 787 788
    return temp;
}