MapWidget.cc 24.6 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),
33
        lastUpdate(0),
pixhawk's avatar
pixhawk committed
34 35 36
        m_ui(new Ui::MapWidget)
{
    m_ui->setupUi(this);
pixhawk's avatar
pixhawk committed
37

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

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

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

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

53
    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
54

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

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

65 66 67 68
    // MAV FLIGHT TRACKS
    tracks = new qmapcontrol::MapLayer("Tracking", mapadapter);
    mc->addLayer(tracks);

lm's avatar
lm committed
69 70
    // WAYPOINT LAYER
    // create a layer with the mapadapter and type GeometryLayer (for waypoints)
71
    geomLayer = new qmapcontrol::GeometryLayer("Waypoints", mapadapter);
72
    mc->addLayer(geomLayer);
pixhawk's avatar
pixhawk committed
73 74 75



76 77 78
    //
    //    Layer* gsatLayer = new Layer("Google Satellite", gsat, Layer::MapLayer);
    //    mc->addLayer(gsatLayer);
pixhawk's avatar
pixhawk committed
79

lm's avatar
lm committed
80 81 82 83
    // SET INITIAL POSITION AND ZOOM
    // Set default zoom level
    mc->setZoom(16);
    // Zurich, ETH
84
    mc->setView(QPointF(8.548056,47.376389));
pixhawk's avatar
pixhawk committed
85

86 87
    // Veracruz Mexico
    //mc->setView(QPointF(-96.105208,19.138955));
pixhawk's avatar
pixhawk committed
88

lm's avatar
lm committed
89 90 91
    // Add controls to select map provider
    /////////////////////////////////////////////////
    QActionGroup* mapproviderGroup = new QActionGroup(this);
92 93 94 95 96
    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
97 98 99 100 101 102 103 104
    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
105

lm's avatar
lm committed
106
    // Overlay seems currently broken
107 108 109 110 111
    //    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
112

113 114 115 116 117 118
    //    mapproviderGroup->addAction(googleSatAction);
    //    mapproviderGroup->addAction(osmAction);
    //    mapproviderGroup->addAction(yahooActionOverlay);
    //    mapproviderGroup->addAction(googleActionMap);
    //    mapproviderGroup->addAction(yahooActionMap);
    //    mapproviderGroup->addAction(yahooActionSatellite);
pixhawk's avatar
pixhawk committed
119

lm's avatar
lm committed
120 121 122 123
    // Create map provider selection menu
    mapMenu = new QMenu(this);
    mapMenu->addActions(mapproviderGroup->actions());
    mapMenu->addSeparator();
124
    //    mapMenu->addAction(yahooActionOverlay);
pixhawk's avatar
pixhawk committed
125

lm's avatar
lm committed
126 127 128
    mapButton = new QPushButton(this);
    mapButton->setText("Map Source");
    mapButton->setMenu(mapMenu);
pixhawk's avatar
pixhawk committed
129

pixhawk's avatar
pixhawk committed
130
    // display the MapControl in the application
lm's avatar
lm committed
131
    QGridLayout* layout = new QGridLayout(this);
pixhawk's avatar
pixhawk committed
132
    layout->setMargin(0);
lm's avatar
lm committed
133 134 135 136 137 138 139 140
    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
141
    setLayout(layout);
pixhawk's avatar
pixhawk committed
142

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

150 151 152 153 154
    zoomin->setMaximumWidth(30);
    zoomout->setMaximumWidth(30);
    createPath->setMaximumWidth(30);
    clearTracking->setMaximumWidth(30);
    followgps->setMaximumWidth(30);
pixhawk's avatar
pixhawk committed
155

156 157 158 159 160
    // 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
161

162
    // add buttons to control the map (zoom, GPS tracking and WP capture)
lm's avatar
lm committed
163 164 165 166 167 168 169
    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);
170
    innerlayout->addWidget(clearTracking, 4, 0);
lm's avatar
lm committed
171
    // Add spacers to compress buttons on the top left
172 173
    innerlayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 5, 0);
    innerlayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 0, 1, 0, 6);
lm's avatar
lm committed
174 175
    innerlayout->setRowStretch(0, 1);
    innerlayout->setRowStretch(1, 100);
pixhawk's avatar
pixhawk committed
176
    mc->setLayout(innerlayout);
