mapTilesInScene.insert(url.toString(), mapTile);
m_mapScene->addMapTile(mapTile);
- }
+
+ removeStackedTiles(mapTile);
- }
++
++ qDebug() << "Tile count: " << m_mapScene->items().count();
++ }
}
QGraphicsScene* MapEngine::scene()
QRect MapEngine::calculateGrid(QPointF 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);
emit locationChanged(m_sceneCoordinate);
if (centerTileChanged(sceneCoordinate)) {
- calculateTileGrid(sceneCoordinate);
- removeTilesOutOfBounds();
+ calculateNewTiles(sceneCoordinate);
- //removeOldTiles();
++ removeOldTiles();
}
}
{
//qDebug() << __PRETTY_FUNCTION__;
-- int zoomFactor = 1 << (MAX_MAP_ZOOM_LEVEL - m_zoomLevel);
--
QPointF topLeft = convertTileNumberToSceneCoordinate(m_zoomLevel, viewGrid.topLeft());
QPointF bottomRight = convertTileNumberToSceneCoordinate(m_zoomLevel, viewGrid.bottomRight() + QPoint(1, 1));
qreal width = bottomRight.x() - topLeft.x();
}
}
}
+}
+
+void MapEngine::removeStackedTiles(MapTile *tile)
+{
- QList<QGraphicsItem *> collidingItems = tile->collidingItems(Qt::ContainsItemBoundingRect);
-
- qDebug() << "Colliding items: " << collidingItems.count();
++ QList<QGraphicsItem *> collidingItems = tile->collidingItems(Qt::IntersectsItemBoundingRect);
+ foreach (QGraphicsItem *item, collidingItems) {
- if (item->isObscured()) {
- qDebug() << "Deleted:" << item->boundingRect();
- MapTile *tmp = dynamic_cast<MapTile *>(item);
- m_mapScene->removeItem(tmp);
- mapTilesInScene.remove(buildURL(tmp->zoomLevel(), tmp->tileNumber()).toString());
++
++ QRectF itemSceneRect = item->mapRectToScene(item->boundingRect());
++ QList<QGraphicsItem *> stackedItems = m_mapScene->items(itemSceneRect, Qt::IntersectsItemBoundingRect);
++
++ foreach(QGraphicsItem *stackedItem, stackedItems) {
++ if (item != stackedItem) {
++ MapTile *tmp = dynamic_cast<MapTile *>(item);
++ m_mapScene->removeItem(tmp);
++ mapTilesInScene.remove(buildURL(tmp->zoomLevel(), tmp->tileNumber()).toString());
++ }
+ }
+ }
}
void MapEngine::viewResized(const QSize &size)
{
m_viewSize = size;
-- setLocation(m_sceneCoordinate);
++ //setLocation(m_sceneCoordinate);
++ calculateNewTiles(m_sceneCoordinate);
}
void MapEngine::zoomIn()
{
++ qDebug() << __PRETTY_FUNCTION__;
++
if (m_zoomLevel >= MAX_MAP_ZOOM_LEVEL)
return;
emit zoomLevelChanged(m_zoomLevel);
setZValues();
--
-- /// @todo START FETCHING TILES
- calculateTileGrid(m_sceneCoordinate);
+ calculateNewTiles(m_sceneCoordinate);
++ removeOldTiles();
}
void MapEngine::zoomOut()
{
++ qDebug() << __PRETTY_FUNCTION__;
++
if (m_zoomLevel <= MIN_MAP_ZOOM_LEVEL)
return;
emit zoomLevelChanged(m_zoomLevel);
setZValues();
--
-- /// @todo START FETCHING TILES
- calculateTileGrid(m_sceneCoordinate);
-}
-
-void MapEngine::setZoomLevel(int zoomLevel)
-{
- m_zoomLevel = zoomLevel;
-}
-
-int MapEngine::getZoomLevel()
-{
- return m_zoomLevel;
+ calculateNewTiles(m_sceneCoordinate);
++ removeOldTiles();
}
void MapEngine::setZValues()
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)
{
int pow = 1 << (MAX_MAP_ZOOM_LEVEL - zoomLevel);
void setViewLocation(QPointF latLonCoordinate);
/**
-- * @brief Converts latitude and longitude to scene coordinates.
++ * @brief Convert latitude and longitude to scene coordinates.
*
* @param latLonCoordinate latitude and longitude values
* @return scene coordinate
QUrl buildURL(int zoomLevel, QPoint tileNumbers);
/**
-- * @brief Parses given URL to zoom, x and y values. Parsed values are
++ * @brief Parse given URL to zoom, x and y values. Parsed values are
* placed in variables given as parameters.
*
* @param url url to parse
*/
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 Calculates grid of tile coordinates from current scene coordinate.
++ * @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);
+
+ /**
+ * @brief Calculate new tiles to fetch.
+ *
+ * @param sceneCoordinate scene's center coordinate
+ */
+ void calculateNewTiles(QPointF sceneCoordinate);
+
+ /**
- * @brief Removes tiles which are out of view bounds.
++ * @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 Checks if center tile has changed.
++ * @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);
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:
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;
-- QPointF m_sceneCoordinate;
-- QQueue<QString> mapTilesInView;
-- QPoint m_centerTile;
-- QRect viewGrid;
++ QSize m_viewSize; ///< Current view size
++ QPointF m_sceneCoordinate; ///< Current center coordinate
++ QPoint m_centerTile; ///< Current center tile
++ QRect viewGrid; ///< Current grid of tiles in view
};
#endif // MAPENGINE_H
return currentTransform.m11();
}
-void MapView::scrollContentsBy (int dx, int dy)
++//void MapView::scrollContentsBy (int dx, int dy)
++//{
++// qDebug() << __PRETTY_FUNCTION__ << "dx:" << dx << "dy:" << dy;
++//
++// QGraphicsView::scrollContentsBy(dx, dy);
++//}
++
+void MapView::mouseMoveEvent(QMouseEvent *event)
{
- qDebug() << __PRETTY_FUNCTION__ << "dx:" << dx << "dy:" << dy;
+ m_scenePosition += m_mousePosition - mapToScene(event->pos());
- QGraphicsView::scrollContentsBy(dx, dy);
+ emit viewScrolled(m_scenePosition);
+ //qDebug() << __PRETTY_FUNCTION__ << "m_scenePosition" << m_scenePosition;
+
+ m_mousePosition = mapToScene(event->pos());
}
-//void MapView::mouseMoveEvent(QMouseEvent *event)
-//{
-// m_scenePosition += m_mousePosition - mapToScene(event->pos());
-//
-// emit viewScrolled(m_scenePosition);
-// //qDebug() << __PRETTY_FUNCTION__ << "m_scenePosition" << m_scenePosition;
-//
-// m_mousePosition = mapToScene(event->pos());
-//}
-//
-//void MapView::mousePressEvent(QMouseEvent *event)
-//{
-// m_mousePosition = mapToScene(event->pos());
-// m_scenePosition = mapToScene(width() / 2 - 1, height() / 2 - 1);
-//}
+void MapView::mousePressEvent(QMouseEvent *event)
+{
+ m_mousePosition = mapToScene(event->pos());
+ m_scenePosition = mapToScene(width() / 2 - 1, height() / 2 - 1);
+}
void MapView::centerToSceneCoordinates(QPointF sceneCoordinate)
*/
MapView(QWidget *parent = 0);
+ protected:
- void scrollContentsBy(int dx, int dy);
++// void scrollContentsBy(int dx, int dy);
+
private:
//
/**
private slots:
void convertTileNumberToSceneCoordinate();
// void setViewLocation();
- // void convertLatLonToSceneCoordinate();
+ void convertLatLonToSceneCoordinate_data();
+ void convertLatLonToSceneCoordinate();
- void calculateRect();
- void setLocation();
-// void removeTilesOutOfBounds();
- void calculateTileGrid();
- void convert();
+ void setLocationNewTilesCount();
+ void setLocationRemovedTilesCount();
- // void calculateTileGrid();
- // void convert();
++ void zoomOutRemovedTilesCount();
++ void zoomInRemovedTilesCount();
};
/**
* @brief Test converting real world cordinates to scene coordinates
* @todo Implement
*/
- //void TestMapEngine::convertLatLonToSceneCoordinate()
- //{
- // QCOMPARE(MapEngine::convertLatLonToSceneCoordinate(QPointF(25.5, 65.0)), QPointF(73, 33));
- // QCOMPARE(MapEngine::convertLatLonToSceneCoordinate(QPointF(25.5, 65.0)), QPointF(1, 0));
- // QCOMPARE(MapEngine::convertLatLonToSceneCoordinate(QPointF(-190.0, 65.0)), QPointF(UNDEFINED, UNDEFINED));
- // QCOMPARE(MapEngine::convertLatLonToSceneCoordinate(QPointF(20.0, 65.0)), QPointF(UNDEFINED, UNDEFINED));
- //}
+ 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();
}
-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"
DEPENDPATH += .
INCLUDEPATH += . \
../../../src/
--#DEFINES += QT_NO_DEBUG_OUTPUT
++DEFINES += QT_NO_DEBUG_OUTPUT
# Input
SOURCES += testmapengine.cpp \