Skip to content
MapWidget.cc 8.3 KiB
Newer Older
pixhawk's avatar
pixhawk committed
/*=====================================================================

PIXHAWK Micro Air Vehicle Flying Robotics Toolkit

(c) 2009, 2010 PIXHAWK PROJECT  <http://pixhawk.ethz.ch>

This file is part of the PIXHAWK project

    PIXHAWK 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.

    PIXHAWK 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 PIXHAWK. If not, see <http://www.gnu.org/licenses/>.

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

/**
 * @file
 *   @brief Implementation of map view
 *
 *   @author Lorenz Meier <mavteam@student.ethz.ch>
 *
 */

#include "MapWidget.h"
#include "ui_MapWidget.h"
lm's avatar
lm committed
#include "UASInterface.h"
#include "UASManager.h"
pixhawk's avatar
pixhawk committed

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

pixhawk's avatar
pixhawk committed
MapWidget::MapWidget(QWidget *parent) :
        QWidget(parent),
        zoomLevel(0),
        uasIcons(),
        uasTrails(),
pixhawk's avatar
pixhawk committed
        m_ui(new Ui::MapWidget)
{
    m_ui->setupUi(this);
    // Accept focus by clicking or keyboard
    this->setFocusPolicy(Qt::StrongFocus);

    // create MapControl
    mc = new MapControl(QSize(320, 240));
    mc->showScale(true);
    mc->enablePersistentCache();

    //uasIcons = QMap<int, CirclePoint*>();
pixhawk's avatar
pixhawk committed

pixhawk's avatar
pixhawk committed
    //QSize(480,640)
    //      ImageManager::instance()->setProxy("www-cache", 8080);

    // create MapAdapter to get maps from
    TileMapAdapter* osmAdapter = new TileMapAdapter("tile.openstreetmap.org", "/%1/%2/%3.png", 256, 0, 17);
    //GoogleSatMapAdapter* gSatAdapter = new GoogleSatMapAdapter();

    // create a layer with the mapadapter and type MapLayer
lm's avatar
lm committed
    osmLayer = new Layer("Custom Layer", osmAdapter, Layer::MapLayer);
pixhawk's avatar
pixhawk committed
    //Layer* gSatLayer = new Layer("Custom Layer", gSatAdapter, Layer::MapLayer);

    // add Layer to the MapControl
    mc->addLayer(osmLayer);
    //mc->addLayer(gSatLayer);

    // display the MapControl in the application
    QHBoxLayout* layout = new QHBoxLayout;
    layout->setMargin(0);
    layout->addWidget(mc);
    setLayout(layout);

    // create buttons as controls for zoom
    QPushButton* zoomin = new QPushButton(QIcon(":/images/actions/list-add.svg"), "", this);
    QPushButton* zoomout = new QPushButton(QIcon(":/images/actions/list-remove.svg"), "", this);
    followgps = new QPushButton(QIcon(":/images/actions/system-lock-screen.svg"), "", this);
    followgps->setCheckable(true);
pixhawk's avatar
pixhawk committed
    // gpsposition = new QLabel();
pixhawk's avatar
pixhawk committed
    zoomin->setMaximumWidth(50);
    zoomout->setMaximumWidth(50);
    followgps->setMaximumWidth(50);
    //gpsposition->setFont(QFont("Arial", 10));

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

    // add zoom buttons to the layout of the MapControl
    QVBoxLayout* innerlayout = new QVBoxLayout;
    innerlayout->addWidget(zoomin);
    innerlayout->addWidget(zoomout);
    innerlayout->addWidget(followgps);
    //innerlayout->addWidget(gpsposition);
    mc->setLayout(innerlayout);

    //GPS_Neo* gm = new GPS_Neo();
    //connect(gm, SIGNAL(new_position(float, QPointF)),
    //                  this, SLOT(updatePosition(float, QPointF)));
    //gm->start();

    mc->setZoom(3);
lm's avatar
lm committed

    connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(addUAS(UASInterface*)));
pixhawk's avatar
pixhawk committed
}

MapWidget::~MapWidget()
{
    delete m_ui;
}
lm's avatar
lm committed
/**
 *
 * @param uas the UAS/MAV to monitor/display with the HUD
 */
void MapWidget::addUAS(UASInterface* uas)
{
    mav = uas;
    connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64)));
lm's avatar
lm committed
}

void MapWidget::updateGlobalPosition(UASInterface* uas, double lat, double lon, double alt, quint64 usec)
{
    Q_UNUSED(usec);
pixhawk's avatar
pixhawk committed
    quint64 currTime = MG::TIME::getGroundTimeNow();
    if (currTime - lastUpdate > 90)
pixhawk's avatar
pixhawk committed
    {
        lastUpdate = currTime;
        // create a LineString
        //QList<Point*> points;
        // Points with a circle
        // A QPen can be used to customize the
        //pointpen->setWidth(3);
        //points.append(new CirclePoint(lat, lon, 10, uas->getUASName(), Point::Middle, pointpen));

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

            // Icon
            QPen* pointpen = new QPen(uasColor);
            CirclePoint* p = new CirclePoint(lat, lon, 10, uas->getUASName(), Point::Middle, pointpen);
            uasIcons.insert(uas->getUASID(), p);
            osmLayer->addGeometry(p);

            // Line
            // A QPen also can use transparency

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

            // Add the LineString to the layer
            osmLayer->addGeometry(ls);
        }
        else
        {
            CirclePoint* p = uasIcons.value(uas->getUASID());
            p->setCoordinate(QPointF(lat, lon));
            // Extend trail
            uasTrails.value(uas->getUASID())->addPoint(new Point(lat, lon, QString("lat: %1 lon: %2").arg(lat, lon)));
        }

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

        // Connect click events of the layer to this object
        //connect(osmLayer, SIGNAL(geometryClicked(Geometry*, QPoint)),
        //                  this, SLOT(geometryClicked(Geometry*, QPoint)));

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


lm's avatar
lm committed
void MapWidget::updatePosition(float time, double lat, double lon)
pixhawk's avatar
pixhawk committed
{
    //gpsposition->setText(QString::number(time) + " / " + QString::number(lat) + " / " + QString::number(lon));
pixhawk's avatar
pixhawk committed
    if (followgps->isChecked())
    {
lm's avatar
lm committed
        mc->setView(QPointF(lat, lon));
pixhawk's avatar
pixhawk committed
    }
}

void MapWidget::wheelEvent(QWheelEvent *event)
{
    int numDegrees = event->delta() / 8;
    int numSteps = numDegrees / 15;
    // Calculate new zoom level
    int newZoom = mc->currentZoom()+numSteps;
    // Set new zoom level, level is bounded by map control
    mc->setZoom(newZoom);
    // Detail zoom level is the number of steps zoomed in further
    // after the bounding has taken effect
    detailZoom = qAbs(qMin(0, mc->currentZoom()-newZoom));
}

void MapWidget::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_Plus:
        mc->zoomIn();
        break;
    case Qt::Key_Minus:
        mc->zoomOut();
        break;
    case Qt::Key_Left:
        mc->scrollLeft(this->width()/scrollStep);
        break;
    case Qt::Key_Right:
        mc->scrollRight(this->width()/scrollStep);
        break;
    case Qt::Key_Down:
        mc->scrollDown(this->width()/scrollStep);
        break;
    case Qt::Key_Up:
        mc->scrollUp(this->width()/scrollStep);
        break;
    default:
        QWidget::keyPressEvent(event);
    }
}

void MapWidget::resizeEvent(QResizeEvent* event )
pixhawk's avatar
pixhawk committed
{
    Q_UNUSED(event);
    mc->resize(this->size());
pixhawk's avatar
pixhawk committed
}


void MapWidget::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}