MapWidget.cc 24.2 KB
Newer Older
pixhawk's avatar
pixhawk committed
1 2
/*=====================================================================

lm's avatar
lm committed
3
QGroundControl Open Source Ground Control Station
pixhawk's avatar
pixhawk committed
4

lm's avatar
lm committed
5
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
pixhawk's avatar
pixhawk committed
6

lm's avatar
lm committed
7
This file is part of the QGROUNDCONTROL project
pixhawk's avatar
pixhawk committed
8

lm's avatar
lm committed
9
    QGROUNDCONTROL is free software: you can redistribute it and/or modify
pixhawk's avatar
pixhawk committed
10 11 12 13
    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.

lm's avatar
lm committed
14
    QGROUNDCONTROL is distributed in the hope that it will be useful,
pixhawk's avatar
pixhawk committed
15 16 17 18 19
    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
lm's avatar
lm committed
20
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
pixhawk's avatar
pixhawk committed
21 22 23 24 25

======================================================================*/

/**
 * @file
lm's avatar
lm committed
26
 *   @brief Implementation of MapWidget
pixhawk's avatar
pixhawk committed
27 28
 *
 *   @author Lorenz Meier <mavteam@student.ethz.ch>
lm's avatar
lm committed
29
 *   @author Mariano Lizarraga
pixhawk's avatar
pixhawk committed
30 31 32
 *
 */

lm's avatar
lm committed
33 34 35
#include <QComboBox>
#include <QGridLayout>

36

pixhawk's avatar
pixhawk committed
37 38
#include "MapWidget.h"
#include "ui_MapWidget.h"
lm's avatar
lm committed
39 40
#include "UASInterface.h"
#include "UASManager.h"
41 42
#include "MAV2DIcon.h"
#include "Waypoint2DIcon.h"
pixhawk's avatar
pixhawk committed
43

pixhawk's avatar
pixhawk committed
44 45
#include "MG.h"

46

pixhawk's avatar
pixhawk committed
47 48 49
MapWidget::MapWidget(QWidget *parent) :
        QWidget(parent),
        zoomLevel(0),
50 51
        uasIcons(),
        uasTrails(),
52
        mav(NULL),
pixhawk's avatar
pixhawk committed
53 54 55
        m_ui(new Ui::MapWidget)
{
    m_ui->setupUi(this);
56

57 58
    waypointIsDrag = false;

pixhawk's avatar
pixhawk committed
59 60 61 62
    // Accept focus by clicking or keyboard
    this->setFocusPolicy(Qt::StrongFocus);

    // create MapControl
63
    mc = new qmapcontrol::MapControl(QSize(320, 240));
pixhawk's avatar
pixhawk committed
64
    mc->showScale(true);
65
    mc->showCoord(true);
pixhawk's avatar
pixhawk committed
66
    mc->enablePersistentCache();
67
    mc->setMouseTracking(true); // required to update the mouse position for diplay and capture
pixhawk's avatar
pixhawk committed
68 69

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

72
    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");
lm's avatar
lm committed
73 74

    // MAP BACKGROUND
75 76
    mapadapter = new qmapcontrol::GoogleSatMapAdapter();
    l = new qmapcontrol::MapLayer("Google Satellite", mapadapter);
lm's avatar
lm committed
77 78 79
    mc->addLayer(l);

    // STREET OVERLAY
80
    overlay = new qmapcontrol::MapLayer("Overlay", mapadapter_overlay);
lm's avatar
lm committed
81 82
    overlay->setVisible(false);
    mc->addLayer(overlay);
pixhawk's avatar
pixhawk committed
83

lm's avatar
lm committed
84 85
    // WAYPOINT LAYER
    // create a layer with the mapadapter and type GeometryLayer (for waypoints)
86
    geomLayer = new qmapcontrol::GeometryLayer("Waypoints", mapadapter);
87
    mc->addLayer(geomLayer);
lm's avatar
lm committed
88

89 90


lm's avatar
lm committed
91 92 93 94 95 96 97 98
//
//    Layer* gsatLayer = new Layer("Google Satellite", gsat, Layer::MapLayer);
//    mc->addLayer(gsatLayer);

    // SET INITIAL POSITION AND ZOOM
    // Set default zoom level
    mc->setZoom(16);
    // Zurich, ETH
99 100 101 102
    //mc->setView(QPointF(8.548056,47.376389));

    // Veracruz Mexico, ETH
    mc->setView(QPointF(-96.105208,19.138955));
lm's avatar
lm committed
103 104 105 106

    // Add controls to select map provider
    /////////////////////////////////////////////////
    QActionGroup* mapproviderGroup = new QActionGroup(this);
107 108 109 110 111
    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
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
    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*)));

    // Overlay seems currently broken
//    yahooActionOverlay = new QAction(tr("Yahoo: street overlay"), this);
//    yahooActionOverlay->setCheckable(true);
//    yahooActionOverlay->setChecked(overlay->isVisible());
//    connect(yahooActionOverlay, SIGNAL(toggled(bool)),
//            overlay, SLOT(setVisible(bool)));

//    mapproviderGroup->addAction(googleSatAction);
//    mapproviderGroup->addAction(osmAction);
//    mapproviderGroup->addAction(yahooActionOverlay);
//    mapproviderGroup->addAction(googleActionMap);
//    mapproviderGroup->addAction(yahooActionMap);
//    mapproviderGroup->addAction(yahooActionSatellite);

    // Create map provider selection menu
    mapMenu = new QMenu(this);
    mapMenu->addActions(mapproviderGroup->actions());
    mapMenu->addSeparator();
//    mapMenu->addAction(yahooActionOverlay);

    mapButton = new QPushButton(this);
    mapButton->setText("Map Source");
    mapButton->setMenu(mapMenu);
pixhawk's avatar
pixhawk committed
144 145

    // display the MapControl in the application
lm's avatar
lm committed
146
    QGridLayout* layout = new QGridLayout(this);
pixhawk's avatar
pixhawk committed
147
    layout->setMargin(0);
lm's avatar
lm committed
148 149 150 151 152 153 154 155
    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
156 157
    setLayout(layout);

158
    // create buttons to control the map (zoom, GPS tracking and WP capture)
pixhawk's avatar
pixhawk committed
159 160
    QPushButton* zoomin = new QPushButton(QIcon(":/images/actions/list-add.svg"), "", this);
    QPushButton* zoomout = new QPushButton(QIcon(":/images/actions/list-remove.svg"), "", this);
161
    createPath = new QPushButton(QIcon(":/images/actions/go-bottom.svg"), "", this);
pixhawk's avatar
pixhawk committed
162
    followgps = new QPushButton(QIcon(":/images/actions/system-lock-screen.svg"), "", this);
163

pixhawk's avatar
pixhawk committed
164 165
    zoomin->setMaximumWidth(50);
    zoomout->setMaximumWidth(50);
166
    createPath->setMaximumWidth(50);
pixhawk's avatar
pixhawk committed
167 168
    followgps->setMaximumWidth(50);

169 170 171 172 173 174 175
    // 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);

    // add buttons to control the map (zoom, GPS tracking and WP capture)
lm's avatar
lm committed
176 177 178 179 180 181 182 183 184 185 186 187
    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
188 189
    mc->setLayout(innerlayout);

190 191

    // Connect the required signals-slots
192 193 194 195 196 197
    connect(zoomin, SIGNAL(clicked(bool)),
            mc, SLOT(zoomIn()));

    connect(zoomout, SIGNAL(clicked(bool)),
            mc, SLOT(zoomOut()));

198 199
    connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)),
            this, SLOT(addUAS(UASInterface*)));
200
    connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(activeUASSet(UASInterface*)));
201 202 203 204 205

    connect(mc, SIGNAL(mouseEventCoordinate(const QMouseEvent*, const QPointF)),
            this, SLOT(captureMapClick(const QMouseEvent*, const QPointF)));

    connect(createPath, SIGNAL(clicked(bool)),
206
            this, SLOT(createPathButtonClicked(bool)));
207

208

209 210 211
    connect(geomLayer, SIGNAL(geometryClicked(Geometry*,QPoint)),
            this, SLOT(captureGeometryClick(Geometry*, QPoint)));

212 213 214 215 216
    connect(geomLayer, SIGNAL(geometryDragged(Geometry*, QPointF)),
            this, SLOT(captureGeometryDrag(Geometry*, QPointF)));

    connect(geomLayer, SIGNAL(geometryEndDrag(Geometry*, QPointF)),
            this, SLOT(captureGeometryEndDrag(Geometry*, QPointF)));
