Added MapEngine::combineTiles method and modified
[situare] / src / map / mapengine.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        Jussi Laitinen - jussi.laitinen@ixonos.com
7
8    Situare is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License
10    version 2 as published by the Free Software Foundation.
11
12    Situare is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Situare; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
20    USA.
21 */
22
23 #ifndef MAPENGINE_H
24 #define MAPENGINE_H
25
26 #include <QtCore>
27
28 #include "mapcommon.h"
29 #include "mapfetcher.h"
30 #include "mapscene.h"
31 #include "maptile.h"
32
33 /**
34 * @brief Map engine
35 *
36 * Logic for controlling map functionality. Does also include static methods for
37 * converting coordinates.
38 * @author Sami Rämö - sami.ramo (at) ixonos.com
39 * @author Jussi Laitinen - jussi.laitinen (at) ixonos.com
40 */
41 class MapEngine : public QObject
42 {
43     Q_OBJECT
44 public:
45     /**
46     * @brief Constructor
47     *
48     * @param parent Parent
49     */
50     MapEngine(QObject *parent = 0);
51
52 /*******************************************************************************
53  * CLASS SPECIFIC MEMBER FUNCTIONS AND SLOTS
54  ******************************************************************************/
55     /**
56     * @brief Convert latitude and longitude to scene coordinates.
57     *
58     * @param latLonCoordinate latitude and longitude values
59     * @return scene coordinate
60     */
61     static QPoint convertLatLonToSceneCoordinate(QPointF latLonCoordinate);
62
63     /**
64     * @brief Convert MapScene coordinate to tile x & y numbers.
65     *
66     * @param zoomLevel ZoomLevel
67     * @param sceneCoordinate MapScene coordinate
68     * @return QPoint tile x & y numbers
69     */
70     static QPoint convertSceneCoordinateToTileNumber(int zoomLevel, QPoint sceneCoordinate);
71
72     /**
73     * @brief Convert tile x & y numbers to MapScene coordinates
74     *
75     * @param zoomLevel Zoom level
76     * @param tileNumber x & y numbers of the tile
77     * @return QPoint MapScene coordinate
78     */
79     static QPoint convertTileNumberToSceneCoordinate(int zoomLevel, QPoint tileNumber);
80
81     /**
82     * @brief MapEngine initializer
83     *
84     * Set initial location and zoom level for the engine. locationChanged and
85     * zoomLevelChanged signals are emitted, so init should be called after
86     * those signals are connected to MapView.
87     */
88     void init();
89
90     /**
91     * @brief Helper for setting view location based on latitude and longitude
92     * coordinates
93     *
94     * @param latLonCoordinate Latitude & longitude coordinates for location
95     */
96     void setViewLocation(QPointF latLonCoordinate);
97
98     /**
99     * @brief Getter for scene
100     *
101     * @return QGraphicsScene
102     */
103     QGraphicsScene* scene();
104
105 public slots:
106     /**
107     * @brief Slot for setting current view location
108     *
109     * Emits locationChanged signal.
110     * @param sceneCoordinate Scene coordinates for new position
111     */
112     void setLocation(QPoint sceneCoordinate);
113
114     /**
115     * @brief Slot for view resizing.
116     *
117     * @param size view size
118     */
119     void viewResized(const QSize &size);
120
121 private:
122     /**
123     * @brief Build URL for donwloading single map tile from OpenStreetMap tile server
124     *
125     * @param zoomLevel Zoom level
126     * @param tileNumbers Tile x & y numbers
127     * @return URL for the required tile
128     */
129     QUrl buildURL(int zoomLevel, QPoint tileNumbers);
130
131     /**
132     * @brief Calculate grid of tile coordinates from current scene coordinate.
133     *
134     * Grid size is calculated from view size and scene's current center coordinate.
135     *
136     * @param sceneCoordinate scene's current center coordinate
137     * @return QRect grid of tile coordinates
138     */
139     QRect calculateGrid(QPoint sceneCoordinate);
140
141     /**
142     * @brief Calculate new tiles to fetch.
143     *
144     * @param sceneCoordinate scene's center coordinate
145     */
146     void calculateNewTiles(QPoint sceneCoordinate);
147
148     /**
149     * @brief Check if center tile has changed.
150     *
151     * @param sceneCoordinate scene's center coordinate
152     * @return bool true if center tile changed, false otherwise
153     */
154     bool centerTileChanged(QPoint sceneCoordinate);
155
156     /**
157     * @brief Combine tiles' rectangles to one rectangle.
158     *
159     * @param stackedTiles tiles to combine
160     * @return QRectF resulting rectangle
161     */
162     QRectF combineTiles(QGraphicsItem *parentTile, const QList<QGraphicsItem*> &stackedTiles);
163
164     /**
165     * @brief Parse given URL to zoom, x and y values. Parsed values are
166     * placed in variables given as parameters.
167     *
168     * @param url url to parse
169     * @param [out] zoom zoom variable
170     * @param [out] x x variable
171     * @param [out] y y variable
172     */
173     void parseURL(const QUrl &url, int &zoom, int &x, int &y);
174
175     /**
176     * @brief Remove tiles which are stacked.
177     *
178     * Iterate through tiles which are under this map tile and remove obscured
179     * tiles.
180     *
181     * @param newTile new tile covering old tiles
182     */
183     void removeStackedTiles(MapTile *newTile);
184
185     /**
186     * @brief Remove tile.
187     *
188     * Removes tile from scene and list of current tiles in scene.
189     * @param tile MapTile to remove
190     */
191     void removeTile(MapTile *tile);
192
193     /**
194     * @brief Set drawing order of all tiles in the scene
195     *
196     * Check MapTile::setSceneLevel for more information.
197     */
198     void setTilesDrawingLevels();
199
200     /**
201     * @brief Calculate maximum value for tile in this zoom level.
202     *
203     * @param zoomLevel zoom level
204     * @return int tile's maximum value
205     */
206     int tileMaxValue(int zoomLevel);
207
208     /**
209     * @brief Return tile path created from tile values.
210     *
211     * @param zoomLevel tile's zoom level
212     * @param x tile's x value
213     * @param y tile's y value
214     * @return QString tile path
215     */
216     inline QString tilePath(int zoomLevel, int x, int y);
217
218 private slots:
219     /**
220     * @brief Slot for received map tile images
221     *
222     * Does add MapTile objects to MapScene. Zoom level and location is parsed from URL.
223     * @param url URL of the received image
224     * @param pixmap Received pixmap
225     */
226     void mapImageReceived(const QUrl &url, const QPixmap &pixmap);
227
228     /**
229     * @brief Remove tiles which are out of view bounds.
230     */
231     void removeOldTiles();
232
233     /**
234     * @brief Slot for view scaling factor change events
235     *
236     * Can be used to trigger scaling of zoom buttons, friend indicators and other
237     * MapScene elements which should retain their visual size
238     * @param scaleFactor view's scale factor
239     */
240     void scalingFactorChanged(qreal scaleFactor);
241
242     /**
243     * @brief Slot for zooming in
244     *
245     */
246     void zoomIn();
247
248     /**
249     * @brief Slot for zooming out
250     *
251     */
252     void zoomOut();
253
254 /*******************************************************************************
255  * SIGNALS
256  ******************************************************************************/
257 signals:   
258     /**
259     * @brief Signal for image fetching.
260     *
261     * @param url image url
262     */
263     void fetchImage(const QUrl &url);
264
265     /**
266     * @brief Signal for view location change
267     *
268     * @param sceneCoordinate New scene coordinates
269     */
270     void locationChanged(QPoint sceneCoordinate);
271
272     /**
273     * @brief Signal for zoom level change
274     *
275     * @param newZoomLevel New zoom level
276     */
277     void zoomLevelChanged(int newZoomLevel);
278
279 /*******************************************************************************
280  * DATA MEMBERS
281  ******************************************************************************/
282 private:
283     QPoint m_centerTile;    ///< Current center tile
284     MapFetcher *m_mapFetcher; ///< Fetcher for map tiles
285     MapScene *m_mapScene; ///< Scene for map tiles
286     QHash<QString, MapTile *> m_mapTilesInScene;  ///< List of map tiles in map scene
287     QPoint m_sceneCoordinate;  ///< Current center coordinate
288     QRect m_viewGrid; ///< Current grid of tiles in view
289     QSize m_viewSize;   ///< Current view size
290     int m_zoomLevel; ///< Current zoom level
291 };
292
293 #endif // MAPENGINE_H