pixhawk's avatar
pixhawk committed
177 178


179
    // Connect the required signals-slots
180 181
    connect(zoomin, SIGNAL(clicked(bool)),
            mc, SLOT(zoomIn()));
pixhawk's avatar
pixhawk committed
182

183 184
    connect(zoomout, SIGNAL(clicked(bool)),
            mc, SLOT(zoomOut()));
pixhawk's avatar
pixhawk committed
185 186 187 188 189 190 191

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

192 193
    connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)),
            this, SLOT(addUAS(UASInterface*)));
pixhawk's avatar
pixhawk committed
194 195

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

198 199
    connect(mc, SIGNAL(mouseEventCoordinate(const QMouseEvent*, const QPointF)),
            this, SLOT(captureMapClick(const QMouseEvent*, const QPointF)));
pixhawk's avatar
pixhawk committed
200

201
    connect(createPath, SIGNAL(clicked(bool)),
202
            this, SLOT(createPathButtonClicked(bool)));
pixhawk's avatar
pixhawk committed
203 204


205 206
    connect(geomLayer, SIGNAL(geometryClicked(Geometry*,QPoint)),
            this, SLOT(captureGeometryClick(Geometry*, QPoint)));
pixhawk's avatar
pixhawk committed
207

208 209
    connect(geomLayer, SIGNAL(geometryDragged(Geometry*, QPointF)),
            this, SLOT(captureGeometryDrag(Geometry*, QPointF)));
pixhawk's avatar
pixhawk committed
210

211 212
    connect(geomLayer, SIGNAL(geometryEndDrag(Geometry*, QPointF)),
            this, SLOT(captureGeometryEndDrag(Geometry*, QPointF)));
pixhawk's avatar
pixhawk committed
213

214 215 216
    // Configure the WP Path's pen
    pointPen = new QPen(QColor(0, 255,0));
    pointPen->setWidth(3);
217 218
    waypointPath = new qmapcontrol::LineString (wps, "Waypoint path", pointPen);
    mc->layer("Waypoints")->addGeometry(waypointPath);
pixhawk's avatar
pixhawk committed
219

220 221 222 223 224
    //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
225

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

228 229
    drawCamBorder = false;
    radioCamera = 10;
lm's avatar
lm committed
230 231
}

232

lm's avatar
lm committed
233 234 235 236 237 238 239 240
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
241

242
        mapadapter = new qmapcontrol::OSMMapAdapter();
lm's avatar
lm committed
243 244
        l->setMapAdapter(mapadapter);
        geomLayer->setMapAdapter(mapadapter);
pixhawk's avatar
pixhawk committed
245

lm's avatar
lm committed
246 247
        mc->updateRequestNew();
        mc->setZoom(zoom);
248
        //        yahooActionOverlay->setEnabled(false);
lm's avatar
lm committed
249
        overlay->setVisible(false);
250
        //        yahooActionOverlay->setChecked(false);
pixhawk's avatar
pixhawk committed
251

lm's avatar
lm committed
252 253 254 255 256
    }
    else if (action == yahooActionMap)
    {
        int zoom = mapadapter->adaptedZoom();
        mc->setZoom(0);
pixhawk's avatar
pixhawk committed
257

258
        mapadapter = new qmapcontrol::YahooMapAdapter();
lm's avatar
lm committed
259 260
        l->setMapAdapter(mapadapter);
        geomLayer->setMapAdapter(mapadapter);
pixhawk's avatar
pixhawk committed
261

lm's avatar
lm committed
262 263
        mc->updateRequestNew();
        mc->setZoom(zoom);
264
        //        yahooActionOverlay->setEnabled(false);
lm's avatar
lm committed
265
        overlay->setVisible(false);
266
        //        yahooActionOverlay->setChecked(false);
lm's avatar
lm committed
267 268 269 270 271 272
    }
    else if (action == yahooActionSatellite)
    {
        int zoom = mapadapter->adaptedZoom();
        QPointF a = mc->currentCoordinate();
        mc->setZoom(0);
pixhawk's avatar
pixhawk committed
273

274
        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
275
        l->setMapAdapter(mapadapter);
pixhawk's avatar
pixhawk committed
276

lm's avatar
lm committed
277 278
        mc->updateRequestNew();
        mc->setZoom(zoom);
279
        //        yahooActionOverlay->setEnabled(true);
lm's avatar
lm committed
280 281 282 283 284
    }
    else if (action == googleActionMap)
    {
        int zoom = mapadapter->adaptedZoom();
        mc->setZoom(0);
285
        mapadapter = new qmapcontrol::GoogleMapAdapter();
lm's avatar
lm committed
286 287
        l->setMapAdapter(mapadapter);
        geomLayer->setMapAdapter(mapadapter);
pixhawk's avatar
pixhawk committed
288

lm's avatar
lm committed
289 290
        mc->updateRequestNew();
        mc->setZoom(zoom);
291
        //        yahooActionOverlay->setEnabled(false);
lm's avatar
lm committed
292
        overlay->setVisible(false);
293
        //        yahooActionOverlay->setChecked(false);
lm's avatar
lm committed
294 295 296 297 298
    }
    else if (action == googleSatAction)
    {
        int zoom = mapadapter->adaptedZoom();
        mc->setZoom(0);
299
        mapadapter = new qmapcontrol::GoogleSatMapAdapter();
lm's avatar
lm committed
300 301
        l->setMapAdapter(mapadapter);
        geomLayer->setMapAdapter(mapadapter); 
pixhawk's avatar
pixhawk committed
302

lm's avatar
lm committed
303 304
        mc->updateRequestNew();
        mc->setZoom(zoom);
305
        //        yahooActionOverlay->setEnabled(false);
lm's avatar
lm committed
306
        overlay->setVisible(false);
307
        //        yahooActionOverlay->setChecked(false);
lm's avatar
lm committed
308 309 310 311 312
    }
    else
    {
        mapButton->setText("Select..");
    }
313
}
lm's avatar
lm committed
314

lm's avatar
lm committed
315

316
void MapWidget::createPathButtonClicked(bool checked)
lm's avatar
lm committed
317
{
318
    Q_UNUSED(checked);
pixhawk's avatar
pixhawk committed
319

lm's avatar
lm committed
320 321 322 323
    if (createPath->isChecked())
    {
        // change the cursor shape
        this->setCursor(Qt::PointingHandCursor);
324
        mc->setMouseMode(qmapcontrol::MapControl::None);
pixhawk's avatar
pixhawk committed
325 326


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

330 331 332 333 334 335 336
        //        // 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();
337 338 339
    }
    else
    {
pixhawk's avatar
pixhawk committed
340

lm's avatar
lm committed
341
        this->setCursor(Qt::ArrowCursor);
342
        mc->setMouseMode(qmapcontrol::MapControl::Panning);
lm's avatar
lm committed
343
    }
pixhawk's avatar
pixhawk committed
344

345
}
346

347 348 349 350 351 352 353
/**
 * 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
 */
354

355 356
void MapWidget::captureMapClick(const QMouseEvent* event, const QPointF coordinate)
{
357
    //qDebug() << mc->mouseMode();
358
    if (QEvent::MouseButtonRelease == event->type() && createPath->isChecked())
359
    {
360 361
        // Create waypoint name
        QString str;
pixhawk's avatar
pixhawk committed
362

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

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

368 369 370 371 372 373 374 375 376
        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
377

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

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

384
        // Refresh the screen
385
        mc->updateRequest(tempPoint->boundingBox().toRect());
pixhawk's avatar
pixhawk committed
386

387 388
        // emit signal mouse was clicked
        emit captureMapCoordinateClick(coordinate);
389
    }
pixhawk's avatar
pixhawk committed
390 391
}

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


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

402 403 404
        // 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
405

406 407 408 409 410 411 412 413
        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
414 415


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

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

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

tecnosapiens's avatar
tecnosapiens committed
425
        // Refresh the screen
426
        mc->updateRequest(tempPoint->boundingBox().toRect());
427
    }
pixhawk's avatar
pixhawk committed
428

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

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

443

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

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

451 452
}

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


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

459
    // Refresh the screen
460
    mc->updateRequest(geom->boundingBox().toRect());
pixhawk's avatar
pixhawk committed
461

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

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

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

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

482 483
}

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

490 491 492 493 494 495
    // 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
496

497 498
}

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

