dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
opmapgadgetwidget.cpp
Go to the documentation of this file.
1 
15 /*
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful, but
22  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24  * for more details.
25  *
26  * You should have received a copy of the GNU General Public License along
27  * with this program; if not, see <http://www.gnu.org/licenses/>
28  *
29  * Additional note on redistribution: The copyright and license notices above
30  * must be maintained in each individual source file that is a derivative work
31  * of this source file; otherwise redistribution is prohibited.
32  */
33 
34 #include "opmapgadgetwidget.h"
35 #include "ui_opmap_widget.h"
36 #include <QInputDialog>
37 #include <QApplication>
38 #include <QHBoxLayout>
39 #include <QVBoxLayout>
40 #include <QClipboard>
41 #include <QMenu>
42 #include <QStringList>
43 #include <QDir>
44 #include <QFile>
45 #include <QDateTime>
46 
47 #include <math.h>
48 
49 #include "utils/homelocationutil.h"
50 #include "utils/worldmagmodel.h"
51 
53 #include "uavobjects/uavobject.h"
54 
55 #include "positionactual.h"
56 #include "homelocation.h"
57 #include "gpsposition.h"
58 #include "gyros.h"
59 #include "attitudeactual.h"
60 #include "positionactual.h"
61 #include "velocityactual.h"
62 #include "windvelocityactual.h"
63 
64 #include "../pathplanner/pathplannergadgetwidget.h"
65 #include "../pathplanner/waypointdialog.h"
66 
67 // *************************************************************************************
68 
69 #define deg_to_rad ((double)M_PI / 180.0)
70 #define rad_to_deg (180.0 / (double)M_PI)
71 
72 #define earth_mean_radius 6371 // kilometers
73 
74 #define max_digital_zoom 3 // maximum allowed digital zoom level
75 
76 const int safe_area_radius_list[] = { 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000 }; // meters
77 
78 const int uav_trail_time_list[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // seconds
79 
80 const int uav_trail_distance_list[] = { 1, 2, 5, 10, 20, 50, 100, 200, 500 }; // meters
81 
82 const int max_update_rate_list[] = { 100, 200, 500, 1000, 2000, 5000 }; // milliseconds
83 
84 // *************************************************************************************
85 
86 // *************************************************************************************
87 // NOTE: go back to SVN REV 2137 and earlier to get back to experimental waypoint support.
88 // *************************************************************************************
89 
90 // constructor
92  : QFrame(parent)
93 {
94  // **************
95 
96  m_widget = NULL;
97  m_map = NULL;
98  findPlaceCompleter = NULL;
99 
100  m_mouse_waypoint = NULL;
101 
102  pm = NULL;
103  uavo_mgr = NULL;
104  uavo_util_mgr = NULL;
105 
106  m_prev_tile_number = 0;
107 
108  m_min_zoom = m_max_zoom = 0;
109 
110  m_map_mode = Normal_MapMode;
111 
112  m_maxUpdateRate =
113  max_update_rate_list[4]; // 2 seconds //SHOULDN'T THIS BE LOADED FROM THE USER PREFERENCES?
114 
115  m_telemetry_connected = false;
116 
117  m_context_menu_lat_lon = m_mouse_lat_lon = internals::PointLatLng(0, 0);
118 
119  setMouseTracking(true);
120 
121  pm = ExtensionSystem::PluginManager::instance();
122  if (pm) {
123  uavo_mgr = pm->getObject<UAVObjectManager>();
124  uavo_util_mgr = pm->getObject<UAVObjectUtilManager>();
125  }
126 
127  // **************
128  // get current location
129 
130  double latitude = 0;
131  double longitude = 0;
132  double altitude = 0;
133 
134  // current position
135  getUAVPosition(latitude, longitude, altitude);
136 
137  internals::PointLatLng pos_lat_lon = internals::PointLatLng(latitude, longitude);
138 
139  // **************
140  // default home position
141 
142  m_home_position.coord = pos_lat_lon;
143  m_home_position.altitude = altitude;
144  m_home_position.locked = false;
145 
146  // **************
147  // create the widget that holds the user controls and the map
148 
149  m_widget = new Ui::OPMap_Widget();
150  m_widget->setupUi(this);
151 
152  // **************
153  // create the central map widget
154 
155  m_map = new mapcontrol::TLMapWidget(); // create the map object
156 
157  m_map->setFrameStyle(QFrame::NoFrame); // no border frame
158 
159  m_map->configuration->DragButton = Qt::LeftButton; // use the left mouse button for map dragging
160 
161  m_widget->horizontalSliderZoom->setMinimum(m_map->MinZoom()); //
162  m_widget->horizontalSliderZoom->setMaximum(m_map->MaxZoom() + max_digital_zoom); //
163 
164  m_min_zoom = m_widget->horizontalSliderZoom->minimum(); // minimum zoom we can accept
165  m_max_zoom = m_widget->horizontalSliderZoom->maximum(); // maximum zoom we can accept
166 
167  m_map->SetMouseWheelZoomType(
168  internals::MouseWheelZoomType::MousePositionWithoutCenter); // set how the mouse wheel zoom
169  // functions
170  m_map->SetFollowMouse(true); // we want a contiuous mouse position reading
171 
172  m_map->SetShowHome(true); // display the HOME position on the map
173  m_map->SetShowUAV(true); // display the UAV position on the map
174 
175  m_map->Home->SetSafeArea(
176  safe_area_radius_list[0]); // set radius (meters) //SHOULDN'T THE DEFAULT BE USER DEFINED?
177  m_map->Home->SetShowSafeArea(
178  true); // show the safe area //SHOULDN'T THE DEFAULT BE USER DEFINED?
179  m_map->Home->SetToggleRefresh(true);
180 
181  if (m_map->Home)
182  connect(m_map->Home, &mapcontrol::HomeItem::homedoubleclick, this,
183  &OPMapGadgetWidget::onHomeDoubleClick);
184  m_map->UAV->SetTrailTime(uav_trail_time_list[0]); // seconds
185  m_map->UAV->SetTrailDistance(uav_trail_distance_list[1]); // meters
186 
187  m_map->UAV->SetTrailType(UAVTrailType::ByTimeElapsed);
188  if (m_map->GPS) {
189  m_map->GPS->SetTrailTime(uav_trail_time_list[0]); // seconds
190  m_map->GPS->SetTrailDistance(uav_trail_distance_list[1]); // meters
191 
192  m_map->GPS->SetTrailType(UAVTrailType::ByTimeElapsed);
193  }
194  // **************
195 
196  setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
197 
198  QVBoxLayout *layout = new QVBoxLayout;
199  layout->setSpacing(0);
200  layout->setContentsMargins(0, 0, 0, 0);
201  layout->addWidget(m_map);
202  m_widget->mapWidget->setLayout(layout);
203 
204  m_widget->toolButtonMagicWaypointMapMode->setChecked(false);
205  m_widget->toolButtonNormalMapMode->setChecked(true);
206  hideMagicWaypointControls();
207 
208  m_widget->labelUAVPos->setText("---");
209  m_widget->labelMapPos->setText("---");
210  m_widget->labelMousePos->setText("---");
211  m_widget->labelMapZoom->setText("---");
212  m_widget->labelNEDCoords->setText("---");
213 
214  m_widget->progressBarMap->setMaximum(1);
215 
216  connect(m_map, &mapcontrol::TLMapWidget::zoomChanged, this,
217  &OPMapGadgetWidget::zoomChanged); // map zoom change signals
219  &OPMapGadgetWidget::OnCurrentPositionChanged); // map poisition change signals
220  connect(m_map, &mapcontrol::TLMapWidget::OnTileLoadComplete, this,
221  &OPMapGadgetWidget::OnTileLoadComplete); // tile loading stop signals
222  connect(m_map, &mapcontrol::TLMapWidget::OnTileLoadStart, this,
223  &OPMapGadgetWidget::OnTileLoadStart); // tile loading start signals
224  connect(m_map, &mapcontrol::TLMapWidget::OnTilesStillToLoad, this,
225  &OPMapGadgetWidget::OnTilesStillToLoad); // tile loading signals
227  &OPMapGadgetWidget::wpDoubleClickEvent);
228  m_map->SetCurrentPosition(m_home_position.coord); // set the map position
229  m_map->Home->SetCoord(m_home_position.coord); // set the HOME position
230  m_map->UAV->SetUAVPos(m_home_position.coord, 0.0); // set the UAV position
231  m_map->UAV->update();
232  if (m_map->GPS)
233  m_map->GPS->SetUAVPos(m_home_position.coord, 0.0); // set the GPS position
234 
235  // Connect to the existing model
236  ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
237  model = pm->getObject<FlightDataModel>();
238  Q_ASSERT(model);
239 
240  // Get the path planner selection model to keep the gadget in sync with the map
241  selectionModel = pm->getObject<QItemSelectionModel>();
242  Q_ASSERT(selectionModel);
243  mapProxy = new ModelMapProxy(this, m_map, model, selectionModel);
244 
245  magicWayPoint = m_map->magicWPCreate();
246  magicWayPoint->setVisible(false);
247 
248  m_map->setOverlayOpacity(0.5);
249 
250  // **************
251  // create various context menu (mouse right click menu) actions
252 
253  createActions();
254 
255  // **************
256  // connect to the UAVObject updates we require to become a bit aware of our environment:
257 
258  if (pm) {
259  // Register for Home Location state changes
260  if (uavo_mgr) {
261  UAVDataObject *obj =
262  dynamic_cast<UAVDataObject *>(uavo_mgr->getObject(QString("HomeLocation")));
263  if (obj) {
264  connect(obj, &UAVObject::objectUpdated, this,
266  }
267  }
268 
269  // Listen to telemetry connection events
270  TelemetryManager *telMngr = pm->getObject<TelemetryManager>();
271  if (telMngr) {
272  connect(telMngr, &TelemetryManager::connected, this,
274  connect(telMngr, &TelemetryManager::disconnected, this,
276  }
277  }
278 
279  // Update the home location if it is already set:
280  if (uavo_util_mgr) {
281  bool set;
282  double LLA[3];
283  if (uavo_util_mgr->getHomeLocation(set, LLA) == 0) {
284  if (set)
285  setHome(internals::PointLatLng(LLA[0], LLA[1]), LLA[2]);
286  }
287  }
288 
289  // **************
290  // create the desired timers
291 
292  m_updateTimer = new QTimer();
293  m_updateTimer->setInterval(m_maxUpdateRate);
294  connect(m_updateTimer, &QTimer::timeout, this, &OPMapGadgetWidget::updatePosition);
295  m_updateTimer->start();
296 
297  m_statusUpdateTimer = new QTimer();
298  m_statusUpdateTimer->setInterval(200);
299  connect(m_statusUpdateTimer, &QTimer::timeout, this, &OPMapGadgetWidget::updateMousePos);
300  m_statusUpdateTimer->start();
301  // **************
302 
303  // Connect windspeed update
304  WindVelocityActual *windVelocityActual = WindVelocityActual::GetInstance(uavo_mgr);
305  connect(windVelocityActual, &UAVObject::objectUpdated, this,
306  &OPMapGadgetWidget::updateWindspeed);
307 
308  m_map->setFocus();
309 }
310 
311 // destructor
313 {
314  if (m_map) {
315  disconnect(m_map, nullptr, nullptr, nullptr);
316  m_map->SetShowHome(false); // doing this appears to stop the map lib crashing on exit
317  m_map->SetShowUAV(false); // " "
318  }
319 
320  if (m_map) {
321  delete m_map;
322  m_map = NULL;
323  }
324 
325  if (!mapProxy.isNull())
326  delete mapProxy;
327 }
328 
329 // *************************************************************************************
330 // widget signals .. the mouseMoveEvent does not get called - don't yet know why
331 
332 void OPMapGadgetWidget::resizeEvent(QResizeEvent *event)
333 {
334  QWidget::resizeEvent(event);
335 }
336 
337 void OPMapGadgetWidget::mouseMoveEvent(QMouseEvent *event)
338 {
339  if (m_widget && m_map) {
340  }
341 
342  if (event->buttons() & Qt::LeftButton) {
343  }
344  QWidget::mouseMoveEvent(event);
345 }
346 void OPMapGadgetWidget::wpDoubleClickEvent(WayPointItem *wp)
347 {
348  m_mouse_waypoint = wp;
349  onEditWayPointAct_triggered();
350 }
351 
352 void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
353 { // the user has right clicked on the map - create the pop-up context menu and display it
354 
355  QString s;
356 
357  if (!m_widget || !m_map)
358  return;
359 
360  if (event->reason() != QContextMenuEvent::Mouse)
361  return; // not a mouse click event
362 
363  // current mouse position
364  QPoint p = m_map->mapFromGlobal(event->globalPos());
365  m_context_menu_lat_lon = m_map->GetFromLocalToLatLng(p);
366 
367  if (!m_map->contentsRect().contains(p))
368  return; // the mouse click was not on the map
369 
370  // show the mouse position
371  s = QString::number(m_context_menu_lat_lon.Lat(), 'f', 7) + " "
372  + QString::number(m_context_menu_lat_lon.Lng(), 'f', 7);
373  m_widget->labelMousePos->setText(s);
374 
375  // find out if we have a waypoint under the mouse cursor
376  QGraphicsItem *item = m_map->itemAt(p);
377  m_mouse_waypoint = qgraphicsitem_cast<mapcontrol::WayPointItem *>(item);
378 
379  // find out if the waypoint is locked (or not)
380  bool waypoint_locked = false;
381  if (m_mouse_waypoint)
382  waypoint_locked = (m_mouse_waypoint->flags() & QGraphicsItem::ItemIsMovable) == 0;
383 
384  // ****************
385  // Dynamically create the popup menu
386  QMenu contextMenu;
387  contextMenu.addAction(closeAct1);
388  contextMenu.addSeparator();
389  contextMenu.addAction(reloadAct);
390  contextMenu.addSeparator();
391  contextMenu.addAction(ripAct);
392  contextMenu.addSeparator();
393 
394  QMenu maxUpdateRateSubMenu(
395  tr("&Max Update Rate ") + "(" + QString::number(m_maxUpdateRate) + " ms)", this);
396  for (int i = 0; i < maxUpdateRateAct.count(); i++)
397  maxUpdateRateSubMenu.addAction(maxUpdateRateAct.at(i));
398  contextMenu.addMenu(&maxUpdateRateSubMenu);
399 
400  contextMenu.addSeparator();
401 
402  switch (m_map_mode) {
403  case Normal_MapMode:
404  s = tr(" (Normal)");
405  break;
407  s = tr(" (Magic Waypoint)");
408  break;
409  default:
410  s = tr(" (Unknown)");
411  break;
412  }
413  for (int i = 0; i < mapModeAct.count(); i++) { // set the menu to checked (or not)
414  QAction *act = mapModeAct.at(i);
415  if (!act)
416  continue;
417  if (act->data().toInt() == (int)m_map_mode)
418  act->setChecked(true);
419  }
420  QMenu mapModeSubMenu(tr("Map mode") + s, this);
421  for (int i = 0; i < mapModeAct.count(); i++)
422  mapModeSubMenu.addAction(mapModeAct.at(i));
423  contextMenu.addMenu(&mapModeSubMenu);
424 
425  contextMenu.addSeparator();
426 
427  QMenu copySubMenu(tr("Copy"), this);
428  copySubMenu.addAction(copyMouseLatLonToClipAct);
429  copySubMenu.addAction(copyMouseLatToClipAct);
430  copySubMenu.addAction(copyMouseLonToClipAct);
431  contextMenu.addMenu(&copySubMenu);
432 
433  contextMenu.addSeparator();
434  contextMenu.addAction(changeDefaultLocalAndZoom);
435  contextMenu.addSeparator();
436 
437  QMenu safeArea("Safety Area definitions");
438  // menu.addAction(showSafeAreaAct);
439  QMenu safeAreaSubMenu(
440  tr("Safe Area Radius") + " (" + QString::number(m_map->Home->SafeArea()) + "m)", this);
441  for (int i = 0; i < safeAreaAct.count(); i++)
442  safeAreaSubMenu.addAction(safeAreaAct.at(i));
443  safeArea.addMenu(&safeAreaSubMenu);
444  safeArea.addAction(showSafeAreaAct);
445  contextMenu.addMenu(&safeArea);
446 
447  contextMenu.addSeparator();
448 
449  contextMenu.addAction(showCompassRoseAct);
450  contextMenu.addAction(showWindCompassAction);
451 
452  contextMenu.addAction(showDiagnostics);
453 
454  contextMenu.addAction(showUAVInfo);
455 
456  contextMenu.addSeparator()->setText(tr("Zoom"));
457 
458  contextMenu.addAction(zoomInAct);
459  contextMenu.addAction(zoomOutAct);
460 
461  QMenu zoomSubMenu(tr("&Zoom ") + "(" + QString::number(m_map->ZoomTotal()) + ")", this);
462  for (int i = 0; i < zoomAct.count(); i++)
463  zoomSubMenu.addAction(zoomAct.at(i));
464  contextMenu.addMenu(&zoomSubMenu);
465 
466  contextMenu.addSeparator();
467 
468  contextMenu.addAction(goMouseClickAct);
469 
470  contextMenu.addSeparator()->setText(tr("HOME"));
471 
472  contextMenu.addAction(setHomeAct);
473  contextMenu.addAction(showHomeAct);
474  contextMenu.addAction(goHomeAct);
475 
476  // ****
477  // uav trails
478  QMenu uav_menu(tr("UAV"));
479  uav_menu.addSeparator()->setText(tr("UAV Trail"));
480  contextMenu.addMenu(&uav_menu);
481  QMenu uavTrailTypeSubMenu(
482  tr("UAV trail type") + " ("
483  + mapcontrol::Helper::StrFromUAVTrailType(m_map->UAV->GetTrailType()) + ")",
484  this);
485  for (int i = 0; i < uavTrailTypeAct.count(); i++)
486  uavTrailTypeSubMenu.addAction(uavTrailTypeAct.at(i));
487  uav_menu.addMenu(&uavTrailTypeSubMenu);
488 
489  QMenu uavTrailTimeSubMenu(
490  tr("UAV trail time") + " (" + QString::number(m_map->UAV->TrailTime()) + " sec)", this);
491  for (int i = 0; i < uavTrailTimeAct.count(); i++)
492  uavTrailTimeSubMenu.addAction(uavTrailTimeAct.at(i));
493  uav_menu.addMenu(&uavTrailTimeSubMenu);
494 
495  QMenu uavTrailDistanceSubMenu(tr("UAV trail distance") + " ("
496  + QString::number(m_map->UAV->TrailDistance()) + " meters)",
497  this);
498  for (int i = 0; i < uavTrailDistanceAct.count(); i++)
499  uavTrailDistanceSubMenu.addAction(uavTrailDistanceAct.at(i));
500  uav_menu.addMenu(&uavTrailDistanceSubMenu);
501 
502  uav_menu.addAction(showTrailAct);
503 
504  uav_menu.addAction(showTrailLineAct);
505 
506  uav_menu.addAction(clearUAVtrailAct);
507 
508  // ****
509 
510  uav_menu.addSeparator()->setText(tr("UAV"));
511 
512  uav_menu.addAction(showUAVAct);
513  uav_menu.addAction(followUAVpositionAct);
514  uav_menu.addAction(followUAVheadingAct);
515  uav_menu.addAction(goUAVAct);
516 
517  // *********
518  switch (m_map_mode) {
519  case Normal_MapMode:
520  // only show the waypoint stuff if not in 'magic waypoint' mode
521 
522  contextMenu.addSeparator()->setText(tr("Waypoints"));
523 
524  contextMenu.addAction(wayPointEditorAct);
525  contextMenu.addAction(addWayPointActFromContextMenu);
526 
527  if (m_mouse_waypoint) { // we have a waypoint under the mouse
528  contextMenu.addAction(editWayPointAct);
529 
530  lockWayPointAct->setChecked(waypoint_locked);
531  contextMenu.addAction(lockWayPointAct);
532 
533  if (!waypoint_locked)
534  contextMenu.addAction(deleteWayPointAct);
535  }
536 
537  if (m_map->WPPresent())
538  contextMenu.addAction(clearWayPointsAct); // we have waypoints
539 
540  break;
541 
543  contextMenu.addSeparator()->setText(tr("Waypoints"));
544  contextMenu.addAction(homeMagicWaypointAct);
545  break;
546  }
547  // *********
548 
549  QMenu overlaySubMenu(tr("&Overlay Opacity "), this);
550  for (int i = 0; i < overlayOpacityAct.count(); i++)
551  overlaySubMenu.addAction(overlayOpacityAct.at(i));
552  contextMenu.addMenu(&overlaySubMenu);
553  contextMenu.addSeparator();
554 
555  contextMenu.addAction(closeAct2);
556 
557  contextMenu.exec(event->globalPos()); // popup the menu
558 
559  // ****************
560 }
561 
562 void OPMapGadgetWidget::closeEvent(QCloseEvent *event)
563 {
564  QWidget::closeEvent(event);
565 }
566 
567 // *************************************************************************************
568 // timer signals
569 
574 void OPMapGadgetWidget::updatePosition()
575 {
576  double uav_latitude, uav_longitude, uav_altitude, uav_yaw;
577  double gps_latitude, gps_longitude, gps_altitude, gps_heading;
578 
579  internals::PointLatLng uav_pos;
580  internals::PointLatLng gps_pos;
581 
582  if (!m_widget || !m_map)
583  return;
584 
585  // *************
586  // get the current UAV details
587 
588  // get current UAV position
589  if (!getUAVPosition(uav_latitude, uav_longitude, uav_altitude))
590  return;
591 
592  // get current UAV heading
593  uav_yaw = getUAV_Yaw();
594 
595  uav_pos = internals::PointLatLng(uav_latitude, uav_longitude);
596 
597  // *************
598  // Load GPSPosition UAVO
599  GPSPosition *gpsPositionObj = GPSPosition::GetInstance(uavo_mgr);
600  Q_ASSERT(gpsPositionObj);
601 
602  GPSPosition::DataFields gpsPositionData = gpsPositionObj->getData();
603 
604  // get current GPS heading, latitude, longitude, and altitude
605  gps_heading = gpsPositionData.Heading;
606  gps_latitude = gpsPositionData.Latitude;
607  gps_longitude = gpsPositionData.Longitude;
608  gps_altitude = gpsPositionData.Altitude;
609 
610  gps_pos = internals::PointLatLng(gps_latitude, gps_longitude);
611 
612  //**********************
613  // get the current position and heading estimates
614  AttitudeActual *attitudeActualObj = AttitudeActual::GetInstance(uavo_mgr);
615  PositionActual *positionActualObj = PositionActual::GetInstance(uavo_mgr);
616  VelocityActual *velocityActualObj = VelocityActual::GetInstance(uavo_mgr);
617  Gyros *gyrosObj = Gyros::GetInstance(uavo_mgr);
618 
619  Q_ASSERT(attitudeActualObj);
620  Q_ASSERT(positionActualObj);
621  Q_ASSERT(velocityActualObj);
622  Q_ASSERT(gyrosObj);
623 
624  AttitudeActual::DataFields attitudeActualData = attitudeActualObj->getData();
625  PositionActual::DataFields positionActualData = positionActualObj->getData();
626  VelocityActual::DataFields velocityActualData = velocityActualObj->getData();
627  Gyros::DataFields gyrosData = gyrosObj->getData();
628 
629  double NED[3] = { positionActualData.North, positionActualData.East, positionActualData.Down };
630  double vNED[3] = { velocityActualData.North, velocityActualData.East, velocityActualData.Down };
631 
632  // Set the position and heading estimates in the painter module
633  m_map->UAV->SetNED(NED);
634  m_map->UAV->SetCAS(-1); // THIS NEEDS TO BECOME AIRSPEED, ONCE WE SETTLE ON A UAVO
635  m_map->UAV->SetGroundspeed(vNED, m_maxUpdateRate);
636 
637  // Convert angular velocities into a rotationg rate around the world-frame yaw axis. This is
638  // found by simply taking the dot product of the angular Euler-rate matrix with the angular
639  // rates.
640  float psiRate_dps = 0 * gyrosData.z
641  + sin(attitudeActualData.Roll * deg_to_rad) / cos(attitudeActualData.Pitch * deg_to_rad)
642  * gyrosData.y
643  + cos(attitudeActualData.Roll * deg_to_rad) / cos(attitudeActualData.Pitch * deg_to_rad)
644  * gyrosData.z;
645 
646  // Set the angular rate in the painter module
647  m_map->UAV->SetYawRate(psiRate_dps); // Not correct, but I'm being lazy right now.
648 
649  // *************
650  // display the UAV position
651 
652  QString str = "lat: " + QString::number(uav_pos.Lat(), 'f', 7) + " lon: "
653  + QString::number(uav_pos.Lng(), 'f', 7) + " " + QString::number(uav_yaw, 'f', 1) + "deg"
654  + " " + QString::number(uav_altitude, 'f', 1) + "m";
655  // " " + QString::number(uav_ground_speed_meters_per_second, 'f', 1) + "m/s";
656  m_widget->labelUAVPos->setText(str);
657 
658  // *************
659  // set the UAV icon position on the map
660 
661  m_map->UAV->SetUAVPos(uav_pos, uav_altitude); // set the maps UAV position
662  // qDebug()<<"UAVPOSITION"<<uav_pos.ToString();
663  m_map->UAV->SetUAVHeading(uav_yaw); // set the maps UAV heading
664 
665  // *************
666  // set the GPS icon position on the map
667  if (m_map->GPS) {
668  m_map->GPS->SetUAVPos(gps_pos, gps_altitude); // set the maps GPS position
669  m_map->GPS->SetUAVHeading(gps_heading); // set the maps GPS heading
670  }
671  m_map->UAV->updateTextOverlay();
672  m_map->UAV->update();
673  // *************
674 }
675 
680 void OPMapGadgetWidget::updateMousePos()
681 {
682  if (!m_widget || !m_map)
683  return;
684 
685  QPoint p = m_map->mapFromGlobal(QCursor::pos());
686  internals::PointLatLng lat_lon =
687  m_map->GetFromLocalToLatLng(p); // fetch the current lat/lon mouse position
688  lastLatLngMouse = lat_lon;
689  if (!m_map->contentsRect().contains(p))
690  return; // the mouse is not on the map
691 
692  QGraphicsItem *item = m_map->itemAt(p);
693 
694  // find out if we are over the home position
695  mapcontrol::HomeItem *home = qgraphicsitem_cast<mapcontrol::HomeItem *>(item);
696 
697  // find out if we have a waypoint under the mouse cursor
698  mapcontrol::WayPointItem *wp = qgraphicsitem_cast<mapcontrol::WayPointItem *>(item);
699 
700  if (m_mouse_lat_lon == lat_lon)
701  return; // the mouse has not moved
702 
703  m_mouse_lat_lon = lat_lon; // yes it has!
704 
705  internals::PointLatLng home_lat_lon = m_map->Home->Coord();
706 
707  QString s1 = QString::number(m_mouse_lat_lon.Lat(), 'f', 7) + " "
708  + QString::number(m_mouse_lat_lon.Lng(), 'f', 7);
709  if (wp) {
710  s1 += " wp[" + QString::number(wp->numberAdjusted()) + "]";
711 
712  double dist = distance(home_lat_lon, wp->Coord());
713  double bear = bearing(home_lat_lon, wp->Coord());
714  s1 += " " + QString::number(dist * 1000, 'f', 1) + "m";
715  s1 += " " + QString::number(bear, 'f', 1) + "deg";
716  } else if (home) {
717  s1 += " home";
718 
719  double dist = distance(home_lat_lon, m_mouse_lat_lon);
720  double bear = bearing(home_lat_lon, m_mouse_lat_lon);
721  s1 += " " + QString::number(dist * 1000, 'f', 1) + "m";
722  s1 += " " + QString::number(bear, 'f', 1) + "deg";
723  }
724  m_widget->labelMousePos->setText(s1);
725 
726  double NED[3];
727  double homeLLA[3] = { home_lat_lon.Lat(), home_lat_lon.Lng(), 0 };
728  double LLA[3] = { m_mouse_lat_lon.Lat(), m_mouse_lat_lon.Lng(), 0 };
729  Utils::CoordinateConversions().LLA2NED_HomeLLA(LLA, homeLLA, NED); //<-- This yields, NED, the
730  //tile size in meters,
731  //assuming we are at the
732  //origin in a plate carre
733  //system
734  QString s2 = QString::number(NED[0], 'g', 5) + " " + QString::number(NED[1], 'g', 5);
735  m_widget->labelNEDCoords->setText(s2);
736 }
737 
738 // *************************************************************************************
739 // map signals
740 
744 void OPMapGadgetWidget::zoomChanged(double zoomt, double zoom, double zoomd)
745 {
746  if (!m_widget || !m_map)
747  return;
748 
749  QString s = "tot:" + QString::number(zoomt, 'f', 1) + " rea:" + QString::number(zoom, 'f', 1)
750  + " dig:" + QString::number(zoomd, 'f', 1);
751  m_widget->labelMapZoom->setText(s);
752 
753  int i_zoom = (int)(zoomt + 0.5);
754 
755  if (i_zoom < m_min_zoom)
756  i_zoom = m_min_zoom;
757  else if (i_zoom > m_max_zoom)
758  i_zoom = m_max_zoom;
759 
760  if (m_widget->horizontalSliderZoom->value() != i_zoom)
761  m_widget->horizontalSliderZoom->setValue(i_zoom); // set the GUI zoom slider position
762 
763  int index0_zoom = i_zoom - m_min_zoom; // zoom level starting at index level '0'
764  if (index0_zoom < zoomAct.count())
765  zoomAct.at(index0_zoom)->setChecked(true); // set the right-click context menu zoom level
766 }
767 
768 void OPMapGadgetWidget::OnCurrentPositionChanged(internals::PointLatLng point)
769 {
770  if (!m_widget || !m_map)
771  return;
772 
773  QString coord_str =
774  QString::number(point.Lat(), 'f', 7) + " " + QString::number(point.Lng(), 'f', 7) + " ";
775  m_widget->labelMapPos->setText(coord_str);
776 }
777 
781 void OPMapGadgetWidget::OnTilesStillToLoad(int number)
782 {
783  if (!m_widget || !m_map)
784  return;
785 
786  if (m_widget->progressBarMap->maximum() < number)
787  m_widget->progressBarMap->setMaximum(number);
788 
789  m_widget->progressBarMap->setValue(m_widget->progressBarMap->maximum()
790  - number); // update the progress bar
791 
792  m_prev_tile_number = number;
793 }
794 
798 void OPMapGadgetWidget::OnTileLoadStart()
799 {
800  if (!m_widget || !m_map)
801  return;
802  m_widget->progressBarMap->setVisible(true);
803 }
804 
811 void OPMapGadgetWidget::OnTileLoadComplete()
812 {
813  if (!m_widget || !m_map)
814  return;
815 
816  m_widget->progressBarMap->setVisible(false);
817 }
818 
819 void OPMapGadgetWidget::on_toolButtonZoomP_clicked()
820 {
821  zoomIn();
822 }
823 
824 void OPMapGadgetWidget::on_toolButtonZoomM_clicked()
825 {
826  zoomOut();
827 }
828 
829 void OPMapGadgetWidget::on_toolButtonMapHome_clicked()
830 {
831  goHome();
832 }
833 
834 void OPMapGadgetWidget::on_toolButtonMapUAV_clicked()
835 {
836  if (!m_widget || !m_map)
837  return;
838 
839  followUAVpositionAct->toggle();
840 }
841 
842 void OPMapGadgetWidget::on_toolButtonMapUAVheading_clicked()
843 {
844  if (!m_widget || !m_map)
845  return;
846 
847  followUAVheadingAct->toggle();
848 }
849 
850 void OPMapGadgetWidget::on_horizontalSliderZoom_sliderMoved(int position)
851 {
852  if (!m_widget || !m_map)
853  return;
854 
855  setZoom(position);
856 }
857 
858 void OPMapGadgetWidget::on_toolButtonNormalMapMode_clicked()
859 {
861 }
862 
863 void OPMapGadgetWidget::on_toolButtonMagicWaypointMapMode_clicked()
864 {
866 }
867 
868 void OPMapGadgetWidget::on_toolButtonHomeWaypoint_clicked()
869 {
870  homeMagicWaypoint();
871 }
872 
873 void OPMapGadgetWidget::on_toolButtonMoveToWP_clicked()
874 {
875  moveToMagicWaypointPosition();
876 }
877 
878 // *************************************************************************************
879 // public slots
880 
882 {
883  m_telemetry_connected = true;
884 
885  if (!uavo_util_mgr)
886  return;
887 
888  bool set;
889  double LLA[3];
890 
891  // ***********************
892  // fetch the home location
893 
894  if (uavo_util_mgr->getHomeLocation(set, LLA) < 0)
895  return; // error
896 
897  setHome(internals::PointLatLng(LLA[0], LLA[1]), LLA[2]);
898 
899  if (m_map) {
900  if (m_map->UAV->GetMapFollowType() != UAVMapFollowType::None)
901  m_map->SetCurrentPosition(m_home_position.coord); // set the map position
902  }
903  // ***********************
904 }
905 
907 {
908  m_telemetry_connected = false;
909 }
910 
911 // Updates the Home position icon whenever the HomePosition object is updated
913 {
914  Q_UNUSED(hp);
915  if (!uavo_util_mgr)
916  return;
917  bool set;
918  double LLA[3];
919  if (uavo_util_mgr->getHomeLocation(set, LLA) < 0)
920  return; // error
921  setHome(internals::PointLatLng(LLA[0], LLA[1]), LLA[2]);
922 }
923 
924 // *************************************************************************************
925 // public functions
926 
930 void OPMapGadgetWidget::setHome(QPointF pos)
931 {
932  if (!m_widget || !m_map)
933  return;
934 
935  double latitude = pos.x();
936  double longitude = pos.y();
937 
938  if (latitude > 90)
939  latitude = 90;
940  else if (latitude < -90)
941  latitude = -90;
942 
943  if (longitude != longitude)
944  longitude = 0; // nan detection
945  else if (longitude > 180)
946  longitude = 180;
947  else if (longitude < -180)
948  longitude = -180;
949 
950  setHome(internals::PointLatLng(latitude, longitude), 0);
951 }
952 
956 void OPMapGadgetWidget::setHome(internals::PointLatLng pos_lat_lon, double altitude)
957 {
958  if (!m_widget || !m_map)
959  return;
960 
961  if (pos_lat_lon.Lat() != pos_lat_lon.Lat() || pos_lat_lon.Lng() != pos_lat_lon.Lng())
962  return;
963  ; // nan prevention
964 
965  double latitude = pos_lat_lon.Lat();
966  double longitude = pos_lat_lon.Lng();
967 
968  if (latitude != latitude)
969  latitude = 0; // nan detection
970  else if (latitude > 90)
971  latitude = 90;
972  else if (latitude < -90)
973  latitude = -90;
974 
975  if (longitude != longitude)
976  longitude = 0; // nan detection
977  else if (longitude > 180)
978  longitude = 180;
979  else if (longitude < -180)
980  longitude = -180;
981 
982  // *********
983 
984  m_home_position.coord = internals::PointLatLng(latitude, longitude);
985  m_home_position.altitude = altitude;
986 
987  m_map->Home->SetCoord(m_home_position.coord);
988  m_map->Home->SetAltitude(altitude);
989  m_map->Home->RefreshPos();
990 
991  // move the magic waypoint to keep it within the safe area boundry
992  keepMagicWaypointWithInSafeArea();
993 }
994 
999 {
1000  if (!m_widget || !m_map)
1001  return;
1002 
1003  followUAVpositionAct->setChecked(false);
1004 
1005  internals::PointLatLng home_pos = m_home_position.coord; // get the home location
1006  m_map->SetCurrentPosition(home_pos); // center the map onto the home location
1007 }
1008 
1009 void OPMapGadgetWidget::zoomIn()
1010 {
1011  if (!m_widget || !m_map)
1012  return;
1013 
1014  int zoom = m_map->ZoomTotal() + 1;
1015 
1016  if (zoom < m_min_zoom)
1017  zoom = m_min_zoom;
1018  else if (zoom > m_max_zoom)
1019  zoom = m_max_zoom;
1020 
1021  m_map->SetZoom(zoom);
1022 }
1023 
1024 void OPMapGadgetWidget::zoomOut()
1025 {
1026  if (!m_widget || !m_map)
1027  return;
1028 
1029  int zoom = m_map->ZoomTotal() - 1;
1030 
1031  if (zoom < m_min_zoom)
1032  zoom = m_min_zoom;
1033  else if (zoom > m_max_zoom)
1034  zoom = m_max_zoom;
1035 
1036  m_map->SetZoom(zoom);
1037 }
1038 
1040 {
1041  if (!m_widget || !m_map)
1042  return;
1043 
1044  int list_size = sizeof(max_update_rate_list) / sizeof(max_update_rate_list[0]);
1045  int min_rate = max_update_rate_list[0];
1046  int max_rate = max_update_rate_list[list_size - 1];
1047 
1048  if (update_rate < min_rate)
1049  update_rate = min_rate;
1050  else if (update_rate > max_rate)
1051  update_rate = max_rate;
1052 
1053  m_maxUpdateRate = update_rate;
1054 
1055  if (m_updateTimer)
1056  m_updateTimer->setInterval(m_maxUpdateRate);
1057 
1058  // if (m_statusUpdateTimer)
1059  // m_statusUpdateTimer->setInterval(m_maxUpdateRate);
1060 }
1061 
1063 {
1064  if (!m_widget || !m_map)
1065  return;
1066 
1067  if (zoom < m_min_zoom)
1068  zoom = m_min_zoom;
1069  else if (zoom > m_max_zoom)
1070  zoom = m_max_zoom;
1071 
1072  internals::MouseWheelZoomType::Types zoom_type = m_map->GetMouseWheelZoomType();
1073  m_map->SetMouseWheelZoomType(internals::MouseWheelZoomType::ViewCenter);
1074 
1075  m_map->SetZoom(zoom);
1076 
1077  m_map->SetMouseWheelZoomType(zoom_type);
1078 }
1080 {
1081  if (!m_widget || !m_map)
1082  return;
1083  m_map->setOverlayOpacity(value);
1084  overlayOpacityAct.at(value * 10)->setChecked(true);
1085 }
1086 
1088 {
1089  if (!m_widget || !m_map)
1090  return;
1091 
1092  double latitude = pos.y();
1093  double longitude = pos.x();
1094 
1095  if (latitude != latitude || longitude != longitude)
1096  return; // nan prevention
1097 
1098  if (latitude > 90)
1099  latitude = 90;
1100  else if (latitude < -90)
1101  latitude = -90;
1102 
1103  if (longitude > 180)
1104  longitude = 180;
1105  else if (longitude < -180)
1106  longitude = -180;
1107 
1108  m_map->Home->SetCoord(internals::PointLatLng(latitude, longitude));
1109 }
1110 
1112 {
1113  if (!m_widget || !m_map)
1114  return;
1115 
1116  double latitude = pos.y();
1117  double longitude = pos.x();
1118 
1119  if (latitude != latitude || longitude != longitude)
1120  return; // nan prevention
1121 
1122  if (latitude > 90)
1123  latitude = 90;
1124  else if (latitude < -90)
1125  latitude = -90;
1126 
1127  if (longitude > 180)
1128  longitude = 180;
1129  else if (longitude < -180)
1130  longitude = -180;
1131 
1132  m_map->SetCurrentPosition(internals::PointLatLng(latitude, longitude));
1133 }
1135 {
1136  if (!m_widget || !m_map)
1137  return;
1139 }
1140 
1142 {
1143  if (!m_widget || !m_map)
1144  return;
1146 }
1147 
1148 void OPMapGadgetWidget::setAccessMode(QString accessMode)
1149 {
1150  if (!m_widget || !m_map)
1151  return;
1152 
1154 }
1155 
1156 void OPMapGadgetWidget::setShowTileGridLines(bool showTileGridLines)
1157 {
1158  if (!m_widget || !m_map)
1159  return;
1160 
1161  m_map->SetShowTileGridLines(showTileGridLines);
1162 }
1163 
1164 void OPMapGadgetWidget::setUseMemoryCache(bool useMemoryCache)
1165 {
1166  if (!m_widget || !m_map)
1167  return;
1168 
1169  m_map->configuration->SetUseMemoryCache(useMemoryCache);
1170 }
1171 
1172 void OPMapGadgetWidget::setCacheLocation(QString cacheLocation)
1173 {
1174  if (!m_widget || !m_map)
1175  return;
1176 
1177  cacheLocation = cacheLocation.simplified(); // remove any surrounding spaces
1178 
1179  if (cacheLocation.isEmpty())
1180  return;
1181 
1182  if (!cacheLocation.endsWith(QDir::separator()))
1183  cacheLocation += QDir::separator();
1184 
1185  QDir dir;
1186  if (!dir.exists(cacheLocation))
1187  if (!dir.mkpath(cacheLocation))
1188  return;
1189  m_map->configuration->SetCacheLocation(cacheLocation);
1190 }
1191 
1193 {
1194  if (!m_widget || !m_map)
1195  return;
1196 
1197  if (mode != Normal_MapMode && mode != MagicWaypoint_MapMode)
1198  mode = Normal_MapMode; // fix error
1199 
1200  if (m_map_mode == mode) { // no change in map mode
1201  switch (mode) { // make sure the UI buttons are set correctly
1202  case Normal_MapMode:
1203  m_widget->toolButtonMagicWaypointMapMode->setChecked(false);
1204  m_widget->toolButtonNormalMapMode->setChecked(true);
1205  break;
1206  case MagicWaypoint_MapMode:
1207  m_widget->toolButtonNormalMapMode->setChecked(false);
1208  m_widget->toolButtonMagicWaypointMapMode->setChecked(true);
1209  break;
1210  }
1211  return;
1212  }
1213 
1214  switch (mode) {
1215  case Normal_MapMode:
1216  m_map_mode = Normal_MapMode;
1217 
1218  m_widget->toolButtonMagicWaypointMapMode->setChecked(false);
1219  m_widget->toolButtonNormalMapMode->setChecked(true);
1220 
1221  hideMagicWaypointControls();
1222 
1223  magicWayPoint->setVisible(false);
1224  m_map->WPSetVisibleAll(true);
1225 
1226  break;
1227 
1228  case MagicWaypoint_MapMode:
1229  m_map_mode = MagicWaypoint_MapMode;
1230 
1231  m_widget->toolButtonNormalMapMode->setChecked(false);
1232  m_widget->toolButtonMagicWaypointMapMode->setChecked(true);
1233 
1234  showMagicWaypointControls();
1235 
1236  // delete the normal waypoints from the map
1237 
1238  m_map->WPSetVisibleAll(false);
1239  magicWayPoint->setVisible(true);
1240 
1241  break;
1242  }
1243 }
1244 
1245 void OPMapGadgetWidget::setUserImageLocation(QString userImageLocation)
1246 {
1247  m_map->SetUserImageLocation(userImageLocation);
1248 }
1249 void OPMapGadgetWidget::setUserImageHorizontalScale(double userImageHorizontalScale)
1250 {
1251  m_map->SetUserImageHorizontalScale(userImageHorizontalScale);
1252 }
1253 void OPMapGadgetWidget::setUserImageVerticalScale(double userImageVerticalScale)
1254 {
1255  m_map->SetUserImageVerticalScale(userImageVerticalScale);
1256 }
1257 
1258 // *************************************************************************************
1259 // Context menu stuff
1260 
1261 void OPMapGadgetWidget::createActions()
1262 {
1263  int list_size;
1264 
1265  if (!m_widget || !m_map)
1266  return;
1267 
1268  // ***********************
1269  // create menu actions
1270 
1271  closeAct1 = new QAction(tr("Close menu"), this);
1272  closeAct1->setStatusTip(tr("Close the context menu"));
1273 
1274  closeAct2 = new QAction(tr("Close menu"), this);
1275  closeAct2->setStatusTip(tr("Close the context menu"));
1276 
1277  reloadAct = new QAction(tr("&Reload map"), this);
1278  reloadAct->setShortcut(tr("F5"));
1279  reloadAct->setStatusTip(tr("Reload the map tiles"));
1280  connect(reloadAct, &QAction::triggered, this, &OPMapGadgetWidget::onReloadAct_triggered);
1281  this->addAction(reloadAct);
1282  ripAct = new QAction(tr("&Rip map"), this);
1283  ripAct->setStatusTip(tr("Rip the map tiles"));
1284  connect(ripAct, &QAction::triggered, this, &OPMapGadgetWidget::onRipAct_triggered);
1285 
1286  copyMouseLatLonToClipAct = new QAction(tr("Mouse latitude and longitude"), this);
1287  copyMouseLatLonToClipAct->setStatusTip(
1288  tr("Copy the mouse latitude and longitude to the clipboard"));
1289  connect(copyMouseLatLonToClipAct, &QAction::triggered, this,
1290  &OPMapGadgetWidget::onCopyMouseLatLonToClipAct_triggered);
1291 
1292  copyMouseLatToClipAct = new QAction(tr("Mouse latitude"), this);
1293  copyMouseLatToClipAct->setStatusTip(tr("Copy the mouse latitude to the clipboard"));
1294  connect(copyMouseLatToClipAct, &QAction::triggered, this,
1295  &OPMapGadgetWidget::onCopyMouseLatToClipAct_triggered);
1296 
1297  copyMouseLonToClipAct = new QAction(tr("Mouse longitude"), this);
1298  copyMouseLonToClipAct->setStatusTip(tr("Copy the mouse longitude to the clipboard"));
1299  connect(copyMouseLonToClipAct, &QAction::triggered, this,
1300  &OPMapGadgetWidget::onCopyMouseLonToClipAct_triggered);
1301 
1302  showCompassRoseAct = new QAction(tr("Show compass"), this);
1303  showCompassRoseAct->setStatusTip(tr("Show/Hide the compass"));
1304  showCompassRoseAct->setCheckable(true);
1305  showCompassRoseAct->setChecked(true);
1306  connect(showCompassRoseAct, &QAction::toggled, this,
1307  &OPMapGadgetWidget::onShowCompassRoseAct_toggled);
1308 
1309  showWindCompassAction = new QAction(tr("Show wind compass"), this);
1310  showWindCompassAction->setStatusTip(tr("Show/Hide the wind compass"));
1311  showWindCompassAction->setCheckable(true);
1312  showWindCompassAction->setChecked(false);
1313  connect(showWindCompassAction, &QAction::toggled, this,
1314  &OPMapGadgetWidget::onShowWindCompassAction_toggled);
1315 
1316  showDiagnostics = new QAction(tr("Show Diagnostics"), this);
1317  showDiagnostics->setStatusTip(tr("Show/Hide the diagnostics"));
1318  showDiagnostics->setCheckable(true);
1319  showDiagnostics->setChecked(false);
1320  connect(showDiagnostics, &QAction::toggled, this,
1321  &OPMapGadgetWidget::onShowDiagnostics_toggled);
1322 
1323  showUAVInfo = new QAction(tr("Show UAV Info"), this);
1324  showUAVInfo->setStatusTip(tr("Show/Hide the UAV info"));
1325  showUAVInfo->setCheckable(true);
1326  showUAVInfo->setChecked(false);
1327  connect(showUAVInfo, &QAction::toggled, this, &OPMapGadgetWidget::onShowUAVInfo_toggled);
1328 
1329  showHomeAct = new QAction(tr("Show Home"), this);
1330  showHomeAct->setStatusTip(tr("Show/Hide the Home location"));
1331  showHomeAct->setCheckable(true);
1332  showHomeAct->setChecked(true);
1333  connect(showHomeAct, &QAction::toggled, this, &OPMapGadgetWidget::onShowHomeAct_toggled);
1334 
1335  showUAVAct = new QAction(tr("Show UAV"), this);
1336  showUAVAct->setStatusTip(tr("Show/Hide the UAV"));
1337  showUAVAct->setCheckable(true);
1338  showUAVAct->setChecked(true);
1339  connect(showUAVAct, &QAction::toggled, this, &OPMapGadgetWidget::onShowUAVAct_toggled);
1340 
1341  changeDefaultLocalAndZoom = new QAction(tr("Set default zoom and location"), this);
1342  changeDefaultLocalAndZoom->setStatusTip(
1343  tr("Changes the map default zoom and location to the current values"));
1344  connect(changeDefaultLocalAndZoom, &QAction::triggered, this,
1345  &OPMapGadgetWidget::onChangeDefaultLocalAndZoom);
1346 
1347  zoomInAct = new QAction(tr("Zoom &In"), this);
1348  zoomInAct->setShortcut(Qt::Key_PageUp);
1349  zoomInAct->setStatusTip(tr("Zoom the map in"));
1350  connect(zoomInAct, &QAction::triggered, this, &OPMapGadgetWidget::onGoZoomInAct_triggered);
1351  this->addAction(zoomInAct);
1352 
1353  zoomOutAct = new QAction(tr("Zoom &Out"), this);
1354  zoomOutAct->setShortcut(Qt::Key_PageDown);
1355  zoomOutAct->setStatusTip(tr("Zoom the map out"));
1356  connect(zoomOutAct, &QAction::triggered, this, &OPMapGadgetWidget::onGoZoomOutAct_triggered);
1357  this->addAction(zoomOutAct);
1358 
1359  goMouseClickAct = new QAction(tr("Go to where you right clicked the mouse"), this);
1360  goMouseClickAct->setStatusTip(tr("Center the map onto where you right clicked the mouse"));
1361  connect(goMouseClickAct, &QAction::triggered, this,
1362  &OPMapGadgetWidget::onGoMouseClickAct_triggered);
1363 
1364  setHomeAct = new QAction(tr("Set the home location"), this);
1365  setHomeAct->setStatusTip(tr("Set the home location to where you clicked"));
1366  connect(setHomeAct, &QAction::triggered, this, &OPMapGadgetWidget::onSetHomeAct_triggered);
1367 
1368  goHomeAct = new QAction(tr("Go to &Home location"), this);
1369  goHomeAct->setShortcut(tr("Ctrl+H"));
1370  goHomeAct->setStatusTip(tr("Center the map onto the home location"));
1371  connect(goHomeAct, &QAction::triggered, this, &OPMapGadgetWidget::onGoHomeAct_triggered);
1372 
1373  goUAVAct = new QAction(tr("Go to &UAV location"), this);
1374  goUAVAct->setShortcut(tr("Ctrl+U"));
1375  goUAVAct->setStatusTip(tr("Center the map onto the UAV location"));
1376  connect(goUAVAct, &QAction::triggered, this, &OPMapGadgetWidget::onGoUAVAct_triggered);
1377 
1378  followUAVpositionAct = new QAction(tr("Follow UAV position"), this);
1379  followUAVpositionAct->setShortcut(tr("Ctrl+F"));
1380  followUAVpositionAct->setStatusTip(tr("Keep the map centered onto the UAV"));
1381  followUAVpositionAct->setCheckable(true);
1382  followUAVpositionAct->setChecked(false);
1383  connect(followUAVpositionAct, &QAction::toggled, this,
1384  &OPMapGadgetWidget::onFollowUAVpositionAct_toggled);
1385 
1386  followUAVheadingAct = new QAction(tr("Follow UAV heading"), this);
1387  followUAVheadingAct->setShortcut(tr("Ctrl+F"));
1388  followUAVheadingAct->setStatusTip(tr("Keep the map rotation to the UAV heading"));
1389  followUAVheadingAct->setCheckable(true);
1390  followUAVheadingAct->setChecked(false);
1391  connect(followUAVheadingAct, &QAction::toggled, this,
1392  &OPMapGadgetWidget::onFollowUAVheadingAct_toggled);
1393 
1394  wayPointEditorAct = new QAction(tr("&Waypoint editor"), this);
1395  wayPointEditorAct->setShortcut(tr("Ctrl+W"));
1396  wayPointEditorAct->setStatusTip(tr("Open the waypoint editor"));
1397  connect(wayPointEditorAct, &QAction::triggered, this,
1398  &OPMapGadgetWidget::onOpenWayPointEditorAct_triggered);
1399 
1400  addWayPointActFromContextMenu = new QAction(tr("&Add waypoint"), this);
1401  addWayPointActFromContextMenu->setShortcut(tr("Ctrl+A"));
1402  addWayPointActFromContextMenu->setStatusTip(tr("Add waypoint"));
1403  connect(addWayPointActFromContextMenu, &QAction::triggered, this,
1404  &OPMapGadgetWidget::onAddWayPointAct_triggeredFromContextMenu);
1405 
1406  addWayPointActFromThis = new QAction(tr("&Add waypoint"), this);
1407  addWayPointActFromThis->setShortcut(tr("Ctrl+A"));
1408  addWayPointActFromThis->setStatusTip(tr("Add waypoint"));
1409  connect(addWayPointActFromThis, &QAction::triggered, this,
1410  &OPMapGadgetWidget::onAddWayPointAct_triggeredFromThis);
1411  this->addAction(addWayPointActFromThis);
1412 
1413  editWayPointAct = new QAction(tr("&Edit waypoint"), this);
1414  editWayPointAct->setShortcut(tr("Ctrl+E"));
1415  editWayPointAct->setStatusTip(tr("Edit waypoint"));
1416  connect(editWayPointAct, &QAction::triggered, this,
1417  &OPMapGadgetWidget::onEditWayPointAct_triggered);
1418 
1419  lockWayPointAct = new QAction(tr("&Lock waypoint"), this);
1420  lockWayPointAct->setStatusTip(tr("Lock/Unlock a waypoint"));
1421  lockWayPointAct->setCheckable(true);
1422  lockWayPointAct->setChecked(false);
1423  connect(lockWayPointAct, &QAction::triggered, this,
1424  &OPMapGadgetWidget::onLockWayPointAct_triggered);
1425 
1426  deleteWayPointAct = new QAction(tr("&Delete waypoint"), this);
1427  deleteWayPointAct->setShortcut(tr("Ctrl+D"));
1428  deleteWayPointAct->setStatusTip(tr("Delete waypoint"));
1429  connect(deleteWayPointAct, &QAction::triggered, this,
1430  &OPMapGadgetWidget::onDeleteWayPointAct_triggered);
1431 
1432  clearWayPointsAct = new QAction(tr("&Clear waypoints"), this);
1433  clearWayPointsAct->setShortcut(tr("Ctrl+C"));
1434  clearWayPointsAct->setStatusTip(tr("Clear waypoints"));
1435  connect(clearWayPointsAct, &QAction::triggered, this,
1436  &OPMapGadgetWidget::onClearWayPointsAct_triggered);
1437 
1438  overlayOpacityActGroup = new QActionGroup(this);
1439  connect(overlayOpacityActGroup, &QActionGroup::triggered, this,
1440  &OPMapGadgetWidget::onOverlayOpacityActGroup_triggered);
1441  overlayOpacityAct.clear();
1442  for (int i = 0; i <= 10; i++) {
1443  QAction *overlayAct = new QAction(QString::number(i * 10), overlayOpacityActGroup);
1444  overlayAct->setCheckable(true);
1445  overlayAct->setData(i * 10);
1446  overlayOpacityAct.append(overlayAct);
1447  }
1448 
1449  homeMagicWaypointAct = new QAction(tr("Home magic waypoint"), this);
1450  homeMagicWaypointAct->setStatusTip(tr("Move the magic waypoint to the home position"));
1451  connect(homeMagicWaypointAct, &QAction::triggered, this,
1452  &OPMapGadgetWidget::onHomeMagicWaypointAct_triggered);
1453 
1454  mapModeActGroup = new QActionGroup(this);
1455  connect(mapModeActGroup, &QActionGroup::triggered, this,
1456  &OPMapGadgetWidget::onMapModeActGroup_triggered);
1457  mapModeAct.clear();
1458  {
1459  QAction *map_mode_act;
1460 
1461  map_mode_act = new QAction(tr("Normal"), mapModeActGroup);
1462  map_mode_act->setCheckable(true);
1463  map_mode_act->setChecked(m_map_mode == Normal_MapMode);
1464  map_mode_act->setData((int)Normal_MapMode);
1465  mapModeAct.append(map_mode_act);
1466 
1467  map_mode_act = new QAction(tr("Magic Waypoint"), mapModeActGroup);
1468  map_mode_act->setCheckable(true);
1469  map_mode_act->setChecked(m_map_mode == MagicWaypoint_MapMode);
1470  map_mode_act->setData((int)MagicWaypoint_MapMode);
1471  mapModeAct.append(map_mode_act);
1472  }
1473 
1474  zoomActGroup = new QActionGroup(this);
1475  connect(zoomActGroup, &QActionGroup::triggered, this,
1476  &OPMapGadgetWidget::onZoomActGroup_triggered);
1477  zoomAct.clear();
1478  for (int i = m_min_zoom; i <= m_max_zoom; i++) {
1479  QAction *zoom_act = new QAction(QString::number(i), zoomActGroup);
1480  zoom_act->setCheckable(true);
1481  zoom_act->setData(i);
1482  zoomAct.append(zoom_act);
1483  }
1484 
1485  maxUpdateRateActGroup = new QActionGroup(this);
1486  connect(maxUpdateRateActGroup, &QActionGroup::triggered, this,
1487  &OPMapGadgetWidget::onMaxUpdateRateActGroup_triggered);
1488  maxUpdateRateAct.clear();
1489  list_size = sizeof(max_update_rate_list) / sizeof(max_update_rate_list[0]);
1490  for (int i = 0; i < list_size; i++) {
1491  QAction *maxUpdateRate_act;
1492  int j = max_update_rate_list[i];
1493  maxUpdateRate_act = new QAction(QString::number(j), maxUpdateRateActGroup);
1494  maxUpdateRate_act->setCheckable(true);
1495  maxUpdateRate_act->setData(j);
1496  maxUpdateRate_act->setChecked(j == m_maxUpdateRate);
1497  maxUpdateRateAct.append(maxUpdateRate_act);
1498  }
1499 
1500  // *****
1501  // safe area
1502 
1503  showSafeAreaAct = new QAction(tr("Show Safe Area"), this);
1504  showSafeAreaAct->setStatusTip(tr("Show/Hide the Safe Area around the home location"));
1505  showSafeAreaAct->setCheckable(true);
1506  showSafeAreaAct->setChecked(m_map->Home->ShowSafeArea());
1507  connect(showSafeAreaAct, &QAction::toggled, this,
1508  &OPMapGadgetWidget::onShowSafeAreaAct_toggled);
1509 
1510  safeAreaActGroup = new QActionGroup(this);
1511  connect(safeAreaActGroup, &QActionGroup::triggered, this,
1512  &OPMapGadgetWidget::onSafeAreaActGroup_triggered);
1513  safeAreaAct.clear();
1514  list_size = sizeof(safe_area_radius_list) / sizeof(safe_area_radius_list[0]);
1515  for (int i = 0; i < list_size; i++) {
1516  int safeArea = safe_area_radius_list[i];
1517  QAction *safeArea_act = new QAction(QString::number(safeArea) + "m", safeAreaActGroup);
1518  safeArea_act->setCheckable(true);
1519  safeArea_act->setChecked(safeArea == m_map->Home->SafeArea());
1520  safeArea_act->setData(safeArea);
1521  safeAreaAct.append(safeArea_act);
1522  }
1523 
1524  // *****
1525  // UAV trail
1526 
1527  uavTrailTypeActGroup = new QActionGroup(this);
1528  connect(uavTrailTypeActGroup, &QActionGroup::triggered, this,
1529  &OPMapGadgetWidget::onUAVTrailTypeActGroup_triggered);
1530  uavTrailTypeAct.clear();
1531  QStringList uav_trail_type_list = mapcontrol::Helper::UAVTrailTypes();
1532  for (int i = 0; i < uav_trail_type_list.count(); i++) {
1533  mapcontrol::UAVTrailType::Types uav_trail_type =
1534  mapcontrol::Helper::UAVTrailTypeFromString(uav_trail_type_list[i]);
1535  QAction *uavTrailType_act = new QAction(
1536  mapcontrol::Helper::StrFromUAVTrailType(uav_trail_type), uavTrailTypeActGroup);
1537  uavTrailType_act->setCheckable(true);
1538  uavTrailType_act->setChecked(uav_trail_type == m_map->UAV->GetTrailType());
1539  uavTrailType_act->setData(i);
1540  uavTrailTypeAct.append(uavTrailType_act);
1541  }
1542 
1543  showTrailAct = new QAction(tr("Show Trail dots"), this);
1544  showTrailAct->setStatusTip(tr("Show/Hide the Trail dots"));
1545  showTrailAct->setCheckable(true);
1546  showTrailAct->setChecked(true);
1547  connect(showTrailAct, &QAction::toggled, this, &OPMapGadgetWidget::onShowTrailAct_toggled);
1548 
1549  showTrailLineAct = new QAction(tr("Show Trail lines"), this);
1550  showTrailLineAct->setStatusTip(tr("Show/Hide the Trail lines"));
1551  showTrailLineAct->setCheckable(true);
1552  showTrailLineAct->setChecked(true);
1553  connect(showTrailLineAct, &QAction::toggled, this,
1554  &OPMapGadgetWidget::onShowTrailLineAct_toggled);
1555 
1556  clearUAVtrailAct = new QAction(tr("Clear UAV trail"), this);
1557  clearUAVtrailAct->setStatusTip(tr("Clear the UAV trail"));
1558  connect(clearUAVtrailAct, &QAction::triggered, this,
1559  &OPMapGadgetWidget::onClearUAVtrailAct_triggered);
1560 
1561  uavTrailTimeActGroup = new QActionGroup(this);
1562  connect(uavTrailTimeActGroup, &QActionGroup::triggered, this,
1563  &OPMapGadgetWidget::onUAVTrailTimeActGroup_triggered);
1564  uavTrailTimeAct.clear();
1565  list_size = sizeof(uav_trail_time_list) / sizeof(uav_trail_time_list[0]);
1566  for (int i = 0; i < list_size; i++) {
1567  int uav_trail_time = uav_trail_time_list[i];
1568  QAction *uavTrailTime_act =
1569  new QAction(QString::number(uav_trail_time) + " sec", uavTrailTimeActGroup);
1570  uavTrailTime_act->setCheckable(true);
1571  uavTrailTime_act->setChecked(uav_trail_time == m_map->UAV->TrailTime());
1572  uavTrailTime_act->setData(uav_trail_time);
1573  uavTrailTimeAct.append(uavTrailTime_act);
1574  }
1575 
1576  uavTrailDistanceActGroup = new QActionGroup(this);
1577  connect(uavTrailDistanceActGroup, &QActionGroup::triggered, this,
1578  &OPMapGadgetWidget::onUAVTrailDistanceActGroup_triggered);
1579  uavTrailDistanceAct.clear();
1580  list_size = sizeof(uav_trail_distance_list) / sizeof(uav_trail_distance_list[0]);
1581  for (int i = 0; i < list_size; i++) {
1582  int uav_trail_distance = uav_trail_distance_list[i];
1583  QAction *uavTrailDistance_act =
1584  new QAction(QString::number(uav_trail_distance) + " meters", uavTrailDistanceActGroup);
1585  uavTrailDistance_act->setCheckable(true);
1586  uavTrailDistance_act->setChecked(uav_trail_distance == m_map->UAV->TrailDistance());
1587  uavTrailDistance_act->setData(uav_trail_distance);
1588  uavTrailDistanceAct.append(uavTrailDistance_act);
1589  }
1590 }
1591 
1592 void OPMapGadgetWidget::onReloadAct_triggered()
1593 {
1594  if (!m_widget || !m_map)
1595  return;
1596 
1597  m_map->ReloadMap();
1598 }
1599 
1600 void OPMapGadgetWidget::onRipAct_triggered()
1601 {
1602  m_map->RipMap();
1603 }
1604 
1605 void OPMapGadgetWidget::onCopyMouseLatLonToClipAct_triggered()
1606 {
1607  QClipboard *clipboard = QApplication::clipboard();
1608  clipboard->setText(QString::number(m_context_menu_lat_lon.Lat(), 'f', 7) + ", "
1609  + QString::number(m_context_menu_lat_lon.Lng(), 'f', 7),
1610  QClipboard::Clipboard);
1611 }
1612 
1613 void OPMapGadgetWidget::onCopyMouseLatToClipAct_triggered()
1614 {
1615  QClipboard *clipboard = QApplication::clipboard();
1616  clipboard->setText(QString::number(m_context_menu_lat_lon.Lat(), 'f', 7),
1617  QClipboard::Clipboard);
1618 }
1619 
1620 void OPMapGadgetWidget::onCopyMouseLonToClipAct_triggered()
1621 {
1622  QClipboard *clipboard = QApplication::clipboard();
1623  clipboard->setText(QString::number(m_context_menu_lat_lon.Lng(), 'f', 7),
1624  QClipboard::Clipboard);
1625 }
1626 
1627 void OPMapGadgetWidget::onShowCompassRoseAct_toggled(bool show)
1628 {
1629  if (!m_widget || !m_map)
1630  return;
1631 
1632  m_map->SetShowCompassRose(show);
1633 }
1634 
1635 void OPMapGadgetWidget::onShowWindCompassAction_toggled(bool show)
1636 {
1637  if (!m_widget || !m_map)
1638  return;
1639 
1640  m_map->SetShowWindCompass(show);
1641 }
1642 
1643 void OPMapGadgetWidget::onShowDiagnostics_toggled(bool show)
1644 {
1645  if (!m_widget || !m_map)
1646  return;
1647 
1648  m_map->SetShowDiagnostics(show);
1649 }
1650 
1651 void OPMapGadgetWidget::onShowUAVInfo_toggled(bool show)
1652 {
1653  if (!m_widget || !m_map)
1654  return;
1655 
1656  m_map->UAV->SetShowUAVInfo(show);
1657 }
1658 
1659 void OPMapGadgetWidget::onShowHomeAct_toggled(bool show)
1660 {
1661  if (!m_widget || !m_map)
1662  return;
1663 
1664  m_map->Home->setVisible(show);
1665 }
1666 
1667 void OPMapGadgetWidget::onShowUAVAct_toggled(bool show)
1668 {
1669  if (!m_widget || !m_map)
1670  return;
1671 
1672  m_map->UAV->setVisible(show);
1673  if (m_map->GPS)
1674  m_map->GPS->setVisible(show);
1675 }
1676 
1677 void OPMapGadgetWidget::onShowTrailAct_toggled(bool show)
1678 {
1679  if (!m_widget || !m_map)
1680  return;
1681 
1682  m_map->UAV->SetShowTrail(show);
1683  if (m_map->GPS)
1684  m_map->GPS->SetShowTrail(show);
1685 }
1686 
1687 void OPMapGadgetWidget::onShowTrailLineAct_toggled(bool show)
1688 {
1689  if (!m_widget || !m_map)
1690  return;
1691 
1692  m_map->UAV->SetShowTrailLine(show);
1693  if (m_map->GPS)
1694  m_map->GPS->SetShowTrailLine(show);
1695 }
1696 
1697 void OPMapGadgetWidget::onMapModeActGroup_triggered(QAction *action)
1698 {
1699  if (!m_widget || !m_map || !action)
1700  return;
1701 
1702  opMapModeType mode = (opMapModeType)action->data().toInt();
1703 
1704  setMapMode(mode);
1705 }
1706 
1707 void OPMapGadgetWidget::onGoZoomInAct_triggered()
1708 {
1709  zoomIn();
1710 }
1711 
1712 void OPMapGadgetWidget::onGoZoomOutAct_triggered()
1713 {
1714  zoomOut();
1715 }
1716 
1717 void OPMapGadgetWidget::onZoomActGroup_triggered(QAction *action)
1718 {
1719  if (!m_widget || !m_map || !action)
1720  return;
1721 
1722  setZoom(action->data().toInt());
1723 }
1724 
1725 void OPMapGadgetWidget::onMaxUpdateRateActGroup_triggered(QAction *action)
1726 {
1727  if (!m_widget || !m_map || !action)
1728  return;
1729 
1730  setMaxUpdateRate(action->data().toInt());
1731 }
1732 
1733 void OPMapGadgetWidget::onChangeDefaultLocalAndZoom()
1734 {
1736  m_map->CurrentPosition().Lat(), m_map->ZoomTotal());
1737 }
1738 
1739 void OPMapGadgetWidget::onGoMouseClickAct_triggered()
1740 {
1741  if (!m_widget || !m_map)
1742  return;
1743 
1744  m_map->SetCurrentPosition(
1745  m_map->currentMousePosition()); // center the map onto the mouse position
1746 }
1747 
1748 void OPMapGadgetWidget::onSetHomeAct_triggered()
1749 {
1750  if (!m_widget || !m_map)
1751  return;
1752 
1753  float altitude = 0;
1754  bool ok = false;
1755 
1756  // Get desired HomeLocation altitude from dialog box.
1757  // TODO: Populate box with altitude already in HomeLocation UAVO
1758  altitude = QInputDialog::getDouble(this, tr("Set home altitude"),
1759  tr("In [m], referenced to WGS84 geoid:"), altitude, -100,
1760  100000, 2, &ok);
1761 
1762  if (ok) {
1763  setHome(m_context_menu_lat_lon, altitude);
1764  }
1765 
1766  setHomeLocationObject(); // update the HomeLocation UAVObject
1767 }
1768 
1769 void OPMapGadgetWidget::onGoHomeAct_triggered()
1770 {
1771  if (!m_widget || !m_map)
1772  return;
1773 
1774  goHome();
1775 }
1776 
1777 void OPMapGadgetWidget::onGoUAVAct_triggered()
1778 {
1779  if (!m_widget || !m_map)
1780  return;
1781 
1782  double latitude;
1783  double longitude;
1784  double altitude;
1785  if (getUAVPosition(latitude, longitude, altitude)) // get current UAV position
1786  {
1787  internals::PointLatLng uav_pos =
1788  internals::PointLatLng(latitude, longitude); // current UAV position
1789  internals::PointLatLng map_pos = m_map->CurrentPosition(); // current MAP position
1790  if (map_pos != uav_pos)
1791  m_map->SetCurrentPosition(uav_pos); // center the map onto the UAV
1792  }
1793 }
1794 
1795 void OPMapGadgetWidget::onFollowUAVpositionAct_toggled(bool checked)
1796 {
1797  if (!m_widget || !m_map)
1798  return;
1799 
1800  if (m_widget->toolButtonMapUAV->isChecked() != checked)
1801  m_widget->toolButtonMapUAV->setChecked(checked);
1802 
1803  setMapFollowingMode();
1804 }
1805 
1806 void OPMapGadgetWidget::onFollowUAVheadingAct_toggled(bool checked)
1807 {
1808  if (!m_widget || !m_map)
1809  return;
1810 
1811  if (m_widget->toolButtonMapUAVheading->isChecked() != checked)
1812  m_widget->toolButtonMapUAVheading->setChecked(checked);
1813 
1814  setMapFollowingMode();
1815 }
1816 
1817 void OPMapGadgetWidget::onUAVTrailTypeActGroup_triggered(QAction *action)
1818 {
1819  if (!m_widget || !m_map || !action)
1820  return;
1821 
1822  int trail_type_idx = action->data().toInt();
1823 
1824  QStringList uav_trail_type_list = mapcontrol::Helper::UAVTrailTypes();
1825  mapcontrol::UAVTrailType::Types uav_trail_type =
1826  mapcontrol::Helper::UAVTrailTypeFromString(uav_trail_type_list[trail_type_idx]);
1827 
1828  m_map->UAV->SetTrailType(uav_trail_type);
1829 }
1830 
1831 void OPMapGadgetWidget::onClearUAVtrailAct_triggered()
1832 {
1833  if (!m_widget || !m_map)
1834  return;
1835 
1836  m_map->UAV->DeleteTrail();
1837  if (m_map->GPS)
1838  m_map->GPS->DeleteTrail();
1839 }
1840 
1841 void OPMapGadgetWidget::onUAVTrailTimeActGroup_triggered(QAction *action)
1842 {
1843  if (!m_widget || !m_map || !action)
1844  return;
1845 
1846  int trail_time = (double)action->data().toInt();
1847 
1848  m_map->UAV->SetTrailTime(trail_time);
1849 }
1850 
1851 void OPMapGadgetWidget::onUAVTrailDistanceActGroup_triggered(QAction *action)
1852 {
1853  if (!m_widget || !m_map || !action)
1854  return;
1855 
1856  int trail_distance = action->data().toInt();
1857 
1858  m_map->UAV->SetTrailDistance(trail_distance);
1859 }
1860 
1865 void OPMapGadgetWidget::onOpenWayPointEditorAct_triggered()
1866 {
1867  // create dialog
1868  pathPlannerDialog = new QDialog(this);
1869  pathPlannerDialog->setModal(true);
1870 
1871  // create layout dialog
1872  QHBoxLayout *dialogLayout = new QHBoxLayout(pathPlannerDialog);
1873  pathPlannerDialog->setLayout(dialogLayout);
1874  // create elements of dialog
1875  QPointer<PathPlannerGadgetWidget> widget = new PathPlannerGadgetWidget(pathPlannerDialog);
1876  dialogLayout->addWidget(widget);
1877  pathPlannerDialog->show();
1878  pathPlannerDialog->resize(850, 300);
1879 }
1880 
1881 void OPMapGadgetWidget::onAddWayPointAct_triggeredFromContextMenu()
1882 {
1883  onAddWayPointAct_triggered(m_context_menu_lat_lon);
1884 }
1885 void OPMapGadgetWidget::onAddWayPointAct_triggeredFromThis()
1886 {
1887  onAddWayPointAct_triggered(lastLatLngMouse);
1888 }
1889 
1890 void OPMapGadgetWidget::onAddWayPointAct_triggered(internals::PointLatLng coord)
1891 {
1892  if (!m_widget || !m_map)
1893  return;
1894 
1895  if (m_map_mode != Normal_MapMode)
1896  return;
1897 
1898  mapProxy->createWayPoint(coord);
1899 }
1900 
1906 void OPMapGadgetWidget::onEditWayPointAct_triggered()
1907 {
1908  WaypointDialog *dialog = pm->getObject<WaypointDialog>();
1909  Q_ASSERT(dialog);
1910  if (dialog != NULL)
1911  dialog->show();
1912 }
1913 
1918 void OPMapGadgetWidget::onLockWayPointAct_triggered()
1919 {
1920  if (!m_widget || !m_map || !m_mouse_waypoint)
1921  return;
1922 
1923  if (m_map_mode != Normal_MapMode)
1924  return;
1925 
1926  bool locked = (m_mouse_waypoint->flags() & QGraphicsItem::ItemIsMovable) == 0;
1927  m_mouse_waypoint->setFlag(QGraphicsItem::ItemIsMovable, locked);
1928 
1929  if (!locked)
1930  m_mouse_waypoint->picture.load(QString::fromUtf8(":/opmap/images/waypoint_marker2.png"));
1931  else
1932  m_mouse_waypoint->picture.load(QString::fromUtf8(":/opmap/images/waypoint_marker1.png"));
1933  m_mouse_waypoint->update();
1934 
1935  m_mouse_waypoint = NULL;
1936 }
1937 
1938 void OPMapGadgetWidget::onDeleteWayPointAct_triggered()
1939 {
1940  if (!m_widget || !m_map)
1941  return;
1942 
1943  if (m_map_mode != Normal_MapMode)
1944  return;
1945 
1946  if (!m_mouse_waypoint)
1947  return;
1948 
1949  mapProxy->deleteWayPoint(m_mouse_waypoint->Number());
1950 }
1951 
1952 void OPMapGadgetWidget::onClearWayPointsAct_triggered()
1953 {
1954 
1955  // First, ask to ensure this is what the user wants to do
1956  QMessageBox msgBox(this);
1957  msgBox.setText(tr("Are you sure you want to clear waypoints?"));
1958  msgBox.setInformativeText(tr("All associated data will be lost."));
1959  msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
1960  int ret = msgBox.exec();
1961 
1962  if (ret == QMessageBox::No) {
1963  return;
1964  }
1965 
1966  if (!m_widget || !m_map)
1967  return;
1968 
1969  if (m_map_mode != Normal_MapMode)
1970  return;
1971 
1972  mapProxy->deleteAll();
1973 }
1974 
1975 void OPMapGadgetWidget::onHomeMagicWaypointAct_triggered()
1976 {
1977  // center the magic waypoint on the home position
1978  homeMagicWaypoint();
1979 }
1980 
1981 void OPMapGadgetWidget::onShowSafeAreaAct_toggled(bool show)
1982 {
1983  if (!m_widget || !m_map)
1984  return;
1985 
1986  m_map->Home->SetShowSafeArea(show); // show the safe area
1987  m_map->Home->SetToggleRefresh(true);
1988  m_map->Home->RefreshPos();
1989 }
1990 
1991 void OPMapGadgetWidget::onSafeAreaActGroup_triggered(QAction *action)
1992 {
1993  if (!m_widget || !m_map || !action)
1994  return;
1995 
1996  int radius = action->data().toInt();
1997 
1998  m_map->Home->SetSafeArea(radius); // set the radius (meters)
1999  m_map->Home->RefreshPos();
2000 
2001  // move the magic waypoint if need be to keep it within the safe area around the home position
2002  keepMagicWaypointWithInSafeArea();
2003 }
2004 
2008 void OPMapGadgetWidget::homeMagicWaypoint()
2009 {
2010  if (!m_widget || !m_map)
2011  return;
2012 
2013  if (m_map_mode != MagicWaypoint_MapMode)
2014  return;
2015 
2016  magicWayPoint->SetCoord(m_home_position.coord);
2017 }
2018 
2019 // *************************************************************************************
2020 // move the UAV to the magic waypoint position
2021 
2022 void OPMapGadgetWidget::moveToMagicWaypointPosition()
2023 {
2024  if (!m_widget || !m_map)
2025  return;
2026 
2027  if (m_map_mode != MagicWaypoint_MapMode)
2028  return;
2029 }
2030 
2031 // *************************************************************************************
2032 // show/hide the magic waypoint controls
2033 
2034 void OPMapGadgetWidget::hideMagicWaypointControls()
2035 {
2036  m_widget->lineWaypoint->setVisible(false);
2037  m_widget->toolButtonHomeWaypoint->setVisible(false);
2038  m_widget->toolButtonMoveToWP->setVisible(false);
2039 }
2040 
2041 void OPMapGadgetWidget::showMagicWaypointControls()
2042 {
2043  m_widget->lineWaypoint->setVisible(true);
2044  m_widget->toolButtonHomeWaypoint->setVisible(true);
2045 
2046  m_widget->toolButtonMoveToWP->setVisible(true);
2047 }
2048 
2049 // *************************************************************************************
2050 // move the magic waypoint to keep it within the safe area boundry
2051 
2052 void OPMapGadgetWidget::keepMagicWaypointWithInSafeArea()
2053 {
2054 
2055  // calcute the bearing and distance from the home position to the magic waypoint
2056  double dist = distance(m_home_position.coord, magicWayPoint->Coord());
2057  double bear = bearing(m_home_position.coord, magicWayPoint->Coord());
2058 
2059  // get the maximum safe distance - in kilometers
2060  double boundry_dist = (double)m_map->Home->SafeArea() / 1000;
2061 
2062  if (dist > boundry_dist)
2063  dist = boundry_dist;
2064 
2065  // move the magic waypoint;
2066 
2067  if (m_map_mode == MagicWaypoint_MapMode) { // move the on-screen waypoint
2068  if (magicWayPoint)
2069  magicWayPoint->SetCoord(destPoint(m_home_position.coord, bear, dist));
2070  }
2071 }
2072 
2073 // *************************************************************************************
2074 // return the distance between two points .. in kilometers
2075 
2076 double OPMapGadgetWidget::distance(internals::PointLatLng from, internals::PointLatLng to)
2077 {
2078  double lat1 = from.Lat() * deg_to_rad;
2079  double lon1 = from.Lng() * deg_to_rad;
2080 
2081  double lat2 = to.Lat() * deg_to_rad;
2082  double lon2 = to.Lng() * deg_to_rad;
2083 
2084  return (acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon2 - lon1))
2085  * earth_mean_radius);
2086 
2087  // ***********************
2088 }
2089 
2090 // *************************************************************************************
2091 // return the bearing from one point to another .. in degrees
2092 
2093 double OPMapGadgetWidget::bearing(internals::PointLatLng from, internals::PointLatLng to)
2094 {
2095  double lat1 = from.Lat() * deg_to_rad;
2096  double lon1 = from.Lng() * deg_to_rad;
2097 
2098  double lat2 = to.Lat() * deg_to_rad;
2099  double lon2 = to.Lng() * deg_to_rad;
2100 
2101  // double delta_lat = lat2 - lat1;
2102  double delta_lon = lon2 - lon1;
2103 
2104  double y = sin(delta_lon) * cos(lat2);
2105  double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(delta_lon);
2106  double bear = atan2(y, x) * rad_to_deg;
2107 
2108  bear += 360;
2109  while (bear < 0)
2110  bear += 360;
2111  while (bear >= 360)
2112  bear -= 360;
2113 
2114  return bear;
2115 }
2116 
2117 // *************************************************************************************
2118 // return a destination lat/lon point given a source lat/lon point and the bearing and distance from
2119 // the source point
2120 
2121 internals::PointLatLng OPMapGadgetWidget::destPoint(internals::PointLatLng source, double bear,
2122  double dist)
2123 {
2124  double lat1 = source.Lat() * deg_to_rad;
2125  double lon1 = source.Lng() * deg_to_rad;
2126 
2127  bear *= deg_to_rad;
2128 
2129  double ad = dist / earth_mean_radius;
2130 
2131  double lat2 = asin(sin(lat1) * cos(ad) + cos(lat1) * sin(ad) * cos(bear));
2132  double lon2 = lon1 + atan2(sin(bear) * sin(ad) * cos(lat1), cos(ad) - sin(lat1) * sin(lat2));
2133 
2134  return internals::PointLatLng(lat2 * rad_to_deg, lon2 * rad_to_deg);
2135 }
2136 
2137 // *************************************************************************************
2138 
2139 bool OPMapGadgetWidget::getUAVPosition(double &latitude, double &longitude, double &altitude)
2140 {
2141  double NED[3];
2142  double LLA[3];
2143  double homeLLA[3];
2144 
2145  Q_ASSERT(uavo_mgr != NULL);
2146 
2147  HomeLocation *homeLocation = HomeLocation::GetInstance(uavo_mgr);
2148  Q_ASSERT(homeLocation != NULL);
2149  HomeLocation::DataFields homeLocationData = homeLocation->getData();
2150 
2151  homeLLA[0] = homeLocationData.Latitude / 1e7;
2152  homeLLA[1] = homeLocationData.Longitude / 1e7;
2153  homeLLA[2] = homeLocationData.Altitude;
2154 
2155  PositionActual *positionActual = PositionActual::GetInstance(uavo_mgr);
2156  Q_ASSERT(positionActual != NULL);
2157  PositionActual::DataFields positionActualData = positionActual->getData();
2158 
2159  NED[0] = positionActualData.North;
2160  NED[1] = positionActualData.East;
2161  NED[2] = positionActualData.Down;
2162 
2163  Utils::CoordinateConversions().NED2LLA_HomeLLA(homeLLA, NED, LLA);
2164 
2165  latitude = LLA[0];
2166  longitude = LLA[1];
2167  altitude = LLA[2];
2168 
2169  if (latitude != latitude)
2170  latitude = 0; // nan detection
2171  else if (latitude > 90)
2172  latitude = 90;
2173  else if (latitude < -90)
2174  latitude = -90;
2175 
2176  if (longitude != longitude)
2177  longitude = 0; // nan detection
2178  else if (longitude > 180)
2179  longitude = 180;
2180  else if (longitude < -180)
2181  longitude = -180;
2182 
2183  if (altitude != altitude)
2184  altitude = 0; // nan detection
2185 
2186  return true;
2187 }
2188 
2189 double OPMapGadgetWidget::getUAV_Yaw()
2190 {
2191  if (!uavo_mgr)
2192  return 0;
2193 
2194  UAVObject *obj = dynamic_cast<UAVDataObject *>(uavo_mgr->getObject(QString("AttitudeActual")));
2195  double yaw = obj->getField(QString("Yaw"))->getDouble();
2196 
2197  if (yaw != yaw)
2198  yaw = 0; // nan detection
2199 
2200  while (yaw < 0)
2201  yaw += 360;
2202  while (yaw >= 360)
2203  yaw -= 360;
2204 
2205  return yaw;
2206 }
2207 
2208 // *************************************************************************************
2209 void OPMapGadgetWidget::setMapFollowingMode()
2210 {
2211  if (!m_widget || !m_map)
2212  return;
2213 
2214  if (!followUAVpositionAct->isChecked()) {
2215  m_map->UAV->SetMapFollowType(UAVMapFollowType::None);
2216  m_map->SetRotate(0); // reset map rotation to 0deg
2217  } else if (!followUAVheadingAct->isChecked()) {
2218  m_map->UAV->SetMapFollowType(UAVMapFollowType::CenterMap);
2219  m_map->SetRotate(0); // reset map rotation to 0deg
2220  } else {
2221  m_map->UAV->SetMapFollowType(UAVMapFollowType::CenterMap); // the map library won't let you
2222  // reset the uav rotation if it's
2223  // already in rotate mode
2224 
2225  m_map->UAV->SetUAVHeading(0); // reset the UAV heading to 0deg
2226  m_map->UAV->SetMapFollowType(UAVMapFollowType::CenterAndRotateMap);
2227  }
2228 }
2229 
2230 // *************************************************************************************
2231 // update the HomeLocation UAV Object
2232 
2233 bool OPMapGadgetWidget::setHomeLocationObject()
2234 {
2235  if (!uavo_util_mgr)
2236  return false;
2237 
2238  double LLA[3] = { m_home_position.coord.Lat(), m_home_position.coord.Lng(),
2239  m_home_position.altitude };
2240  return (uavo_util_mgr->setHomeLocation(LLA, false) >= 0);
2241 }
2242 
2243 // *************************************************************************************
2244 
2245 void OPMapGadgetWidget::SetUavPic(QString UAVPic)
2246 {
2247  m_map->SetUavPic(UAVPic);
2248 }
2249 
2250 // *************************************************************************************
2251 void OPMapGadgetWidget::on_tbFind_clicked()
2252 {
2253  QPalette pal = m_widget->leFind->palette();
2254 
2255  GeoCoderStatusCode::Types result =
2256  m_map->SetCurrentPositionByKeywords(m_widget->leFind->text());
2257  if (result == core::GeoCoderStatusCode::OK) {
2258  pal.setColor(m_widget->leFind->backgroundRole(), Qt::green);
2259  m_widget->leFind->setPalette(pal);
2260  m_map->SetZoom(12);
2261  } else {
2262  pal.setColor(m_widget->leFind->backgroundRole(), Qt::red);
2263  m_widget->leFind->setPalette(pal);
2264  }
2265 }
2266 
2267 void OPMapGadgetWidget::onHomeDoubleClick(HomeItem *)
2268 {
2269  new homeEditor(m_map->Home, this);
2270 }
2271 
2272 void OPMapGadgetWidget::onOverlayOpacityActGroup_triggered(QAction *action)
2273 {
2274  if (!m_widget || !m_map || !action)
2275  return;
2276 
2277  m_map->setOverlayOpacity(action->data().toReal() / 100);
2278  emit overlayOpacityChanged(action->data().toReal() / 100);
2279 }
2280 
2281 void OPMapGadgetWidget::on_leFind_returnPressed()
2282 {
2283  on_tbFind_clicked();
2284 }
2285 
2286 void OPMapGadgetWidget::updateWindspeed(UAVObject *obj)
2287 {
2288  Q_UNUSED(obj);
2289 
2290  WindVelocityActual *windVelocityActual = WindVelocityActual::GetInstance(uavo_mgr);
2291  WindVelocityActual::DataFields windVelocityActualData;
2292  windVelocityActualData = windVelocityActual->getData();
2293 
2294  double windVelocity_NED[3] = { windVelocityActualData.North, windVelocityActualData.East,
2295  windVelocityActualData.Down };
2296  m_map->setWindVelocity(windVelocity_NED);
2297 }
void contextMenuEvent(QContextMenuEvent *event)
static QString StrFromUAVTrailType(UAVTrailType::Types const &value)
Converts from Type to String.
Definition: tlmapwidget.h:149
s1
Definition: OPPlots.m:19
void OnWayPointDoubleClicked(WayPointItem *waypoint)
void SetShowDiagnostics(bool const &value)
Definition: tlmapwidget.cpp:80
void SetZoom(double const &value)
Definition: tlmapwidget.h:230
void setHomePosition(QPointF pos)
Qt::MouseButton DragButton
Button used for dragging.
Definition: configuration.h:94
void setUseMemoryCache(bool useMemoryCache)
static MapType::Types MapTypeFromString(QString const &value)
Converts from String to Type.
Definition: tlmapwidget.h:70
void setCacheLocation(QString cacheLocation)
void SetShowUAV(bool const &value)
void SetUavPic(QString UAVPic)
Configuration * configuration
Definition: tlmapwidget.h:247
void SetShowTileGridLines(bool const &value)
Defines if map is to show gridlines.
Definition: tlmapwidget.h:191
void SetMouseWheelZoomType(internals::MouseWheelZoomType::Types const &value)
Definition: tlmapwidget.h:214
void closeEvent(QCloseEvent *)
const int safe_area_radius_list[]
int MaxZoom() const
Returns the maximum zoom for the map.
Definition: tlmapwidget.h:197
void SetUserImageVerticalScale(double vScale)
Definition: tlmapwidget.h:242
void setMapProvider(QString provider)
internals::PointLatLng CurrentPosition() const
Definition: tlmapwidget.h:224
double getDouble(int index=0) const
void SetAccessMode(core::AccessMode::Types const &type)
Sets the access mode for the map (cache only, server and cache...)
Core plugin system that manages the plugins, their life cycle and their registered objects...
Definition: pluginmanager.h:53
void SetFollowMouse(bool const &value)
Definition: tlmapwidget.h:251
void overlayOpacityChanged(qreal)
void setGeoCodingLanguage(QString language)
axis equal end function NED
Definition: OPPlots.m:63
void LLA2NED_HomeLLA(double LLA[3], double homeLLA[3], double NED[3])
void SetCacheLocation(QString const &dir)
Sets the location for the SQLite Database used for caching and the geocoding cache files...
for i
Definition: OPPlots.m:140
void SetShowHome(bool const &value)
void zoomChanged(double zoomt, double zoom, double zoomd)
WayPointItem * magicWPCreate()
void setShowTileGridLines(bool showTileGridLines)
void objectUpdated(UAVObject *obj)
Signal sent whenever any field of the object is updated.
void setUserImageHorizontalScale(double userImageHorizontalScale)
static core::LanguageType::Types LanguageTypeFromString(QString const &value)
Converts from String to Type.
Definition: tlmapwidget.h:108
The WaypointDialog class creates a dialog for editing the properties of a single waypoint.
void setWindVelocity(double windVelocity_NED[3])
opMapModeType
void SetShowWindCompass(bool const &value)
TLMapWidget::SetShowWindCompass Shows the compass rose on the map.
void OnTileLoadStart()
Fires when tiles loading begins.
void setMaxUpdateRate(int update_rate)
double Lng() const
Definition: pointlatlng.h:76
double Lat() const
Definition: pointlatlng.h:64
internals::PointLatLng currentMousePosition()
void SetUavPic(QString UAVPic)
void SetMapType(MapType::Types const &value)
Definition: tlmapwidget.h:240
The ModelMapProxy class maps from the FlightDataModel to the OPMap and provides synchronization, both when the model changes updating the UI and if it is modified on the UI propagating changes to the model.
Definition: modelmapproxy.h:51
void homePositionUpdated(UAVObject *)
void RipMap()
Ripps the current selection to the DB.
void setUserImageVerticalScale(double userImageVerticalScale)
UAVObjectField * getField(const QString &name)
Definition: uavobject.cpp:236
void SetLanguage(core::LanguageType::Types const &type)
Sets the language used for geocaching.
void setPosition(QPointF pos)
void defaultLocationAndZoomChanged(double lng, double lat, double zoom)
void setOverlayOpacity(qreal value)
s2
Definition: OPPlots.m:20
int NED2LLA_HomeLLA(double homeLLA[3], double NED[3], double LLA[3])
double altitude
static core::AccessMode::Types AccessModeFromString(QString const &value)
Converts from String to Type.
Definition: tlmapwidget.h:120
internals::MouseWheelZoomType::Types GetMouseWheelZoomType()
Definition: tlmapwidget.h:213
void SetUserImageLocation(QString location)
Definition: tlmapwidget.h:243
const int max_update_rate_list[]
const int uav_trail_time_list[]
void SetRotate(qreal const &value)
void setMapMode(opMapModeType mode)
void OnTilesStillToLoad(int number)
Fires when the number of tiles in the load queue changes.
static UAVTrailType::Types UAVTrailTypeFromString(QString const &value)
Converts from String to Type.
Definition: tlmapwidget.h:145
A QGraphicsItem representing a WayPoint.
Definition: waypointitem.h:41
static QStringList UAVTrailTypes()
Returns QStringList with string representing all the enum values.
Definition: tlmapwidget.h:153
GeoCoderStatusCode::Types SetCurrentPositionByKeywords(QString const &keys)
Definition: tlmapwidget.h:237
void SetCurrentPosition(internals::PointLatLng const &value)
Definition: tlmapwidget.h:225
int setHomeLocation(double LLA[3], bool save_to_sdcard)
void SetUseMemoryCache(bool const &value)
Used to allow disallow use of memory caching.
const int uav_trail_distance_list[]
void OnCurrentPositionChanged(internals::PointLatLng point)
Fires when map position changes.
LLA
Definition: OPPlots.m:34
internals::PointLatLng coord
x
Definition: OPPlots.m:100
void setHome(QPointF pos)
public functions
void SetUserImageHorizontalScale(double hScale)
Definition: tlmapwidget.h:241
OPMapGadgetWidget(QWidget *parent=nullptr)
UAVObject * getObject(const QString &name, quint32 instId=0)
void homedoubleclick(HomeItem *homeLocation)
void setOverlayOpacity(qreal value)
void OnTileLoadComplete()
Fires when there are no more tiles to load.
void setUserImageLocation(QString userImageLocation)
void resizeEvent(QResizeEvent *event)
void setAccessMode(QString accessMode)
int getHomeLocation(bool &set, double LLA[3])
internals::PointLatLng GetFromLocalToLatLng(QPointF p)
Definition: tlmapwidget.h:254
void mouseMoveEvent(QMouseEvent *event)
void SetShowCompassRose(bool const &value)
TLMapWidget::SetShowCompassRose Shows the compass rose on the map.
void WPSetVisibleAll(bool value)
y
Definition: OPPlots.m:101