1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-13 20:48:42 +01:00
LibrePilot/ground/openpilotgcs/src/plugins/opmap/opmapgadgetwidget.cpp
2013-05-22 22:36:23 +02:00

2334 lines
70 KiB
C++

/**
******************************************************************************
*
* @file opmapgadgetwidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup OPMapPlugin OpenPilot Map Plugin
* @{
* @brief The OpenPilot Map plugin
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define USE_PATHPLANNER
#include "opmapgadgetwidget.h"
#include "ui_opmap_widget.h"
#include <QtGui/QApplication>
#include <QtGui/QHBoxLayout>
#include <QtGui/QVBoxLayout>
#include <QtGui/QClipboard>
#include <QtGui/QMenu>
#include <QStringList>
#include <QDir>
#include <QFile>
#include <QDateTime>
#include <math.h>
#include "utils/stylehelper.h"
#include "utils/homelocationutil.h"
#include "utils/worldmagmodel.h"
#include "uavtalk/telemetrymanager.h"
#include "uavobject.h"
#include "positionstate.h"
#include "homelocation.h"
#include "gpspositionsensor.h"
#include "gyrostate.h"
#include "attitudestate.h"
#include "positionstate.h"
#include "velocitystate.h"
#include "airspeedstate.h"
#define allow_manual_home_location_move
// *************************************************************************************
#define deg_to_rad ((double)M_PI / 180.0)
#define rad_to_deg (180.0 / (double)M_PI)
#define earth_mean_radius 6371 // kilometers
#define max_digital_zoom 3 // maximum allowed digital zoom level
const int safe_area_radius_list[] = { 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000 }; // meters
const int uav_trail_time_list[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // seconds
const int uav_trail_distance_list[] = { 1, 2, 5, 10, 20, 50, 100, 200, 500 }; // meters
const int max_update_rate_list[] = { 100, 200, 500, 1000, 2000, 5000 }; // milliseconds
// *************************************************************************************
// *************************************************************************************
// NOTE: go back to SVN REV 2137 and earlier to get back to experimental waypoint support.
// *************************************************************************************
// constructor
OPMapGadgetWidget::OPMapGadgetWidget(QWidget *parent) : QWidget(parent)
{
// **************
m_widget = NULL;
m_map = NULL;
findPlaceCompleter = NULL;
m_mouse_waypoint = NULL;
pm = NULL;
obm = NULL;
obum = NULL;
m_prev_tile_number = 0;
m_min_zoom = m_max_zoom = 0;
m_map_mode = Normal_MapMode;
m_maxUpdateRate = max_update_rate_list[4]; // 2 seconds //SHOULDN'T THIS BE LOADED FROM THE USER PREFERENCES?
m_telemetry_connected = false;
m_context_menu_lat_lon = m_mouse_lat_lon = internals::PointLatLng(0, 0);
setMouseTracking(true);
pm = ExtensionSystem::PluginManager::instance();
if (pm) {
obm = pm->getObject<UAVObjectManager>();
obum = pm->getObject<UAVObjectUtilManager>();
}
// **************
// get current location
double latitude = 0;
double longitude = 0;
double altitude = 0;
// current position
getUAVPosition(latitude, longitude, altitude);
internals::PointLatLng pos_lat_lon = internals::PointLatLng(latitude, longitude);
// **************
// default home position
m_home_position.coord = pos_lat_lon;
m_home_position.altitude = altitude;
m_home_position.locked = false;
// **************
// create the widget that holds the user controls and the map
m_widget = new Ui::OPMap_Widget();
m_widget->setupUi(this);
// **************
// create the central map widget
m_map = new mapcontrol::OPMapWidget(); // create the map object
m_map->setFrameStyle(QFrame::NoFrame); // no border frame
m_map->setBackgroundBrush(QBrush(Utils::StyleHelper::baseColor())); // tile background
m_map->configuration->DragButton = Qt::LeftButton; // use the left mouse button for map dragging
m_widget->horizontalSliderZoom->setMinimum(m_map->MinZoom()); //
m_widget->horizontalSliderZoom->setMaximum(m_map->MaxZoom() + max_digital_zoom); //
m_min_zoom = m_widget->horizontalSliderZoom->minimum(); // minimum zoom we can accept
m_max_zoom = m_widget->horizontalSliderZoom->maximum(); // maximum zoom we can accept
m_map->SetMouseWheelZoomType(internals::MouseWheelZoomType::MousePositionWithoutCenter); // set how the mouse wheel zoom functions
m_map->SetFollowMouse(true); // we want a contiuous mouse position reading
m_map->SetShowHome(true); // display the HOME position on the map
m_map->SetShowUAV(true); // display the UAV position on the map
m_map->Home->SetSafeArea(safe_area_radius_list[0]); // set radius (meters) //SHOULDN'T THE DEFAULT BE USER DEFINED?
m_map->Home->SetShowSafeArea(true); // show the safe area //SHOULDN'T THE DEFAULT BE USER DEFINED?
m_map->Home->SetToggleRefresh(true);
if (m_map->Home) {
connect(m_map->Home, SIGNAL(homedoubleclick(HomeItem *)), this, SLOT(onHomeDoubleClick(HomeItem *)));
}
m_map->UAV->SetTrailTime(uav_trail_time_list[0]); // seconds
m_map->UAV->SetTrailDistance(uav_trail_distance_list[1]); // meters
m_map->UAV->SetTrailType(UAVTrailType::ByTimeElapsed);
if (m_map->GPS) {
m_map->GPS->SetTrailTime(uav_trail_time_list[0]); // seconds
m_map->GPS->SetTrailDistance(uav_trail_distance_list[1]); // meters
m_map->GPS->SetTrailType(UAVTrailType::ByTimeElapsed);
}
// **************
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
QVBoxLayout *layout = new QVBoxLayout;
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_map);
m_widget->mapWidget->setLayout(layout);
m_widget->toolButtonMagicWaypointMapMode->setChecked(false);
m_widget->toolButtonNormalMapMode->setChecked(true);
hideMagicWaypointControls();
m_widget->labelUAVPos->setText("---");
m_widget->labelMapPos->setText("---");
m_widget->labelMousePos->setText("---");
m_widget->labelMapZoom->setText("---");
m_widget->progressBarMap->setMaximum(1);
connect(m_map, SIGNAL(zoomChanged(double, double, double)), this, SLOT(zoomChanged(double, double, double))); // map zoom change signals
connect(m_map, SIGNAL(OnCurrentPositionChanged(internals::PointLatLng)), this, SLOT(OnCurrentPositionChanged(internals::PointLatLng))); // map poisition change signals
connect(m_map, SIGNAL(OnTileLoadComplete()), this, SLOT(OnTileLoadComplete())); // tile loading stop signals
connect(m_map, SIGNAL(OnTileLoadStart()), this, SLOT(OnTileLoadStart())); // tile loading start signals
connect(m_map, SIGNAL(OnTilesStillToLoad(int)), this, SLOT(OnTilesStillToLoad(int))); // tile loading signals
connect(m_map, SIGNAL(OnWayPointDoubleClicked(WayPointItem *)), this, SLOT(wpDoubleClickEvent(WayPointItem *)));
m_map->SetCurrentPosition(m_home_position.coord); // set the map position
m_map->Home->SetCoord(m_home_position.coord); // set the HOME position
m_map->UAV->SetUAVPos(m_home_position.coord, 0.0); // set the UAV position
m_map->UAV->update();
if (m_map->GPS) {
m_map->GPS->SetUAVPos(m_home_position.coord, 0.0); // set the GPS position
}
#ifdef USE_PATHPLANNER
model = new flightDataModel(this);
table = new pathPlanner();
selectionModel = new QItemSelectionModel(model);
mapProxy = new modelMapProxy(this, m_map, model, selectionModel);
table->setModel(model, selectionModel);
waypoint_edit_dialog = new opmap_edit_waypoint_dialog(this, model, selectionModel);
UAVProxy = new modelUavoProxy(this, model);
connect(table, SIGNAL(sendPathPlanToUAV()), UAVProxy, SLOT(modelToObjects()));
connect(table, SIGNAL(receivePathPlanFromUAV()), UAVProxy, SLOT(objectsToModel()));
#endif
magicWayPoint = m_map->magicWPCreate();
magicWayPoint->setVisible(false);
m_map->setOverlayOpacity(0.5);
// **************
// create various context menu (mouse right click menu) actions
createActions();
// **************
// connect to the UAVObject updates we require to become a bit aware of our environment:
if (pm) {
// Register for Home Location state changes
if (obm) {
UAVDataObject *obj = dynamic_cast<UAVDataObject *>(obm->getObject(QString("HomeLocation")));
if (obj) {
connect(obj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(homePositionUpdated(UAVObject *)));
}
}
// Listen to telemetry connection events
TelemetryManager *telMngr = pm->getObject<TelemetryManager>();
if (telMngr) {
connect(telMngr, SIGNAL(connected()), this, SLOT(onTelemetryConnect()));
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onTelemetryDisconnect()));
}
}
// **************
// create the desired timers
m_updateTimer = new QTimer();
m_updateTimer->setInterval(m_maxUpdateRate);
connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updatePosition()));
m_updateTimer->start();
m_statusUpdateTimer = new QTimer();
m_statusUpdateTimer->setInterval(200);
connect(m_statusUpdateTimer, SIGNAL(timeout()), this, SLOT(updateMousePos()));
m_statusUpdateTimer->start();
// **************
m_map->setFocus();
}
// destructor
OPMapGadgetWidget::~OPMapGadgetWidget()
{
if (m_map) {
disconnect(m_map, 0, 0, 0);
m_map->SetShowHome(false); // doing this appears to stop the map lib crashing on exit
m_map->SetShowUAV(false); // " "
}
if (m_map) {
delete m_map;
m_map = NULL;
}
if (!model.isNull()) {
delete model;
}
if (!table.isNull()) {
delete table;
}
if (!selectionModel.isNull()) {
delete selectionModel;
}
if (!mapProxy.isNull()) {
delete mapProxy;
}
if (!waypoint_edit_dialog.isNull()) {
delete waypoint_edit_dialog;
}
if (!UAVProxy.isNull()) {
delete UAVProxy;
}
}
// *************************************************************************************
// widget signals .. the mouseMoveEvent does not get called - don't yet know why
void OPMapGadgetWidget::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
}
void OPMapGadgetWidget::mouseMoveEvent(QMouseEvent *event)
{
if (m_widget && m_map) {}
if (event->buttons() & Qt::LeftButton) {}
QWidget::mouseMoveEvent(event);
}
void OPMapGadgetWidget::wpDoubleClickEvent(WayPointItem *wp)
{
m_mouse_waypoint = wp;
onEditWayPointAct_triggered();
}
void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
{ // the user has right clicked on the map - create the pop-up context menu and display it
QString s;
if (!m_widget || !m_map) {
return;
}
if (event->reason() != QContextMenuEvent::Mouse) {
return; // not a mouse click event
}
// current mouse position
QPoint p = m_map->mapFromGlobal(event->globalPos());
m_context_menu_lat_lon = m_map->GetFromLocalToLatLng(p);
if (!m_map->contentsRect().contains(p)) {
return; // the mouse click was not on the map
}
// show the mouse position
s = QString::number(m_context_menu_lat_lon.Lat(), 'f', 7) + " " + QString::number(m_context_menu_lat_lon.Lng(), 'f', 7);
m_widget->labelMousePos->setText(s);
// find out if we have a waypoint under the mouse cursor
QGraphicsItem *item = m_map->itemAt(p);
m_mouse_waypoint = qgraphicsitem_cast<mapcontrol::WayPointItem *>(item);
// find out if the waypoint is locked (or not)
bool waypoint_locked = false;
if (m_mouse_waypoint) {
waypoint_locked = (m_mouse_waypoint->flags() & QGraphicsItem::ItemIsMovable) == 0;
}
// ****************
// Dynamically create the popup menu
contextMenu.addAction(closeAct1);
contextMenu.addSeparator();
contextMenu.addAction(reloadAct);
contextMenu.addSeparator();
contextMenu.addAction(ripAct);
contextMenu.addSeparator();
QMenu maxUpdateRateSubMenu(tr("&Max Update Rate ") + "(" + QString::number(m_maxUpdateRate) + " ms)", this);
for (int i = 0; i < maxUpdateRateAct.count(); i++) {
maxUpdateRateSubMenu.addAction(maxUpdateRateAct.at(i));
}
contextMenu.addMenu(&maxUpdateRateSubMenu);
contextMenu.addSeparator();
switch (m_map_mode) {
case Normal_MapMode: s = tr(" (Normal)"); break;
case MagicWaypoint_MapMode: s = tr(" (Magic Waypoint)"); break;
default: s = tr(" (Unknown)"); break;
}
for (int i = 0; i < mapModeAct.count(); i++) { // set the menu to checked (or not)
QAction *act = mapModeAct.at(i);
if (!act) {
continue;
}
if (act->data().toInt() == (int)m_map_mode) {
act->setChecked(true);
}
}
QMenu mapModeSubMenu(tr("Map mode") + s, this);
for (int i = 0; i < mapModeAct.count(); i++) {
mapModeSubMenu.addAction(mapModeAct.at(i));
}
contextMenu.addMenu(&mapModeSubMenu);
contextMenu.addSeparator();
QMenu copySubMenu(tr("Copy"), this);
copySubMenu.addAction(copyMouseLatLonToClipAct);
copySubMenu.addAction(copyMouseLatToClipAct);
copySubMenu.addAction(copyMouseLonToClipAct);
contextMenu.addMenu(&copySubMenu);
contextMenu.addSeparator();
contextMenu.addAction(changeDefaultLocalAndZoom);
contextMenu.addSeparator();
QMenu safeArea("Safety Area definitions");
// menu.addAction(showSafeAreaAct);
QMenu safeAreaSubMenu(tr("Safe Area Radius") + " (" + QString::number(m_map->Home->SafeArea()) + "m)", this);
for (int i = 0; i < safeAreaAct.count(); i++) {
safeAreaSubMenu.addAction(safeAreaAct.at(i));
}
safeArea.addMenu(&safeAreaSubMenu);
safeArea.addAction(showSafeAreaAct);
contextMenu.addMenu(&safeArea);
contextMenu.addSeparator();
contextMenu.addAction(showCompassAct);
contextMenu.addAction(showDiagnostics);
contextMenu.addAction(showUAVInfo);
contextMenu.addSeparator()->setText(tr("Zoom"));
contextMenu.addAction(zoomInAct);
contextMenu.addAction(zoomOutAct);
QMenu zoomSubMenu(tr("&Zoom ") + "(" + QString::number(m_map->ZoomTotal()) + ")", this);
for (int i = 0; i < zoomAct.count(); i++) {
zoomSubMenu.addAction(zoomAct.at(i));
}
contextMenu.addMenu(&zoomSubMenu);
contextMenu.addSeparator();
contextMenu.addAction(goMouseClickAct);
contextMenu.addSeparator()->setText(tr("HOME"));
contextMenu.addAction(setHomeAct);
contextMenu.addAction(showHomeAct);
contextMenu.addAction(goHomeAct);
// ****
// uav trails
QMenu uav_menu(tr("UAV"));
uav_menu.addSeparator()->setText(tr("UAV Trail"));
contextMenu.addMenu(&uav_menu);
QMenu uavTrailTypeSubMenu(tr("UAV trail type") + " (" + mapcontrol::Helper::StrFromUAVTrailType(m_map->UAV->GetTrailType()) + ")", this);
for (int i = 0; i < uavTrailTypeAct.count(); i++) {
uavTrailTypeSubMenu.addAction(uavTrailTypeAct.at(i));
}
uav_menu.addMenu(&uavTrailTypeSubMenu);
QMenu uavTrailTimeSubMenu(tr("UAV trail time") + " (" + QString::number(m_map->UAV->TrailTime()) + " sec)", this);
for (int i = 0; i < uavTrailTimeAct.count(); i++) {
uavTrailTimeSubMenu.addAction(uavTrailTimeAct.at(i));
}
uav_menu.addMenu(&uavTrailTimeSubMenu);
QMenu uavTrailDistanceSubMenu(tr("UAV trail distance") + " (" + QString::number(m_map->UAV->TrailDistance()) + " meters)", this);
for (int i = 0; i < uavTrailDistanceAct.count(); i++) {
uavTrailDistanceSubMenu.addAction(uavTrailDistanceAct.at(i));
}
uav_menu.addMenu(&uavTrailDistanceSubMenu);
uav_menu.addAction(showTrailAct);
uav_menu.addAction(showTrailLineAct);
uav_menu.addAction(clearUAVtrailAct);
// ****
uav_menu.addSeparator()->setText(tr("UAV"));
uav_menu.addAction(showUAVAct);
uav_menu.addAction(followUAVpositionAct);
uav_menu.addAction(followUAVheadingAct);
uav_menu.addAction(goUAVAct);
// *********
#ifdef USE_PATHPLANNER
switch (m_map_mode) {
case Normal_MapMode:
// only show the waypoint stuff if not in 'magic waypoint' mode
contextMenu.addSeparator()->setText(tr("Waypoints"));
contextMenu.addAction(wayPointEditorAct);
contextMenu.addAction(addWayPointActFromContextMenu);
if (m_mouse_waypoint) { // we have a waypoint under the mouse
contextMenu.addAction(editWayPointAct);
lockWayPointAct->setChecked(waypoint_locked);
contextMenu.addAction(lockWayPointAct);
if (!waypoint_locked) {
contextMenu.addAction(deleteWayPointAct);
}
}
if (m_map->WPPresent()) {
contextMenu.addAction(clearWayPointsAct); // we have waypoints
}
break;
case MagicWaypoint_MapMode:
contextMenu.addSeparator()->setText(tr("Waypoints"));
contextMenu.addAction(homeMagicWaypointAct);
break;
}
#endif // ifdef USE_PATHPLANNER
// *********
QMenu overlaySubMenu(tr("&Overlay Opacity "), this);
for (int i = 0; i < overlayOpacityAct.count(); i++) {
overlaySubMenu.addAction(overlayOpacityAct.at(i));
}
contextMenu.addMenu(&overlaySubMenu);
contextMenu.addSeparator();
contextMenu.addAction(closeAct2);
contextMenu.exec(event->globalPos()); // popup the menu
// ****************
}
void OPMapGadgetWidget::closeEvent(QCloseEvent *event)
{
table->close();
QWidget::closeEvent(event);
}
// *************************************************************************************
// timer signals
/**
Updates the UAV position on the map. It is called at a user-defined frequency,
as set inside the map widget.
*/
void OPMapGadgetWidget::updatePosition()
{
double uav_latitude, uav_longitude, uav_altitude, uav_yaw;
double gps_latitude, gps_longitude, gps_altitude, gps_heading;
internals::PointLatLng uav_pos;
internals::PointLatLng gps_pos;
if (!m_widget || !m_map) {
return;
}
QMutexLocker locker(&m_map_mutex);
// *************
// get the current UAV details
// get current UAV position
if (!getUAVPosition(uav_latitude, uav_longitude, uav_altitude)) {
return;
}
// get current UAV heading
uav_yaw = getUAV_Yaw();
uav_pos = internals::PointLatLng(uav_latitude, uav_longitude);
// *************
// get the current GPS position and heading
GPSPositionSensor *gpsPositionObj = GPSPositionSensor::GetInstance(obm);
Q_ASSERT(gpsPositionObj);
GPSPositionSensor::DataFields gpsPositionData = gpsPositionObj->getData();
gps_heading = gpsPositionData.Heading;
gps_latitude = gpsPositionData.Latitude;
gps_longitude = gpsPositionData.Longitude;
gps_altitude = gpsPositionData.Altitude;
gps_pos = internals::PointLatLng(gps_latitude * 1e-7, gps_longitude * 1e-7);
// **********************
// get the current position and heading estimates
AttitudeState *attitudeStateObj = AttitudeState::GetInstance(obm);
PositionState *positionStateObj = PositionState::GetInstance(obm);
VelocityState *velocityStateObj = VelocityState::GetInstance(obm);
AirspeedState *airspeedStateObj = AirspeedState::GetInstance(obm);
GyroState *gyroStateObj = GyroState::GetInstance(obm);
Q_ASSERT(attitudeStateObj);
Q_ASSERT(positionStateObj);
Q_ASSERT(velocityStateObj);
Q_ASSERT(airspeedStateObj);
Q_ASSERT(gyroStateObj);
AttitudeState::DataFields attitudeStateData = attitudeStateObj->getData();
PositionState::DataFields positionStateData = positionStateObj->getData();
VelocityState::DataFields velocityStateData = velocityStateObj->getData();
AirspeedState::DataFields airspeedStateData = airspeedStateObj->getData();
GyroState::DataFields gyroStateData = gyroStateObj->getData();
double NED[3] = { positionStateData.North, positionStateData.East, positionStateData.Down };
double vNED[3] = { velocityStateData.North, velocityStateData.East, velocityStateData.Down };
// Set the position and heading estimates in the painter module
m_map->UAV->SetNED(NED);
m_map->UAV->SetCAS(airspeedStateData.CalibratedAirspeed);
m_map->UAV->SetGroundspeed(vNED, m_maxUpdateRate);
// Convert angular velocities into a rotationg rate around the world-frame yaw axis. This is found by simply taking the dot product of the angular Euler-rate matrix with the angular rates.
float psiRate_dps = 0 * gyroStateData.z + sin(attitudeStateData.Roll * deg_to_rad) / cos(attitudeStateData.Pitch * deg_to_rad) * gyroStateData.y + cos(attitudeStateData.Roll * deg_to_rad) / cos(attitudeStateData.Pitch * deg_to_rad) * gyroStateData.z;
// Set the angular rate in the painter module
m_map->UAV->SetYawRate(psiRate_dps); // Not correct, but I'm being lazy right now.
// *************
// display the UAV position
QString str =
"lat: " + QString::number(uav_pos.Lat(), 'f', 7) +
" lon: " + QString::number(uav_pos.Lng(), 'f', 7) +
" " + QString::number(uav_yaw, 'f', 1) + "deg" +
" " + QString::number(uav_altitude, 'f', 1) + "m";
// " " + QString::number(uav_ground_speed_meters_per_second, 'f', 1) + "m/s";
m_widget->labelUAVPos->setText(str);
// *************
// set the UAV icon position on the map
m_map->UAV->SetUAVPos(uav_pos, uav_altitude); // set the maps UAV position
// qDebug()<<"UAVPOSITION"<<uav_pos.ToString();
m_map->UAV->SetUAVHeading(uav_yaw); // set the maps UAV heading
// *************
// set the GPS icon position on the map
if (m_map->GPS) {
m_map->GPS->SetUAVPos(gps_pos, gps_altitude); // set the maps GPS position
m_map->GPS->SetUAVHeading(gps_heading); // set the maps GPS heading
m_map->GPS->update();
}
m_map->UAV->updateTextOverlay();
m_map->UAV->update();
// *************
}
/**
Update plugin behaviour based on mouse position; Called every few ms by a
timer.
*/
void OPMapGadgetWidget::updateMousePos()
{
if (!m_widget || !m_map) {
return;
}
QMutexLocker locker(&m_map_mutex);
QPoint p = m_map->mapFromGlobal(QCursor::pos());
internals::PointLatLng lat_lon = m_map->GetFromLocalToLatLng(p); // fetch the current lat/lon mouse position
lastLatLngMouse = lat_lon;
if (!m_map->contentsRect().contains(p)) {
return; // the mouse is not on the map
}
// internals::PointLatLng lat_lon = m_map->currentMousePosition(); // fetch the current lat/lon mouse position
QGraphicsItem *item = m_map->itemAt(p);
// find out if we are over the home position
mapcontrol::HomeItem *home = qgraphicsitem_cast<mapcontrol::HomeItem *>(item);
// find out if we have a waypoint under the mouse cursor
mapcontrol::WayPointItem *wp = qgraphicsitem_cast<mapcontrol::WayPointItem *>(item);
if (m_mouse_lat_lon == lat_lon) {
return; // the mouse has not moved
}
m_mouse_lat_lon = lat_lon; // yes it has!
internals::PointLatLng home_lat_lon = m_map->Home->Coord();
QString s = QString::number(m_mouse_lat_lon.Lat(), 'f', 7) + " " + QString::number(m_mouse_lat_lon.Lng(), 'f', 7);
if (wp) {
s += " wp[" + QString::number(wp->numberAdjusted()) + "]";
double dist = distance(home_lat_lon, wp->Coord());
double bear = bearing(home_lat_lon, wp->Coord());
s += " " + QString::number(dist * 1000, 'f', 1) + "m";
s += " " + QString::number(bear, 'f', 1) + "deg";
} else if (home) {
s += " home";
double dist = distance(home_lat_lon, m_mouse_lat_lon);
double bear = bearing(home_lat_lon, m_mouse_lat_lon);
s += " " + QString::number(dist * 1000, 'f', 1) + "m";
s += " " + QString::number(bear, 'f', 1) + "deg";
}
m_widget->labelMousePos->setText(s);
}
// *************************************************************************************
// map signals
/**
Update the Plugin UI to reflect a change in zoom level
*/
void OPMapGadgetWidget::zoomChanged(double zoomt, double zoom, double zoomd)
{
if (!m_widget || !m_map) {
return;
}
QString s = "tot:" + QString::number(zoomt, 'f', 1) + " rea:" + QString::number(zoom, 'f', 1) + " dig:" + QString::number(zoomd, 'f', 1);
m_widget->labelMapZoom->setText(s);
int i_zoom = (int)(zoomt + 0.5);
if (i_zoom < m_min_zoom) {
i_zoom = m_min_zoom;
} else if (i_zoom > m_max_zoom) {
i_zoom = m_max_zoom;
}
if (m_widget->horizontalSliderZoom->value() != i_zoom) {
m_widget->horizontalSliderZoom->setValue(i_zoom); // set the GUI zoom slider position
}
int index0_zoom = i_zoom - m_min_zoom; // zoom level starting at index level '0'
if (index0_zoom < zoomAct.count()) {
zoomAct.at(index0_zoom)->setChecked(true); // set the right-click context menu zoom level
}
}
void OPMapGadgetWidget::OnCurrentPositionChanged(internals::PointLatLng point)
{
if (!m_widget || !m_map) {
return;
}
QString coord_str = QString::number(point.Lat(), 'f', 7) + " " + QString::number(point.Lng(), 'f', 7) + " ";
m_widget->labelMapPos->setText(coord_str);
}
/**
Update the progress bar while there are still tiles to load
*/
void OPMapGadgetWidget::OnTilesStillToLoad(int number)
{
if (!m_widget || !m_map) {
return;
}
if (m_widget->progressBarMap->maximum() < number) {
m_widget->progressBarMap->setMaximum(number);
}
m_widget->progressBarMap->setValue(m_widget->progressBarMap->maximum() - number); // update the progress bar
m_prev_tile_number = number;
}
/**
Show the progress bar as soon as the map lib starts downloading
*/
void OPMapGadgetWidget::OnTileLoadStart()
{
if (!m_widget || !m_map) {
return;
}
m_widget->progressBarMap->setVisible(true);
}
/**
Hide the progress bar once the map lib has finished downloading
TODO: somehow this gets called before tile load is actually complete?
*/
void OPMapGadgetWidget::OnTileLoadComplete()
{
if (!m_widget || !m_map) {
return;
}
m_widget->progressBarMap->setVisible(false);
}
void OPMapGadgetWidget::on_toolButtonZoomP_clicked()
{
QMutexLocker locker(&m_map_mutex);
zoomIn();
}
void OPMapGadgetWidget::on_toolButtonZoomM_clicked()
{
QMutexLocker locker(&m_map_mutex);
zoomOut();
}
void OPMapGadgetWidget::on_toolButtonMapHome_clicked()
{
QMutexLocker locker(&m_map_mutex);
goHome();
}
void OPMapGadgetWidget::on_toolButtonMapUAV_clicked()
{
if (!m_widget || !m_map) {
return;
}
QMutexLocker locker(&m_map_mutex);
followUAVpositionAct->toggle();
}
void OPMapGadgetWidget::on_toolButtonMapUAVheading_clicked()
{
if (!m_widget || !m_map) {
return;
}
followUAVheadingAct->toggle();
}
void OPMapGadgetWidget::on_horizontalSliderZoom_sliderMoved(int position)
{
if (!m_widget || !m_map) {
return;
}
QMutexLocker locker(&m_map_mutex);
setZoom(position);
}
void OPMapGadgetWidget::on_toolButtonNormalMapMode_clicked()
{
setMapMode(Normal_MapMode);
}
void OPMapGadgetWidget::on_toolButtonMagicWaypointMapMode_clicked()
{
setMapMode(MagicWaypoint_MapMode);
}
void OPMapGadgetWidget::on_toolButtonHomeWaypoint_clicked()
{
homeMagicWaypoint();
}
void OPMapGadgetWidget::on_toolButtonMoveToWP_clicked()
{
moveToMagicWaypointPosition();
}
// *************************************************************************************
// public slots
void OPMapGadgetWidget::onTelemetryConnect()
{
m_telemetry_connected = true;
if (!obum) {
return;
}
bool set;
double LLA[3];
// ***********************
// fetch the home location
if (obum->getHomeLocation(set, LLA) < 0) {
return; // error
}
setHome(internals::PointLatLng(LLA[0], LLA[1]), LLA[2]);
if (m_map) {
if (m_map->UAV->GetMapFollowType() != UAVMapFollowType::None) {
m_map->SetCurrentPosition(m_home_position.coord); // set the map position
}
}
// ***********************
}
void OPMapGadgetWidget::onTelemetryDisconnect()
{
m_telemetry_connected = false;
}
// Updates the Home position icon whenever the HomePosition object is updated
void OPMapGadgetWidget::homePositionUpdated(UAVObject *hp)
{
Q_UNUSED(hp);
if (!obum) {
return;
}
bool set;
double LLA[3];
if (obum->getHomeLocation(set, LLA) < 0) {
return; // error
}
setHome(internals::PointLatLng(LLA[0], LLA[1]), LLA[2]);
}
// *************************************************************************************
// public functions
/**
Sets the home position on the map widget
*/
void OPMapGadgetWidget::setHome(QPointF pos)
{
if (!m_widget || !m_map) {
return;
}
double latitude = pos.x();
double longitude = pos.y();
if (latitude > 90) {
latitude = 90;
} else if (latitude < -90) {
latitude = -90;
}
if (longitude != longitude) {
longitude = 0; // nan detection
} else if (longitude > 180) {
longitude = 180;
} else if (longitude < -180) {
longitude = -180;
}
setHome(internals::PointLatLng(latitude, longitude), 0);
}
/**
Sets the home position on the map widget
*/
void OPMapGadgetWidget::setHome(internals::PointLatLng pos_lat_lon, double altitude)
{
if (!m_widget || !m_map) {
return;
}
if (pos_lat_lon.Lat() != pos_lat_lon.Lat() || pos_lat_lon.Lng() != pos_lat_lon.Lng()) {
return;
}
; // nan prevention
double latitude = pos_lat_lon.Lat();
double longitude = pos_lat_lon.Lng();
if (latitude != latitude) {
latitude = 0; // nan detection
} else if (latitude > 90) {
latitude = 90;
} else if (latitude < -90) {
latitude = -90;
}
if (longitude != longitude) {
longitude = 0; // nan detection
} else if (longitude > 180) {
longitude = 180;
} else if (longitude < -180) {
longitude = -180;
}
// *********
m_home_position.coord = internals::PointLatLng(latitude, longitude);
m_home_position.altitude = altitude;
m_map->Home->SetCoord(m_home_position.coord);
m_map->Home->SetAltitude(altitude);
m_map->Home->RefreshPos();
// move the magic waypoint to keep it within the safe area boundry
keepMagicWaypointWithInSafeArea();
}
/**
Centers the map over the home position
*/
void OPMapGadgetWidget::goHome()
{
if (!m_widget || !m_map) {
return;
}
followUAVpositionAct->setChecked(false);
internals::PointLatLng home_pos = m_home_position.coord; // get the home location
m_map->SetCurrentPosition(home_pos); // center the map onto the home location
}
void OPMapGadgetWidget::zoomIn()
{
if (!m_widget || !m_map) {
return;
}
int zoom = m_map->ZoomTotal() + 1;
if (zoom < m_min_zoom) {
zoom = m_min_zoom;
} else if (zoom > m_max_zoom) {
zoom = m_max_zoom;
}
m_map->SetZoom(zoom);
}
void OPMapGadgetWidget::zoomOut()
{
if (!m_widget || !m_map) {
return;
}
int zoom = m_map->ZoomTotal() - 1;
if (zoom < m_min_zoom) {
zoom = m_min_zoom;
} else if (zoom > m_max_zoom) {
zoom = m_max_zoom;
}
m_map->SetZoom(zoom);
}
void OPMapGadgetWidget::setMaxUpdateRate(int update_rate)
{
if (!m_widget || !m_map) {
return;
}
int list_size = sizeof(max_update_rate_list) / sizeof(max_update_rate_list[0]);
int min_rate = max_update_rate_list[0];
int max_rate = max_update_rate_list[list_size - 1];
if (update_rate < min_rate) {
update_rate = min_rate;
} else if (update_rate > max_rate) {
update_rate = max_rate;
}
m_maxUpdateRate = update_rate;
if (m_updateTimer) {
m_updateTimer->setInterval(m_maxUpdateRate);
}
// if (m_statusUpdateTimer)
// m_statusUpdateTimer->setInterval(m_maxUpdateRate);
}
void OPMapGadgetWidget::setZoom(int zoom)
{
if (!m_widget || !m_map) {
return;
}
if (zoom < m_min_zoom) {
zoom = m_min_zoom;
} else if (zoom > m_max_zoom) {
zoom = m_max_zoom;
}
internals::MouseWheelZoomType::Types zoom_type = m_map->GetMouseWheelZoomType();
m_map->SetMouseWheelZoomType(internals::MouseWheelZoomType::ViewCenter);
m_map->SetZoom(zoom);
m_map->SetMouseWheelZoomType(zoom_type);
}
void OPMapGadgetWidget::setOverlayOpacity(qreal value)
{
if (!m_widget || !m_map) {
return;
}
m_map->setOverlayOpacity(value);
overlayOpacityAct.at(value * 10)->setChecked(true);
}
void OPMapGadgetWidget::setHomePosition(QPointF pos)
{
if (!m_widget || !m_map) {
return;
}
double latitude = pos.y();
double longitude = pos.x();
if (latitude != latitude || longitude != longitude) {
return; // nan prevention
}
if (latitude > 90) {
latitude = 90;
} else if (latitude < -90) {
latitude = -90;
}
if (longitude > 180) {
longitude = 180;
} else if (longitude < -180) {
longitude = -180;
}
m_map->Home->SetCoord(internals::PointLatLng(latitude, longitude));
}
void OPMapGadgetWidget::setPosition(QPointF pos)
{
if (!m_widget || !m_map) {
return;
}
double latitude = pos.y();
double longitude = pos.x();
if (latitude != latitude || longitude != longitude) {
return; // nan prevention
}
if (latitude > 90) {
latitude = 90;
} else if (latitude < -90) {
latitude = -90;
}
if (longitude > 180) {
longitude = 180;
} else if (longitude < -180) {
longitude = -180;
}
m_map->SetCurrentPosition(internals::PointLatLng(latitude, longitude));
}
void OPMapGadgetWidget::setMapProvider(QString provider)
{
if (!m_widget || !m_map) {
return;
}
m_map->SetMapType(mapcontrol::Helper::MapTypeFromString(provider));
}
void OPMapGadgetWidget::setAccessMode(QString accessMode)
{
if (!m_widget || !m_map) {
return;
}
m_map->configuration->SetAccessMode(mapcontrol::Helper::AccessModeFromString(accessMode));
}
void OPMapGadgetWidget::setUseOpenGL(bool useOpenGL)
{
if (!m_widget || !m_map) {
return;
}
m_map->SetUseOpenGL(useOpenGL);
}
void OPMapGadgetWidget::setShowTileGridLines(bool showTileGridLines)
{
if (!m_widget || !m_map) {
return;
}
m_map->SetShowTileGridLines(showTileGridLines);
}
void OPMapGadgetWidget::setUseMemoryCache(bool useMemoryCache)
{
if (!m_widget || !m_map) {
return;
}
m_map->configuration->SetUseMemoryCache(useMemoryCache);
}
void OPMapGadgetWidget::setCacheLocation(QString cacheLocation)
{
if (!m_widget || !m_map) {
return;
}
cacheLocation = cacheLocation.simplified(); // remove any surrounding spaces
if (cacheLocation.isEmpty()) {
return;
}
if (!cacheLocation.endsWith(QDir::separator())) {
cacheLocation += QDir::separator();
}
QDir dir;
if (!dir.exists(cacheLocation)) {
if (!dir.mkpath(cacheLocation)) {
return;
}
}
m_map->configuration->SetCacheLocation(cacheLocation);
}
void OPMapGadgetWidget::setMapMode(opMapModeType mode)
{
if (!m_widget || !m_map) {
return;
}
if (mode != Normal_MapMode && mode != MagicWaypoint_MapMode) {
mode = Normal_MapMode; // fix error
}
if (m_map_mode == mode) { // no change in map mode
switch (mode) { // make sure the UI buttons are set correctly
case Normal_MapMode:
m_widget->toolButtonMagicWaypointMapMode->setChecked(false);
m_widget->toolButtonNormalMapMode->setChecked(true);
break;
case MagicWaypoint_MapMode:
m_widget->toolButtonNormalMapMode->setChecked(false);
m_widget->toolButtonMagicWaypointMapMode->setChecked(true);
break;
}
return;
}
switch (mode) {
case Normal_MapMode:
m_map_mode = Normal_MapMode;
m_widget->toolButtonMagicWaypointMapMode->setChecked(false);
m_widget->toolButtonNormalMapMode->setChecked(true);
hideMagicWaypointControls();
magicWayPoint->setVisible(false);
m_map->WPSetVisibleAll(true);
break;
case MagicWaypoint_MapMode:
m_map_mode = MagicWaypoint_MapMode;
m_widget->toolButtonNormalMapMode->setChecked(false);
m_widget->toolButtonMagicWaypointMapMode->setChecked(true);
showMagicWaypointControls();
// delete the normal waypoints from the map
m_map->WPSetVisibleAll(false);
magicWayPoint->setVisible(true);
break;
}
}
// *************************************************************************************
// Context menu stuff
void OPMapGadgetWidget::createActions()
{
int list_size;
if (!m_widget || !m_map) {
return;
}
// ***********************
// create menu actions
closeAct1 = new QAction(tr("Close menu"), this);
closeAct1->setStatusTip(tr("Close the context menu"));
closeAct2 = new QAction(tr("Close menu"), this);
closeAct2->setStatusTip(tr("Close the context menu"));
reloadAct = new QAction(tr("&Reload map"), this);
reloadAct->setShortcut(tr("F5"));
reloadAct->setStatusTip(tr("Reload the map tiles"));
connect(reloadAct, SIGNAL(triggered()), this, SLOT(onReloadAct_triggered()));
this->addAction(reloadAct);
ripAct = new QAction(tr("&Rip map"), this);
ripAct->setStatusTip(tr("Rip the map tiles"));
connect(ripAct, SIGNAL(triggered()), this, SLOT(onRipAct_triggered()));
copyMouseLatLonToClipAct = new QAction(tr("Mouse latitude and longitude"), this);
copyMouseLatLonToClipAct->setStatusTip(tr("Copy the mouse latitude and longitude to the clipboard"));
connect(copyMouseLatLonToClipAct, SIGNAL(triggered()), this, SLOT(onCopyMouseLatLonToClipAct_triggered()));
copyMouseLatToClipAct = new QAction(tr("Mouse latitude"), this);
copyMouseLatToClipAct->setStatusTip(tr("Copy the mouse latitude to the clipboard"));
connect(copyMouseLatToClipAct, SIGNAL(triggered()), this, SLOT(onCopyMouseLatToClipAct_triggered()));
copyMouseLonToClipAct = new QAction(tr("Mouse longitude"), this);
copyMouseLonToClipAct->setStatusTip(tr("Copy the mouse longitude to the clipboard"));
connect(copyMouseLonToClipAct, SIGNAL(triggered()), this, SLOT(onCopyMouseLonToClipAct_triggered()));
showCompassAct = new QAction(tr("Show compass"), this);
showCompassAct->setStatusTip(tr("Show/Hide the compass"));
showCompassAct->setCheckable(true);
showCompassAct->setChecked(true);
connect(showCompassAct, SIGNAL(toggled(bool)), this, SLOT(onShowCompassAct_toggled(bool)));
showDiagnostics = new QAction(tr("Show Diagnostics"), this);
showDiagnostics->setStatusTip(tr("Show/Hide the diagnostics"));
showDiagnostics->setCheckable(true);
showDiagnostics->setChecked(false);
connect(showDiagnostics, SIGNAL(toggled(bool)), this, SLOT(onShowDiagnostics_toggled(bool)));
showUAVInfo = new QAction(tr("Show UAV Info"), this);
showUAVInfo->setStatusTip(tr("Show/Hide the UAV info"));
showUAVInfo->setCheckable(true);
showUAVInfo->setChecked(false);
connect(showUAVInfo, SIGNAL(toggled(bool)), this, SLOT(onShowUAVInfo_toggled(bool)));
showHomeAct = new QAction(tr("Show Home"), this);
showHomeAct->setStatusTip(tr("Show/Hide the Home location"));
showHomeAct->setCheckable(true);
showHomeAct->setChecked(true);
connect(showHomeAct, SIGNAL(toggled(bool)), this, SLOT(onShowHomeAct_toggled(bool)));
showUAVAct = new QAction(tr("Show UAV"), this);
showUAVAct->setStatusTip(tr("Show/Hide the UAV"));
showUAVAct->setCheckable(true);
showUAVAct->setChecked(true);
connect(showUAVAct, SIGNAL(toggled(bool)), this, SLOT(onShowUAVAct_toggled(bool)));
changeDefaultLocalAndZoom = new QAction(tr("Set default zoom and location"), this);
changeDefaultLocalAndZoom->setStatusTip(tr("Changes the map default zoom and location to the current values"));
connect(changeDefaultLocalAndZoom, SIGNAL(triggered()), this, SLOT(onChangeDefaultLocalAndZoom()));
zoomInAct = new QAction(tr("Zoom &In"), this);
zoomInAct->setShortcut(Qt::Key_PageUp);
zoomInAct->setStatusTip(tr("Zoom the map in"));
connect(zoomInAct, SIGNAL(triggered()), this, SLOT(onGoZoomInAct_triggered()));
this->addAction(zoomInAct);
zoomOutAct = new QAction(tr("Zoom &Out"), this);
zoomOutAct->setShortcut(Qt::Key_PageDown);
zoomOutAct->setStatusTip(tr("Zoom the map out"));
connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(onGoZoomOutAct_triggered()));
this->addAction(zoomOutAct);
goMouseClickAct = new QAction(tr("Go to where you right clicked the mouse"), this);
goMouseClickAct->setStatusTip(tr("Center the map onto where you right clicked the mouse"));
connect(goMouseClickAct, SIGNAL(triggered()), this, SLOT(onGoMouseClickAct_triggered()));
setHomeAct = new QAction(tr("Set the home location"), this);
setHomeAct->setStatusTip(tr("Set the home location to where you clicked"));
#if !defined(allow_manual_home_location_move)
setHomeAct->setEnabled(false);
#endif
connect(setHomeAct, SIGNAL(triggered()), this, SLOT(onSetHomeAct_triggered()));
goHomeAct = new QAction(tr("Go to &Home location"), this);
goHomeAct->setShortcut(tr("Ctrl+H"));
goHomeAct->setStatusTip(tr("Center the map onto the home location"));
connect(goHomeAct, SIGNAL(triggered()), this, SLOT(onGoHomeAct_triggered()));
goUAVAct = new QAction(tr("Go to &UAV location"), this);
goUAVAct->setShortcut(tr("Ctrl+U"));
goUAVAct->setStatusTip(tr("Center the map onto the UAV location"));
connect(goUAVAct, SIGNAL(triggered()), this, SLOT(onGoUAVAct_triggered()));
followUAVpositionAct = new QAction(tr("Follow UAV position"), this);
followUAVpositionAct->setShortcut(tr("Ctrl+F"));
followUAVpositionAct->setStatusTip(tr("Keep the map centered onto the UAV"));
followUAVpositionAct->setCheckable(true);
followUAVpositionAct->setChecked(false);
connect(followUAVpositionAct, SIGNAL(toggled(bool)), this, SLOT(onFollowUAVpositionAct_toggled(bool)));
followUAVheadingAct = new QAction(tr("Follow UAV heading"), this);
followUAVheadingAct->setShortcut(tr("Ctrl+F"));
followUAVheadingAct->setStatusTip(tr("Keep the map rotation to the UAV heading"));
followUAVheadingAct->setCheckable(true);
followUAVheadingAct->setChecked(false);
connect(followUAVheadingAct, SIGNAL(toggled(bool)), this, SLOT(onFollowUAVheadingAct_toggled(bool)));
/*
TODO: Waypoint support is disabled for v1.0
*/
#ifdef USE_PATHPLANNER
wayPointEditorAct = new QAction(tr("&Waypoint editor"), this);
wayPointEditorAct->setShortcut(tr("Ctrl+W"));
wayPointEditorAct->setStatusTip(tr("Open the waypoint editor"));
connect(wayPointEditorAct, SIGNAL(triggered()), this, SLOT(onOpenWayPointEditorAct_triggered()));
addWayPointActFromContextMenu = new QAction(tr("&Add waypoint"), this);
addWayPointActFromContextMenu->setShortcut(tr("Ctrl+A"));
addWayPointActFromContextMenu->setStatusTip(tr("Add waypoint"));
connect(addWayPointActFromContextMenu, SIGNAL(triggered()), this, SLOT(onAddWayPointAct_triggeredFromContextMenu()));
addWayPointActFromThis = new QAction(tr("&Add waypoint"), this);
addWayPointActFromThis->setShortcut(tr("Ctrl+A"));
addWayPointActFromThis->setStatusTip(tr("Add waypoint"));
connect(addWayPointActFromThis, SIGNAL(triggered()), this, SLOT(onAddWayPointAct_triggeredFromThis()));
this->addAction(addWayPointActFromThis);
editWayPointAct = new QAction(tr("&Edit waypoint"), this);
editWayPointAct->setShortcut(tr("Ctrl+E"));
editWayPointAct->setStatusTip(tr("Edit waypoint"));
connect(editWayPointAct, SIGNAL(triggered()), this, SLOT(onEditWayPointAct_triggered()));
lockWayPointAct = new QAction(tr("&Lock waypoint"), this);
lockWayPointAct->setStatusTip(tr("Lock/Unlock a waypoint"));
lockWayPointAct->setCheckable(true);
lockWayPointAct->setChecked(false);
connect(lockWayPointAct, SIGNAL(triggered()), this, SLOT(onLockWayPointAct_triggered()));
deleteWayPointAct = new QAction(tr("&Delete waypoint"), this);
deleteWayPointAct->setShortcut(tr("Ctrl+D"));
deleteWayPointAct->setStatusTip(tr("Delete waypoint"));
connect(deleteWayPointAct, SIGNAL(triggered()), this, SLOT(onDeleteWayPointAct_triggered()));
clearWayPointsAct = new QAction(tr("&Clear waypoints"), this);
clearWayPointsAct->setShortcut(tr("Ctrl+C"));
clearWayPointsAct->setStatusTip(tr("Clear waypoints"));
connect(clearWayPointsAct, SIGNAL(triggered()), this, SLOT(onClearWayPointsAct_triggered()));
#endif // ifdef USE_PATHPLANNER
overlayOpacityActGroup = new QActionGroup(this);
connect(overlayOpacityActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onOverlayOpacityActGroup_triggered(QAction *)));
overlayOpacityAct.clear();
for (int i = 0; i <= 10; i++) {
QAction *overlayAct = new QAction(QString::number(i * 10), overlayOpacityActGroup);
overlayAct->setCheckable(true);
overlayAct->setData(i * 10);
overlayOpacityAct.append(overlayAct);
}
homeMagicWaypointAct = new QAction(tr("Home magic waypoint"), this);
homeMagicWaypointAct->setStatusTip(tr("Move the magic waypoint to the home position"));
connect(homeMagicWaypointAct, SIGNAL(triggered()), this, SLOT(onHomeMagicWaypointAct_triggered()));
mapModeActGroup = new QActionGroup(this);
connect(mapModeActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onMapModeActGroup_triggered(QAction *)));
mapModeAct.clear();
{
QAction *map_mode_act;
map_mode_act = new QAction(tr("Normal"), mapModeActGroup);
map_mode_act->setCheckable(true);
map_mode_act->setChecked(m_map_mode == Normal_MapMode);
map_mode_act->setData((int)Normal_MapMode);
mapModeAct.append(map_mode_act);
map_mode_act = new QAction(tr("Magic Waypoint"), mapModeActGroup);
map_mode_act->setCheckable(true);
map_mode_act->setChecked(m_map_mode == MagicWaypoint_MapMode);
map_mode_act->setData((int)MagicWaypoint_MapMode);
mapModeAct.append(map_mode_act);
}
zoomActGroup = new QActionGroup(this);
connect(zoomActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onZoomActGroup_triggered(QAction *)));
zoomAct.clear();
for (int i = m_min_zoom; i <= m_max_zoom; i++) {
QAction *zoom_act = new QAction(QString::number(i), zoomActGroup);
zoom_act->setCheckable(true);
zoom_act->setData(i);
zoomAct.append(zoom_act);
}
maxUpdateRateActGroup = new QActionGroup(this);
connect(maxUpdateRateActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onMaxUpdateRateActGroup_triggered(QAction *)));
maxUpdateRateAct.clear();
list_size = sizeof(max_update_rate_list) / sizeof(max_update_rate_list[0]);
for (int i = 0; i < list_size; i++) {
QAction *maxUpdateRate_act;
int j = max_update_rate_list[i];
maxUpdateRate_act = new QAction(QString::number(j), maxUpdateRateActGroup);
maxUpdateRate_act->setCheckable(true);
maxUpdateRate_act->setData(j);
maxUpdateRate_act->setChecked(j == m_maxUpdateRate);
maxUpdateRateAct.append(maxUpdateRate_act);
}
// *****
// safe area
showSafeAreaAct = new QAction(tr("Show Safe Area"), this);
showSafeAreaAct->setStatusTip(tr("Show/Hide the Safe Area around the home location"));
showSafeAreaAct->setCheckable(true);
showSafeAreaAct->setChecked(m_map->Home->ShowSafeArea());
connect(showSafeAreaAct, SIGNAL(toggled(bool)), this, SLOT(onShowSafeAreaAct_toggled(bool)));
safeAreaActGroup = new QActionGroup(this);
connect(safeAreaActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onSafeAreaActGroup_triggered(QAction *)));
safeAreaAct.clear();
list_size = sizeof(safe_area_radius_list) / sizeof(safe_area_radius_list[0]);
for (int i = 0; i < list_size; i++) {
int safeArea = safe_area_radius_list[i];
QAction *safeArea_act = new QAction(QString::number(safeArea) + "m", safeAreaActGroup);
safeArea_act->setCheckable(true);
safeArea_act->setChecked(safeArea == m_map->Home->SafeArea());
safeArea_act->setData(safeArea);
safeAreaAct.append(safeArea_act);
}
// *****
// UAV trail
uavTrailTypeActGroup = new QActionGroup(this);
connect(uavTrailTypeActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onUAVTrailTypeActGroup_triggered(QAction *)));
uavTrailTypeAct.clear();
QStringList uav_trail_type_list = mapcontrol::Helper::UAVTrailTypes();
for (int i = 0; i < uav_trail_type_list.count(); i++) {
mapcontrol::UAVTrailType::Types uav_trail_type = mapcontrol::Helper::UAVTrailTypeFromString(uav_trail_type_list[i]);
QAction *uavTrailType_act = new QAction(mapcontrol::Helper::StrFromUAVTrailType(uav_trail_type), uavTrailTypeActGroup);
uavTrailType_act->setCheckable(true);
uavTrailType_act->setChecked(uav_trail_type == m_map->UAV->GetTrailType());
uavTrailType_act->setData(i);
uavTrailTypeAct.append(uavTrailType_act);
}
showTrailAct = new QAction(tr("Show Trail dots"), this);
showTrailAct->setStatusTip(tr("Show/Hide the Trail dots"));
showTrailAct->setCheckable(true);
showTrailAct->setChecked(true);
connect(showTrailAct, SIGNAL(toggled(bool)), this, SLOT(onShowTrailAct_toggled(bool)));
showTrailLineAct = new QAction(tr("Show Trail lines"), this);
showTrailLineAct->setStatusTip(tr("Show/Hide the Trail lines"));
showTrailLineAct->setCheckable(true);
showTrailLineAct->setChecked(true);
connect(showTrailLineAct, SIGNAL(toggled(bool)), this, SLOT(onShowTrailLineAct_toggled(bool)));
clearUAVtrailAct = new QAction(tr("Clear UAV trail"), this);
clearUAVtrailAct->setStatusTip(tr("Clear the UAV trail"));
connect(clearUAVtrailAct, SIGNAL(triggered()), this, SLOT(onClearUAVtrailAct_triggered()));
uavTrailTimeActGroup = new QActionGroup(this);
connect(uavTrailTimeActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onUAVTrailTimeActGroup_triggered(QAction *)));
uavTrailTimeAct.clear();
list_size = sizeof(uav_trail_time_list) / sizeof(uav_trail_time_list[0]);
for (int i = 0; i < list_size; i++) {
int uav_trail_time = uav_trail_time_list[i];
QAction *uavTrailTime_act = new QAction(QString::number(uav_trail_time) + " sec", uavTrailTimeActGroup);
uavTrailTime_act->setCheckable(true);
uavTrailTime_act->setChecked(uav_trail_time == m_map->UAV->TrailTime());
uavTrailTime_act->setData(uav_trail_time);
uavTrailTimeAct.append(uavTrailTime_act);
}
uavTrailDistanceActGroup = new QActionGroup(this);
connect(uavTrailDistanceActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onUAVTrailDistanceActGroup_triggered(QAction *)));
uavTrailDistanceAct.clear();
list_size = sizeof(uav_trail_distance_list) / sizeof(uav_trail_distance_list[0]);
for (int i = 0; i < list_size; i++) {
int uav_trail_distance = uav_trail_distance_list[i];
QAction *uavTrailDistance_act = new QAction(QString::number(uav_trail_distance) + " meters", uavTrailDistanceActGroup);
uavTrailDistance_act->setCheckable(true);
uavTrailDistance_act->setChecked(uav_trail_distance == m_map->UAV->TrailDistance());
uavTrailDistance_act->setData(uav_trail_distance);
uavTrailDistanceAct.append(uavTrailDistance_act);
}
}
void OPMapGadgetWidget::onReloadAct_triggered()
{
if (!m_widget || !m_map) {
return;
}
m_map->ReloadMap();
}
void OPMapGadgetWidget::onRipAct_triggered()
{
m_map->RipMap();
}
void OPMapGadgetWidget::onCopyMouseLatLonToClipAct_triggered()
{
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(QString::number(m_context_menu_lat_lon.Lat(), 'f', 7) + ", " + QString::number(m_context_menu_lat_lon.Lng(), 'f', 7), QClipboard::Clipboard);
}
void OPMapGadgetWidget::onCopyMouseLatToClipAct_triggered()
{
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(QString::number(m_context_menu_lat_lon.Lat(), 'f', 7), QClipboard::Clipboard);
}
void OPMapGadgetWidget::onCopyMouseLonToClipAct_triggered()
{
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(QString::number(m_context_menu_lat_lon.Lng(), 'f', 7), QClipboard::Clipboard);
}
void OPMapGadgetWidget::onShowCompassAct_toggled(bool show)
{
if (!m_widget || !m_map) {
return;
}
m_map->SetShowCompass(show);
}
void OPMapGadgetWidget::onShowDiagnostics_toggled(bool show)
{
if (!m_widget || !m_map) {
return;
}
m_map->SetShowDiagnostics(show);
}
void OPMapGadgetWidget::onShowUAVInfo_toggled(bool show)
{
if (!m_widget || !m_map) {
return;
}
m_map->UAV->SetShowUAVInfo(show);
}
void OPMapGadgetWidget::onShowHomeAct_toggled(bool show)
{
if (!m_widget || !m_map) {
return;
}
m_map->Home->setVisible(show);
}
void OPMapGadgetWidget::onShowUAVAct_toggled(bool show)
{
if (!m_widget || !m_map) {
return;
}
m_map->UAV->setVisible(show);
if (m_map->GPS) {
m_map->GPS->setVisible(show);
}
}
void OPMapGadgetWidget::onShowTrailAct_toggled(bool show)
{
if (!m_widget || !m_map) {
return;
}
m_map->UAV->SetShowTrail(show);
if (m_map->GPS) {
m_map->GPS->SetShowTrail(show);
}
}
void OPMapGadgetWidget::onShowTrailLineAct_toggled(bool show)
{
if (!m_widget || !m_map) {
return;
}
m_map->UAV->SetShowTrailLine(show);
if (m_map->GPS) {
m_map->GPS->SetShowTrailLine(show);
}
}
void OPMapGadgetWidget::onMapModeActGroup_triggered(QAction *action)
{
if (!m_widget || !m_map || !action) {
return;
}
opMapModeType mode = (opMapModeType)action->data().toInt();
setMapMode(mode);
}
void OPMapGadgetWidget::onGoZoomInAct_triggered()
{
zoomIn();
}
void OPMapGadgetWidget::onGoZoomOutAct_triggered()
{
zoomOut();
}
void OPMapGadgetWidget::onZoomActGroup_triggered(QAction *action)
{
if (!m_widget || !m_map || !action) {
return;
}
setZoom(action->data().toInt());
}
void OPMapGadgetWidget::onMaxUpdateRateActGroup_triggered(QAction *action)
{
if (!m_widget || !m_map || !action) {
return;
}
setMaxUpdateRate(action->data().toInt());
}
void OPMapGadgetWidget::onChangeDefaultLocalAndZoom()
{
emit defaultLocationAndZoomChanged(m_map->CurrentPosition().Lng(), m_map->CurrentPosition().Lat(), m_map->ZoomTotal());
}
void OPMapGadgetWidget::onGoMouseClickAct_triggered()
{
if (!m_widget || !m_map) {
return;
}
m_map->SetCurrentPosition(m_map->currentMousePosition()); // center the map onto the mouse position
}
void OPMapGadgetWidget::onSetHomeAct_triggered()
{
if (!m_widget || !m_map) {
return;
}
float altitude = 0;
bool ok;
// Get desired HomeLocation altitude from dialog box.
// TODO: Populate box with altitude already in HomeLocation UAVO
altitude = QInputDialog::getDouble(this, tr("Set home altitude"),
tr("In [m], referenced to WGS84:"), altitude, -100, 100000, 2, &ok);
setHome(m_context_menu_lat_lon, altitude);
setHomeLocationObject(); // update the HomeLocation UAVObject
}
void OPMapGadgetWidget::onGoHomeAct_triggered()
{
if (!m_widget || !m_map) {
return;
}
goHome();
}
void OPMapGadgetWidget::onGoUAVAct_triggered()
{
if (!m_widget || !m_map) {
return;
}
double latitude;
double longitude;
double altitude;
if (getUAVPosition(latitude, longitude, altitude)) { // get current UAV position
internals::PointLatLng uav_pos = internals::PointLatLng(latitude, longitude); // current UAV position
internals::PointLatLng map_pos = m_map->CurrentPosition(); // current MAP position
if (map_pos != uav_pos) {
m_map->SetCurrentPosition(uav_pos); // center the map onto the UAV
}
}
}
void OPMapGadgetWidget::onFollowUAVpositionAct_toggled(bool checked)
{
if (!m_widget || !m_map) {
return;
}
if (m_widget->toolButtonMapUAV->isChecked() != checked) {
m_widget->toolButtonMapUAV->setChecked(checked);
}
setMapFollowingMode();
}
void OPMapGadgetWidget::onFollowUAVheadingAct_toggled(bool checked)
{
if (!m_widget || !m_map) {
return;
}
if (m_widget->toolButtonMapUAVheading->isChecked() != checked) {
m_widget->toolButtonMapUAVheading->setChecked(checked);
}
setMapFollowingMode();
}
void OPMapGadgetWidget::onUAVTrailTypeActGroup_triggered(QAction *action)
{
if (!m_widget || !m_map || !action) {
return;
}
int trail_type_idx = action->data().toInt();
QStringList uav_trail_type_list = mapcontrol::Helper::UAVTrailTypes();
mapcontrol::UAVTrailType::Types uav_trail_type = mapcontrol::Helper::UAVTrailTypeFromString(uav_trail_type_list[trail_type_idx]);
m_map->UAV->SetTrailType(uav_trail_type);
}
void OPMapGadgetWidget::onClearUAVtrailAct_triggered()
{
if (!m_widget || !m_map) {
return;
}
m_map->UAV->DeleteTrail();
if (m_map->GPS) {
m_map->GPS->DeleteTrail();
}
}
void OPMapGadgetWidget::onUAVTrailTimeActGroup_triggered(QAction *action)
{
if (!m_widget || !m_map || !action) {
return;
}
int trail_time = (double)action->data().toInt();
m_map->UAV->SetTrailTime(trail_time);
}
void OPMapGadgetWidget::onUAVTrailDistanceActGroup_triggered(QAction *action)
{
if (!m_widget || !m_map || !action) {
return;
}
int trail_distance = action->data().toInt();
m_map->UAV->SetTrailDistance(trail_distance);
}
void OPMapGadgetWidget::onOpenWayPointEditorAct_triggered()
{
table->show();
}
void OPMapGadgetWidget::onAddWayPointAct_triggeredFromContextMenu()
{
onAddWayPointAct_triggered(m_context_menu_lat_lon);
}
void OPMapGadgetWidget::onAddWayPointAct_triggeredFromThis()
{
onAddWayPointAct_triggered(lastLatLngMouse);
}
void OPMapGadgetWidget::onAddWayPointAct_triggered(internals::PointLatLng coord)
{
if (!m_widget || !m_map) {
return;
}
if (m_map_mode != Normal_MapMode) {
return;
}
mapProxy->createWayPoint(coord);
}
/**
* Called when the user asks to edit a waypoint from the map
*
* TODO: should open an interface to edit waypoint properties, or
* propagate the signal to a specific WP plugin (tbd).
**/
void OPMapGadgetWidget::onEditWayPointAct_triggered()
{
if (!m_widget || !m_map) {
return;
}
if (m_map_mode != Normal_MapMode) {
return;
}
if (!m_mouse_waypoint) {
return;
}
waypoint_edit_dialog->editWaypoint(m_mouse_waypoint);
m_mouse_waypoint = NULL;
}
/**
* TODO: unused for v1.0
*/
void OPMapGadgetWidget::onLockWayPointAct_triggered()
{
if (!m_widget || !m_map || !m_mouse_waypoint) {
return;
}
if (m_map_mode != Normal_MapMode) {
return;
}
bool locked = (m_mouse_waypoint->flags() & QGraphicsItem::ItemIsMovable) == 0;
m_mouse_waypoint->setFlag(QGraphicsItem::ItemIsMovable, locked);
if (!locked) {
m_mouse_waypoint->picture.load(QString::fromUtf8(":/opmap/images/waypoint_marker2.png"));
} else {
m_mouse_waypoint->picture.load(QString::fromUtf8(":/opmap/images/waypoint_marker1.png"));
}
m_mouse_waypoint->update();
m_mouse_waypoint = NULL;
}
void OPMapGadgetWidget::onDeleteWayPointAct_triggered()
{
if (!m_widget || !m_map) {
return;
}
if (m_map_mode != Normal_MapMode) {
return;
}
if (!m_mouse_waypoint) {
return;
}
mapProxy->deleteWayPoint(m_mouse_waypoint->Number());
}
void OPMapGadgetWidget::onClearWayPointsAct_triggered()
{
// First, ask to ensure this is what the user wants to do
QMessageBox msgBox;
msgBox.setText(tr("Are you sure you want to clear waypoints?"));
msgBox.setInformativeText(tr("All associated data will be lost."));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
int ret = msgBox.exec();
if (ret == QMessageBox::No) {
return;
}
if (!m_widget || !m_map) {
return;
}
if (m_map_mode != Normal_MapMode) {
return;
}
mapProxy->deleteAll();
}
void OPMapGadgetWidget::onHomeMagicWaypointAct_triggered()
{
// center the magic waypoint on the home position
homeMagicWaypoint();
}
void OPMapGadgetWidget::onShowSafeAreaAct_toggled(bool show)
{
if (!m_widget || !m_map) {
return;
}
m_map->Home->SetShowSafeArea(show); // show the safe area
m_map->Home->SetToggleRefresh(true);
m_map->Home->RefreshPos();
}
void OPMapGadgetWidget::onSafeAreaActGroup_triggered(QAction *action)
{
if (!m_widget || !m_map || !action) {
return;
}
int radius = action->data().toInt();
m_map->Home->SetSafeArea(radius); // set the radius (meters)
m_map->Home->RefreshPos();
// move the magic waypoint if need be to keep it within the safe area around the home position
keepMagicWaypointWithInSafeArea();
}
/**
* move the magic waypoint to the home position
**/
void OPMapGadgetWidget::homeMagicWaypoint()
{
if (!m_widget || !m_map) {
return;
}
if (m_map_mode != MagicWaypoint_MapMode) {
return;
}
magicWayPoint->SetCoord(m_home_position.coord);
}
// *************************************************************************************
// move the UAV to the magic waypoint position
void OPMapGadgetWidget::moveToMagicWaypointPosition()
{
if (!m_widget || !m_map) {
return;
}
if (m_map_mode != MagicWaypoint_MapMode) {
return;
}
}
// *************************************************************************************
// show/hide the magic waypoint controls
void OPMapGadgetWidget::hideMagicWaypointControls()
{
m_widget->lineWaypoint->setVisible(false);
m_widget->toolButtonHomeWaypoint->setVisible(false);
m_widget->toolButtonMoveToWP->setVisible(false);
}
void OPMapGadgetWidget::showMagicWaypointControls()
{
m_widget->lineWaypoint->setVisible(true);
m_widget->toolButtonHomeWaypoint->setVisible(true);
#if defined(allow_manual_home_location_move)
m_widget->toolButtonMoveToWP->setVisible(true);
#else
m_widget->toolButtonMoveToWP->setVisible(false);
#endif
}
// *************************************************************************************
// move the magic waypoint to keep it within the safe area boundry
void OPMapGadgetWidget::keepMagicWaypointWithInSafeArea()
{
// calcute the bearing and distance from the home position to the magic waypoint
double dist = distance(m_home_position.coord, magicWayPoint->Coord());
double bear = bearing(m_home_position.coord, magicWayPoint->Coord());
// get the maximum safe distance - in kilometers
double boundry_dist = (double)m_map->Home->SafeArea() / 1000;
if (dist > boundry_dist) {
dist = boundry_dist;
}
// move the magic waypoint;
if (m_map_mode == MagicWaypoint_MapMode) { // move the on-screen waypoint
if (magicWayPoint) {
magicWayPoint->SetCoord(destPoint(m_home_position.coord, bear, dist));
}
}
}
// *************************************************************************************
// return the distance between two points .. in kilometers
double OPMapGadgetWidget::distance(internals::PointLatLng from, internals::PointLatLng to)
{
double lat1 = from.Lat() * deg_to_rad;
double lon1 = from.Lng() * deg_to_rad;
double lat2 = to.Lat() * deg_to_rad;
double lon2 = to.Lng() * deg_to_rad;
return acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon2 - lon1)) * earth_mean_radius;
// ***********************
}
// *************************************************************************************
// return the bearing from one point to another .. in degrees
double OPMapGadgetWidget::bearing(internals::PointLatLng from, internals::PointLatLng to)
{
double lat1 = from.Lat() * deg_to_rad;
double lon1 = from.Lng() * deg_to_rad;
double lat2 = to.Lat() * deg_to_rad;
double lon2 = to.Lng() * deg_to_rad;
// double delta_lat = lat2 - lat1;
double delta_lon = lon2 - lon1;
double y = sin(delta_lon) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(delta_lon);
double bear = atan2(y, x) * rad_to_deg;
bear += 360;
while (bear < 0) {
bear += 360;
}
while (bear >= 360) {
bear -= 360;
}
return bear;
}
// *************************************************************************************
// return a destination lat/lon point given a source lat/lon point and the bearing and distance from the source point
internals::PointLatLng OPMapGadgetWidget::destPoint(internals::PointLatLng source, double bear, double dist)
{
double lat1 = source.Lat() * deg_to_rad;
double lon1 = source.Lng() * deg_to_rad;
bear *= deg_to_rad;
double ad = dist / earth_mean_radius;
double lat2 = asin(sin(lat1) * cos(ad) + cos(lat1) * sin(ad) * cos(bear));
double lon2 = lon1 + atan2(sin(bear) * sin(ad) * cos(lat1), cos(ad) - sin(lat1) * sin(lat2));
return internals::PointLatLng(lat2 * rad_to_deg, lon2 * rad_to_deg);
}
// *************************************************************************************
bool OPMapGadgetWidget::getUAVPosition(double &latitude, double &longitude, double &altitude)
{
double NED[3];
double LLA[3];
double homeLLA[3];
Q_ASSERT(obm != NULL);
HomeLocation *homeLocation = HomeLocation::GetInstance(obm);
Q_ASSERT(homeLocation != NULL);
HomeLocation::DataFields homeLocationData = homeLocation->getData();
homeLLA[0] = homeLocationData.Latitude / 1e7;
homeLLA[1] = homeLocationData.Longitude / 1e7;
homeLLA[2] = homeLocationData.Altitude;
PositionState *positionState = PositionState::GetInstance(obm);
Q_ASSERT(positionState != NULL);
PositionState::DataFields positionStateData = positionState->getData();
NED[0] = positionStateData.North;
NED[1] = positionStateData.East;
NED[2] = positionStateData.Down;
Utils::CoordinateConversions().NED2LLA_HomeLLA(homeLLA, NED, LLA);
latitude = LLA[0];
longitude = LLA[1];
altitude = LLA[2];
if (latitude != latitude) {
latitude = 0; // nan detection
} else if (latitude > 90) {
latitude = 90;
} else if (latitude < -90) {
latitude = -90;
}
if (longitude != longitude) {
longitude = 0; // nan detection
} else if (longitude > 180) {
longitude = 180;
} else if (longitude < -180) {
longitude = -180;
}
if (altitude != altitude) {
altitude = 0; // nan detection
}
return true;
}
double OPMapGadgetWidget::getUAV_Yaw()
{
if (!obm) {
return 0;
}
UAVObject *obj = dynamic_cast<UAVDataObject *>(obm->getObject(QString("AttitudeState")));
double yaw = obj->getField(QString("Yaw"))->getDouble();
if (yaw != yaw) {
yaw = 0; // nan detection
}
while (yaw < 0) {
yaw += 360;
}
while (yaw >= 360) {
yaw -= 360;
}
return yaw;
}
bool OPMapGadgetWidget::getGPSPositionSensor(double &latitude, double &longitude, double &altitude)
{
double LLA[3];
if (!obum) {
return false;
}
if (obum->getGPSPositionSensor(LLA) < 0) {
return false; // error
}
latitude = LLA[0];
longitude = LLA[1];
altitude = LLA[2];
return true;
}
// *************************************************************************************
void OPMapGadgetWidget::setMapFollowingMode()
{
if (!m_widget || !m_map) {
return;
}
if (!followUAVpositionAct->isChecked()) {
m_map->UAV->SetMapFollowType(UAVMapFollowType::None);
m_map->SetRotate(0); // reset map rotation to 0deg
} else if (!followUAVheadingAct->isChecked()) {
m_map->UAV->SetMapFollowType(UAVMapFollowType::CenterMap);
m_map->SetRotate(0); // reset map rotation to 0deg
} else {
m_map->UAV->SetMapFollowType(UAVMapFollowType::CenterMap); // the map library won't let you reset the uav rotation if it's already in rotate mode
m_map->UAV->SetUAVHeading(0); // reset the UAV heading to 0deg
m_map->UAV->SetMapFollowType(UAVMapFollowType::CenterAndRotateMap);
}
}
// *************************************************************************************
// update the HomeLocation UAV Object
bool OPMapGadgetWidget::setHomeLocationObject()
{
if (!obum) {
return false;
}
double LLA[3] = { m_home_position.coord.Lat(), m_home_position.coord.Lng(), m_home_position.altitude };
return obum->setHomeLocation(LLA, true) >= 0;
}
// *************************************************************************************
void OPMapGadgetWidget::SetUavPic(QString UAVPic)
{
m_map->SetUavPic(UAVPic);
}
void OPMapGadgetWidget::on_tbFind_clicked()
{
QPalette pal = m_widget->leFind->palette();
int result = m_map->SetCurrentPositionByKeywords(m_widget->leFind->text());
if (result == core::GeoCoderStatusCode::G_GEO_SUCCESS) {
pal.setColor(m_widget->leFind->backgroundRole(), Qt::green);
m_widget->leFind->setPalette(pal);
m_map->SetZoom(12);
} else {
pal.setColor(m_widget->leFind->backgroundRole(), Qt::red);
m_widget->leFind->setPalette(pal);
}
}
void OPMapGadgetWidget::onHomeDoubleClick(HomeItem *)
{
new homeEditor(m_map->Home, this);
}
void OPMapGadgetWidget::onOverlayOpacityActGroup_triggered(QAction *action)
{
if (!m_widget || !m_map || !action) {
return;
}
m_map->setOverlayOpacity(action->data().toReal() / 100);
emit overlayOpacityChanged(action->data().toReal() / 100);
}
void OPMapGadgetWidget::on_leFind_returnPressed()
{
on_tbFind_clicked();
}