217 218 219 220 221

    // Configure the WP Path's pen
    pointPen = new QPen(QColor(0, 255,0));
    pointPen->setWidth(3);

222
    path = new qmapcontrol::LineString (wps, "UAV Path", pointPen);
lm's avatar
lm committed
223
    mc->layer("Waypoints")->addGeometry(path);
224

225 226 227 228 229 230 231 232 233 234 235 236 237
    //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);

    //camLine = new qmapcontrol::LineString(camPoints,"Camera Eje", camBorderPen);

    drawCamBorder = false;
    radioCamera = 10;



238
    this->setVisible(false);
lm's avatar
lm committed
239 240
}

241

lm's avatar
lm committed
242 243 244 245 246 247 248 249
void MapWidget::mapproviderSelected(QAction* action)
{
    //delete mapadapter;
    mapButton->setText(action->text());
    if (action == osmAction)
    {
        int zoom = mapadapter->adaptedZoom();
        mc->setZoom(0);
250

251
        mapadapter = new qmapcontrol::OSMMapAdapter();
lm's avatar
lm committed
252 253
        l->setMapAdapter(mapadapter);
        geomLayer->setMapAdapter(mapadapter);
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);
260

lm's avatar
lm committed
261 262 263 264 265 266
    }
    else if (action == yahooActionMap)
    {
        int zoom = mapadapter->adaptedZoom();
        mc->setZoom(0);

267
        mapadapter = new qmapcontrol::YahooMapAdapter();
lm's avatar
lm committed
268 269 270 271 272
        l->setMapAdapter(mapadapter);
        geomLayer->setMapAdapter(mapadapter);

        mc->updateRequestNew();
        mc->setZoom(zoom);
273
//        yahooActionOverlay->setEnabled(false);
lm's avatar
lm committed
274
        overlay->setVisible(false);
275
//        yahooActionOverlay->setChecked(false);
lm's avatar
lm committed
276 277 278 279 280 281
    }
    else if (action == yahooActionSatellite)
    {
        int zoom = mapadapter->adaptedZoom();
        QPointF a = mc->currentCoordinate();
        mc->setZoom(0);
282

283
        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
284
        l->setMapAdapter(mapadapter);
pixhawk's avatar
pixhawk committed
285

lm's avatar
lm committed
286 287
        mc->updateRequestNew();
        mc->setZoom(zoom);
288
//        yahooActionOverlay->setEnabled(true);
lm's avatar
lm committed
289 290 291 292 293
    }
    else if (action == googleActionMap)
    {
        int zoom = mapadapter->adaptedZoom();
        mc->setZoom(0);
294
        mapadapter = new qmapcontrol::GoogleMapAdapter();
lm's avatar
lm committed
295 296 297 298 299
        l->setMapAdapter(mapadapter);
        geomLayer->setMapAdapter(mapadapter);

        mc->updateRequestNew();
        mc->setZoom(zoom);
300
//        yahooActionOverlay->setEnabled(false);
lm's avatar
lm committed
301
        overlay->setVisible(false);
302
//        yahooActionOverlay->setChecked(false);
lm's avatar
lm committed
303 304 305 306 307
    }
    else if (action == googleSatAction)
    {
        int zoom = mapadapter->adaptedZoom();
        mc->setZoom(0);
308
        mapadapter = new qmapcontrol::GoogleSatMapAdapter();
lm's avatar
lm committed
309 310 311 312 313
        l->setMapAdapter(mapadapter);
        geomLayer->setMapAdapter(mapadapter); 

        mc->updateRequestNew();
        mc->setZoom(zoom);
314
//        yahooActionOverlay->setEnabled(false);
lm's avatar
lm committed
315
        overlay->setVisible(false);
316
//        yahooActionOverlay->setChecked(false);
lm's avatar
lm committed
317 318 319 320 321
    }
    else
    {
        mapButton->setText("Select..");
    }
322
}
lm's avatar
lm committed
323

lm's avatar
lm committed
324

