USA.
*/
-
#include <QtGui/QApplication>
#include "ui/mainwindow.h"
+#include "mapfetcherqueue.h"
int main(int argc, char *argv[])
{
Copyright (C) 2010 Ixonos Plc. Authors:
Sami Rämö - sami.ramo@ixonos.com
+ Jussi Laitinen - jussi.laitinen@ixonos.com
Situare is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
#include "maptile.h"
//#include "mapscene.h"
+#include <QtCore>
+#include <QtGlobal>
+
MapEngine::MapEngine(MapView *mapView, QWidget *parent)
: QObject(parent)
{
// mapTile->setPixmap();
// m_mapScene->addMapTile(mapTile);
}
+
+QPoint MapEngine::latLonToTile(qreal latitude, qreal longitude, int zoom)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ qreal z = static_cast<qreal>(1 << zoom);
+
+ qreal x = static_cast<qreal>((longitude + 180.0) / 360.0);
+ qreal y = static_cast<qreal>((1.0 - log(tan(latitude * M_PI / 180.0) + 1.0
+ / cos(latitude * M_PI / 180.0)) / M_PI) / 2.0);
+
+ return QPoint(qFloor(x*z), qFloor(y*z));
+}
+
+qreal MapEngine::tileXToLongitude(int x, int zoom)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ qreal z = static_cast<qreal>(1 << zoom);
+ qreal lon = x / z * 360.0 - 180.0;
+ qDebug() << lon;
+ return lon;
+}
+
+qreal MapEngine::tileYToLatitude(int y, int zoom)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ qreal z = static_cast<qreal>(1 << zoom);
+ qreal n = M_PI - 2 * M_PI * y / zoom;
+ return 180.0 / (M_PI * atan(0.5 * exp(n) - exp(-n)));
+}
Copyright (C) 2010 Ixonos Plc. Authors:
Sami Rämö - sami.ramo@ixonos.com
+ Jussi Laitinen - jussi.laitinen@ixonos.com
Situare is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
USA.
*/
-
-
#ifndef MAPENGINE_H
#define MAPENGINE_H
#include <math.h>
+#include <QtCore>
+
#include "mapview.h"
#include "mapscene.h"
/// \param latLonCoordinate Latitude & longitude coordinates for location
void setViewLocation(QPointF latLonCoordinate);
+ QPoint latLonToTile(qreal latitude, qreal longitude, int zoom);
+
+ /**
+ * @brief Transforms tile x value to longitude.
+ *
+ * @fn tileXToLongitude
+ * @param x tile x value
+ * @param zoom zoom value
+ * @return qreal longitude
+ */
+ qreal tileXToLongitude(int x, int zoom);
+
+ /**
+ * @brief Transforms tile y value to latitude.
+ *
+ * @fn tileYToLatitude
+ * @param y tile y value
+ * @param zoom zoom value
+ * @return qreal latitude
+ */
+ qreal tileYToLatitude(int y, int zoom);
+
private slots:
void mapImageReceived(const QUrl *url, const QPixmap *pixmap);
--- /dev/null
+/*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Jussi Laitinen - jussi.laitinen@ixonos.com
+
+ Situare is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ Situare 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 Situare; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+*/
+
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QUrl>
+#include <QDebug>
+#include <QPixmap>
+#include <QNetworkDiskCache>
+#include <QDesktopServices>
+
+#include "mapfetcher.h"
+
+static int MAX_PARALLEL_DOWNLOADS = 2;
+
+MapFetcher::MapFetcher(QObject *parent, QNetworkAccessManager *manager)
+ : QObject(parent), m_manager(manager)
+{
+ QNetworkDiskCache *diskCache = new QNetworkDiskCache(this);
+
+ diskCache->setCacheDirectory(QDesktopServices::storageLocation(
+ QDesktopServices::CacheLocation));
+
+ m_manager->setCache(diskCache);
+
+ connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadFinished(QNetworkReply*)));
+}
+
+void MapFetcher::fetchMapImage(const QUrl &url)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ if (url.isEmpty() || !url.isValid())
+ return;
+
+ if (downloadQueue.length() < MAX_PARALLEL_DOWNLOADS)
+ QTimer::singleShot(0, this, SLOT(startNextDownload()));
+
+ downloadQueue.enqueue(url);
+}
+
+void MapFetcher::startNextDownload()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ if (downloadQueue.isEmpty())
+ return;
+
+ QUrl url = downloadQueue.dequeue();
+ QNetworkRequest request(url);
+ request.setRawHeader("User-Agent", "Map Test");
+ request.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
+ QNetworkRequest::PreferCache);
+
+ QNetworkReply *reply = m_manager->get(request);
+ currentDownloads.append(reply);
+}
+
+void MapFetcher::downloadFinished(QNetworkReply *reply)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ if (reply->error() == QNetworkReply::NoError) {
+ QImage image;
+ QUrl url = reply->url();
+
+ if (!image.load(reply, 0))
+ image = QImage();
+
+ emit mapImageReceived(url, QPixmap::fromImage(image));
+ }
+ else {
+ emit error(reply->errorString());
+ }
+
+ currentDownloads.removeAll(reply);
+ reply->deleteLater();
+ startNextDownload();
+}
+
+MapFetcher::~MapFetcher()
+{
+
+}
--- /dev/null
+/*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Jussi Laitinen - jussi.laitinen@ixonos.com
+
+ Situare is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ Situare 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 Situare; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+*/
+
+#ifndef MAPFETCHER_H
+#define MAPFETCHER_H
+
+#include <QtCore>
+#include <QNetworkAccessManager>
+
+#include "mapfetcher.h"
+
+class QNetworkReply;
+class QUrl;
+
+/**
+* @brief MapFetcher handles requests to get map tiles.
+*
+*
+*
+* @class MapFetcher mapfetcher.h "map/mapfetcher.h"
+*/
+class MapFetcher : public QObject
+{
+ Q_OBJECT
+
+public:
+ /**
+ * @brief Constructor for MapFetcher.
+ *
+ * @fn MapFetcher
+ * @param parent parent object
+ */
+ MapFetcher(QObject *parent = 0, QNetworkAccessManager *manager = 0);
+
+ ~MapFetcher();
+
+ /**
+ * @brief Fetch image from given URL.
+ *
+ * @fn fetchMapImage
+ * @param url URL to image
+ */
+ void fetchMapImage(const QUrl &url);
+
+signals:
+ /**
+ * @brief Signal which is emitted when a map tile
+ * is received from the server and loaded to pixmap.
+ *
+ * @fn mapImageReceived
+ * @param url URL to image
+ * @param image image pixmap
+ */
+ void mapImageReceived(const QUrl &url, const QPixmap &image);
+
+ /**
+ * @brief Signal which is emitted when there is error
+ * in network reply.
+ *
+ * @fn error
+ * @param message error message
+ */
+ void error(const QString &message);
+
+public slots:
+
+ /**
+ * @brief This slot is called when network manager has finished
+ * the download.
+ *
+ * @fn downloadFinished
+ * @param reply
+ */
+ void downloadFinished(QNetworkReply *reply);
+
+ /**
+ * @brief This slot is called when next download is started.
+ *
+ * @fn startNextDownload
+ */
+ void startNextDownload();
+
+private:
+
+ QNetworkAccessManager *m_manager;
+ QList<QNetworkReply*> currentDownloads;
+ QQueue<QUrl> downloadQueue;
+};
+
+#endif
--- /dev/null
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QUrl>
+#include <QDebug>
+#include <QPixmap>
+#include <QNetworkDiskCache>
+#include <QDesktopServices>
+#include <QTimer>
+#include <QMutex>
+
+#include "mapfetcherqueue.h"
+
+static int MAX_QUEUE = 10;
+
+MapFetcherQueue::MapFetcherQueue(QObject *parent)
+ : QObject(parent)
+ , downloadCount(0)
+{
+ QNetworkDiskCache *diskCache = new QNetworkDiskCache(this);
+ diskCache->setCacheDirectory(QDesktopServices::storageLocation(
+ QDesktopServices::CacheLocation));
+ m_manager.setCache(diskCache);
+}
+
+void MapFetcherQueue::fetchMapImage(const QUrl &url)
+{
+ if (url.isEmpty())
+ return;
+
+ if (downloadQueue.isEmpty())
+ QTimer::singleShot(0, this, SLOT(startNextDownload()));
+
+ if (downloadQueue.length() >= MAX_QUEUE) {
+ qDebug() << "removed from queue";
+ deleteCurrent();
+ downloadQueue.dequeue();
+ }
+
+ downloadQueue.enqueue(url);
+ qDebug() << "fetchMapImage() " << url.path();
+}
+
+void MapFetcherQueue::startNextDownload()
+{
+ if (downloadQueue.isEmpty())
+ return;
+
+ QUrl url = downloadQueue.dequeue();
+
+ QNetworkRequest request(url);
+ request.setRawHeader("User-Agent", "Map Test");
+ request.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
+ QNetworkRequest::PreferCache);
+
+ currentDownload = m_manager.get(request);
+ connect(currentDownload, SIGNAL(finished()), this, SLOT(downloadFinished()));
+ connect(currentDownload, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));
+ connect(currentDownload, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(networkError()));
+}
+
+void MapFetcherQueue::downloadFinished()
+{
+ static int counter = 0;
+ qDebug() << "downloadFinished(): " << counter++;
+
+ deleteCurrent();
+ startNextDownload();
+}
+
+void MapFetcherQueue::deleteCurrent()
+{
+ mutex.lock();
+ if (currentDownload != NULL)
+ currentDownload->deleteLater();
+ mutex.unlock();
+}
+
+void MapFetcherQueue::downloadReadyRead()
+{
+ qDebug() << "downloadReadyRead()" << currentDownload->url().path();
+
+ if (currentDownload->error()) {
+ qDebug() << "ERROR";
+ emit error(currentDownload->errorString());
+ }
+ else {
+ QImage image;
+ QUrl url = currentDownload->url();
+ if (!image.load(currentDownload, 0))
+ image = QImage();
+
+ emit mapImageReceived(url, QPixmap::fromImage(image));
+ }
+}
+
+void MapFetcherQueue::networkError()
+{
+ emit error(currentDownload->errorString());
+}
+
+MapFetcherQueue::~MapFetcherQueue()
+{
+
+}
--- /dev/null
+#ifndef MAPFETCHERQUEUE_H
+#define MAPFETCHERQUEUE_H
+
+#include <QtCore>
+#include <QNetworkAccessManager>
+
+class QNetworkReply;
+class QUrl;
+class QMutex;
+
+#include "mapfetcher.h"
+
+/**
+* @brief MapFetcher handles requests to get map tiles.
+*
+*
+*
+* @class MapFetcher mapfetcher.h "map/mapfetcher.h"
+*/
+class MapFetcherQueue : public QObject
+{
+ Q_OBJECT
+
+public:
+ /**
+ * @brief Constructor for MapFetcher.
+ *
+ * @fn MapFetcher
+ * @param parent parent object
+ */
+ MapFetcherQueue(QObject *parent = 0);
+
+ ~MapFetcherQueue();
+
+ /**
+ * @brief Fetch image from given URL.
+ *
+ * @fn fetchMapImage
+ * @param url URL to image
+ */
+ void fetchMapImage(const QUrl &url);
+
+ void deleteCurrent();
+
+signals:
+ /**
+ * @brief Signal which is emitted when a map tile
+ * is received from the server and loaded to pixmap.
+ *
+ * @fn mapImageReceived
+ * @param url URL to image
+ * @param image image pixmap
+ */
+ void mapImageReceived(const QUrl &url, const QPixmap &image);
+
+ /**
+ * @brief Signal which is emitted when there is error
+ * in network reply.
+ *
+ * @fn error
+ * @param message error message
+ */
+ void error(const QString &message);
+
+private slots:
+ /**
+ * @brief This slot is called when network manager has finished
+ * the download.
+ *
+ * @fn downloadFinished
+ * @param reply
+ */
+ void downloadFinished();
+
+ void startNextDownload();
+ void downloadReadyRead();
+ void networkError();
+
+
+private:
+ QNetworkAccessManager m_manager;
+ QQueue<QUrl> downloadQueue;
+ QNetworkReply *currentDownload;
+ QTime downloadTime;
+ QMutex mutex;
+
+ int downloadCount;
+};
+
+#endif
map/mapengine.cpp \
map/mapview.cpp \
map/mapscene.cpp \
- map/maptile.cpp
+ map/maptile.cpp \
+ map/mapfetcher.cpp
HEADERS += ui/mainwindow.h \
ui/mapviewscreen.h \
map/mapengine.h \
map/mapview.h \
map/mapscene.h \
- map/maptile.h
+ map/maptile.h \
+ map/mapfetcher.h
# -----------------------------------------------------------------
-/*
- Situare - A location system for Facebook
- Copyright (C) 2010 Ixonos Plc. Authors:
-
- Henri Lampela - henri.lampela@ixonos.com
- Kaj Wallin - kaj.wallin@ixonos.com
-
- Situare is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as published by the Free Software Foundation.
-
- Situare 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 Situare; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- USA.
-*/
-
-#include <QtGui>
-#include "mainwindow.h"
-#include "listviewscreen.h"
-#include "mapviewscreen.h"
-
-MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent)
-{
- qDebug() << __PRETTY_FUNCTION__;
- QWidget *widget = new QWidget;
- setCentralWidget(widget);
- createViews();
- QVBoxLayout *mainLayout = new QVBoxLayout;
- infoLabel = new QLabel(tr("Click \"view\", to change between views"),this);
- infoLabel->setAttribute(Qt::WA_TranslucentBackground, true);
- mainLayout->addWidget(infoLabel);
- mainLayout->addWidget(situareViews);
- widget->setLayout(mainLayout);
- createMenus();
-
- setWindowTitle(tr("View"));
-}
-
-MainWindow::~MainWindow()
-{
- qDebug() << __PRETTY_FUNCTION__;
- delete toListViewAct;
- delete toMapViewAct;
- delete situareViews;
- delete infoLabel;
-}
-
-void MainWindow::createMenus()
-{
- qDebug() << __PRETTY_FUNCTION__;
- toListViewAct = new QAction(tr("List"), this);
- connect(toListViewAct, SIGNAL(triggered()), this, SLOT(toListView()));
- toMapViewAct = new QAction(tr("Map"), this);
- connect(toMapViewAct, SIGNAL(triggered()), this, SLOT(toMapView()));
- viewMenu = menuBar()->addMenu(tr("View"));
- viewMenu->addAction(toListViewAct);
- viewMenu->addAction(toMapViewAct);
-}
-
-void MainWindow::createViews()
-{
- qDebug() << __PRETTY_FUNCTION__;
- situareViews = new QStackedWidget;
- situareViews->addWidget(new ListViewScreen);
- situareViews->addWidget(new MapViewScreen);
-}
-
-void MainWindow::toListView()
-{
- qDebug() << __PRETTY_FUNCTION__;
- switchView(0);
-}
-
-void MainWindow::toMapView()
-{
- qDebug() << __PRETTY_FUNCTION__;
- switchView(1);
-}
-
-void MainWindow::switchView(int nextIndex)
-{
- qDebug() << __PRETTY_FUNCTION__ << ":" << nextIndex;
- if (nextIndex < 0 || nextIndex > 1) {
- qDebug() << tr("Illegal parameter value in MainWindow::switchView");
- return;
- }
- situareViews->setCurrentIndex(nextIndex);
- infoLabel->setText(tr("Current: %1").arg(situareViews->currentIndex()));
- switch (situareViews->currentIndex()) {
- case 0:
- setWindowTitle(tr("List"));
- break;
- case 1:
- setWindowTitle(tr("Map"));
- break;
- default:
- qDebug() << tr("Illegal switch value in MainWindow::switchView");
- break;
- }
-}
-
-int MainWindow::getViewIndex()
-{
- return situareViews->currentIndex();
-}
-/*
- Situare - A location system for Facebook
- Copyright (C) 2010 Ixonos Plc. Authors:
-
- Henri Lampela - henri.lampela@ixonos.com
- Kaj Wallin - kaj.wallin@ixonos.com
-
- Situare is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as published by the Free Software Foundation.
-
- Situare 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 Situare; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- USA.
-*/
-
-
-#ifndef MAINWINDOW_H
-#define MAINWINDOW_H
-
-#include <QtGui/QMainWindow>
-#include <QWidget>
-#include <QDebug>
-
-class QLabel;
-class QStackedWidget;
-
-/**
-* @Main Window Class
-*
-* @class MainWindow mainwindow.h "src/ui/mainwindow.h"
-*/
-class MainWindow : public QMainWindow
-{
- Q_OBJECT
-
-public:
- MainWindow(QWidget *parent = 0);
- ~MainWindow();
-
- /**
- * @brief Public method to get current index of the view. Used for Unit testing
- *
- * @fn getViewIndex
- */
- int getViewIndex();
-
-private:
- /**
- * @brief Private method to create List and Map views as a stacked widget
- *
- * @fn createViews
- */
- void createViews();
- /**
- * @brief Widget Stack object for the List and Map Views
- *
- * @var situareViews
- */
- QStackedWidget *situareViews;
-
- /**
- * @brief Private method to create the Menu items
- *
- * @fn createMenus
- */
- void createMenus();
- QMenu *viewMenu;
-
- /**
- * @brief Action item for changing view to List View
- *
- * @var toListViewAct
- */
- QAction *toListViewAct;
- /**
- * @brief Action item for changing view to Map View
- *
- * @var toMapViewAct
- */
- QAction *toMapViewAct;
-
- /**
- * @brief Method used to switch active view.
- *
- * @fn switchView
- * @param int 0 for listview, 1 for mapview
- */
- void switchView(int);
-
- /**
- * @brief DUMMY LABEL, REMOVE WHEN BOTH VIEWS ARE COMPLETE
- *
- * @var infoLabel
- * @todo REMOVE THIS
- */
- QLabel *infoLabel;
-
-
-public slots:
- /**
- * @brief Public slot, which initiates toListViewAct action to switch view
- *
- * @fn toListView
- */
- void toListView();
- /**
- * @brief Public slot, which initiates toMapViewAct action to switch view
- *
- * @fn toMapView
- */
- void toMapView();
-};
-
-#endif // MAINWINDOW_H
--- /dev/null
+/*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Jussi Laitinen - jussi.laitinen@ixonos.com
+
+ Situare is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ Situare 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 Situare; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+*/
+
+#include <QNetworkAccessManager>
+#include <QDebug>
+#include <QTimer>
+#include <QImage>
+#include <QBuffer>
+#include "networkaccessmanagermock.h"
+#include "networkreplymock.h"
+
+
+
+NetworkAccessManagerMock::NetworkAccessManagerMock(QNetworkAccessManager *manager, QObject *parent)
+ : QNetworkAccessManager(parent)
+ , mode(0)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ setCache(manager->cache());
+ setCookieJar(manager->cookieJar());
+ //setProxy(manager->proxy());
+ setProxyFactory(manager->proxyFactory());
+
+ //connect(this, SIGNAL(error(QNetworkRequest*)), this, SLOT(generateError(QNetworkRequest)));
+}
+
+void NetworkAccessManagerMock::setMode(int mode)
+{
+ this->mode = mode;
+}
+
+void NetworkAccessManagerMock::debug()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+}
+
+NetworkReplyMock *NetworkAccessManagerMock::get(const QNetworkRequest &request)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ this->request = request;
+ reply = new NetworkReplyMock(this);
+
+ switch (this->mode) {
+
+ case NetworkAccessManagerMock::CORRECT:
+ QTimer::singleShot(0, this, SLOT(generateCorrectReply()));
+ break;
+ case NetworkAccessManagerMock::INCORRECT:
+ QTimer::singleShot(0, this, SLOT(generateError()));
+ break;
+ case NetworkAccessManagerMock::DELAYED_CORRECT:
+ QTimer::singleShot(0, this, SLOT(generateDelayedCorrectReply()));
+ break;
+ case NetworkAccessManagerMock::CORRUPTED_IMAGE:
+ QTimer::singleShot(0, this, SLOT(generateCorruptedImageReply()));
+ break;
+ default:
+ QTimer::singleShot(0, this, SLOT(generateCorrectReply()));
+ break;
+ }
+
+ return reply;
+}
+
+void NetworkAccessManagerMock::generateError()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ reply->setUrl(request.url());
+ reply->setError(QNetworkReply::HostNotFoundError, "Host not found");
+ emit finished(reply);
+}
+
+void NetworkAccessManagerMock::generateCorrectReply()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ reply->setUrl(request.url());
+ QImage image;
+ if (!image.load("res/images/static/testTile.png", 0))
+ image = QImage();
+ else
+ qDebug() << "image loaded";
+
+ QByteArray array;
+ QBuffer buffer(&array);
+ buffer.open(QBuffer::WriteOnly);
+ if (image.save(&buffer, "PNG"))
+ qDebug() << "image saved";
+ buffer.close();
+ reply->setData(array);
+ emit finished(reply);
+}
+
+void NetworkAccessManagerMock::generateDelayedCorrectReply()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ QTimer::singleShot(4000, this, SLOT(generateCorrectReply()));
+}
+
+void NetworkAccessManagerMock::generateCorruptedImageReply()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ reply->setUrl(request.url());
+ QImage image;
+ if (!image.load("res/images/static/testTile.png", 0))
+ image = QImage();
+ else
+ qDebug() << "image loaded";
+
+ QByteArray array;
+ array.append("PNG.?ASDSADSDSADSAD");
+ reply->setData(array);
+ emit finished(reply);
+}
--- /dev/null
+/*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Jussi Laitinen - jussi.laitinen@ixonos.com
+
+ Situare is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ Situare 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 Situare; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+*/
+
+#ifndef NETWORKACCESSMANAGERMOCK_H
+#define NETWORKACCESSMANAGERMOCK_H
+
+#include <QNetworkAccessManager>
+#include "networkreplymock.h"
+
+class NetworkAccessManagerMock : public QNetworkAccessManager
+{
+ Q_OBJECT
+
+public:
+ NetworkAccessManagerMock(QNetworkAccessManager *manager = 0, QObject *parent = 0);
+
+ NetworkReplyMock *get(const QNetworkRequest &request);
+
+ void setMode(int mode);
+
+ void debug();
+
+ enum {CORRECT, INCORRECT, DELAYED_CORRECT, CORRUPTED_IMAGE};
+
+signals:
+ void finished(NetworkReplyMock *reply);
+
+private slots:
+ void generateError();
+ void generateCorrectReply();
+ void generateDelayedCorrectReply();
+ void generateCorruptedImageReply();
+
+private:
+ NetworkReplyMock *reply;
+ QNetworkRequest request;
+ int mode;
+};
+
+#endif // NETWORKACCESSMANAGERMOCK_H
--- /dev/null
+/*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Jussi Laitinen - jussi.laitinen@ixonos.com
+
+ Situare is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ Situare 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 Situare; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+*/
+
+#include <QNetworkReply>
+#include <QDebug>
+
+#include "networkreplymock.h"
+
+NetworkReplyMock::NetworkReplyMock(QObject *parent)
+ : QNetworkReply(parent)
+ , m_offset(0)
+
+{
+
+}
+
+void NetworkReplyMock::setError(NetworkError errorCode, const QString &errorString)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ QNetworkReply::setError(errorCode, errorString);
+}
+
+
+qint64 NetworkReplyMock::readData(char *data, qint64 maxLen)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ if (m_offset < m_content.size()) {
+ qint64 number = qMin(maxLen, m_content.size() - m_offset);
+ memcpy(data, m_content.constData() + m_offset, number);
+ m_offset += number;
+ return number;
+ }
+ else {
+ return -1;
+ }
+}
+
+QByteArray NetworkReplyMock::readAll()
+{
+ return m_content;
+}
+
+void NetworkReplyMock::setUrl(const QUrl &url)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ QNetworkReply::setUrl(url);
+}
+
+void NetworkReplyMock::abort()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+}
+
+void NetworkReplyMock::test()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+}
+
+void NetworkReplyMock::setData(const QByteArray &content)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
+ setHeader(QNetworkRequest::ContentLengthHeader, QVariant(this->m_content.size()));
+ m_content.append(content);
+ qDebug() << "Content size: " << m_content.size();
+}
--- /dev/null
+/*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Jussi Laitinen - jussi.laitinen@ixonos.com
+
+ Situare is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ Situare 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 Situare; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+*/
+
+#ifndef NETWORKREPLYMOCK_H
+#define NETWORKREPLYMOCK_H
+
+#include <QNetworkReply>
+#include <QDebug>
+
+class NetworkReplyMock : public QNetworkReply
+{
+ Q_OBJECT
+
+public:
+ NetworkReplyMock(QObject *parent = 0);
+ void abort();
+ qint64 bytesAvailable() const
+ {
+ return m_content.size() - m_offset;
+ }
+ bool isSequential() const
+ {
+ return true;
+ }
+ void setError(NetworkError errorCode, const QString &errorString);
+ void setData(const QByteArray &content);
+ void setUrl(const QUrl &url);
+ void test();
+ QByteArray readAll();
+
+protected:
+ qint64 readData(char *data, qint64 maxlen);
+
+private:
+ QByteArray m_content;
+ qint64 m_offset;
+};
+
+#endif // NETWORKREPLYMOCK_H
--- /dev/null
+/*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Jussi Laitinen - jussi.laitinen@ixonos.com
+
+ Situare is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ Situare 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 Situare; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+*/
+
+#include <QtTest/QtTest>
+#include <QUrl>
+#include <QImage>
+#include <QNetworkAccessManager>
+#include <QLabel>
+
+#include "../../../src/map/mapfetcher.h"
+#include "networkaccessmanagermock.h"
+#include "networkreplymock.h"
+
+/**
+* @brief
+*
+* @class TestMapFetcher testmapfetcher.cpp "tests/testMap/testmapfetcher.cpp"
+*/
+class TestMapFetcher : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * @brief TestMapFetcher is a test class for MapFetcher class.
+ *
+ * @fn TestMapFetcher
+ */
+ TestMapFetcher();
+
+
+private slots:
+ /**
+ * @brief Tests fetchImage method with empty URL as parameter.
+ *
+ * @fn testFetchImageEmptyURL
+ */
+ void testFetchImageEmptyURL();
+ /**
+ * @brief Tests fetchImage method with incorrect URL as parameter.
+ *
+ * @fn testFetchImageIncorrectURL
+ */
+ void testFetchImageIncorrectURL();
+ /**
+ * @brief Tests fetchImage method with correct URL as parameter.
+ *
+ * @fn testFetchImageCorrectURL
+ */
+ void testFetchImageCorrectURL();
+
+ void testFetchCorruptedImage();
+
+ /**
+ * @brief Tests fetchImage method 20 times with correct URLs
+ * as parameters.
+ *
+ * @fn testFetchImage20URLs
+ */
+ void testFetchImage20URLs();
+ /**
+ * @brief Tests fetchImage method 50 times with correct URLs
+ * as parameters.
+ *
+ * @fn testFetchImage50URLs
+ */
+ void testFetchImage50URLs();
+
+private:
+ MapFetcher *mapFetcher;
+ NetworkAccessManagerMock *managerMock;
+};
+
+TestMapFetcher::TestMapFetcher()
+{
+ QNetworkAccessManager *manager = new QNetworkAccessManager();
+ managerMock = new NetworkAccessManagerMock(manager, this);
+ mapFetcher = new MapFetcher(this, managerMock);
+}
+
+void TestMapFetcher::testFetchImageEmptyURL()
+{
+ QUrl url("");
+ mapFetcher->fetchMapImage(url);
+}
+
+void TestMapFetcher::testFetchImageIncorrectURL()
+{
+ managerMock->setMode(NetworkAccessManagerMock::INCORRECT);
+
+ QSignalSpy imageReceivedErrorSpy(mapFetcher, SIGNAL(error(QString)));
+
+ QVERIFY(imageReceivedErrorSpy.isValid());
+
+ //Incorrect URL
+ QUrl url1("http://tile.openstreetmap.org/7/63/22.gi");
+ mapFetcher->fetchMapImage(url1);
+ QTest::qWait(1000);
+ QCOMPARE(imageReceivedErrorSpy.count(), 1);
+}
+
+void TestMapFetcher::testFetchImageCorrectURL()
+{
+ managerMock->setMode(NetworkAccessManagerMock::CORRECT);
+
+ QSignalSpy imageReceivedSpy(mapFetcher, SIGNAL(mapImageReceived(QUrl,QPixmap)));
+
+ QVERIFY(imageReceivedSpy.isValid());
+
+ //Correct URL
+ QUrl url2("http://tile.openstreetmap.org/7/63/42.png");
+ mapFetcher->fetchMapImage(url2);
+ QTest::qWait(2000);
+ QCOMPARE(imageReceivedSpy.count(), 1);
+ QList<QVariant> signalArgs2 = imageReceivedSpy.takeLast();
+ QCOMPARE(url2, signalArgs2.at(0).toUrl());
+}
+
+void TestMapFetcher::testFetchCorruptedImage()
+{
+ QSignalSpy imageReceivedSpy(mapFetcher, SIGNAL(mapImageReceived(QUrl,QPixmap)));
+
+ QVERIFY(imageReceivedSpy.isValid());
+
+ //Correct URL
+ QUrl url2("http://tile.openstreetmap.org/7/63/1.png");
+ mapFetcher->fetchMapImage(url2);
+ QTest::qWait(1000);
+ QCOMPARE(imageReceivedSpy.count(), 1);
+ QList<QVariant> signalArgs2 = imageReceivedSpy.takeLast();
+ QCOMPARE(url2, signalArgs2.at(0).toUrl());
+}
+
+void TestMapFetcher::testFetchImage20URLs()
+{
+ managerMock->setMode(NetworkAccessManagerMock::CORRECT);
+
+ QSignalSpy imageReceivedSpy(mapFetcher, SIGNAL(mapImageReceived(QUrl,QPixmap)));
+ QSignalSpy imageReceivedErrorSpy(mapFetcher, SIGNAL(error(QString)));
+
+ QVERIFY(imageReceivedSpy.isValid());
+
+ //20 requests
+ for (int i = 1; i < 3; ++i) {
+ for (int j = 0; j < 10; ++j) {
+ QUrl url(QString("http://tile.openstreetmap.org/18/23/%1%2.png").arg(i).arg(j));
+ mapFetcher->fetchMapImage(url);
+ }
+ }
+ QTest::qWait(2000);
+ int totalCount = imageReceivedSpy.count() + imageReceivedErrorSpy.count();
+ QCOMPARE(totalCount, 20);
+}
+
+void TestMapFetcher::testFetchImage50URLs()
+{
+ managerMock->setMode(NetworkAccessManagerMock::CORRECT);
+
+ QSignalSpy imageReceivedSpy(mapFetcher, SIGNAL(mapImageReceived(QUrl,QPixmap)));
+ QSignalSpy imageReceivedErrorSpy(mapFetcher, SIGNAL(error(QString)));
+
+ QVERIFY(imageReceivedSpy.isValid());
+
+ //50 requests
+ for (int i = 1; i < 6; ++i) {
+ for (int j = 0; j < 10; ++j) {
+ QUrl url(QString("http://tile.openstreetmap.org/18/24/%1%2.png").arg(i).arg(j));
+ mapFetcher->fetchMapImage(url);
+ }
+ }
+
+ QTest::qWait(5000);
+ int totalCount = imageReceivedSpy.count() + imageReceivedErrorSpy.count();
+ QCOMPARE(totalCount, 50);
+}
+
+QTEST_MAIN(TestMapFetcher)
+#include "testmapfetcher.moc"
--- /dev/null
+QT += network testlib
+
+HEADERS += networkreplymock.h \
+ networkaccessmanagermock.h \
+ ../../../src/map/mapfetcher.h
+SOURCES += testmapfetcher.cpp \
+ networkreplymock.cpp \
+ networkreplydummy.cpp \
+ networkaccessmanagermock.cpp \
+ ../../../src/map/mapfetcher.cpp