Newer
Older
/*==================================================================
======================================================================*/
/**
* @file
lm
committed
#include "QGC.h"
#include "UASInterface.h"
#include "UASManager.h"
lm
committed
#include "MAV2DIcon.h"
#include "Waypoint2DIcon.h"
pixhawk
committed
#include "UASWaypointManager.h"
uasIcons(),
uasTrails(),
pixhawk
committed
mav(NULL),
initialized(false),
}
void MapWidget::init()
{
if (!initialized)
{
mc = new qmapcontrol::MapControl(this->size());
// display the MapControl in the application
QGridLayout* layout = new QGridLayout(this);
layout->setMargin(0);
layout->setSpacing(0);
layout->addWidget(mc, 0, 0);
setLayout(layout);
// VISUAL MAP STYLE
QString buttonStyle("QAbstractButton { background-color: rgba(20, 20, 20, 45%); border-color: rgba(10, 10, 10, 50%)} QAbstractButton:checked { border: 2px solid #379AC3; }");
mc->setPen(QGC::colorCyan.darker(400));
lm
committed
lm
committed
// Accept focus by clicking or keyboard
this->setFocusPolicy(Qt::StrongFocus);
// create MapControl
mc->showScale(true);
mc->showCoord(true);
mc->enablePersistentCache();
mc->setMouseTracking(true); // required to update the mouse position for diplay and capture
// create MapAdapter to get maps from
//TileMapAdapter* osmAdapter = new TileMapAdapter("tile.openstreetmap.org", "/%1/%2/%3.png", 256, 0, 17);
qmapcontrol::MapAdapter* mapadapter_overlay = new qmapcontrol::YahooMapAdapter("us.maps3.yimg.com", "/aerial.maps.yimg.com/png?v=2.2&t=h&s=256&x=%2&y=%3&z=%1");
// MAP BACKGROUND
mapadapter = new qmapcontrol::GoogleSatMapAdapter();
l = new qmapcontrol::MapLayer("Google Satellite", mapadapter);
mc->addLayer(l);
// STREET OVERLAY
overlay = new qmapcontrol::MapLayer("Overlay", mapadapter_overlay);
overlay->setVisible(false);
mc->addLayer(overlay);
// MAV FLIGHT TRACKS
tracks = new qmapcontrol::MapLayer("Tracking", mapadapter);
mc->addLayer(tracks);
// WAYPOINT LAYER
// create a layer with the mapadapter and type GeometryLayer (for waypoints)
geomLayer = new qmapcontrol::GeometryLayer("Waypoints", mapadapter);
mc->addLayer(geomLayer);
homePosition = new qmapcontrol::GeometryLayer("Station", mapadapter);
mc->addLayer(homePosition);
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
//
// Layer* gsatLayer = new Layer("Google Satellite", gsat, Layer::MapLayer);
// mc->addLayer(gsatLayer);
// Zurich, ETH
int lastZoom = 16;
double lastLat = 47.376889;
double lastLon = 8.548056;
QSettings settings;
settings.beginGroup("QGC_MAPWIDGET");
lastLat = settings.value("LAST_LATITUDE", lastLat).toDouble();
lastLon = settings.value("LAST_LONGITUDE", lastLon).toDouble();
lastZoom = settings.value("LAST_ZOOM", lastZoom).toInt();
settings.endGroup();
// SET INITIAL POSITION AND ZOOM
// Set default zoom level
mc->setZoom(lastZoom);
mc->setView(QPointF(lastLon, lastLat));
// Veracruz Mexico
//mc->setView(QPointF(-96.105208,19.138955));
// Add controls to select map provider
/////////////////////////////////////////////////
QActionGroup* mapproviderGroup = new QActionGroup(this);
osmAction = new QAction(QIcon(":/images/mapproviders/openstreetmap.png"), tr("OpenStreetMap"), mapproviderGroup);
yahooActionMap = new QAction(QIcon(":/images/mapproviders/yahoo.png"), tr("Yahoo: Map"), mapproviderGroup);
yahooActionSatellite = new QAction(QIcon(":/images/mapproviders/yahoo.png"), tr("Yahoo: Satellite"), mapproviderGroup);
googleActionMap = new QAction(QIcon(":/images/mapproviders/google.png"), tr("Google: Map"), mapproviderGroup);
googleSatAction = new QAction(QIcon(":/images/mapproviders/google.png"), tr("Google: Sat"), mapproviderGroup);
osmAction->setCheckable(true);
yahooActionMap->setCheckable(true);
yahooActionSatellite->setCheckable(true);
googleActionMap->setCheckable(true);
googleSatAction->setCheckable(true);
googleSatAction->setChecked(true);
connect(mapproviderGroup, SIGNAL(triggered(QAction*)),
this, SLOT(mapproviderSelected(QAction*)));
// Overlay seems currently broken
// yahooActionOverlay = new QAction(tr("Yahoo: street overlay"), this);
// yahooActionOverlay->setCheckable(true);
// yahooActionOverlay->setChecked(overlay->isVisible());
// connect(yahooActionOverlay, SIGNAL(toggled(bool)),
// overlay, SLOT(setVisible(bool)));
// mapproviderGroup->addAction(googleSatAction);
// mapproviderGroup->addAction(osmAction);
// mapproviderGroup->addAction(yahooActionOverlay);
// mapproviderGroup->addAction(googleActionMap);
// mapproviderGroup->addAction(yahooActionMap);
// mapproviderGroup->addAction(yahooActionSatellite);
// Create map provider selection menu
mapMenu = new QMenu(this);
mapMenu->addActions(mapproviderGroup->actions());
mapMenu->addSeparator();
// mapMenu->addAction(yahooActionOverlay);
mapButton = new QPushButton(this);
mapButton->setText("Map Source");
mapButton->setMenu(mapMenu);
mapButton->setStyleSheet(buttonStyle);
// create buttons to control the map (zoom, GPS tracking and WP capture)
QPushButton* zoomin = new QPushButton(QIcon(":/images/actions/list-add.svg"), "", this);
zoomin->setStyleSheet(buttonStyle);
QPushButton* zoomout = new QPushButton(QIcon(":/images/actions/list-remove.svg"), "", this);
zoomout->setStyleSheet(buttonStyle);
createPath = new QPushButton(QIcon(":/images/actions/go-bottom.svg"), "", this);
createPath->setStyleSheet(buttonStyle);
createPath->setToolTip(tr("Start / end waypoint add mode"));
createPath->setStatusTip(tr("Start / end waypoint add mode"));
// clearTracking = new QPushButton(QIcon(""), "", this);
// clearTracking->setStyleSheet(buttonStyle);
followgps = new QPushButton(QIcon(":/images/actions/system-lock-screen.svg"), "", this);
followgps->setStyleSheet(buttonStyle);
followgps->setToolTip(tr("Follow the position of the current MAV with the map center"));
followgps->setStatusTip(tr("Follow the position of the current MAV with the map center"));
QPushButton* goToButton = new QPushButton(QIcon(""), "T", this);
goToButton->setStyleSheet(buttonStyle);
goToButton->setToolTip(tr("Enter a latitude/longitude position to move the map to"));
goToButton->setStatusTip(tr("Enter a latitude/longitude position to move the map to"));
setHome = new QPushButton(QIcon(":/images/actions/go-home.svg"), "", this);
setHome->setStyleSheet(buttonStyle);
setHome->setToolTip(tr("Set home"));
setHome->setStatusTip(tr("Set home"));
zoomin->setMaximumWidth(30);
zoomout->setMaximumWidth(30);
createPath->setMaximumWidth(30);
// clearTracking->setMaximumWidth(30);
followgps->setMaximumWidth(30);
// Set checkable buttons
// TODO: Currently checked buttons are are very difficult to distinguish when checked.
// create a style and the slots to change the background so it is easier to distinguish
followgps->setCheckable(true);
createPath->setCheckable(true);
// add buttons to control the map (zoom, GPS tracking and WP capture)
QGridLayout* innerlayout = new QGridLayout(mc);
innerlayout->setMargin(3);
innerlayout->setSpacing(3);
innerlayout->addWidget(zoomin, 0, 0);
innerlayout->addWidget(zoomout, 1, 0);
innerlayout->addWidget(followgps, 2, 0);
innerlayout->addWidget(createPath, 3, 0);
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
//innerlayout->addWidget(clearTracking, 4, 0);
// Add spacers to compress buttons on the top left
innerlayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 5, 0);
innerlayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 0, 1, 0, 7);
innerlayout->addWidget(mapButton, 0, 6);
innerlayout->addWidget(goToButton, 0, 7);
innerlayout->setRowStretch(0, 1);
innerlayout->setRowStretch(1, 100);
mc->setLayout(innerlayout);
// Configure the WP Path's pen
pointPen = new QPen(QColor(0, 255,0));
pointPen->setWidth(3);
waypointPath = new qmapcontrol::LineString (wps, "Waypoint path", pointPen);
mc->layer("Waypoints")->addGeometry(waypointPath);
// Done set state
initialized = true;
// Connect the required signals-slots
connect(zoomin, SIGNAL(clicked(bool)),
mc, SLOT(zoomIn()));
connect(zoomout, SIGNAL(clicked(bool)),
mc, SLOT(zoomOut()));
connect(goToButton, SIGNAL(clicked()), this, SLOT(goTo()));
QList<UASInterface*> systems = UASManager::instance()->getUASList();
foreach(UASInterface* system, systems)
{
addUAS(system);
}
connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)),
this, SLOT(addUAS(UASInterface*)));
activeUASSet(UASManager::instance()->getActiveUAS());
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(activeUASSet(UASInterface*)));
connect(mc, SIGNAL(mouseEventCoordinate(const QMouseEvent*, const QPointF)),
this, SLOT(captureMapClick(const QMouseEvent*, const QPointF)));
connect(createPath, SIGNAL(clicked(bool)),
this, SLOT(createPathButtonClicked(bool)));
connect(setHome, SIGNAL(clicked(bool)), this, SLOT(createHomePositionClick(bool)));
connect(mc, SIGNAL(mouseEventCoordinate(const QMouseEvent*,QPointF)), this,
SLOT(createHomePosition(const QMouseEvent*,QPointF)));
//connect(setHome, SIGNAL(clicked(bool)), this, SLOT(createHomePosition(bool)));
connect(geomLayer, SIGNAL(geometryClicked(Geometry*,QPoint)),
this, SLOT(captureGeometryClick(Geometry*, QPoint)));
connect(geomLayer, SIGNAL(geometryDragged(Geometry*, QPointF)),
this, SLOT(captureGeometryDrag(Geometry*, QPointF)));
connect(geomLayer, SIGNAL(geometryEndDrag(Geometry*, QPointF)),
this, SLOT(captureGeometryEndDrag(Geometry*, QPointF)));
qDebug() << "CHECK END";
}
lm
committed
void MapWidget::goTo()
{
bool ok;
QString text = QInputDialog::getText(this, tr("Please enter coordinates"),
tr("Coordinates (Lat,Lon):"), QLineEdit::Normal,
QString("%1,%2").arg(mc->currentCoordinate().y()).arg(mc->currentCoordinate().x()), &ok);
if (ok && !text.isEmpty())
{
QStringList split = text.split(",");
if (split.length() == 2)
{
bool convert;
double latitude = split.first().toDouble(&convert);
ok &= convert;
double longitude = split.last().toDouble(&convert);
ok &= convert;
if (ok)
{
mc->setView(QPointF(longitude, latitude));
}
}
}
lm
committed
}
Mariano Lizarraga
committed
void MapWidget::mapproviderSelected(QAction* action)
{
//delete mapadapter;
mapButton->setText(action->text());
if (action == osmAction)
{
int zoom = mapadapter->adaptedZoom();
mc->setZoom(0);
mapadapter = new qmapcontrol::OSMMapAdapter();
l->setMapAdapter(mapadapter);
geomLayer->setMapAdapter(mapadapter);
homePosition->setMapAdapter(mapadapter);
if (isVisible()) mc->updateRequestNew();
mc->setZoom(zoom);
// yahooActionOverlay->setEnabled(false);
overlay->setVisible(false);
// yahooActionOverlay->setChecked(false);
}
else if (action == yahooActionMap)
{
int zoom = mapadapter->adaptedZoom();
mc->setZoom(0);
mapadapter = new qmapcontrol::YahooMapAdapter();
l->setMapAdapter(mapadapter);
geomLayer->setMapAdapter(mapadapter);
homePosition->setMapAdapter(mapadapter);
if (isVisible()) mc->updateRequestNew();
mc->setZoom(zoom);
// yahooActionOverlay->setEnabled(false);
overlay->setVisible(false);
// yahooActionOverlay->setChecked(false);
}
else if (action == yahooActionSatellite)
{
int zoom = mapadapter->adaptedZoom();
QPointF a = mc->currentCoordinate();
mc->setZoom(0);
mapadapter = new qmapcontrol::YahooMapAdapter("us.maps3.yimg.com", "/aerial.maps.yimg.com/png?v=1.7&t=a&s=256&x=%2&y=%3&z=%1");
l->setMapAdapter(mapadapter);
geomLayer->setMapAdapter(mapadapter);
homePosition->setMapAdapter(mapadapter);
if (isVisible()) mc->updateRequestNew();
mc->setZoom(zoom);
overlay->setVisible(false);
// yahooActionOverlay->setEnabled(true);
}
else if (action == googleActionMap)
{
int zoom = mapadapter->adaptedZoom();
mc->setZoom(0);
mapadapter = new qmapcontrol::GoogleMapAdapter();
l->setMapAdapter(mapadapter);
geomLayer->setMapAdapter(mapadapter);
homePosition->setMapAdapter(mapadapter);
if (isVisible()) mc->updateRequestNew();
mc->setZoom(zoom);
// yahooActionOverlay->setEnabled(false);
overlay->setVisible(false);
// yahooActionOverlay->setChecked(false);
}
else if (action == googleSatAction)
{
int zoom = mapadapter->adaptedZoom();
mc->setZoom(0);
mapadapter = new qmapcontrol::GoogleSatMapAdapter();
l->setMapAdapter(mapadapter);
geomLayer->setMapAdapter(mapadapter);
homePosition->setMapAdapter(mapadapter);
if (isVisible()) mc->updateRequestNew();
mc->setZoom(zoom);
// yahooActionOverlay->setEnabled(false);
overlay->setVisible(false);
// yahooActionOverlay->setChecked(false);
}
else
{
mapButton->setText("Select..");
}
Mariano Lizarraga
committed
}
void MapWidget::createPathButtonClicked(bool checked)
if (createPath->isChecked())
{
// change the cursor shape
this->setCursor(Qt::PointingHandCursor);
mc->setMouseMode(qmapcontrol::MapControl::None);
// emit signal start to create a Waypoint global
//emit createGlobalWP(true, mc->currentCoordinate());
// // Clear the previous WP track
// // TODO: Move this to an actual clear track button and add a warning dialog
// mc->layer("Waypoints")->clearGeometries();
// wps.clear();
// path->setPoints(wps);
// mc->layer("Waypoints")->addGeometry(path);
// wpIndex.clear();
}
else
{
this->setCursor(Qt::ArrowCursor);
mc->setMouseMode(qmapcontrol::MapControl::Panning);
}
}
Mariano Lizarraga
committed
}
Mariano Lizarraga
committed
/**
* Captures a click on the map and if in create WP path mode, it adds the WP on MouseButtonRelease
*
* @param event The mouse event
* @param coordinate The coordinate in which it occured the mouse event
* @note This slot is connected to the mouseEventCoordinate of the QMapControl object
*/
pixhawk
committed
void MapWidget::captureMapClick(const QMouseEvent* event, const QPointF coordinate)
{
if (QEvent::MouseButtonRelease == event->type() && createPath->isChecked())
pixhawk
committed
{
// Create waypoint name
QString str;
// create the WP and set everything in the LineString to display the path
Waypoint2DIcon* tempCirclePoint;
double altitude = 0.0;
double yaw = 0.0;
int wpListCount = mav->getWaypointManager()->getWaypointList().count();
if (wpListCount > 0)
{
altitude = mav->getWaypointManager()->getWaypointList().at(wpListCount-1)->getAltitude();
yaw = mav->getWaypointManager()->getWaypointList().at(wpListCount-1)->getYaw();
}
mav->getWaypointManager()->addWaypoint(new Waypoint(wpListCount, coordinate.y(), coordinate.x(), altitude, yaw, true));
pixhawk
committed
str = QString("%1").arg(waypointPath->numberOfPoints());
tempCirclePoint = new Waypoint2DIcon(coordinate.x(), coordinate.y(), 20, str, qmapcontrol::Point::Middle);
pixhawk
committed
wpIcons.append(tempCirclePoint);
pixhawk
committed
mc->layer("Waypoints")->addGeometry(tempCirclePoint);
pixhawk
committed
qmapcontrol::Point* tempPoint = new qmapcontrol::Point(coordinate.x(), coordinate.y(),str);
wps.append(tempPoint);
waypointPath->addPoint(tempPoint);
// Refresh the screen
if (isVisible()) mc->updateRequest(tempPoint->boundingBox().toRect());
pixhawk
committed
}
pixhawk
committed
//emit captureMapCoordinateClick(coordinate);
}
}
void MapWidget::updateWaypoint(int uas, Waypoint* wp)
{
// Update waypoint list and redraw map (last parameter)
pixhawk
committed
updateWaypoint(uas, wp, true);
}
/**
* This function is called if a a single waypoint is updated and
* also if the whole list changes.
*/
pixhawk
committed
void MapWidget::updateWaypoint(int uas, Waypoint* wp, bool updateView)
{
pixhawk
committed
{
// Make sure this is the right UAS
if (uas == this->mav->getUASID())
// Only accept waypoints in global coordinate frame
if (wp->getFrame() == MAV_FRAME_GLOBAL)
{
// We're good, this is a global waypoint
// Get the index of this waypoint
// note the call to getGlobalFrameIndexOf()
// as we're only handling global waypoints
int wpindex = UASManager::instance()->getUASForId(uas)->getWaypointManager()->getGlobalFrameIndexOf(wp);
// If not found, return (this should never happen, but helps safety)
if (wpindex == -1) return;
// Check if wp exists yet in map
if (!(wpIcons.count() > wpindex))
pixhawk
committed
{
coordinate.setX(wp->getLongitude());
coordinate.setY(wp->getLatitude());
createWaypointGraphAtMap(wpindex, coordinate);
}
else
{
// Waypoint exists, update it if we're not
// currently dragging it with the mouse
if(!waypointIsDrag)
pixhawk
committed
{
QPointF coordinate;
coordinate.setX(wp->getLongitude());
coordinate.setY(wp->getLatitude());
Point* waypoint;
waypoint = wps.at(wpindex);
if (waypoint)
// First set waypoint coordinate
waypoint->setCoordinate(coordinate);
// Now update icon position
wpIcons.at(wpindex)->setCoordinate(coordinate);
// Update pen
wpIcons.at(wpindex)->setPen(mavPens.value(uas));
// Then waypoint line coordinate
Point* linesegment = NULL;
// If the line segment already exists, just update it
// else create a new one
if (waypointPath->points().size() > wpindex)
{
linesegment = waypointPath->points().at(wpindex);
if (linesegment) linesegment->setCoordinate(coordinate);
}
else
{
waypointPath->addPoint(waypoint);
}
// Update view
if (updateView) if (isVisible()) mc->updateRequest(waypoint->boundingBox().toRect());
pixhawk
committed
}
}
}
// Check if the index of this waypoint is larger than the global
// waypoint list. This implies that the coordinate frame of this
// waypoint was changed and the list containing only global
// waypoints was shortened. Thus update the whole list
if (waypointPath->points().count() > UASManager::instance()->getUASForId(uas)->getWaypointManager()->getGlobalFrameCount())
{
updateWaypointList(uas);
}
lm
committed
}
void MapWidget::createWaypointGraphAtMap(int id, const QPointF coordinate)
{
//if (!wpExists(coordinate))
// Create waypoint name
QString str;
// create the WP and set everything in the LineString to display the path
//CirclePoint* tempCirclePoint = new CirclePoint(coordinate.x(), coordinate.y(), 10, str);
Waypoint2DIcon* tempCirclePoint;
pixhawk
committed
int uas = mav->getUASID();
pixhawk
committed
qDebug() << "Waypoint list count:" << str;
tempCirclePoint = new Waypoint2DIcon(coordinate.x(), coordinate.y(), 20, str, qmapcontrol::Point::Middle, mavPens.value(uas));
tempCirclePoint = new Waypoint2DIcon(coordinate.x(), coordinate.y(), 20, str, qmapcontrol::Point::Middle);
}
mc->layer("Waypoints")->addGeometry(tempCirclePoint);
Point* tempPoint = new Point(coordinate.x(), coordinate.y(),str);
wps.append(tempPoint);
waypointPath->addPoint(tempPoint);
//wpIndex.insert(str,tempPoint);
qDebug()<<"Funcion createWaypointGraphAtMap WP= "<<str<<" -> x= "<<tempPoint->latitude()<<" y= "<<tempPoint->longitude();
if (isVisible()) if (isVisible()) mc->updateRequest(tempPoint->boundingBox().toRect());
//// // emit signal mouse was clicked
// emit captureMapCoordinateClick(coordinate);
}
pixhawk
committed
int MapWidget::wpExists(const QPointF coordinate)
{
if (mc)
{
for (int i = 0; i < wps.size(); i++){
if (wps.at(i)->latitude() == coordinate.y() &&
wps.at(i)->longitude()== coordinate.x())
{
return 1;
}
pixhawk
committed
void MapWidget::captureGeometryClick(Geometry* geom, QPoint point)
{
if (mc) mc->setMouseMode(qmapcontrol::MapControl::None);
pixhawk
committed
void MapWidget::captureGeometryDrag(Geometry* geom, QPointF coordinate)
{
if (isVisible()) mc->updateRequest(geom->boundingBox().toRect());
pixhawk
committed
// Get waypoint index in list
bool wpIndexOk;
int index = geom->name().toInt(&wpIndexOk);
Waypoint2DIcon* point2Find = dynamic_cast <Waypoint2DIcon*> (geom);
if (wpIndexOk && point2Find && wps.count() > index)
// Update visual
point2Find->setCoordinate(coordinate);
waypointPath->points().at(index)->setCoordinate(coordinate);
if (isVisible()) mc->updateRequest(waypointPath->boundingBox().toRect());
// Update waypoint data storage
if (mav)
QVector<Waypoint*> wps = mav->getWaypointManager()->getGlobalFrameWaypointList();
if (wps.size() > index)
pixhawk
committed
{
Waypoint* wp = wps.at(index);
wp->setLatitude(coordinate.y());
wp->setLongitude(coordinate.x());
mav->getWaypointManager()->notifyOfChange(wp);
pixhawk
committed
}
// qDebug() << geom->name();
temp = geom->get_myIndex();
//qDebug() << temp;
emit sendGeometryEndDrag(coordinate,temp);
waypointIsDrag = false;
void MapWidget::captureGeometryEndDrag(Geometry* geom, QPointF coordinate)
tecnosapiens
committed
{
Q_UNUSED(geom);
Q_UNUSED(coordinate);
// TODO: Investigate why when creating the waypoint path this slot is being called
// Only change the mouse mode back to panning when not creating a WP path
if (!createPath->isChecked())
{
waypointIsDrag = false;
mc->setMouseMode(qmapcontrol::MapControl::Panning);
}
Mariano Lizarraga
committed
}
/**
*
* @param uas the UAS/MAV to monitor/display with the HUD
*/
void MapWidget::addUAS(UASInterface* uas)
{
connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(systemSpecsChanged(int)), this, SLOT(updateSystemSpecs(int)));
pixhawk
committed
}
/**
* Update the whole list of waypoints. This is e.g. necessary if the list order changed.
* The UAS manager will emit the appropriate signal whenever updating the list
* is necessary.
*/
pixhawk
committed
void MapWidget::updateWaypointList(int uas)
{
pixhawk
committed
{
// Get already existing waypoints
UASInterface* uasInstance = UASManager::instance()->getUASForId(uas);
if (uasInstance)
{
// Get update rect of old content, this is what will be redrawn
// in the last step
QRect updateRect = waypointPath->boundingBox().toRect();
pixhawk
committed
// Get all waypoints, including non-global waypoints
QVector<Waypoint*> wpList = uasInstance->getWaypointManager()->getWaypointList();
pixhawk
committed
// Clear if necessary
if (wpList.count() == 0)
{
clearWaypoints(uas);
return;
}
pixhawk
committed
// Trim internal list to number of global waypoints in the waypoint manager list
int overSize = waypointPath->points().count() - uasInstance->getWaypointManager()->getGlobalFrameCount();
if (overSize > 0)
pixhawk
committed
{
// Remove n waypoints at the end of the list
// the remaining waypoints will be updated
// in the next step
for (int i = 0; i < overSize; ++i)
{
wps.removeLast();
mc->layer("Waypoints")->removeGeometry(wpIcons.last());
wpIcons.removeLast();
waypointPath->points().removeLast();
}
pixhawk
committed
}
// Load all existing waypoints into map view
foreach (Waypoint* wp, wpList)
{
// Block map draw updates, since we update everything in the next step
// but update internal data structures.
// Please note that updateWaypoint() ignores non-global waypoints
updateWaypoint(mav->getUASID(), wp, false);
}
// Update view
if (isVisible()) mc->updateRequest(updateRect);
}
pixhawk
committed
}
}
void MapWidget::redoWaypoints(int uas)
{
// QObject* sender = QObject::sender();
// UASWaypointManager* manager = dynamic_cast<UASWaypointManager*>(sender);
// if (sender)
// {
// Get waypoint list for this MAV
// Clear all waypoints
//clearWaypoints();
pixhawk
committed
// Re-add the updated waypoints
// }
updateWaypointList(uas);
lm
committed
void MapWidget::activeUASSet(UASInterface* uas)
{
pixhawk
committed
// Disconnect old MAV
if (mav)
{
// Disconnect the waypoint manager / data storage from the UI
pixhawk
committed
disconnect(mav->getWaypointManager(), SIGNAL(waypointListChanged(int)), this, SLOT(updateWaypointList(int)));
pixhawk
committed
disconnect(mav->getWaypointManager(), SIGNAL(waypointChanged(int, Waypoint*)), this, SLOT(updateWaypoint(int,Waypoint*)));
pixhawk
committed
disconnect(this, SIGNAL(waypointCreated(Waypoint*)), mav->getWaypointManager(), SLOT(addWaypoint(Waypoint*)));
}
lm
committed
{
mav = uas;
QColor color = mav->getColor();
color.setAlphaF(0.9);
QPen* pen = new QPen(color);
pen->setWidth(3.0);
pixhawk
committed
mavPens.insert(mav->getUASID(), pen);
// FIXME Remove after refactoring
waypointPath->setPen(pen);
// Delete all waypoints and add waypoint from new system
//redoWaypoints();
updateWaypointList(uas->getUASID());
pixhawk
committed
// Connect the waypoint manager / data storage to the UI
pixhawk
committed
connect(mav->getWaypointManager(), SIGNAL(waypointListChanged(int)), this, SLOT(updateWaypointList(int)));
pixhawk
committed
connect(mav->getWaypointManager(), SIGNAL(waypointChanged(int, Waypoint*)), this, SLOT(updateWaypoint(int,Waypoint*)));
pixhawk
committed
connect(this, SIGNAL(waypointCreated(Waypoint*)), mav->getWaypointManager(), SLOT(addWaypoint(Waypoint*)));
updateSystemSpecs(mav->getUASID());
updateSelectedSystem(mav->getUASID());
mc->updateRequest(waypointPath->boundingBox().toRect());
}
}
void MapWidget::updateSystemSpecs(int uas)
{
foreach (qmapcontrol::Point* p, uasIcons.values())
MAV2DIcon* icon = dynamic_cast<MAV2DIcon*>(p);
if (icon && icon->getUASId() == uas)
{
// Set new airframe
icon->setAirframe(UASManager::instance()->getUASForId(uas)->getAirframe());
icon->drawIcon();
}
}
}
}
void MapWidget::updateSelectedSystem(int uas)
{
{
foreach (qmapcontrol::Point* p, uasIcons.values())
{
MAV2DIcon* icon = dynamic_cast<MAV2DIcon*>(p);
if (icon)
{
// Set as selected if ids match
icon->setSelectedUAS((icon->getUASId() == uas));
}
}
lm
committed
}
}
void MapWidget::updateAttitude(UASInterface* uas, double roll, double pitch, double yaw, quint64 usec)
{
Q_UNUSED(roll);
Q_UNUSED(pitch);
Q_UNUSED(usec);
MAV2DIcon* icon = dynamic_cast<MAV2DIcon*>(uasIcons.value(uas->getUASID(), NULL));
if (icon)
{
icon->setYaw(yaw);
}
/**
* Updates the global position of one MAV and append the last movement to the trail
*
* @param uas The unmanned air system
* @param lat Latitude in WGS84 ellipsoid
* @param lon Longitutde in WGS84 ellipsoid
* @param alt Altitude over mean sea level
* @param usec Timestamp of the position message in milliseconds FIXME will move to microseconds
*/
void MapWidget::updateGlobalPosition(UASInterface* uas, double lat, double lon, double alt, quint64 usec)
{
Q_UNUSED(usec);
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
// create a LineString
//QList<Point*> points;
// Points with a circle
// A QPen can be used to customize the
//pointpen->setWidth(3);
//points.append(new CirclePoint(lat, lon, 10, uas->getUASName(), Point::Middle, pointpen));
qmapcontrol::Point* p;
QPointF coordinate;
coordinate.setX(lon);
coordinate.setY(lat);
if (!uasIcons.contains(uas->getUASID()))
{
// Get the UAS color
QColor uasColor = uas->getColor();
// Icon
//QPen* pointpen = new QPen(uasColor);
qDebug() << "2D MAP: ADDING" << uas->getUASName() << __FILE__ << __LINE__;
p = new MAV2DIcon(uas, 68, uas->getSystemType(), uas->getColor(), QString("%1").arg(uas->getUASID()), qmapcontrol::Point::Middle);
uasIcons.insert(uas->getUASID(), p);
mc->layer("Waypoints")->addGeometry(p);
// Line
// A QPen also can use transparency
// QList<qmapcontrol::Point*> points;
// points.append(new qmapcontrol::Point(coordinate.x(), coordinate.y()));
// QPen* linepen = new QPen(uasColor.darker());
// linepen->setWidth(2);
// // Create tracking line string
// qmapcontrol::LineString* ls = new qmapcontrol::LineString(points, QString("%1").arg(uas->getUASID()), linepen);
// uasTrails.insert(uas->getUASID(), ls);
// // Add the LineString to the layer
// mc->layer("Waypoints")->addGeometry(ls);
}
else
{
// p = dynamic_cast<MAV2DIcon*>(uasIcons.value(uas->getUASID()));
// if (p)
// {
p = uasIcons.value(uas->getUASID());
p->setCoordinate(QPointF(lon, lat));
//p->setYaw(uas->getYaw());
// }
// Extend trail
// uasTrails.value(uas->getUASID())->addPoint(new qmapcontrol::Point(coordinate.x(), coordinate.y()));
}
if (isVisible()) mc->updateRequest(p->boundingBox().toRect());
//if (isVisible()) mc->updateRequestNew();//(uasTrails.value(uas->getUASID())->boundingBox().toRect());
if (this->mav && uas->getUASID() == this->mav->getUASID())
// Limit the position update rate
quint64 currTime = MG::TIME::getGroundTimeNow();
if (currTime - lastUpdate > 120)
{
lastUpdate = currTime;
// Sets the view to the interesting area
if (followgps->isChecked())
{
updatePosition(0, lon, lat);
}
else
{
// Refresh the screen
//if (isVisible()) mc->updateRequestNew();
}
}
/**
* Center the view on this position
*/
void MapWidget::updatePosition(float time, double lat, double lon)
//gpsposition->setText(QString::number(time) + " / " + QString::number(lat) + " / " + QString::number(lon));
if (mc) mc->setView(QPointF(lat, lon));
}
}
void MapWidget::wheelEvent(QWheelEvent *event)
{
if (mc)
{
int numDegrees = event->delta() / 8;
int numSteps = numDegrees / 15;
// Calculate new zoom level
int newZoom = mc->currentZoom()+numSteps;
// Set new zoom level, level is bounded by map control
mc->setZoom(newZoom);
// Detail zoom level is the number of steps zoomed in further
// after the bounding has taken effect
detailZoom = qAbs(qMin(0, mc->currentZoom()-newZoom));
// visual field of camera
//updateCameraPosition(20*newZoom,0,"no");
}
void MapWidget::keyPressEvent(QKeyEvent *event)
{
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
if (mc)
{
switch (event->key()) {
case Qt::Key_Plus:
mc->zoomIn();
break;
case Qt::Key_Minus:
mc->zoomOut();
break;
case Qt::Key_Left:
mc->scrollLeft(this->width()/scrollStep);
break;
case Qt::Key_Right:
mc->scrollRight(this->width()/scrollStep);
break;
case Qt::Key_Down:
mc->scrollDown(this->width()/scrollStep);
break;
case Qt::Key_Up:
mc->scrollUp(this->width()/scrollStep);
break;
default:
QWidget::keyPressEvent(event);
}
void MapWidget::resizeEvent(QResizeEvent* event )
Q_UNUSED(event);
void MapWidget::showEvent(QShowEvent* event)
{
Q_UNUSED(event);
// if (isVisible())
// {
// if (!initialized)
// {
// init();
// }
// }
}
void MapWidget::hideEvent(QHideEvent* event)
{
Q_UNUSED(event);
if (mc)
{
QSettings settings;
settings.beginGroup("QGC_MAPWIDGET");
QPointF currentPos = mc->currentCoordinate();
settings.setValue("LAST_LATITUDE", currentPos.y());
settings.setValue("LAST_LONGITUDE", currentPos.x());
settings.setValue("LAST_ZOOM", mc->currentZoom());
settings.endGroup();
settings.sync();
}
void MapWidget::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
break;
default:
break;
}
}
pixhawk
committed
void MapWidget::clearWaypoints(int uas)
pixhawk
committed
{
Q_UNUSED(uas);
// Clear the previous WP track
pixhawk
committed
//mc->layer("Waypoints")->clearGeometries();
wps.clear();
foreach (Point* p, wpIcons)
{
mc->layer("Waypoints")->removeGeometry(p);
}
wpIcons.clear();
pixhawk
committed
// Get bounding box of this object BEFORE deleting the content
QRect box = waypointPath->boundingBox().toRect();
pixhawk
committed
// Delete the content
waypointPath->points().clear();
//delete waypointPath;
//waypointPath = new
//mc->layer("Waypoints")->addGeometry(waypointPath);
//wpIndex.clear();
if (isVisible()) mc->updateRequest(box);//(waypointPath->boundingBox().toRect());
pixhawk
committed
if(createPath->isChecked())
{
createPath->click();
}
}
pixhawk
committed
void MapWidget::clearPath(int uas)
mc->layer("Tracking")->clearGeometries();
foreach (qmapcontrol::LineString* ls, uasTrails)
{
QPen* linepen = ls->pen();
delete ls;
qmapcontrol::LineString* lsNew = new qmapcontrol::LineString(QList<qmapcontrol::Point*>(), "", linepen);
mc->layer("Tracking")->addGeometry(lsNew);
}
// FIXME update this with update request only for bounding box of trails
if (isVisible()) mc->updateRequestNew();//(QRect(0, 0, width(), height()));
tecnosapiens
committed
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
void MapWidget::createHomePosition(const QMouseEvent *event, const QPointF coordinate)
{
if (QEvent::MouseButtonRelease == event->type() && setHome->isChecked())
{
homeCoordinate= coordinate;
Waypoint2DIcon* tempCirclePoint;
double latitud = homeCoordinate.x();
double longitud = homeCoordinate.y();
tempCirclePoint = new Waypoint2DIcon(
latitud,
longitud,
20, "g", qmapcontrol::Point::Middle);
QPen* pencil = new QPen(Qt::blue);
tempCirclePoint->setPen(pencil);
mc->layer("Station")->clearGeometries();
mc->layer("Station")->addGeometry(tempCirclePoint);
qmapcontrol::Point* tempPoint = new qmapcontrol::Point(latitud, longitud,"g");
if (isVisible())
{
mc->updateRequest(tempPoint->boundingBox().toRect());
}
}
}
void MapWidget::createHomePositionClick(bool click)
{
Q_UNUSED(click);
if (!setHome->isChecked())
{
UASManager::instance()->setHomePosition(
static_cast<double>(homeCoordinate.x()),
static_cast<double>(homeCoordinate.y()), 0);
qDebug()<<"Set home position "<<homeCoordinate.x()<<" "<<homeCoordinate.y();
}
}