325
void MapWidget::createPathButtonClicked(bool checked)
lm's avatar
lm committed
326
{
327 328
  Q_UNUSED(checked);

329 330


lm's avatar
lm committed
331 332 333 334
    if (createPath->isChecked())
    {
        // change the cursor shape
        this->setCursor(Qt::PointingHandCursor);
335
        mc->setMouseMode(qmapcontrol::MapControl::None);
lm's avatar
lm committed
336

337

338
        // emit signal start to create a Waypoint global
339
        emit createGlobalWP(true, mc->currentCoordinate());
340

341 342 343 344 345 346 347
//        // 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();
348 349


lm's avatar
lm committed
350
    } else {
351

lm's avatar
lm committed
352
        this->setCursor(Qt::ArrowCursor);
353
        mc->setMouseMode(qmapcontrol::MapControl::Panning);
354 355


lm's avatar
lm committed
356
    }
357

358
}
359

360 361 362 363 364 365 366
/**
 * 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
 */
367

368 369
void MapWidget::captureMapClick(const QMouseEvent* event, const QPointF coordinate)
{
370

371 372
  qDebug() << mc->mouseMode();

373 374
  if (QEvent::MouseButtonRelease == event->type() && createPath->isChecked())
    {
375 376 377
    // Create waypoint name
    QString str;

378
    str = QString("%1").arg(path->numberOfPoints());
379 380

    // create the WP and set everything in the LineString to display the path
381 382 383 384 385 386 387 388 389 390
    Waypoint2DIcon* tempCirclePoint;

    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);
    }
391 392
    mc->layer("Waypoints")->addGeometry(tempCirclePoint);

393
    qmapcontrol::Point* tempPoint = new qmapcontrol::Point(coordinate.x(), coordinate.y(),str);
394 395 396 397
    wps.append(tempPoint);
    path->addPoint(tempPoint);

    wpIndex.insert(str,tempPoint);
398

399
    // Refresh the screen
400
    mc->updateRequestNew();
401 402 403

    // emit signal mouse was clicked
    emit captureMapCoordinateClick(coordinate);
404

405
  }
pixhawk's avatar
pixhawk committed
406 407
}

408 409
void MapWidget::createWaypointGraphAtMap(const QPointF coordinate)
{
410
  if (!wpExists(coordinate)){
411 412 413
    // Create waypoint name
    QString str;

tecnosapiens's avatar
tecnosapiens committed
414

415 416 417
    str = QString("%1").arg(path->numberOfPoints());

    // create the WP and set everything in the LineString to display the path
418 419 420 421 422 423 424 425 426 427 428
    //CirclePoint* tempCirclePoint = new CirclePoint(coordinate.x(), coordinate.y(), 10, str);
    Waypoint2DIcon* tempCirclePoint;

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


431 432 433 434 435 436 437
    mc->layer("Waypoints")->addGeometry(tempCirclePoint);

    Point* tempPoint = new Point(coordinate.x(), coordinate.y(),str);
    wps.append(tempPoint);
    path->addPoint(tempPoint);

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

tecnosapiens's avatar
tecnosapiens committed
440
        // Refresh the screen
441
    mc->updateRequestNew();
442
  }
443 444 445 446 447

////    // emit signal mouse was clicked
//    emit captureMapCoordinateClick(coordinate);
}

448 449 450 451 452 453 454 455 456 457
int MapWidget::wpExists(const QPointF coordinate){
  for (int i = 0; i < wps.size(); i++){
    if (wps.at(i)->latitude() == coordinate.y() &&
        wps.at(i)->longitude()== coordinate.x()){
      return 1;
    }
  }
  return 0;
}

458

459 460
void MapWidget::captureGeometryClick(Geometry* geom, QPoint point)
{
461 462 463 464 465
  Q_UNUSED(geom);
  Q_UNUSED(point);

  mc->setMouseMode(qmapcontrol::MapControl::None);

466 467
}

468 469
void MapWidget::captureGeometryDrag(Geometry* geom, QPointF coordinate)
{
470

471

472 473
  waypointIsDrag = true;

474 475 476 477
  // Refresh the screen
  mc->updateRequestNew();

  int temp = 0;
478
  qmapcontrol::Point* point2Find;
479 480
  point2Find = wpIndex[geom->name()];

lm's avatar
lm committed
481 482 483
  if (point2Find)
  {
      point2Find->setCoordinate(coordinate);
484

485
      point2Find = dynamic_cast <qmapcontrol::Point*> (geom);
lm's avatar
lm committed
486 487 488
      if (point2Find)
      {
          point2Find->setCoordinate(coordinate);
489

lm's avatar
lm committed
490 491 492 493 494 495
          // qDebug() << geom->name();
          temp = geom->get_myIndex();
          //qDebug() << temp;
          emit sendGeometryEndDrag(coordinate,temp);
      }
  }
496

497 498
}

499
void MapWidget::captureGeometryEndDrag(Geometry* geom, QPointF coordinate)
500 501
{

502 503 504 505 506
  // TODO: Investigate why when creating the waypoint path this slot is being called

  // Only change the mouse mode back to panning when not creating a WP path
  if (!createPath->isChecked()){
    waypointIsDrag = false;
507
    mc->setMouseMode(qmapcontrol::MapControl::Panning);
508
  }
509

510 511
}

pixhawk's avatar
pixhawk committed
512 513 514 515
MapWidget::~MapWidget()
{
    delete m_ui;
}
lm's avatar
lm committed
516 517 518 519 520 521
/**
 *
 * @param uas the UAS/MAV to monitor/display with the HUD
 */
void MapWidget::addUAS(UASInterface* uas)
{
522
    connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64)));
lm's avatar
lm committed
523 524
}

525 526 527 528 529 530 531 532 533
void MapWidget::activeUASSet(UASInterface* uas)
{
    if (uas)
    {
        mav = uas;
        path->setPen(new QPen(mav->getColor()));
    }
}

lm's avatar
lm committed
534 535 536 537 538 539 540 541 542
/**
 * 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
543 544 545
void MapWidget::updateGlobalPosition(UASInterface* uas, double lat, double lon, double alt, quint64 usec)
{
    Q_UNUSED(usec);
546
    Q_UNUSED(alt); // FIXME Use altitude
pixhawk's avatar
pixhawk committed
547
    quint64 currTime = MG::TIME::getGroundTimeNow();
548
    if (currTime - lastUpdate > 90)
pixhawk's avatar
pixhawk committed
549 550
    {
        lastUpdate = currTime;
551 552 553 554 555 556 557 558 559 560 561 562 563 564
        // 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));

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

            // Icon
            QPen* pointpen = new QPen(uasColor);
565
            qDebug() << uas->getUASName();
566
            MAV2DIcon* p = new MAV2DIcon(lat, lon, 20, uas->getUASName(), qmapcontrol::Point::Middle, pointpen);
567
            uasIcons.insert(uas->getUASID(), p);
lm's avatar
lm committed
568
            geomLayer->addGeometry(p);
569 570 571 572

            // Line
            // A QPen also can use transparency

573 574
            QList<qmapcontrol::Point*> points;
            points.append(new qmapcontrol::Point(lat, lon, QString("lat: %1 lon: %2").arg(lat, lon)));
575 576 577
            QPen* linepen = new QPen(uasColor.darker());
            linepen->setWidth(2);
            // Add the Points and the QPen to a LineString
578
            qmapcontrol::LineString* ls = new qmapcontrol::LineString(points, uas->getUASName(), linepen);
579 580 581
            uasTrails.insert(uas->getUASID(), ls);

            // Add the LineString to the layer
lm's avatar
lm committed
582
            geomLayer->addGeometry(ls);
583 584 585
        }
        else
        {
586 587 588 589 590 591
            MAV2DIcon* p = dynamic_cast<MAV2DIcon*>(uasIcons.value(uas->getUASID()));
            if (p)
            {
                p->setCoordinate(QPointF(lat, lon));
                p->setYaw(uas->getYaw());
            }
592
            // Extend trail
593
            uasTrails.value(uas->getUASID())->addPoint(new qmapcontrol::Point(lat, lon, QString("lat: %1 lon: %2").arg(lat, lon)));
594 595 596 597 598 599 600 601 602
        }

        //    points.append(new CirclePoint(8.275145, 50.016992, 15, "Wiesbaden-Mainz-Kastel, Johannes-Goßner-Straße", Point::Middle, pointpen));
        //    points.append(new CirclePoint(8.270476, 50.021426, 15, "Wiesbaden-Mainz-Kastel, Ruthof", Point::Middle, pointpen));
        //    // "Blind" Points
        //    points.append(new Point(8.266445, 50.025913, "Wiesbaden-Mainz-Kastel, Mudra Kaserne"));
        //    points.append(new Point(8.260378, 50.030345, "Wiesbaden-Mainz-Amoneburg, Dyckerhoffstraße"));

        // Connect click events of the layer to this object
603
        // connect(osmLayer, SIGNAL(geometryClicked(Geometry*, QPoint)),
604 605 606 607 608 609 610 611
        //                  this, SLOT(geometryClicked(Geometry*, QPoint)));

        // Sets the view to the interesting area
        //QList<QPointF> view;
        //view.append(QPointF(8.24764, 50.0319));
        //view.append(QPointF(8.28412, 49.9998));
        // mc->setView(view);
        updatePosition(0, lat, lon);
pixhawk's avatar
pixhawk committed
612 613
    }
}
pixhawk's avatar
pixhawk committed
614

lm's avatar
lm committed
615 616 617
/**
 * Center the view on this position
 */
