Updated tests cases matching the new tabs
[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        Pekka Nissinen - pekka.nissinen@ixonos.com
8        Ville Tiensuu - ville.tiensuu@ixonos.com
9        Henri Lampela - henri.lampela@ixonos.com
10
11    Situare is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License
13    version 2 as published by the Free Software Foundation.
14
15    Situare is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with Situare; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
23    USA.
24 */
25
26 #ifndef MAPENGINE_H
27 #define MAPENGINE_H
28
29 #include <QtCore>
30
31 #include "routing/route.h"
32 #include "coordinates/geocoordinate.h"
33 #include "coordinates/scenecoordinate.h"
34
35 class QGraphicsScene;
36
37 class FriendItemsHandler;
38 class GPSLocationItem;
39 class MapFetcher;
40 class MapRouteItem;
41 class MapScene;
42 class MapScroller;
43 class MapTile;
44 class OwnLocationItem;
45 class User;
46
47 /**
48  * @brief Map engine
49  *
50  * Logic for controlling map functionality. Does also include static methods for
51  * converting coordinates.
52  *
53  * NOTE: MapEngine must have a view attached before using it!
54  *
55  * @author Sami Rämö - sami.ramo (at) ixonos.com
56  * @author Jussi Laitinen - jussi.laitinen (at) ixonos.com
57  * @author Pekka Nissinen - pekka.nissinen (at) ixonos.com
58  * @author Ville Tiensuu - ville.tiensuu (at) ixonos.com
59  */
60 class MapEngine : public QObject
61 {
62     Q_OBJECT
63
64 public:
65     /**
66      * @brief Constructor
67      *
68      * @param parent Parent
69      */
70     MapEngine(QObject *parent = 0);
71
72     /**
73      * @brief Destructor
74      * Saves view of the map to settings file
75      */
76     ~MapEngine();
77
78 /*******************************************************************************
79  * MEMBER FUNCTIONS AND SLOTS
80  ******************************************************************************/
81 public:
82     /**
83      * @brief Coordinates of the current center point
84      *
85      * @return Current coordinates
86      */
87     GeoCoordinate centerGeoCoordinate();
88
89     /**
90      * @brief Convert MapScene coordinate to tile x & y numbers.
91      *
92      * @param zoomLevel ZoomLevel
93      * @param coordinate MapScene coordinate
94      * @return tile x & y numbers
95      */
96     static QPoint convertSceneCoordinateToTileNumber(int zoomLevel, SceneCoordinate coordinate);
97
98     /**
99      * @brief Set initial values for the map
100      *
101      * Set initial location and zoom level from the settings, if available, or use the default
102      * values set in the constructor. Signals locationChanged() and zoomLevelChanged() are emitted,
103      * so init should be called after those signals are connected.
104      */
105     void init();
106
107     /**
108      * @brief Return given value translated between min and max
109      *
110      * If given value is not inside the given range (min <= value <= max), then the allowed range
111      * is adder or subtracted until the value does fit in the range.
112      *
113      * @param value Value to be normalized
114      * @param min Minimum allowed value
115      * @param max Maximum allowed value
116      * @return value which is moved to be inside the given limits
117      */
118     static int normalize(int value, int min, int max);
119
120     /**
121      * @brief Getter for scene
122      *
123      * @return QGraphicsScene
124      */
125     QGraphicsScene* scene();
126
127     /**
128      * @brief Sets new zoom level
129      *
130      * @return newZoomLevel value that is set to new zoom level
131      */
132     void setZoomLevel(const int newZoomLevel);
133
134 public slots:
135     /**
136      * @brief Center smoothly to given latitude and longitude coordinates.
137      *
138      * @param coordinate Latitude & longitude coordinates for location
139      */
140     void centerToCoordinates(GeoCoordinate coordinate);
141
142     /**
143      * @brief Slot to catch user own location data
144      *
145      * @param user User info
146      */
147     void receiveOwnLocation(User *user);
148
149     /**
150      * @brief Set auto centering.
151      *
152      * @param enabled true if enabled, false otherwise
153      */
154     void setAutoCentering(bool enabled);
155
156     /**
157      * @brief Slot for enabling / disabling GPS
158      *
159      * GPS location item is disabled or enabled based on GPS state
160      *
161      * @param enabled True is GPS is enabled, otherwise false
162      */
163     void setGPSEnabled(bool enabled);
164
165     /**
166      * @brief Slot for view resizing.
167      *
168      * @param size view size
169      */
170     void viewResized(const QSize &size);
171
172 private:
173     /**
174      * @brief Calculate grid of tile coordinates from current scene coordinate.
175      *
176      * Grid size is calculated from view size and scene's current center coordinate.
177      *
178      * @param coordinate scene's current center coordinate
179      * @return QRect grid of tile coordinates
180      */
181     QRect calculateTileGrid(SceneCoordinate coordinate);
182
183     /**
184     * @brief Center and zoom to given rect
185     *
186     * Map is centered to center point of the rect and zoomed so that whole rect is visible
187     * as big as possible.
188     *
189     * @param rect Target rect
190     * @param useMargins true if margins should be added to rect, false otherwise
191     */
192     void centerAndZoomTo(QRect rect, bool useMargins = true);
193
194     /**
195     * @brief Returns the rect of the current scene area drawn on the view
196     *
197     * @returns Rect of the current scene area drawn on the view
198     */
199     QRectF currentViewSceneRect() const;
200
201     /**
202      * @brief Request disabling of auto centering if centered too far from the real location.
203      *
204      * @param coordinate scene's center coordinate
205      */
206     void disableAutoCenteringIfRequired(SceneCoordinate coordinate);
207
208     /**
209      * @brief Get new tiles.
210      *
211      * Calculates which tiles has to be fetched. Does emit fetchImage for tiles which
212      * aren't already in the scene.
213      * @param coordinate scene's center coordinate
214      */
215     void getTiles(SceneCoordinate coordinate);
216
217     /**
218      * @brief Check if auto centering is enabled
219      *
220      * @return true if enabled, false otherwise
221      */
222     bool isAutoCenteringEnabled();
223
224     /**
225      * @brief Check if center tile has changed.
226      *
227      * @param coordinate scene's center coordinate
228      * @return bool true if center tile changed, false otherwise
229      */
230     bool isCenterTileChanged(SceneCoordinate coordinate);
231
232     /**
233      * @brief Set size of tiles grid based on view size
234      *
235      * @param viewSize Current view size
236      */
237     void setTilesGridSize(const QSize &viewSize);
238
239     /**
240      * @brief Updates direction and distance values to indicator button
241      *
242      * Calculate and update direction and distance values and send those to indicator button
243      */
244     void updateDirectionIndicator();
245
246     /**
247      * @brief Updates the current view rect including margins
248      *
249      * Calculates tiles rect in scene based on m_viewTilesGrid and
250      * calls MapScene::viewRectUpdated()
251      */
252     void updateViewTilesSceneRect();
253
254     /**
255      * @brief Calculate scale at the map center of the map in meters/pixel
256      *
257      * @return qreal Scale of the map in meters/pixel
258      */
259     qreal viewResolution();
260
261     /**
262      * @brief This method is ran always when the map is zoomed
263      *
264      * This method is the right place for all actions which must be done when ever map is zoomed.
265      */
266     void zoomed();
267
268 private slots:
269     /**
270     * @brief Slot for clearing the current route
271     */
272     void clearRoute();
273
274     /**
275      * @brief This slot is called after friend items position have been updated
276      *
277      * Does run MapScene::spanItems()
278      */
279     void friendsPositionsUpdated();
280
281     /**
282      * @brief Slot for GPS position updates
283      *
284      * GPS location item is updated and map centered to new location (if automatic
285      * centering is enabled).
286      *
287      * @param position New coordinates from GPS
288      * @param accuracy Accuracy of the GPS fix
289      */
290     void gpsPositionUpdate(GeoCoordinate position, qreal accuracy);
291
292     /**
293      * @brief Slot for received map tile images
294      *
295      * Does receive map tile images from MapFetcher. Calls MapScene::addTile() for creating and adding
296      * the actual MapTile object to the MapScene.
297      *
298      * Tile is added also to outside the world horizontal limits, if required, for spanning the map.
299      *
300      * @param zoomLevel Zoom level
301      * @param x Tile x index
302      * @param y Tile y index
303      * @param image Received pixmap
304      */
305     void mapImageReceived(int zoomLevel, int x, int y, const QPixmap &image);
306
307     /**
308      * @brief Called when MapScroller state is changed
309      *
310      * Does check if the smooth scroll effect was interrupted and should the auto centering
311      * feature to be disabled.
312      *
313      * @param newState New state
314      */
315     void scrollerStateChanged(QAbstractAnimation::State newState);
316
317     /**
318      * @brief Scroll smoothly to given scene position
319      *
320      * @param coordinate Target position in the scene
321      */
322     void scrollToPosition(SceneCoordinate coordinate);
323
324     /**
325      * @brief Set center point in the scene
326      *
327      * Does emit locationChanged signal.
328      * @param coordinate Scene coordinates for new position
329      */
330     void setCenterPosition(SceneCoordinate coordinate);
331
332     /**
333      * @brief Builds and sets route, also centers it
334      *
335      * @param route Route route information
336      */
337     void setRoute(Route &route);
338
339     /**
340     * @brief Shows map area defined by bounds.
341     *
342     * Calls centerAndZoomTo() with area defined by bounds.
343     * @param swBound south-west bound of location item
344     * @param neBound north-east bound of location item
345     */
346     void showMapArea(const GeoCoordinate &swBound, const GeoCoordinate &neBound);
347
348     /**
349      * @brief Slot for actions after view zoom is finished
350      *
351      * Does run removeOutOfViewTiles
352      */
353     void viewZoomFinished();
354
355     /**
356      * @brief Slot for zooming in
357      */
358     void zoomIn();
359
360     /**
361      * @brief Slot for zooming out
362      */
363     void zoomOut();
364
365 /*******************************************************************************
366  * SIGNALS
367  ******************************************************************************/
368 signals:
369     /**
370     * @brief Signal when direction and distance from current map center point to current GPS
371     *        location is changed
372     *
373     * @param direction Direction in degrees
374     * @param distance Distance in meters
375     * @param draw Should the indicator triangle be drawn or not
376     */
377     void directionIndicatorValuesUpdate(qreal direction, qreal distance, bool draw);
378
379     /**
380     * @brief Signals error
381     *
382     * @param context error context
383     * @param error error code
384     */
385     void error(const int context, const int error);
386
387     /**
388      * @brief Signal for image fetching.
389      *
390      * @param zoomLevel Zoom level
391      * @param x Tile x index
392      * @param y Tile y index
393      */
394     void fetchImage(int zoomLevel, int x, int y);
395
396     /**
397     * @brief Signal when friend image is ready
398     *
399     * @param user Friend
400     */
401     void friendImageReady(User *user);
402
403     /**
404      * @brief Signal when friend list locations are fetched
405      *
406      * @param friendsList Friends list data
407      */
408     void friendsLocationsReady(QList<User *> &friendsList);
409
410     /**
411      * @brief Request view centering to new locaiton
412      *
413      * @param coordinate New scene coordinates
414      */
415     void locationChanged(SceneCoordinate coordinate);
416
417     /**
418      * @brief Signal is emitted when location item is clicked.
419      *
420      * @param userIDs list of friends user IDs in the group
421      */
422     void locationItemClicked(const QList<QString> &userIDs);
423
424     /**
425      * @brief Signal to notify map scrolling.
426      */
427     void mapScrolledManually();
428
429     /**
430      * @brief Signal to notify when map is zoomed in to the maxmimum.
431      */
432     void maxZoomLevelReached();
433
434     /**
435      * @brief Signal to notify when map is zoomed out to the minimum.
436      */
437     void minZoomLevelReached();
438
439     /**
440      * @brief Signal to pass the scale of the map to map scale
441      */
442     void newMapResolution(qreal scale);
443
444     /**
445      * @brief Request view changing zoom level
446      *
447      * @param newZoomLevel New zoom level
448      */
449     void zoomLevelChanged(int newZoomLevel);
450
451 /*******************************************************************************
452  * DATA MEMBERS
453  ******************************************************************************/
454 private:
455     bool m_autoCenteringEnabled;    ///< Auto centering enabled
456     bool m_scrollStartedByGps;      ///< Smooth scroll is started by GPS?
457     bool m_smoothScrollRunning;     ///< Smooth scroll is running?
458     bool m_zoomedIn;                ///< Flag for checking if zoomed in when zoom is finished
459
460     int m_zoomLevel;                ///< Current zoom level
461
462     QPoint m_centerTile;            ///< Current center tile
463     SceneCoordinate m_lastAutomaticPosition; ///< Last automatically set position in scene coordinate
464     SceneCoordinate m_sceneCoordinate;       ///< Current center coordinate
465
466     QRect m_viewTilesGrid;          ///< Current grid of tiles in view (includes margin)
467
468     QSize m_tilesGridSize;          ///< Current size of the tiles grid
469     QSize m_viewSize;               ///< Current view size
470
471     FriendItemsHandler *m_friendItemsHandler;   ///< Handler for friend and group items
472     GeoCoordinate m_gpsPosition;                ///< Latest GPS position
473     GPSLocationItem *m_gpsLocationItem;         ///< Item pointing current location from GPS
474     MapFetcher *m_mapFetcher;                   ///< Fetcher for map tiles
475     MapRouteItem *m_mapRouteItem;               ///< Map route item
476     MapScene *m_mapScene;                       ///< Scene for map tiles
477     MapScroller *m_scroller;                    ///< Kinetic scroller
478     OwnLocationItem *m_ownLocation;             ///< Item to show own location
479 };
480
481 #endif // MAPENGINE_H