From 9717f87cc079d6f7e191769cb8fc23c6b2e6b95e Mon Sep 17 00:00:00 2001
From: pixhawk <pixhawk@student.ethz.ch>
Date: Thu, 13 Jan 2011 07:16:30 +0100
Subject: [PATCH] Experimental support for larger map tile buffer

---
 lib/QMapControl/src/layermanager.cpp | 28 +++++++++++++++++++---------
 lib/QMapControl/src/layermanager.h   | 12 +++++++++---
 lib/QMapControl/src/mapcontrol.cpp   | 26 ++++++++++++++++++++++++++
 lib/QMapControl/src/mapcontrol.h     |  9 +++++++++
 src/ui/MapWidget.cc                  | 26 +++++++++++++++++++++++---
 5 files changed, 86 insertions(+), 15 deletions(-)

diff --git a/lib/QMapControl/src/layermanager.cpp b/lib/QMapControl/src/layermanager.cpp
index 3358605..51bc9b9 100644
--- a/lib/QMapControl/src/layermanager.cpp
+++ b/lib/QMapControl/src/layermanager.cpp
@@ -29,12 +29,9 @@ namespace qmapcontrol
     LayerManager::LayerManager(MapControl* mapcontrol, QSize size)
         :mapcontrol(mapcontrol), scroll(QPoint(0,0)), size(size), whilenewscroll(QPoint(0,0))
     {
-        // genauer berechnen?
-        offSize = size *2;
-        composedOffscreenImage = QPixmap(offSize);
-        composedOffscreenImage2 = QPixmap(offSize);
+        setOffscreenImageFactor(2);
         zoomImage = QPixmap(size);
-        zoomImage.fill(Qt::white);
+        zoomImage.fill(Qt::black);
         screenmiddle = QPoint(size.width()/2, size.height()/2);
     }
 
@@ -44,6 +41,19 @@ namespace qmapcontrol
         mylayers.clear();
     }
 
+    void LayerManager::setOffscreenImageFactor(float factor)
+    {
+        offSize = size * factor;
+        offFactor = factor;
+        composedOffscreenImage = QPixmap(offSize);
+        composedOffscreenImage2 = QPixmap(offSize);
+    }
+
+    float LayerManager::offscreenImageFactor()
+    {
+        return offFactor;
+    }
+
     QPointF LayerManager::currentCoordinate() const
     {
         return mapmiddle;
@@ -229,7 +239,7 @@ namespace qmapcontrol
 
         if (clearImage)
         {
-            composedOffscreenImage2.fill(Qt::white);
+            composedOffscreenImage2.fill(Qt::black);
         }
 
         QPainter painter(&composedOffscreenImage2);
@@ -264,7 +274,7 @@ namespace qmapcontrol
         // layer rendern abbrechen?
         zoomImageScroll = QPoint(0,0);
 
-        zoomImage.fill(Qt::white);
+        zoomImage.fill(Qt::black);
         QPixmap tmpImg = composedOffscreenImage.copy(screenmiddle.x()+scroll.x(),screenmiddle.y()+scroll.y(), size.width(), size.height());
 
         QPainter painter(&zoomImage);
@@ -455,11 +465,11 @@ namespace qmapcontrol
     void LayerManager::resize(QSize newSize)
     {
         size = newSize;
-        offSize = newSize *2;
+        offSize = newSize *offFactor;
         composedOffscreenImage = QPixmap(offSize);
         composedOffscreenImage2 = QPixmap(offSize);
         zoomImage = QPixmap(newSize);
-        zoomImage.fill(Qt::white);
+        zoomImage.fill(Qt::black);
 
         screenmiddle = QPoint(newSize.width()/2, newSize.height()/2);
 
diff --git a/lib/QMapControl/src/layermanager.h b/lib/QMapControl/src/layermanager.h
index c11a1ca..d28c647 100644
--- a/lib/QMapControl/src/layermanager.h
+++ b/lib/QMapControl/src/layermanager.h
@@ -121,6 +121,11 @@ namespace qmapcontrol
          */
         void setZoom(int zoomlevel);
 
+        //! Sets the factor the offscreen image should be larger than the visible area
+        void setOffscreenImageFactor(float factor);
+        //! Get the factor the offscreen image is larger than the screen
+        float offscreenImageFactor();
+
         //! The Viewport of the display
         /*!
          * Returns the visible viewport in world coordinates
@@ -172,7 +177,7 @@ namespace qmapcontrol
     private:
         LayerManager& operator=(const LayerManager& rhs);
         LayerManager(const LayerManager& old);
-        //! This method have to be invoked to draw a new offscreen image
+        //! This method has to be invoked to draw a new offscreen image
         /*!
          * @param clearImage if the current offscreeen image should be cleared
          * @param showZoomImage if a zoom image should be painted
@@ -188,8 +193,9 @@ namespace qmapcontrol
         QPoint scroll; // scrollvalue of the offscreen image
         QPoint zoomImageScroll; // scrollvalue of the zoom image
 
-        QSize size; // widget size
-        QSize offSize; // size of the offscreen image
+        QSize size;      ///< widget size
+        QSize offSize;   ///< size of the offscreen image
+        float offFactor; ///< Size of the offscreen image
 
         QPixmap composedOffscreenImage;
         QPixmap composedOffscreenImage2;
diff --git a/lib/QMapControl/src/mapcontrol.cpp b/lib/QMapControl/src/mapcontrol.cpp
index c01a95e..d982f36 100644
--- a/lib/QMapControl/src/mapcontrol.cpp
+++ b/lib/QMapControl/src/mapcontrol.cpp
@@ -23,6 +23,9 @@
 *
 */
 
+#include <QDialog>
+#include <QDesktopServices>
+
 #include "mapcontrol.h"
 namespace qmapcontrol
 {
@@ -61,6 +64,29 @@ namespace qmapcontrol
         return layermanager->layer(layername);
     }
 
+    void MapControl::setOffscreenImageFactor(double factor)
+    {
+        layermanager->setOffscreenImageFactor(factor);
+    }
+
+    float MapControl::offscreenImageFactor()
+    {
+        return layermanager->offscreenImageFactor();
+    }
+
+    void MapControl::openImageSaveDialog()
+    {
+        QString fileName = QFileDialog::getSaveFileName(this, tr("Save Image as"), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), tr("Image file (*.jpg *.png);;"));
+        if (fileName != "")
+        {
+            if (!fileName.contains(".png") && !fileName.contains(".jpg"))
+            {
+                fileName.append(".png");
+            }
+            layermanager->getImage().save(fileName, fileName.split(".").last().toUpper().toAscii(), 95);
+        }
+    }
+
     QList<QString> MapControl::layers() const
     {
         return layermanager->layers();
diff --git a/lib/QMapControl/src/mapcontrol.h b/lib/QMapControl/src/mapcontrol.h
index db790f4..f07f0b3 100644
--- a/lib/QMapControl/src/mapcontrol.h
+++ b/lib/QMapControl/src/mapcontrol.h
@@ -92,6 +92,9 @@ namespace qmapcontrol
          */
         Layer* layer ( const QString& layername ) const;
 
+        //! The factor the offscreen image is larger than the current viewport
+        float offscreenImageFactor();
+
         //! returns the names of all layers
         /*!
          * @return returns a QList with the names of all layers
@@ -354,6 +357,12 @@ namespace qmapcontrol
          */
         void resize(const QSize newSize);
 
+        //! Open a popup to save the current offscreen image to disk
+        void openImageSaveDialog();
+
+        //! Sets the factor the offscreen image should be larger than the visible area */
+        void setOffscreenImageFactor(double factor);
+
     private slots:
         void tick();
         void loadingFinished();
diff --git a/src/ui/MapWidget.cc b/src/ui/MapWidget.cc
index 443ee5f..af7fb72 100644
--- a/src/ui/MapWidget.cc
+++ b/src/ui/MapWidget.cc
@@ -13,6 +13,7 @@
 #include <QComboBox>
 #include <QGridLayout>
 #include <QDir>
+#include <QDoubleSpinBox>
 
 #include "QGC.h"
 #include "MapWidget.h"
@@ -38,7 +39,7 @@ MapWidget::MapWidget(QWidget *parent) :
     mc = new qmapcontrol::MapControl(QSize(320, 240));
 
     //   VISUAL MAP STYLE
-    QString buttonStyle("QAbstractButton { background-color: rgba(20, 20, 20, 45%); border-color: rgba(10, 10, 10, 50%)}");
+    QString buttonStyle("QAbstractButton { background-color: rgba(20, 20, 20, 45%); border-color: rgba(10, 10, 10, 50%)}  QDoubleSpinBox { background-color: rgba(20, 20, 20, 45%); border-color: rgba(10, 10, 10, 50%)}");
     mc->setPen(QGC::colorCyan.darker(400));
 
 
@@ -163,6 +164,19 @@ MapWidget::MapWidget(QWidget *parent) :
     QPushButton* goToButton = new QPushButton(QIcon(""), "T", this);
     goToButton->setStyleSheet(buttonStyle);
 
+    // SAVE FILES
+    QPushButton* saveButton = new QPushButton(QIcon(""), "S", this);
+    saveButton->setStyleSheet(buttonStyle);
+
+    // SET OFFSCREEN BUFFER SIZE
+    QDoubleSpinBox* offscreenSpinBox = new QDoubleSpinBox(this);
+    offscreenSpinBox->setStyleSheet(buttonStyle);
+    offscreenSpinBox->setMinimum(2);
+    offscreenSpinBox->setMaximum(30);
+    offscreenSpinBox->setValue(mc->offscreenImageFactor());
+    connect(offscreenSpinBox, SIGNAL(valueChanged(double)), mc, SLOT(setOffscreenImageFactor(double)));
+
+
     zoomin->setMaximumWidth(30);
     zoomout->setMaximumWidth(30);
     createPath->setMaximumWidth(30);
@@ -188,8 +202,10 @@ MapWidget::MapWidget(QWidget *parent) :
     // 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->addWidget(mapButton, 0, 2);
+    innerlayout->addWidget(goToButton, 0, 3);
+    innerlayout->addWidget(saveButton, 0, 4);
+    innerlayout->addWidget(offscreenSpinBox, 0, 5);
     innerlayout->setRowStretch(0, 1);
     innerlayout->setRowStretch(1, 100);
     mc->setLayout(innerlayout);
@@ -204,6 +220,8 @@ MapWidget::MapWidget(QWidget *parent) :
 
     connect(goToButton, SIGNAL(clicked()), this, SLOT(goTo()));
 
+    connect(saveButton, SIGNAL(clicked()), mc, SLOT(openImageSaveDialog()));
+
     QList<UASInterface*> systems = UASManager::instance()->getUASList();
     foreach(UASInterface* system, systems)
     {
@@ -248,6 +266,8 @@ MapWidget::MapWidget(QWidget *parent) :
 
     drawCamBorder = false;
     radioCamera = 10;
+
+    //mc->setOffscreenImageFactor(15);
 }
 
 void MapWidget::goTo()