lm's avatar
lm committed
618
void MapWidget::updatePosition(float time, double lat, double lon)
pixhawk's avatar
pixhawk committed
619
{
lm's avatar
lm committed
620
    Q_UNUSED(time);
621
    //gpsposition->setText(QString::number(time) + " / " + QString::number(lat) + " / " + QString::number(lon));
pixhawk's avatar
pixhawk committed
622 623
    if (followgps->isChecked())
    {
lm's avatar
lm committed
624
        mc->setView(QPointF(lat, lon));
pixhawk's avatar
pixhawk committed
625 626 627 628 629 630 631 632 633 634 635 636 637 638
    }
}

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));
639 640 641 642

    // visual field of camera
     updateCameraPosition(20*newZoom,0,"no");

pixhawk's avatar
pixhawk committed
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
}

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

671
void MapWidget::resizeEvent(QResizeEvent* event )
pixhawk's avatar
pixhawk committed
672
{
673 674
    Q_UNUSED(event);
    mc->resize(this->size());
pixhawk's avatar
pixhawk committed
675 676 677 678 679 680 681 682 683 684 685 686 687 688
}


void MapWidget::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
689 690 691 692 693 694 695 696 697 698
void MapWidget::clearPath()
{
    // Clear the previous WP track

    mc->layer("Waypoints")->clearGeometries();
    wps.clear();
    path->setPoints(wps);
    mc->layer("Waypoints")->addGeometry(path);
    wpIndex.clear();
    mc->updateRequestNew();
699

700

701 702 703 704 705
    if(createPath->isChecked())
    {
        createPath->click();
    }

706
}
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731

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

        QPointF coordinate;
        coordinate.setX(lon);
        coordinate.setY(lat);

        Point* point2Find;
        point2Find = wpIndex[QString::number(index)];
        point2Find->setCoordinate(coordinate);

        point2Find = dynamic_cast <Point*> (mc->layer("Waypoints")->get_Geometry(index));
        point2Find->setCoordinate(coordinate);

        // Refresh the screen
        mc->updateRequestNew();
   }


}

732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
void MapWidget::updateCameraPosition(double radio, double bearing, QString dir)
{
    //camPoints.clear();
    QPointF currentPos = mc->currentCoordinate();
//    QPointF actualPos = getPointxBearing_Range(currentPos.y(),currentPos.x(),bearing,distance);

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

//    camPoints.append(tempPoint1);
//    camPoints.append(tempPoint2);

//    camLine->setPoints(camPoints);

     QPen* camBorderPen = new QPen(QColor(255,0,0));
    camBorderPen->setWidth(2);

    //radio = mc->currentZoom()

    if(drawCamBorder)
    {
        //clear camera borders
        mc->layer("Camera")->clearGeometries();

        //create a camera borders
        qmapcontrol::CirclePoint* camBorder = new qmapcontrol::CirclePoint(currentPos.x(), currentPos.y(), radio, "camBorder", qmapcontrol::Point::Middle, camBorderPen);

       //camBorder->setCoordinate(currentPos);

        mc->layer("Camera")->addGeometry(camBorder);
       // mc->layer("Camera")->addGeometry(camLine);
        mc->updateRequestNew();

    }
   else
   {
       //clear camera borders
       mc->layer("Camera")->clearGeometries();
       mc->updateRequestNew();

   }


}

void MapWidget::drawBorderCamAtMap(bool status)
{
    drawCamBorder = status;
    updateCameraPosition(20,0,"no");

}

QPointF MapWidget::getPointxBearing_Range(double lat1, double lon1, double bearing, double distance)
{
    QPointF temp;

    double rad = M_PI/180;

    bearing = bearing*rad;
    temp.setX((lon1 + ((distance/60) * (sin(bearing)))));
    temp.setY((lat1 + ((distance/60) * (cos(bearing)))));

    return temp;
}