mapTilesInScene.insert(url.toString(), mapTile);
m_mapScene->addMapTile(mapTile);
- }
+
+ removeStackedTiles(mapTile);
+
- qDebug() << "Tile count: " << m_mapScene->items().count();
++ //qDebug() << "Tile count: " << m_mapScene->items().count();
+ }
}
QGraphicsScene* MapEngine::scene()
return (1 << zoomLevel) - 1;
}
- QRect MapEngine::calculateGrid(QPointF sceneCoordinate)
+ QRect MapEngine::calculateGrid(QPoint sceneCoordinate)
{
QPoint tileCoordinate = convertSceneCoordinateToTileNumber(m_zoomLevel, sceneCoordinate);
-
int gridWidth = (m_viewSize.width()/TILE_SIZE_X + 1) + (GRID_PADDING*2);
int gridHeight = (m_viewSize.height()/TILE_SIZE_Y + 1) + (GRID_PADDING*2);
-
int topLeftX = tileCoordinate.x() - (gridWidth/2);
int topLeftY = tileCoordinate.y() - (gridHeight/2);
return QRect(topLeftX, topLeftY, gridWidth, gridHeight);
}
- void MapEngine::setLocation(QPointF sceneCoordinate)
+ void MapEngine::setLocation(QPoint sceneCoordinate)
{
++ //qDebug() << __PRETTY_FUNCTION__;
++
m_sceneCoordinate = sceneCoordinate;
- emit locationChanged(m_sceneCoordinate);
if (centerTileChanged(sceneCoordinate)) {
- calculateTileGrid(sceneCoordinate);
- removeTilesOutOfBounds();
+ calculateNewTiles(sceneCoordinate);
+ removeOldTiles();
}
}
return (centerTile != temp);
}
- void MapEngine::calculateNewTiles(QPointF sceneCoordinate)
-void MapEngine::calculateTileGrid(QPoint sceneCoordinate)
++void MapEngine::calculateNewTiles(QPoint sceneCoordinate)
{
//qDebug() << __PRETTY_FUNCTION__;
* @param tileNumber x & y numbers of the tile
* @return QPoint MapScene coordinate
*/
--
static QPoint convertTileNumberToSceneCoordinate(int zoomLevel, QPoint tileNumber)
{
int pow = 1 << (MAX_MAP_ZOOM_LEVEL - zoomLevel);
return QPoint(x, y);
}
+ /**
+ * @brief Convert MapScene coordinate to tile x & y numbers.
+ *
+ * @param zoomLevel ZoomLevel
+ * @param sceneCoordinate MapScene coordinate
+ * @return QPoint tile x & y numbers
+ */
- static QPoint convertSceneCoordinateToTileNumber(int zoomLevel, QPointF sceneCoordinate)
+ static QPoint convertSceneCoordinateToTileNumber(int zoomLevel, QPoint sceneCoordinate)
{
int pow = 1 << (MAX_MAP_ZOOM_LEVEL - zoomLevel);
int x = static_cast<int>(sceneCoordinate.x() / (TILE_SIZE_X*pow));
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 QPointF(x*z*TILE_SIZE_X, y*z*TILE_SIZE_Y);
+ return QPointF(x*z*TILE_SIZE_X, y*z*TILE_SIZE_Y).toPoint();
}
- QRect calculateGrid(QPoint sceneCoordinate);
-
- void removeTilesOutOfBounds();
-
- void calculateTileGrid(QPoint sceneCoordinate);
-
public slots:
/**
* @brief Slot for setting current view location
*/
void setZValues();
+ /**
+ * @brief Calculate maximum value for tile in this zoom level.
+ *
+ * @param zoomLevel zoom level
+ * @return int tile's maximum value
+ */
int tileMaxValue(int zoomLevel);
+ /**
+ * @brief Calculate grid of tile coordinates from current scene coordinate.
+ *
+ * Grid size is calculated from view size and scene's current center coordinate.
+ *
+ * @param sceneCoordinate scene's current center coordinate
+ * @return QRect grid of tile coordinates
+ */
- QRect calculateGrid(QPointF sceneCoordinate);
++ QRect calculateGrid(QPoint sceneCoordinate);
+
+ /**
+ * @brief Calculate new tiles to fetch.
+ *
+ * @param sceneCoordinate scene's center coordinate
+ */
- void calculateNewTiles(QPointF sceneCoordinate);
++ void calculateNewTiles(QPoint sceneCoordinate);
+
+ /**
+ * @brief Remove tiles which are out of view bounds.
+ */
+ void removeOldTiles();
+
+ /**
+ * @brief Remove tiles which are stacked.
+ *
+ * Iterate through tiles which are under this map tile and remove obscured
+ * tiles.
+ *
+ * @param tile new tile covering old tiles
+ */
+ void removeStackedTiles(MapTile *tile);
+
+ /**
+ * @brief Check if center tile has changed.
+ *
+ * @param sceneCoordinate scene's center coordinate
+ * @return bool true if center tile changed, false otherwise
+ */
- bool centerTileChanged(QPointF sceneCoordinate);
++ bool centerTileChanged(QPoint sceneCoordinate);
private slots:
/**
*/
void zoomLevelChanged(int newZoomLevel);
+ /**
+ * @brief Signal for image fetching.
+ *
+ * @param url image url
+ */
void fetchImage(const QUrl &url);
- /**
- * @brief Signal for centering to scene coordinate.
- *
- * @param sceneCoordinate center scene coordinate
- */
- void centerToSceneCoordinates(QPointF sceneCoordinate);
-
private:
- bool centerTileChanged(QPoint sceneCoordinate);
-
MapScene *m_mapScene; ///< Scene for map tiles
MapFetcher *m_mapFetcher; ///< Fetcher for map tiles
int m_zoomLevel; ///< Current zoom level
QHash<QString, MapTile *> mapTilesInScene; ///< List of map tiles in map scene
- QSize m_viewSize;
- QPoint m_sceneCoordinate;
- QQueue<QString> mapTilesInView;
- QPoint m_centerTile;
- QRect viewGrid;
+ QSize m_viewSize; ///< Current view size
- QPointF m_sceneCoordinate; ///< Current center coordinate
++ QPoint m_sceneCoordinate; ///< Current center coordinate
+ QPoint m_centerTile; ///< Current center tile
+ QRect viewGrid; ///< Current grid of tiles in view
};
#endif // MAPENGINE_H
--- /dev/null
+ /*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Sami Rämö - sami.ramo@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 "map/mapengine.h"
+
+ class TestMapEngine: public QObject
+ {
+ Q_OBJECT
+ private slots:
+ void convertTileNumberToSceneCoordinate();
+ // void setViewLocation();
+ void convertLatLonToSceneCoordinate_data();
+ void convertLatLonToSceneCoordinate();
- void calculateRect();
- void setLocation();
-// void removeTilesOutOfBounds();
- void calculateTileGrid();
- void convert();
++ void setLocationNewTilesCount();
++ void setLocationRemovedTilesCount();
++ void zoomOutRemovedTilesCount();
++ void zoomInRemovedTilesCount();
+ };
+
+ /**
+ * @brief Test converting tile numbers to scene coordinates
+ *
+ * Different zoom levels are also tested
+ */
+ void TestMapEngine::convertTileNumberToSceneCoordinate()
+ {
+ QCOMPARE(MapEngine::convertTileNumberToSceneCoordinate(18, QPoint(0,0)), QPoint(0,0));
+ QCOMPARE(MapEngine::convertTileNumberToSceneCoordinate(18, QPoint(1,2)), QPoint(256,512));
+ QCOMPARE(MapEngine::convertTileNumberToSceneCoordinate(16, QPoint(3,4)), QPoint(3072,4096));
+ }
+
+ /**
+ * @brief DUMMY TESTCASE!
+ *
+ * @todo Actual test should be added when there is something to be tested
+ */
+ //void TestMapEngine::setViewLocation()
+ //{
+ // MapEngine mapEngine;
+ // mapEngine.setViewLocation(QPointF(25.0000, 65.0000));
+ //}
+
+ /**
+ * @brief Test data for converting latitude and longitude coordinates to scene coordinates
+ */
+ void TestMapEngine::convertLatLonToSceneCoordinate_data()
+ {
+ QTest::addColumn<QPointF>("coordinate");
+ QTest::addColumn<QPointF>("result");
+
+ QTest::newRow("top left") << QPointF(-180, 85.0511) << QPointF(0, 0);
+ QTest::newRow("bottom right") << QPointF(180, -85.0511) << QPointF(67108863, 67108863);
+ }
+
+ /**
+ * @brief Test converting real world cordinates to scene coordinates
+ * @todo Implement
+ */
+ void TestMapEngine::convertLatLonToSceneCoordinate()
+ {
+ QFETCH(QPointF, coordinate);
+ QFETCH(QPointF, result);
+
+ QCOMPARE(MapEngine::convertLatLonToSceneCoordinate(coordinate), result);
+ }
+
-void TestMapEngine::calculateRect()
++void TestMapEngine::setLocationNewTilesCount()
+ {
- MapEngine engine;
++ MapEngine engine;
+ engine.viewResized(QSize(800, 480));
- engine.setZoomLevel(14);
-
- int zoomFactor = 1 << (MAX_MAP_ZOOM_LEVEL - engine.getZoomLevel());
-
- QRect grid1 = QRect(-1, 0, 6, 4);
- QCOMPARE(engine.calculateGrid(QPointF(550.23*zoomFactor, 550.23*zoomFactor)), grid1);
-
- 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 grid4 = QRect(1016, 497, 8, 7);
- QCOMPARE(engine.calculateGrid(QPointF(1020*TILE_SIZE_X*zoomFactor, 500*TILE_SIZE_Y*zoomFactor)), grid4);
-}
-
-void TestMapEngine::setLocation()
-{
- MapEngine engine;
- engine.setZoomLevel(14);
- engine.viewResized(QSize(800, 480));
-
- int zoomFactor = 1 << (MAX_MAP_ZOOM_LEVEL - engine.getZoomLevel());
+
+ QSignalSpy fetchImageSpy(&engine, SIGNAL(fetchImage(QUrl)));
+ QTest::qWait(1000);
+ fetchImageSpy.clear();
+
- engine.setLocation(QPointF(1220.23*zoomFactor, 1220.23*zoomFactor));
++ engine.setLocation(QPointF(1220.23*16, 1220.23*16));
+ 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));
++ engine.setLocation(QPointF((1220.23+TILE_SIZE_X)*16, (1220.23+TILE_SIZE_Y)*16));
+ QTest::qWait(1000);
+ QCOMPARE(fetchImageSpy.count(), 9);
+ fetchImageSpy.clear();
+ }
+
-void TestMapEngine::convert()
++void TestMapEngine::setLocationRemovedTilesCount()
+ {
- int zoomFactor = 1 << (MAX_MAP_ZOOM_LEVEL - 14);
++ MapEngine engine;
++ engine.viewResized(QSize(800, 480));
++
++ const int maxItemsCount = 30;
+
- 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);
++ engine.setLocation(QPointF(1220.23*16, 1220.23*16));
++ QTest::qWait(1000);
++ engine.setLocation(QPointF(2220.23*16, 2220.23*16));
++ QTest::qWait(1000);
++ QVERIFY(engine.scene()->items().count() <= maxItemsCount);
++
++ engine.setLocation(QPointF(520.23*16, 2220.23*16));
++ QTest::qWait(1000);
++ engine.setLocation(QPointF(2220.23*16, 520.23*16));
++ QTest::qWait(1000);
+
- QCOMPARE(tileNumber, tile);
++ QVERIFY(engine.scene()->items().count() <= maxItemsCount);
+ }
+
-void TestMapEngine::calculateTileGrid()
++void TestMapEngine::zoomInRemovedTilesCount()
+ {
+ MapEngine engine;
-
+ engine.viewResized(QSize(800, 480));
- engine.setZoomLevel(14);
+
- int zoomFactor = 1 << (MAX_MAP_ZOOM_LEVEL - engine.getZoomLevel());
++ const int maxItemsCount = 30;
++
++ engine.setLocation(QPointF(1220.23*16, 1220.23*16));
++ QTest::qWait(1000);
++ QTest::qWait(1000);
++ QVERIFY(engine.scene()->items().count() <= maxItemsCount);
+
- engine.calculateTileGrid(QPointF(1020*TILE_SIZE_X*zoomFactor, 500*TILE_SIZE_X*zoomFactor));
++ engine.setLocation(QPointF(520.23*16, 2220.23*16));
++ QTest::qWait(1000);
++ engine.setLocation(QPointF(2220.23*16, 520.23*16));
++ QTest::qWait(1000);
++
++ QVERIFY(engine.scene()->items().count() <= maxItemsCount);
+ }
+
-//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);
-//}
++void TestMapEngine::zoomOutRemovedTilesCount()
++{
++ MapEngine engine;
++ engine.viewResized(QSize(800, 480));
++
++ const int maxItemsCount = 30;
++
++ engine.setLocation(QPointF(1220.23*16, 1220.23*16));
++ QTest::qWait(1000);
++ engine.setLocation(QPointF(2220.23*16, 2220.23*16));
++ QTest::qWait(1000);
++ QVERIFY(engine.scene()->items().count() <= maxItemsCount);
++
++ engine.setLocation(QPointF(520.23*16, 2220.23*16));
++ QTest::qWait(1000);
++ engine.setLocation(QPointF(2220.23*16, 520.23*16));
++ QTest::qWait(1000);
++
++ QVERIFY(engine.scene()->items().count() <= maxItemsCount);
++}
+
+ QTEST_MAIN(TestMapEngine)
+ #include "testmapengine.moc"