Updated tests cases matching the new tabs
[situare] / src / map / mapscene.h
1 /*
2    Situare - A location system for Facebook
3    Copyright (C) 2010  Ixonos Plc. Authors:
4
5        Sami Rämö - sami.ramo@ixonos.com
6
7    Situare is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License
9    version 2 as published by the Free Software Foundation.
10
11    Situare is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with Situare; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
19    USA.
20 */
21
22 #ifndef MAPSCENE_H
23 #define MAPSCENE_H
24
25 #include <QGraphicsScene>
26
27 #include "maptile.h"
28
29 class SceneCoordinate;
30
31 /**
32 * @brief Map scene for storing MapTile items
33 *
34 * @author Sami Rämö - sami.ramo (at) ixonos.com
35 */
36 class MapScene : public QGraphicsScene
37 {
38     Q_OBJECT
39 public:
40     /**
41     * @brief Constructor
42     *
43     * Scene size is set to the amount of pixels on closest zoom level
44     * @param parent Parent
45     */
46     MapScene(QObject *parent = 0);
47
48 /*******************************************************************************
49  * MEMBER FUNCTIONS AND SLOTS
50  ******************************************************************************/
51 public:
52     /**
53     * @brief Create and add new MapTile to MapScene
54     *
55     * If there is a tile with same parameters already in the scene, it will be removed
56     * before adding the new tile.
57     *
58     * @param zoomLevel Zoom level of the new tile
59     * @param tileNumber X & Y indexes of the tile
60     * @param image Map tile picture
61     * @param viewZoomLevel Current view zoom level (for setting the zValue)
62     */
63     void addTile(int zoomLevel, QPoint tileNumber, const QPixmap &image, int viewZoomLevel);
64
65     /**
66     * @brief Enqueue stacked tiles removal request
67     *
68     * Removal is triggered after events have been processed so the UI
69     * stays more responsive
70     * @param newTile New tile, which area under it is inspected
71     */
72     void enqueueRemoveStackedTiles(MapTile *newTile);
73
74     /**
75     * @brief Calculates scene horizontal resolution in given latitude
76     *
77     * @param latitude Resolution is calculated in this latitude
78     * @returns Scene horizontal resolution (meters/pixel)
79     */
80     static qreal horizontalResolutionAtLatitude(double latitude);
81
82     /**
83     * @brief Returns tile mathcing given hash key
84     *
85     * @param hashKey
86     * @return Returns tile matching given hash key, or 0 if no match found
87     */
88     MapTile* tileInScene(QString hashKey);
89
90     /**
91     * @brief Remove tiles which are out of view bounds.
92     *
93     * Does not remove tiles which are duplicated from current view to opposite side of
94     * the scene.
95     *
96     * @param tilesGrid Current tiles grid
97     * @param zoomLevel Current zoom level
98     */
99     void removeOutOfViewTiles(QRect tilesGrid, int zoomLevel);
100
101     /**
102     * @brief Remove tiles which are stacked.
103     *
104     * Iterate through tiles which are under this map tile and remove tiles which
105     * are fully obscured by this new tile. Tiles which are only partially
106     * obscured by this new tile are not checked, and thus deleted, because of
107     * the required complexity of the algorithm and processing power. Those tiles
108     * will be removed when they go out of the view area caused by scrolling or
109     * zooming in enough.
110     *
111     * @param newTile new tile covering old tiles
112     */
113     void removeStackedTiles(MapTile *newTile);
114
115     /**
116     * @brief Remove tile.
117     *
118     * Removes tile from scene and list of current tiles in scene.
119     * @param tile MapTile to remove
120     */
121     void removeTile(MapTile *tile);
122
123     /**
124       * @brief Set allowed amount of exceeding the world vertical limits
125       *
126       * Limit is set so that vertical limits of the world can be scrolled to middle of
127       * the view.
128       *
129       * @param viewHeight Height of the view
130       * @param zoomLevel Current zoom level
131       */
132     void setSceneVerticalOverlap(int viewHeight, int zoomLevel);
133
134     /**
135     * @brief Set drawing order of all tiles in the scene
136     *
137     * Check MapTile::setSceneLevel for more information.
138     * @param zoomLevel Current zoom level
139     */
140     void setTilesDrawingLevels(int zoomLevel);
141
142     /**
143       * @brief Setter for m_viewTilesGrid
144       *
145       * @param grid Tile grid
146       */
147     void setTilesGrid(QRect grid);
148
149     /**
150       * @brief Setter for m_zoomLevel
151       *
152       * @param zoomLevel Zoom level
153       */
154     void setZoomLevel(int zoomLevel);
155
156     /**
157       * @brief Span items (others than MapTile) to opposite side of the scene
158       *
159       * @param viewSceneRect Scene area which is currently drawn on the view
160       */
161     void spanItems(QRectF viewSceneRect);
162
163     /**
164     * @brief Save new tiles scene rect
165     *
166     * Tiles scene rect must be saved to local scope whenever it changes because
167     * it is used by removal algorithms and some of the algorithms are run
168     * delayed so the actual tiles scene rect may change before the cleanup
169     * algorithm is run.
170     *
171     * @param tilesSceneRect New view rect
172     */
173     void tilesSceneRectUpdated(QRect tilesSceneRect);
174
175 private:
176     /**
177       * @brief Move map items horizontally in the scene (not MapTile items)
178       *
179       * MapTile items are not moved!
180       *
181       * Move items which intersect the given rect.
182       *
183       * @param from Items colliding given rect are moved
184       * @param distance How much to move each item
185       */
186     void moveIntersectingItemsHorizontally(QRect from, int distance);
187
188 private slots:
189     /**
190       * @brief Remove tiles from other than current zoom levels
191       *
192       * Does remove tiles only if all tiles in current m_viewTilesGrid are in the scene.
193       */
194     void removeOtherLevelTiles();
195
196     /**
197     * @brief Slot for running next queued removal of stacked tiles
198     *
199     */
200     void runNextStackedTilesRemoval();
201
202 /*******************************************************************************
203  * DATA MEMBERS
204  ******************************************************************************/
205 private:
206     bool m_isRemoveStackedTilesRunning;           ///< Is singleshot timer already running
207     int m_zoomLevel;                              ///< Current zoom level
208     QHash<QString, MapTile *> m_mapTilesInScene;  ///< List of map tiles in map scene
209     QList<MapTile *> m_removeStackedTilesList;    ///< "Queue" for stacked tiles removal requests
210     QRect m_tilesSceneRect;                       ///< Current viewable area
211     QRect m_viewTilesGrid;                        ///< Current grid of tiles
212 };
213
214 #endif // MAPSCENE_H