#include <QHash>
#include <QHashIterator>
#include <QQueue>
+#include <QRect>
#include "mapengine.h"
#include "maptile.h"
MapEngine::MapEngine(QObject *parent)
: QObject(parent)
, m_zoomLevel(14)
- , m_viewSize(QSize(800, 480))
+ , m_viewSize(QSize(973, 614))
+ , m_centerTile(QPoint(-1, -1))
{
m_mapScene = new MapScene(this);
void MapEngine::mapImageReceived(const QUrl &url, const QPixmap &pixmap)
{
- if (!mapTilesInScene.contains(url.toString())) {
+ if (mapTilesInScene.contains(url.toString())) {
int zoom = -1;
int x = -1;
int y = -1;
mapTilesInScene.insert(url.toString(), mapTile);
m_mapScene->addMapTile(mapTile);
- qDebug() << "Tile count: " << mapTilesInScene.size();
+ //qDebug() << "Map scene tile count: " << m_mapScene->items().count();
+ //qDebug() << "Map hash tile count: " << mapTilesInScene.size();
}
- removeTiles();
+ //removeTiles(viewGrid);
}
QGraphicsScene* MapEngine::scene()
int gridWidth = (m_viewSize.width()/TILE_SIZE_X + 1) + (GRID_PADDING*2);
int gridHeight = (m_viewSize.height()/TILE_SIZE_Y + 1) + (GRID_PADDING*2);
- qDebug() << "Grid size: " << gridWidth << "x" << gridHeight;
-
int topLeftX = tileCoordinate.x() - (gridWidth/2);
int topLeftY = tileCoordinate.y() - (gridHeight/2);
- return QRect(topLeftX, topLeftY, gridWidth, gridHeight);
+ return QRect(topLeftX, topLeftY, gridWidth, gridHeight);
}
void MapEngine::setLocation(QPointF sceneCoordinate)
{
m_sceneCoordinate = sceneCoordinate;
emit locationChanged(m_sceneCoordinate);
- calculateTileGrid();
+
+ if (centerTileChanged(sceneCoordinate)) {
+ calculateTileGrid(sceneCoordinate);
+ removeTilesOutOfBounds();
+ }
}
-void MapEngine::calculateTileGrid()
+bool MapEngine::centerTileChanged(QPointF sceneCoordinate)
{
- QRect grid = calculateGrid(m_sceneCoordinate);
- int topLeftX = grid.topLeft().x();
- int topLeftY = grid.topLeft().y();
- int bottomRightX = grid.bottomRight().x();
- int bottomRightY = grid.bottomRight().y();
+ QPoint centerTile = convertSceneCoordinateToTileNumber(m_zoomLevel, sceneCoordinate);
+ QPoint temp = m_centerTile;
+ m_centerTile = centerTile;
- int tileMaxVal = tileMaxValue(m_zoomLevel);
+ return (centerTile != temp);
+}
- QList<QString> tiles;
+void MapEngine::calculateTileGrid(QPointF sceneCoordinate)
+{
+ //qDebug() << __PRETTY_FUNCTION__;
+
+ viewGrid = calculateGrid(m_sceneCoordinate);
+
+ int topLeftX = viewGrid.topLeft().x();
+ int topLeftY = viewGrid.topLeft().y();
+ int bottomRightX = viewGrid.bottomRight().x();
+ int bottomRightY = viewGrid.bottomRight().y();
+
+ int tileMaxVal = tileMaxValue(m_zoomLevel);
for (int x = topLeftX; x <= bottomRightX; ++x) {
for (int y = topLeftY; y <= bottomRightY; ++y) {
QUrl url = buildURL(m_zoomLevel, QPoint(tileX, tileY));
- if (!mapTilesInScene.contains(url.toString()))
+ if (!mapTilesInScene.contains(url.toString())) {
+ mapTilesInScene.insert(url.toString(), NULL);
emit fetchImage(url);
-
- tiles.append(url.toString());
+ }
}
}
-
- //removeTiles(tiles);
}
-void MapEngine::removeTiles()
+void MapEngine::removeTilesOutOfBounds()
{
-// QHash<QString, MapTile*> removedTiles = mapTilesInScene;
-//
-// foreach (QString tileUrl, tiles) {
-// if (!mapTilesInScene.contains(tileUrl))
-// tilesToRemove.enqueue(tileUrl);
-// }
-
+ //qDebug() << __PRETTY_FUNCTION__;
int zoomFactor = 1 << (MAX_ZOOM_LEVEL - m_zoomLevel);
- qreal topLeftX = m_sceneCoordinate.x() - (m_viewSize.width()/2*zoomFactor);
- qreal topLeftY = m_sceneCoordinate.y() - (m_viewSize.height()/2*zoomFactor);
-
- qreal width = m_viewSize.width()*zoomFactor;
- qreal height = m_viewSize.height()*zoomFactor;
-
- qDebug() << topLeftX << ", " << topLeftY << " " << m_viewSize.width() << "x" << m_viewSize.height();
+ QPointF topLeft = convertTileNumberToSceneCoordinate(m_zoomLevel, viewGrid.topLeft());
+ QPointF bottomRight = convertTileNumberToSceneCoordinate(m_zoomLevel, viewGrid.bottomRight() + QPoint(1, 1));
+ qreal width = bottomRight.x() - topLeft.x();
+ qreal height = bottomRight.y() - topLeft.y();
- QList<QGraphicsItem *> viewTiles = m_mapScene->items(topLeftX, topLeftY, width, height);
+ QList<QGraphicsItem *> viewTiles = m_mapScene->items(topLeft.x(), topLeft.y(), width, height, Qt::IntersectsItemShape);
QList<QGraphicsItem *> allTiles = m_mapScene->items();
- qDebug() << "All tiles size: " << allTiles.size();
- qDebug() << "View tiles size: " << viewTiles.size();
-
- foreach (QGraphicsItem *tile, viewTiles) {
+ foreach (QGraphicsItem *tile, viewTiles)
allTiles.removeOne(tile);
- }
- qDebug() << "All tiles size after removing view items: " << allTiles.size();
+ QHashIterator<QString, MapTile *> i(mapTilesInScene);
+
+ while (i.hasNext()) {
+ i.next();
+ if (allTiles.contains(i.value())) {
+ MapTile *tile = i.value();
+ if (tile) {
+ mapTilesInScene.remove(i.key());
+ m_mapScene->removeItem(tile);
+ delete tile;
+ }
+ }
+ }
- foreach (QGraphicsItem *tile, allTiles) {
- m_mapScene->removeItem(tile);
- delete tile;
- }
}
void MapEngine::viewResized(const QSize &size)
void MapEngine::zoomIn()
{
- //removeTiles();
-
- /*if (m_zoomLevel >= MAX_ZOOM_LEVEL)
+ if (m_zoomLevel >= MAX_ZOOM_LEVEL)
return;
m_zoomLevel++;
emit zoomLevelChanged(m_zoomLevel);
/// @todo START FETCHING TILES
- calculateTileGrid();*/
+ calculateTileGrid(m_sceneCoordinate);
}
void MapEngine::zoomOut()
m_zoomLevel--;
emit zoomLevelChanged(m_zoomLevel);
/// @todo START FETCHING TILES
- calculateTileGrid();
+ calculateTileGrid(m_sceneCoordinate);
}
void MapEngine::setZoomLevel(int zoomLevel)
//void convertLatLonToTile();
void calculateRect();
void setLocation();
- void removeTiles();
+// void removeTilesOutOfBounds();
+ void calculateTileGrid();
+ void convert();
};
/**
QRect grid2 = QRect(-3, -2, 6, 4);
QCOMPARE(engine.calculateGrid(QPointF(0.23*zoomFactor, 0.23*zoomFactor)), grid2);
+ QRect grid3 = QRect(1017, 498, 6, 4);
+ QCOMPARE(engine.calculateGrid(QPointF(1020*TILE_SIZE_X*zoomFactor, 500*TILE_SIZE_Y*zoomFactor)), grid3);
+
engine.viewResized(QSize(1280, 1024));
- QRect grid3 = QRect(1016, 497, 8, 7);
- QCOMPARE(engine.calculateGrid(QPointF(1020*TILE_SIZE_X*zoomFactor, 500*TILE_SIZE_Y*zoomFactor)), grid3);
+ QRect grid4 = QRect(1016, 497, 8, 7);
+ QCOMPARE(engine.calculateGrid(QPointF(1020*TILE_SIZE_X*zoomFactor, 500*TILE_SIZE_Y*zoomFactor)), grid4);
}
void TestMapEngine::setLocation()
int zoomFactor = 1 << (MAX_ZOOM_LEVEL - engine.getZoomLevel());
QSignalSpy fetchImageSpy(&engine, SIGNAL(fetchImage(QUrl)));
- QTest::qWait(2000);
+ QTest::qWait(1000);
fetchImageSpy.clear();
engine.setLocation(QPointF(1220.23*zoomFactor, 1220.23*zoomFactor));
- QTest::qWait(2000);
+ QTest::qWait(1000);
QCOMPARE(fetchImageSpy.count(), 6*4);
+ fetchImageSpy.clear();
+
+ //Move one tile right and one down = 9 new tiles
+ engine.setLocation(QPointF((1220.23+TILE_SIZE_X)*zoomFactor, (1220.23+TILE_SIZE_Y)*zoomFactor));
+ QTest::qWait(1000);
+ QCOMPARE(fetchImageSpy.count(), 9);
+ fetchImageSpy.clear();
+}
+
+void TestMapEngine::convert()
+{
+ int zoomFactor = 1 << (MAX_ZOOM_LEVEL - 14);
- //Move one tile right and one up = 7 new tiles
-// engine.setLocation(QPointF((550.23 + 256.0)*16, (550.23 + 256.0)*16));
-// QTest::qWait(2000);
-// QCOMPARE(fetchImageSpy.count(), 5*3+7);
+ QPoint tileNumber = QPoint(1020, 500);
+ QPointF sceneCoordinate = QPointF(tileNumber.x()*TILE_SIZE_X*zoomFactor, tileNumber.y()*TILE_SIZE_Y*zoomFactor);
+ QPoint tile = MapEngine::convertSceneCoordinateToTileNumber(14, sceneCoordinate);
+
+ QCOMPARE(tileNumber, tile);
}
-void TestMapEngine::removeTiles()
+void TestMapEngine::calculateTileGrid()
{
MapEngine engine;
- engine.viewResized(QSize());
+ engine.viewResized(QSize(800, 480));
+ engine.setZoomLevel(14);
+
+ int zoomFactor = 1 << (MAX_ZOOM_LEVEL - engine.getZoomLevel());
+
+ engine.calculateTileGrid(QPointF(1020*TILE_SIZE_X*zoomFactor, 500*TILE_SIZE_X*zoomFactor));
}
+//void TestMapEngine::removeTilesOutOfBounds()
+//{
+// MapEngine engine;
+// engine.viewResized(QSize(800, 480));
+// engine.setZoomLevel(14);
+//
+// int zoomFactor = 1 << (MAX_ZOOM_LEVEL - engine.getZoomLevel());
+//
+// engine.setLocation(QPointF(1220.23*zoomFactor, 1220.23*zoomFactor));
+// qDebug() << "Scene items: " << engine.scene()->items().count();
+// QTest::qWait(1000);
+// //Move one tile right and one tile down
+// engine.setLocation(QPointF((1220.23+TILE_SIZE_X)*zoomFactor, (1220.23+TILE_SIZE_Y)*zoomFactor));
+// QCOMPARE(engine.scene()->items().count(), 15);
+//}
+
QTEST_MAIN(TestMapEngine)
#include "testmapengine.moc"