512 513 514 515 516
void MapWidget::activeUASSet(UASInterface* uas)
{
    if (uas)
    {
        mav = uas;
517 518 519 520 521
        QColor color = mav->getColor();
        color.setAlphaF(0.6);
        QPen* pen = new QPen(color);
        pen->setWidth(3.0);
        // FIXME Load waypoints of this system
522 523 524
    }
}

lm's avatar
lm committed
525 526 527 528 529 530 531 532 533
/**
 * 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
534 535 536
void MapWidget::updateGlobalPosition(UASInterface* uas, double lat, double lon, double alt, quint64 usec)
{
    Q_UNUSED(usec);
537
    Q_UNUSED(alt); // FIXME Use altitude
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590

    // 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));

    MAV2DIcon* p;

    if (!uasIcons.contains(uas->getUASID()))
    {
        // Get the UAS color
        QColor uasColor = uas->getColor();

        // Icon
        QPen* pointpen = new QPen(uasColor);
        qDebug() << uas->getUASName();
        p = new MAV2DIcon(lat, lon, 20, uas->getUASName(), qmapcontrol::Point::Middle, pointpen);
        uasIcons.insert(uas->getUASID(), p);
        tracks->addGeometry(p);

        // Line
        // A QPen also can use transparency

        QList<qmapcontrol::Point*> points;
        points.append(new qmapcontrol::Point(lat, lon, ""));
        QPen* linepen = new QPen(uasColor.darker());
        linepen->setWidth(2);

        // Create tracking line string
        qmapcontrol::LineString* ls = new qmapcontrol::LineString(points, uas->getUASName(), linepen);
        uasTrails.insert(uas->getUASID(), ls);

        // Add the LineString to the layer
        mc->layer("Tracking")->addGeometry(ls);
    }
    else
    {
        p = dynamic_cast<MAV2DIcon*>(uasIcons.value(uas->getUASID()));
        if (p)
        {
            p->setCoordinate(QPointF(lat, lon));
            p->setYaw(uas->getYaw());
        }
        // Extend trail
        uasTrails.value(uas->getUASID())->addPoint(new qmapcontrol::Point(lat, lon, ""));
    }

    //mc->updateRequestNew();//(uasTrails.value(uas->getUASID())->boundingBox().toRect());


    // Limit the position update rate
pixhawk's avatar
pixhawk committed
591
    quint64 currTime = MG::TIME::getGroundTimeNow();
592
    if (currTime - lastUpdate > 120)
pixhawk's avatar
pixhawk committed
593 594
    {
        lastUpdate = currTime;
595 596
        // Sets the view to the interesting area
        if (followgps->isChecked())
597
        {
598
            updatePosition(0, lat, lon);
599 600 601
        }
        else
        {
602 603
            // Refresh the screen
            //mc->updateRequestNew();
604
        }
pixhawk's avatar
pixhawk committed
605 606
    }
}
pixhawk's avatar
pixhawk committed
607

lm's avatar
lm committed
608 609 610
/**
 * Center the view on this position
 */
lm's avatar
lm committed
611
void MapWidget::updatePosition(float time, double lat, double lon)
pixhawk's avatar
pixhawk committed
612
{
lm's avatar
lm committed
613
    Q_UNUSED(time);
614
    //gpsposition->setText(QString::number(time) + " / " + QString::number(lat) + " / " + QString::number(lon));
615
    if (followgps->isChecked() && isVisible())
pixhawk's avatar
pixhawk committed
616
    {
lm's avatar
lm committed
617
        mc->setView(QPointF(lat, lon));
pixhawk's avatar
pixhawk committed
618 619 620 621 622 623 624 625 626 627 628 629 630 631
    }
}

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
632

633
    // visual field of camera
634
    updateCameraPosition(20*newZoom,0,"no");
pixhawk's avatar
pixhawk committed
635

pixhawk's avatar
pixhawk committed
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
}

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);
    }
}

664
void MapWidget::resizeEvent(QResizeEvent* event )
pixhawk's avatar
pixhawk committed
665
{
666 667
    Q_UNUSED(event);
    mc->resize(this->size());
pixhawk's avatar
pixhawk committed
668 669
}

670 671 672 673 674 675 676 677 678 679
void MapWidget::showEvent(QShowEvent* event)
{
    Q_UNUSED(event);
}

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

pixhawk's avatar
pixhawk committed
680 681 682 683 684 685 686 687 688 689 690 691

void MapWidget::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
692 693

void MapWidget::clearWaypoints()
694 695
{
    // Clear the previous WP track
pixhawk's avatar
pixhawk committed
696

697 698
    mc->layer("Waypoints")->clearGeometries();
    wps.clear();
699 700
    waypointPath->setPoints(wps);
    mc->layer("Waypoints")->addGeometry(waypointPath);
701
    wpIndex.clear();
702
    mc->updateRequest(waypointPath->boundingBox().toRect());
pixhawk's avatar
pixhawk committed
703

704 705 706 707
    if(createPath->isChecked())
    {
        createPath->click();
    }
708
}
pixhawk's avatar
pixhawk committed
709

710 711 712 713 714 715 716 717 718 719 720 721
void MapWidget::clearPath()
{
    mc->layer("Tracking")->clearGeometries();
    foreach (qmapcontrol::LineString* ls, uasTrails)
    {
        QPen* linepen = ls->pen();
        delete ls;
        qmapcontrol::LineString* lsNew = new qmapcontrol::LineString(QList<qmapcontrol::Point*>(), "", linepen);
        mc->layer("Tracking")->addGeometry(lsNew);
    }
    // FIXME update this with update request only for bounding box of trails
    mc->updateRequest(QRect(0, 0, width(), height()));
722
}
723 724 725 726 727 728

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

730 731 732
        QPointF coordinate;
        coordinate.setX(lon);
        coordinate.setY(lat);
pixhawk's avatar
pixhawk committed
733

734 735 736
        Point* point2Find;
        point2Find = wpIndex[QString::number(index)];
        point2Find->setCoordinate(coordinate);
pixhawk's avatar
pixhawk committed
737

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

741
        // Refresh the screen
742
        mc->updateRequest(point2Find->boundingBox().toRect());
743
    }
pixhawk's avatar
pixhawk committed
744 745


746 747
}

748 749
void MapWidget::updateCameraPosition(double radio, double bearing, QString dir)
{
750 751
  Q_UNUSED(bearing);
  Q_UNUSED(dir);
752 753
    //camPoints.clear();
    QPointF currentPos = mc->currentCoordinate();
754
    //    QPointF actualPos = getPointxBearing_Range(currentPos.y(),currentPos.x(),bearing,distance);
pixhawk's avatar
pixhawk committed
755

756 757
    //    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
758

759 760
    //    camPoints.append(tempPoint1);
    //    camPoints.append(tempPoint2);
pixhawk's avatar
pixhawk committed
761

762
    //    camLine->setPoints(camPoints);
pixhawk's avatar
pixhawk committed
763

764
    QPen* camBorderPen = new QPen(QColor(255,0,0));
765
    camBorderPen->setWidth(2);
pixhawk's avatar
pixhawk committed
766

767
    //radio = mc->currentZoom()
pixhawk's avatar
pixhawk committed
768

769 770 771 772
    if(drawCamBorder)
    {
        //clear camera borders
        mc->layer("Camera")->clearGeometries();
pixhawk's avatar
pixhawk committed
773

774 775
        //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
776

777
        //camBorder->setCoordinate(currentPos);
pixhawk's avatar
pixhawk committed
778

779
        mc->layer("Camera")->addGeometry(camBorder);
780
        // mc->layer("Camera")->addGeometry(camLine);
781
        mc->updateRequestNew();
pixhawk's avatar
pixhawk committed
782

783
    }
784 785 786 787 788
    else
    {
        //clear camera borders
        mc->layer("Camera")->clearGeometries();
        mc->updateRequestNew();
pixhawk's avatar
pixhawk committed
789

790
    }
pixhawk's avatar
pixhawk committed
791 792


793 794 795 796 797 798
}

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

800 801 802 803 804
}

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

806
    double rad = M_PI/180;
pixhawk's avatar
pixhawk committed
807

808 809 810
    bearing = bearing*rad;
    temp.setX((lon1 + ((distance/60) * (sin(bearing)))));
    temp.setY((lat1 + ((distance/60) * (cos(bearing)))));
pixhawk's avatar
pixhawk committed
811

812 813 814
    return temp;
}