Commit 69229517 authored by lm's avatar lm

Map caching works now, uav following as well. Waypoint lines and some...

Map caching works now, uav following as well. Waypoint lines and some graphical tweaks needed, but its very close to an alpha release now
parent 59bbbfbe
...@@ -60,7 +60,8 @@ HEADERS += opmapcontrol.h \ ...@@ -60,7 +60,8 @@ HEADERS += opmapcontrol.h \
src/internals/projections/mercatorprojection.h \ src/internals/projections/mercatorprojection.h \
src/internals/projections/mercatorprojectionyandex.h \ src/internals/projections/mercatorprojectionyandex.h \
src/internals/projections/platecarreeprojection.h \ src/internals/projections/platecarreeprojection.h \
src/internals/projections/platecarreeprojectionpergo.h src/internals/projections/platecarreeprojectionpergo.h \
src/libs/opmapcontrol/src/mapwidget/waypointlineitem.h
FORMS += src/mapwidget/mapripform.ui FORMS += src/mapwidget/mapripform.ui
SOURCES += src/core/alllayersoftype.cpp \ SOURCES += src/core/alllayersoftype.cpp \
src/core/cache.cpp \ src/core/cache.cpp \
...@@ -104,5 +105,6 @@ SOURCES += src/core/alllayersoftype.cpp \ ...@@ -104,5 +105,6 @@ SOURCES += src/core/alllayersoftype.cpp \
src/internals/projections/mercatorprojection.cpp \ src/internals/projections/mercatorprojection.cpp \
src/internals/projections/mercatorprojectionyandex.cpp \ src/internals/projections/mercatorprojectionyandex.cpp \
src/internals/projections/platecarreeprojection.cpp \ src/internals/projections/platecarreeprojection.cpp \
src/internals/projections/platecarreeprojectionpergo.cpp src/internals/projections/platecarreeprojectionpergo.cpp \
src/libs/opmapcontrol/src/mapwidget/waypointlineitem.cpp
RESOURCES += src/mapwidget/mapresources.qrc RESOURCES += src/mapwidget/mapresources.qrc
...@@ -109,6 +109,13 @@ namespace mapcontrol ...@@ -109,6 +109,13 @@ namespace mapcontrol
double ZoomDigi(); double ZoomDigi();
double ZoomTotal(); double ZoomTotal();
/**
* @brief The area currently selected by the user
*
* @return The rectangle in lat/lon coordinates currently selected
*/
internals::RectLatLng SelectedArea()const{return selectedArea;}
protected: protected:
void mouseMoveEvent ( QGraphicsSceneMouseEvent * event ); void mouseMoveEvent ( QGraphicsSceneMouseEvent * event );
void mousePressEvent ( QGraphicsSceneMouseEvent * event ); void mousePressEvent ( QGraphicsSceneMouseEvent * event );
...@@ -190,7 +197,6 @@ namespace mapcontrol ...@@ -190,7 +197,6 @@ namespace mapcontrol
int MinZoom()const{return minZoom;} int MinZoom()const{return minZoom;}
internals::MouseWheelZoomType::Types GetMouseWheelZoomType(){return core->GetMouseWheelZoomType();} internals::MouseWheelZoomType::Types GetMouseWheelZoomType(){return core->GetMouseWheelZoomType();}
void SetSelectedArea(internals::RectLatLng const& value){selectedArea = value;this->update();} void SetSelectedArea(internals::RectLatLng const& value){selectedArea = value;this->update();}
internals::RectLatLng SelectedArea()const{return selectedArea;}
internals::RectLatLng BoundsOfMap; internals::RectLatLng BoundsOfMap;
void Offset(int const& x, int const& y); void Offset(int const& x, int const& y);
bool CanDragMap()const{return core->CanDragMap;} bool CanDragMap()const{return core->CanDragMap;}
......
...@@ -94,12 +94,18 @@ namespace mapcontrol ...@@ -94,12 +94,18 @@ namespace mapcontrol
UAVItem* newUAV = new UAVItem(map,this); UAVItem* newUAV = new UAVItem(map,this);
newUAV->setParentItem(map); newUAV->setParentItem(map);
UAVS.insert(id, newUAV); UAVS.insert(id, newUAV);
QGraphicsItemGroup* waypointLine = new QGraphicsItemGroup();
waypointLine->setParentItem(map);
waypointLines.insert(id, waypointLine);
return newUAV; return newUAV;
} }
void OPMapWidget::AddUAV(int id, UAVItem* uav) void OPMapWidget::AddUAV(int id, UAVItem* uav)
{ {
uav->setParentItem(map); uav->setParentItem(map);
QGraphicsItemGroup* waypointLine = new QGraphicsItemGroup();
waypointLine->setParentItem(map);
waypointLines.insert(id, waypointLine);
UAVS.insert(id, uav); UAVS.insert(id, uav);
} }
......
#include "waypointlineitem.h"
WaypointLineItem::WaypointLineItem()
{
}
#ifndef WAYPOINTLINEITEM_H
#define WAYPOINTLINEITEM_H
#include <QGraphicsLineItem>
class WaypointLineItem : public QGraphicsLineItem
{
public:
WaypointLineItem();
};
#endif // WAYPOINTLINEITEM_H
...@@ -18,6 +18,42 @@ void QGCMapToolBar::setMap(QGCMapWidget* map) ...@@ -18,6 +18,42 @@ void QGCMapToolBar::setMap(QGCMapWidget* map)
{ {
connect(ui->goToButton, SIGNAL(clicked()), map, SLOT(showGoToDialog())); connect(ui->goToButton, SIGNAL(clicked()), map, SLOT(showGoToDialog()));
connect(ui->goHomeButton, SIGNAL(clicked()), map, SLOT(goHome())); connect(ui->goHomeButton, SIGNAL(clicked()), map, SLOT(goHome()));
connect(map, SIGNAL(OnTileLoadStart()), this, SLOT(tileLoadStart()));
connect(map, SIGNAL(OnTileLoadComplete()), this, SLOT(tileLoadEnd()));
connect(map, SIGNAL(OnTilesStillToLoad(int)), this, SLOT(tileLoadProgress(int)));
connect(ui->ripMapButton, SIGNAL(clicked()), map, SLOT(cacheVisibleRegion()));
ui->followCheckBox->setChecked(map->getFollowUAVEnabled());
connect(ui->followCheckBox, SIGNAL(clicked(bool)), map, SLOT(setFollowUAVEnabled(bool)));
// Edit mode handling
ui->editButton->hide();
}
}
void QGCMapToolBar::tileLoadStart()
{
ui->posLabel->setText(QString("Starting to load tiles.."));
}
void QGCMapToolBar::tileLoadEnd()
{
ui->posLabel->setText(QString("Finished"));
}
void QGCMapToolBar::tileLoadProgress(int progress)
{
if (progress == 1)
{
ui->posLabel->setText(QString("1 tile to load.."));
}
else if (progress > 0)
{
ui->posLabel->setText(QString("%1 tiles to load..").arg(progress));
}
else
{
tileLoadEnd();
} }
} }
......
...@@ -19,6 +19,11 @@ public: ...@@ -19,6 +19,11 @@ public:
void setMap(QGCMapWidget* map); void setMap(QGCMapWidget* map);
public slots:
void tileLoadStart();
void tileLoadEnd();
void tileLoadProgress(int progress);
protected: protected:
QGCMapWidget* map; QGCMapWidget* map;
......
...@@ -20,13 +20,6 @@ ...@@ -20,13 +20,6 @@
<property name="margin"> <property name="margin">
<number>4</number> <number>4</number>
</property> </property>
<item>
<widget class="QLabel" name="posLabel">
<property name="text">
<string>00.00 00.00</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="goToButton"> <widget class="QPushButton" name="goToButton">
<property name="text"> <property name="text">
...@@ -48,6 +41,13 @@ ...@@ -48,6 +41,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="ripMapButton">
<property name="text">
<string>Cache</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QCheckBox" name="followCheckBox"> <widget class="QCheckBox" name="followCheckBox">
<property name="text"> <property name="text">
...@@ -55,6 +55,13 @@ ...@@ -55,6 +55,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="posLabel">
<property name="text">
<string>00.00 00.00</string>
</property>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
......
...@@ -10,9 +10,12 @@ QGCMapWidget::QGCMapWidget(QWidget *parent) : ...@@ -10,9 +10,12 @@ QGCMapWidget::QGCMapWidget(QWidget *parent) :
mapcontrol::OPMapWidget(parent), mapcontrol::OPMapWidget(parent),
currWPManager(NULL), currWPManager(NULL),
firingWaypointChange(NULL), firingWaypointChange(NULL),
maxUpdateInterval(2) // 2 seconds maxUpdateInterval(2), // 2 seconds
followUAVEnabled(false)
{ {
// Widget is inactive until shown // Widget is inactive until shown
// Set cache mode
} }
QGCMapWidget::~QGCMapWidget() QGCMapWidget::~QGCMapWidget()
...@@ -152,7 +155,7 @@ void QGCMapWidget::storeSettings() ...@@ -152,7 +155,7 @@ void QGCMapWidget::storeSettings()
void QGCMapWidget::mouseDoubleClickEvent(QMouseEvent* event) void QGCMapWidget::mouseDoubleClickEvent(QMouseEvent* event)
{ {
//OPMapWidget::mouseDoubleClickEvent(event); OPMapWidget::mouseDoubleClickEvent(event);
if (currEditMode == EDIT_MODE_WAYPOINTS) if (currEditMode == EDIT_MODE_WAYPOINTS)
{ {
// If a waypoint manager is available // If a waypoint manager is available
...@@ -213,6 +216,7 @@ void QGCMapWidget::activeUASSet(UASInterface* uas) ...@@ -213,6 +216,7 @@ void QGCMapWidget::activeUASSet(UASInterface* uas)
connect(this, SIGNAL(waypointCreated(Waypoint*)), currWPManager, SLOT(addWaypoint(Waypoint*))); connect(this, SIGNAL(waypointCreated(Waypoint*)), currWPManager, SLOT(addWaypoint(Waypoint*)));
connect(this, SIGNAL(waypointChanged(Waypoint*)), currWPManager, SLOT(notifyOfChange(Waypoint*))); connect(this, SIGNAL(waypointChanged(Waypoint*)), currWPManager, SLOT(notifyOfChange(Waypoint*)));
updateSelectedSystem(uas->getUASID()); updateSelectedSystem(uas->getUASID());
followUAVID = uas->getUASID();
} }
} }
...@@ -246,6 +250,8 @@ void QGCMapWidget::updateGlobalPosition(UASInterface* uas, double lat, double lo ...@@ -246,6 +250,8 @@ void QGCMapWidget::updateGlobalPosition(UASInterface* uas, double lat, double lo
// Set new lat/lon position of UAV icon // Set new lat/lon position of UAV icon
internals::PointLatLng pos_lat_lon = internals::PointLatLng(lat, lon); internals::PointLatLng pos_lat_lon = internals::PointLatLng(lat, lon);
uav->SetUAVPos(pos_lat_lon, alt); uav->SetUAVPos(pos_lat_lon, alt);
// Follow status
if (followUAVEnabled && uas->getUASID() == followUAVID) SetCurrentPosition(pos_lat_lon);
// Convert from radians to degrees and apply // Convert from radians to degrees and apply
uav->SetUAVHeading((uas->getYaw()/M_PI)*180.0f); uav->SetUAVHeading((uas->getYaw()/M_PI)*180.0f);
} }
...@@ -265,14 +271,15 @@ void QGCMapWidget::updateGlobalPosition() ...@@ -265,14 +271,15 @@ void QGCMapWidget::updateGlobalPosition()
if (uav == NULL) if (uav == NULL)
{ {
MAV2DIcon* newUAV = new MAV2DIcon(map, this, system); MAV2DIcon* newUAV = new MAV2DIcon(map, this, system);
newUAV->setParentItem(map); AddUAV(system->getUASID(), newUAV);
UAVS.insert(system->getUASID(), newUAV); uav = newUAV;
uav = GetUAV(system->getUASID());
} }
// Set new lat/lon position of UAV icon // Set new lat/lon position of UAV icon
internals::PointLatLng pos_lat_lon = internals::PointLatLng(system->getLatitude(), system->getLongitude()); internals::PointLatLng pos_lat_lon = internals::PointLatLng(system->getLatitude(), system->getLongitude());
uav->SetUAVPos(pos_lat_lon, system->getAltitude()); uav->SetUAVPos(pos_lat_lon, system->getAltitude());
// Follow status
if (followUAVEnabled && system->getUASID() == followUAVID) SetCurrentPosition(pos_lat_lon);
// Convert from radians to degrees and apply // Convert from radians to degrees and apply
uav->SetUAVHeading((system->getYaw()/M_PI)*180.0f); uav->SetUAVHeading((system->getYaw()/M_PI)*180.0f);
} }
...@@ -316,7 +323,7 @@ void QGCMapWidget::showGoToDialog() ...@@ -316,7 +323,7 @@ void QGCMapWidget::showGoToDialog()
bool ok; bool ok;
QString text = QInputDialog::getText(this, tr("Please enter coordinates"), QString text = QInputDialog::getText(this, tr("Please enter coordinates"),
tr("Coordinates (Lat,Lon):"), QLineEdit::Normal, tr("Coordinates (Lat,Lon):"), QLineEdit::Normal,
QString("%1,%2").arg(CurrentPosition().Lat()).arg( CurrentPosition().Lng()), &ok); QString("%1,%2").arg(CurrentPosition().Lat(), 0, 'g', 6).arg(CurrentPosition().Lng(), 0, 'g', 6), &ok);
if (ok && !text.isEmpty()) { if (ok && !text.isEmpty()) {
QStringList split = text.split(","); QStringList split = text.split(",");
if (split.length() == 2) { if (split.length() == 2) {
...@@ -357,6 +364,26 @@ void QGCMapWidget::setUpdateRateLimit(float seconds) ...@@ -357,6 +364,26 @@ void QGCMapWidget::setUpdateRateLimit(float seconds)
updateTimer.start(maxUpdateInterval*1000); updateTimer.start(maxUpdateInterval*1000);
} }
void QGCMapWidget::cacheVisibleRegion()
{
internals::RectLatLng rect = map->SelectedArea();
if (rect.IsEmpty())
{
QMessageBox msgBox(this);
msgBox.setIcon(QMessageBox::Information);
msgBox.setText("Cannot cache tiles for offline use");
msgBox.setInformativeText("Please select an area first by holding down SHIFT or ALT and selecting the area with the left mouse button.");
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
RipMap();
// FIXME UNSELECT AREA NOW
}
// WAYPOINT MAP INTERACTION FUNCTIONS // WAYPOINT MAP INTERACTION FUNCTIONS
...@@ -407,73 +434,84 @@ void QGCMapWidget::updateWaypoint(int uas, Waypoint* wp) ...@@ -407,73 +434,84 @@ void QGCMapWidget::updateWaypoint(int uas, Waypoint* wp)
{ {
// Source of the event was in this widget, do nothing // Source of the event was in this widget, do nothing
if (firingWaypointChange == wp) return; if (firingWaypointChange == wp) return;
// Currently only accept waypoint updates from the UAS in focus // Currently only accept waypoint updates from the UAS in focus
// this has to be changed to accept read-only updates from other systems as well. // this has to be changed to accept read-only updates from other systems as well.
if (UASManager::instance()->getUASForId(uas)->getWaypointManager() == currWPManager) { if (UASManager::instance()->getUASForId(uas)->getWaypointManager() == currWPManager) {
// Only accept waypoints in global coordinate frame // Only accept waypoints in global coordinate frame
if (((wp->getFrame() == MAV_FRAME_GLOBAL) || (wp->getFrame() == MAV_FRAME_GLOBAL_RELATIVE_ALT)) && wp->isNavigationType()) { if (((wp->getFrame() == MAV_FRAME_GLOBAL) || (wp->getFrame() == MAV_FRAME_GLOBAL_RELATIVE_ALT)) && wp->isNavigationType()) {
// We're good, this is a global waypoint // We're good, this is a global waypoint
// Get the index of this waypoint // Get the index of this waypoint
// note the call to getGlobalFrameAndNavTypeIndexOf() // note the call to getGlobalFrameAndNavTypeIndexOf()
// as we're only handling global waypoints // as we're only handling global waypoints
int wpindex = UASManager::instance()->getUASForId(uas)->getWaypointManager()->getGlobalFrameAndNavTypeIndexOf(wp); int wpindex = UASManager::instance()->getUASForId(uas)->getWaypointManager()->getGlobalFrameAndNavTypeIndexOf(wp);
UASInterface* uasInstance = UASManager::instance()->getUASForId(uas); UASInterface* uasInstance = UASManager::instance()->getUASForId(uas);
// If not found, return (this should never happen, but helps safety) // If not found, return (this should never happen, but helps safety)
if (wpindex == -1) return; if (wpindex == -1) return;
// Mark this wp as currently edited // Mark this wp as currently edited
firingWaypointChange = wp; firingWaypointChange = wp;
// Check if wp exists yet in map // Check if wp exists yet in map
if (!waypointsToIcons.contains(wp)) { if (!waypointsToIcons.contains(wp)) {
// Create icon for new WP // Create icon for new WP
Waypoint2DIcon* icon = new Waypoint2DIcon(map, this, wp, uasInstance->getColor(), wpindex); Waypoint2DIcon* icon = new Waypoint2DIcon(map, this, wp, uasInstance->getColor(), wpindex);
ConnectWP(icon); ConnectWP(icon);
icon->setParentItem(map); icon->setParentItem(map);
// Update maps to allow inverse data association // Update maps to allow inverse data association
waypointsToIcons.insert(wp, icon); waypointsToIcons.insert(wp, icon);
iconsToWaypoints.insert(icon, wp); iconsToWaypoints.insert(icon, wp);
} else {
// Waypoint exists, block it's signals and update it // Add line element
mapcontrol::WayPointItem* icon = waypointsToIcons.value(wp); qDebug() << "ADDING LINE";
// Make sure we don't die on a null pointer mapcontrol::TrailLineItem* line = new mapcontrol::TrailLineItem(internals::PointLatLng(0.2, 0.2), icon->Coord(), QBrush(Qt::red), map);
// this should never happen, just a precaution QGraphicsItemGroup* group = waypointLines.value(uas, NULL);
if (!icon) return; if (group)
// Block outgoing signals to prevent an infinite signal loop {
// should not happen, just a precaution group->addToGroup(line);
this->blockSignals(true); qDebug() << "ADDED LINE!";
// Update the WP }
Waypoint2DIcon* wpicon = dynamic_cast<Waypoint2DIcon*>(icon); line->setVisible(true);
if (wpicon) } else {
{ // Waypoint exists, block it's signals and update it
// Let icon read out values directly from waypoint mapcontrol::WayPointItem* icon = waypointsToIcons.value(wp);
icon->SetNumber(wpindex); // Make sure we don't die on a null pointer
wpicon->updateWaypoint(); // this should never happen, just a precaution
} if (!icon) return;
else // Block outgoing signals to prevent an infinite signal loop
{ // should not happen, just a precaution
// Use safe standard interfaces for non Waypoint-class based wps this->blockSignals(true);
icon->SetCoord(internals::PointLatLng(wp->getLatitude(), wp->getLongitude())); // Update the WP
icon->SetAltitude(wp->getAltitude()); Waypoint2DIcon* wpicon = dynamic_cast<Waypoint2DIcon*>(icon);
icon->SetHeading(wp->getYaw()); if (wpicon)
icon->SetNumber(wpindex); {
} // Let icon read out values directly from waypoint
// Re-enable signals again icon->SetNumber(wpindex);
this->blockSignals(false); wpicon->updateWaypoint();
}
else
{
// Use safe standard interfaces for non Waypoint-class based wps
icon->SetCoord(internals::PointLatLng(wp->getLatitude(), wp->getLongitude()));
icon->SetAltitude(wp->getAltitude());
icon->SetHeading(wp->getYaw());
icon->SetNumber(wpindex);
} }
// Re-enable signals again
this->blockSignals(false);
}
firingWaypointChange = NULL; firingWaypointChange = NULL;
} else { } else {
// Check if the index of this waypoint is larger than the global // Check if the index of this waypoint is larger than the global
// waypoint list. This implies that the coordinate frame of this // waypoint list. This implies that the coordinate frame of this
// waypoint was changed and the list containing only global // waypoint was changed and the list containing only global
// waypoints was shortened. Thus update the whole list // waypoints was shortened. Thus update the whole list
if (waypointsToIcons.size() > UASManager::instance()->getUASForId(uas)->getWaypointManager()->getGlobalFrameAndNavTypeCount()) { if (waypointsToIcons.size() > UASManager::instance()->getUASForId(uas)->getWaypointManager()->getGlobalFrameAndNavTypeCount()) {
updateWaypointList(uas); updateWaypointList(uas);
}
} }
} }
}
} }
/** /**
......
...@@ -24,6 +24,9 @@ public: ...@@ -24,6 +24,9 @@ public:
// double headingP1P2(internals::PointLatLng p1, internals::PointLatLng p2); // double headingP1P2(internals::PointLatLng p1, internals::PointLatLng p2);
// internals::PointLatLng targetLatLon(internals::PointLatLng source, double heading, double dist); // internals::PointLatLng targetLatLon(internals::PointLatLng source, double heading, double dist);
/** @brief Map centered on current active system */
bool getFollowUAVEnabled() { return followUAVEnabled; }
signals: signals:
void homePositionChanged(double latitude, double longitude, double altitude); void homePositionChanged(double latitude, double longitude, double altitude);
/** @brief Signal for newly created map waypoints */ /** @brief Signal for newly created map waypoints */
...@@ -53,6 +56,10 @@ public slots: ...@@ -53,6 +56,10 @@ public slots:
void updateHomePosition(double latitude, double longitude, double altitude); void updateHomePosition(double latitude, double longitude, double altitude);
/** @brief Set update rate limit */ /** @brief Set update rate limit */
void setUpdateRateLimit(float seconds); void setUpdateRateLimit(float seconds);
/** @brief Cache visible region to harddisk */
void cacheVisibleRegion();
/** @brief Set follow mode */
void setFollowUAVEnabled(bool enabled) { followUAVEnabled = enabled; }
void loadSettings(); void loadSettings();
void storeSettings(); void storeSettings();
...@@ -85,6 +92,8 @@ protected: ...@@ -85,6 +92,8 @@ protected:
EDIT_MODE_CACHING EDIT_MODE_CACHING
}; };
editMode currEditMode; ///< The current edit mode on the map editMode currEditMode; ///< The current edit mode on the map
bool followUAVEnabled; ///< Does the map follow the UAV?
int followUAVID; ///< Which UAV should be tracked?
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment