Refactored MapScene clean-up code
authorSami Rämö <sami.ramo@ixonos.com>
Thu, 22 Apr 2010 09:32:15 +0000 (12:32 +0300)
committerSami Rämö <sami.ramo@ixonos.com>
Thu, 22 Apr 2010 09:32:15 +0000 (12:32 +0300)
* Moved MapScene related methods from MapEngine to MapScene

* Set signal to be emitted when zooming in is finished
  and use that signal to launch removing of tiles which
  are out of the view area

Doxyfile
src/map/mapengine.cpp
src/map/mapengine.h
src/map/mapscene.cpp
src/map/mapscene.h
src/map/mapview.cpp
src/map/mapview.h
src/ui/mapviewscreen.cpp

index 1ba01a2..2b3dcdd 100644 (file)
--- a/Doxyfile
+++ b/Doxyfile
@@ -611,7 +611,7 @@ EXCLUDE_SYMLINKS       = NO
 # against the file with absolute path, so to exclude all test directories
 # for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       =
+EXCLUDE_PATTERNS       = */moc_*
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
index 392b5f0..4617284 100644 (file)
@@ -97,17 +97,16 @@ void MapEngine::mapImageReceived(const QUrl &url, const QPixmap &pixmap)
 
     parseURL(url, zoom, x, y);
     QString hashKey = tilePath(zoom, x, y);
-    if (!m_mapTilesInScene.contains(hashKey)) {
+    if (!m_mapScene->isTileInScene(hashKey)) {
 
         MapTile *mapTile = new MapTile();
         mapTile->setZoomLevel(zoom);
         mapTile->setTileNumber(QPoint(x, y));
         mapTile->setPixmap(pixmap);
 
-        m_mapTilesInScene.insert(hashKey, mapTile);
-        m_mapScene->addMapTile(mapTile);
+        m_mapScene->addTile(mapTile, hashKey);
 
-        removeStackedTiles(mapTile);
+        m_mapScene->removeStackedTiles(mapTile, viewRect());
    }
 }
 
@@ -148,7 +147,7 @@ void MapEngine::setLocation(QPoint sceneCoordinate)
 
     if (isCenterTileChanged(sceneCoordinate)) {
         getTiles(sceneCoordinate);
-        removeTilesOutOfView();
+        m_mapScene->removeOutOfViewTiles(viewRect());
     }
 }
 
@@ -192,47 +191,12 @@ void MapEngine::getTiles(QPoint sceneCoordinate)
 
             QUrl url = buildURL(m_zoomLevel, QPoint(tileX, tileY));
 
-            if (!m_mapTilesInScene.contains(tilePath(m_zoomLevel, tileX, tileY)))
+            if (!m_mapScene->isTileInScene(tilePath(m_zoomLevel, tileX, tileY)))
                 emit fetchImage(url);
         }
     }
 }
 
-void MapEngine::removeTile(MapTile *tile)
-{
-//    qDebug() << __PRETTY_FUNCTION__;
-
-    if (tile) {
-       m_mapTilesInScene.remove(tilePath(tile->zoomLevel(), tile->tileNumber().x(),
-                                         tile->tileNumber().y()));
-       m_mapScene->removeItem(tile);
-       delete tile;
-    }
-}
-
-void MapEngine::removeTilesOutOfView()
-{
-//    qDebug() << __PRETTY_FUNCTION__;
-
-    QList<QGraphicsItem *> viewTiles = m_mapScene->items(viewRect(), Qt::ContainsItemBoundingRect);
-    QList<QGraphicsItem *> allTiles = m_mapScene->items();
-
-//    qDebug() << __PRETTY_FUNCTION__ << "All tiles:" << allTiles.count();
-//    qDebug() << __PRETTY_FUNCTION__ << "Tiles in view area:" << viewTiles.count();
-
-    //Remove tiles which are in view from allTiles
-    foreach (QGraphicsItem *tile, viewTiles)
-        allTiles.removeOne(tile);
-
-
-    //Remove tiles out of view
-    foreach (QGraphicsItem *tile, allTiles) {
-        MapTile *tileToRemove = dynamic_cast<MapTile *>(tile);
-        if (tileToRemove)
-            removeTile(tileToRemove);
-    }
-}
-
 QRect MapEngine::viewRect()
 {
     QPoint topLeft = convertTileNumberToSceneCoordinate(m_zoomLevel, m_viewGrid.topLeft());
@@ -241,47 +205,17 @@ QRect MapEngine::viewRect()
     return QRect(topLeft, bottomRight);
 }
 
-void MapEngine::removeStackedTiles(MapTile *newTile)
-{
-//    qDebug() << __PRETTY_FUNCTION__;
-
-    QRectF newTileSceneRect = newTile->sceneBoundingRect();
-
-    //Loop all items under new tile
-    QList<QGraphicsItem *> collidingTiles = newTile->collidingItems(Qt::IntersectsItemBoundingRect);
-//    qDebug() << __PRETTY_FUNCTION__ << "Colliding tiles before:" << collidingTiles.count();
-    foreach (QGraphicsItem *collidingTile, collidingTiles) {
-
-
-        QRectF collidingTileSceneRect = collidingTile->sceneBoundingRect();
-
-        // remove tile if it is obscured by new tile
-        if (newTileSceneRect.contains(collidingTileSceneRect)) {
-            MapTile *tile = dynamic_cast<MapTile *>(collidingTile);
-            if (tile)
-                removeTile(tile);
-        }
-        else {
-            // remove tile if it is obscured in the view area
-            QRect collidingTileViewableArea =
-                    collidingTileSceneRect.intersected(viewRect()).toRect();
-            if (collidingTile->isObscured(collidingTileViewableArea)) {
-                qDebug() << __PRETTY_FUNCTION__ << "Deleting obscured item";
-                MapTile *tile = dynamic_cast<MapTile *>(collidingTile);
-                if (tile)
-                    removeTile(tile);
-            }
-        }
-    }
-//    qDebug() << __PRETTY_FUNCTION__ << "All tiles after:"
-//             << newTile->collidingItems(Qt::IntersectsItemBoundingRect).count();
-}
-
 void MapEngine::viewResized(const QSize &size)
 {
     m_viewSize = size;
     getTiles(m_sceneCoordinate);
-    removeTilesOutOfView();
+    m_mapScene->removeOutOfViewTiles(viewRect());
+}
+
+void MapEngine::viewZoomInFinished()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    m_mapScene->removeOutOfViewTiles(viewRect());
 }
 
 void MapEngine::zoomIn()
@@ -292,12 +226,9 @@ void MapEngine::zoomIn()
         m_zoomLevel++;
         emit zoomLevelChanged(m_zoomLevel);
 
-        setTilesDrawingLevels();
+        m_mapScene->setTilesDrawingLevels(m_zoomLevel);
 
         getTiles(m_sceneCoordinate);
-
-        // remove unused tiles after zooming is done
-        QTimer::singleShot(ZOOM_TIME*2, this, SLOT(removeTilesOutOfView()));
     }
 }
 
@@ -309,25 +240,12 @@ void MapEngine::zoomOut()
         m_zoomLevel--;
         emit zoomLevelChanged(m_zoomLevel);
 
-        setTilesDrawingLevels();
+        m_mapScene->setTilesDrawingLevels(m_zoomLevel);
 
         getTiles(m_sceneCoordinate);
     }
 }
 
-void MapEngine::setTilesDrawingLevels()
-{
-//    qDebug() << __PRETTY_FUNCTION__ << "m_zoomLevel:" << m_zoomLevel;
-
-    QList<QGraphicsItem *> items = m_mapScene->items();
-
-    for (int i = 0; i < items.size(); ++i) {
-        MapTile *item = dynamic_cast<MapTile *>(items.at(i));
-        if (item)
-            item->setSceneLevel(m_zoomLevel);
-    }
-}
-
 QString MapEngine::tilePath(int zoomLevel, int x, int y)
 {
     QString tilePathString(QString::number(zoomLevel) + "/");
index 00b5c27..4b156ab 100644 (file)
@@ -55,6 +55,7 @@ public:
 /*******************************************************************************
  * MEMBER FUNCTIONS AND SLOTS
  ******************************************************************************/
+public:
     /**
     * @brief Convert latitude and longitude to scene coordinates.
     *
@@ -105,6 +106,16 @@ public:
     */
     QGraphicsScene* scene();
 
+    /**
+    * @brief Return tile path created from tile values.
+    *
+    * @param zoomLevel tile's zoom level
+    * @param x tile's x value
+    * @param y tile's y value
+    * @return QString tile path
+    */
+    static QString tilePath(int zoomLevel, int x, int y);
+
 public slots:
     /**
     * @brief Slot for immovable scene items position correction
@@ -177,31 +188,6 @@ private:
     void parseURL(const QUrl &url, int &zoom, int &x, int &y);
 
     /**
-    * @brief Remove tiles which are stacked.
-    *
-    * Iterate through tiles which are under this map tile and remove obscured
-    * tiles.
-    *
-    * @param newTile new tile covering old tiles
-    */
-    void removeStackedTiles(MapTile *newTile);
-
-    /**
-    * @brief Remove tile.
-    *
-    * Removes tile from scene and list of current tiles in scene.
-    * @param tile MapTile to remove
-    */
-    void removeTile(MapTile *tile);
-
-    /**
-    * @brief Set drawing order of all tiles in the scene
-    *
-    * Check MapTile::setSceneLevel for more information.
-    */
-    void setTilesDrawingLevels();
-
-    /**
     * @brief Calculate maximum value for tile in this zoom level.
     *
     * @param zoomLevel zoom level
@@ -210,16 +196,6 @@ private:
     int tileMaxValue(int zoomLevel);
 
     /**
-    * @brief Return tile path created from tile values.
-    *
-    * @param zoomLevel tile's zoom level
-    * @param x tile's x value
-    * @param y tile's y value
-    * @return QString tile path
-    */
-    QString tilePath(int zoomLevel, int x, int y);
-
-    /**
     * @brief Returns the current view rect including margins
     *
     * @return Current view rect
@@ -237,9 +213,11 @@ private slots:
     void mapImageReceived(const QUrl &url, const QPixmap &pixmap);
 
     /**
-    * @brief Remove tiles which are out of view bounds.
+    * @brief Slot for actions after view zoom is finished
+    *
+    * Does run removeOutOfViewTiles
     */
-    void removeTilesOutOfView();
+    void viewZoomInFinished();
 
     /**
     * @brief Slot for zooming in
@@ -285,7 +263,6 @@ private:
     MapFetcher *m_mapFetcher; ///< Fetcher for map tiles
     MapScene *m_mapScene; ///< Scene for map tiles
     MapZoomPanel *m_mapZoomPanel; ///< Toolbar for zoom buttons
-    QHash<QString, MapTile *> m_mapTilesInScene;  ///< List of map tiles in map scene
     QPoint m_centerTile; ///< Current center tile
     QPoint m_sceneCoordinate; ///< Current center coordinate
     QRect m_viewGrid; ///< Current grid of tiles in view (includes margin)
index f7b55ba..8889744 100644 (file)
@@ -33,7 +33,99 @@ MapScene::MapScene(QObject *parent)
     setSceneRect(0, 0, maxPixelsX, maxPixelsY);
 }
 
-void MapScene::addMapTile(MapTile *mapTile)
+void MapScene::addTile(MapTile *mapTile, QString hashKey)
 {
+    m_mapTilesInScene.insert(hashKey, mapTile);
     addItem(mapTile);
 }
+
+bool MapScene::isTileInScene(QString hashKey)
+{
+    return m_mapTilesInScene.contains(hashKey);
+}
+
+void MapScene::removeOutOfViewTiles(QRect viewRect)
+{
+//    qDebug() << __PRETTY_FUNCTION__;
+
+    QList<QGraphicsItem *> viewTiles = items(viewRect, Qt::ContainsItemBoundingRect);
+    QList<QGraphicsItem *> allTiles = items();
+
+//    qDebug() << __PRETTY_FUNCTION__ << "All tiles:" << allTiles.count();
+//    qDebug() << __PRETTY_FUNCTION__ << "Tiles in view area:" << viewTiles.count();
+
+    //Remove tiles which are in view from allTiles
+    foreach (QGraphicsItem *tile, viewTiles)
+        allTiles.removeOne(tile);
+
+
+    //Remove tiles out of view
+    foreach (QGraphicsItem *tile, allTiles) {
+        MapTile *tileToRemove = dynamic_cast<MapTile *>(tile);
+        if (tileToRemove)
+            removeTile(tileToRemove);
+    }
+}
+
+void MapScene::removeStackedTiles(MapTile *newTile, QRect viewRect)
+{
+//    qDebug() << __PRETTY_FUNCTION__;
+
+    QRectF newTileSceneRect = newTile->sceneBoundingRect();
+
+    //Loop all items under new tile
+    QList<QGraphicsItem *> collidingTiles = newTile->collidingItems(Qt::IntersectsItemBoundingRect);
+//    qDebug() << __PRETTY_FUNCTION__ << "Colliding tiles before:" << collidingTiles.count();
+    foreach (QGraphicsItem *collidingTile, collidingTiles) {
+
+
+        QRectF collidingTileSceneRect = collidingTile->sceneBoundingRect();
+
+        // remove tile if it is obscured by new tile
+        if (newTileSceneRect.contains(collidingTileSceneRect)) {
+            MapTile *tile = dynamic_cast<MapTile *>(collidingTile);
+            if (tile)
+                removeTile(tile);
+        }
+        else {
+            // remove tile if it is obscured in the view area
+            QRect collidingTileViewableArea =
+                    collidingTileSceneRect.intersected(viewRect).toRect();
+            if (collidingTile->isObscured(collidingTileViewableArea)) {
+                qDebug() << __PRETTY_FUNCTION__ << "Deleting obscured item";
+                MapTile *tile = dynamic_cast<MapTile *>(collidingTile);
+                if (tile)
+                    removeTile(tile);
+            }
+        }
+    }
+//    qDebug() << __PRETTY_FUNCTION__ << "All tiles after:"
+//             << newTile->collidingItems(Qt::IntersectsItemBoundingRect).count();
+}
+
+
+void MapScene::removeTile(MapTile *tile)
+{
+//    qDebug() << __PRETTY_FUNCTION__;
+
+    if (tile) {
+        m_mapTilesInScene.remove(MapEngine::tilePath(tile->zoomLevel(),
+                                                     tile->tileNumber().x(),
+                                                     tile->tileNumber().y()));
+       removeItem(tile);
+       delete tile;
+    }
+}
+
+void MapScene::setTilesDrawingLevels(int zoomLevel)
+{
+//    qDebug() << __PRETTY_FUNCTION__ << "m_zoomLevel:" << m_zoomLevel;
+
+    QList<QGraphicsItem *> allItems = items();
+
+    for (int i = 0; i < allItems.size(); ++i) {
+        MapTile *item = dynamic_cast<MapTile *>(allItems.at(i));
+        if (item)
+            item->setSceneLevel(zoomLevel);
+    }
+}
index 4ba5896..7c6c446 100644 (file)
@@ -43,14 +43,64 @@ public:
     MapScene(QObject *parent = 0);
 
 /*******************************************************************************
- * CLASS SPECIFIC MEMBER FUNCTIONS AND SLOTS
+ * MEMBER FUNCTIONS AND SLOTS
  ******************************************************************************/
+public:
     /**
     * @brief Add MapTile item to scene
     *
     * @param mapTile Map tile item to be added
+    * @param hashKey Hash key for the tile
     */
-    void addMapTile(MapTile *mapTile);
+    void addTile(MapTile *mapTile, QString hashKey);
+
+    /**
+    * @brief Returns if tile mathcing hash key is already in the scene
+    *
+    * @param hashKey
+    * @return True if tile was in the scene, otherwise false
+    */
+    bool isTileInScene(QString hashKey);
+
+    /**
+    * @brief Remove tiles which are out of view bounds.
+    *
+    * @param viewRect Current view rect
+    */
+    void removeOutOfViewTiles(QRect viewRect);
+
+    /**
+    * @brief Remove tiles which are stacked.
+    *
+    * Iterate through tiles which are under this map tile and remove obscured
+    * tiles.
+    *
+    * @param newTile new tile covering old tiles
+    * @param viewRect Current view rect
+    */
+    void removeStackedTiles(MapTile *newTile, QRect viewRect);
+
+    /**
+    * @brief Remove tile.
+    *
+    * Removes tile from scene and list of current tiles in scene.
+    * @param tile MapTile to remove
+    */
+    void removeTile(MapTile *tile);
+
+    /**
+    * @brief Set drawing order of all tiles in the scene
+    *
+    * Check MapTile::setSceneLevel for more information.
+    * @param zoomLevel Current zoom level
+    */
+    void setTilesDrawingLevels(int zoomLevel);
+
+/*******************************************************************************
+ * DATA MEMBERS
+ ******************************************************************************/
+private:
+    QHash<QString, MapTile *> m_mapTilesInScene;  ///< List of map tiles in map scene
 };
 
 #endif // MAPSCENE_H
index ee68274..15de9cb 100644 (file)
@@ -61,6 +61,7 @@ void MapView::setZoomLevel(int zoomLevel)
 void MapView::timerEvent(QTimerEvent *event)
 {
     if (event->timerId() == m_timerID) {
+        bool finished = false;
         qreal scaleFactor = currentScale();
 
 //        qDebug() << __PRETTY_FUNCTION__
@@ -70,6 +71,7 @@ void MapView::timerEvent(QTimerEvent *event)
         if (fabs(m_zoomTargetScale - scaleFactor) <= fabs(m_zoomScaleDelta)) {
             scaleFactor = m_zoomTargetScale;
             killTimer(event->timerId());
+            finished = true;
         }
         else {
             scaleFactor += m_zoomScaleDelta;
@@ -83,6 +85,9 @@ void MapView::timerEvent(QTimerEvent *event)
         transform.scale(scaleFactor, scaleFactor);
         setTransform(transform);
        emit viewContentChanged(mapToScene(viewport()->x(), viewport()->y()).toPoint());
+
+        if (finished && m_zoomScaleDelta > 0)
+            emit viewZoomInFinished();
     }
 }
 
index 17eeb88..7f13f52 100644 (file)
@@ -125,6 +125,12 @@ signals:
     void viewScrolled(QPoint sceneCoordinate);
 
     /**
+    * @brief Signal for informing that zooming in is finished
+    *
+    */
+    void viewZoomInFinished();
+
+    /**
     * @brief Signal for updating view content
     *
     * Signal is emitted when view content needs an update.
index a7ca8fa..de749a8 100644 (file)
@@ -39,6 +39,7 @@ MapViewScreen::MapViewScreen(QWidget *parent)
     connect(mapView, SIGNAL(viewResized(QSize)), mapEngine, SLOT(viewResized(QSize)));
     connect(mapView, SIGNAL(viewContentChanged(QPoint)),
             mapEngine, SLOT(alignImmovableItems(QPoint)));
+    connect(mapView, SIGNAL(viewZoomInFinished()), mapEngine, SLOT(viewZoomInFinished()));
 
     QHBoxLayout *mapViewLayout = new QHBoxLayout;
     //DEBUG