9bb207b80d3ed068ebd214a26cae2ccb74884275
[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
10    Situare is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License
12    version 2 as published by the Free Software Foundation.
13
14    Situare is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with Situare; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
22    USA.
23 */
24
25 #ifndef MAPENGINE_H
26 #define MAPENGINE_H
27
28 #include <QtCore>
29
30 class QGraphicsScene;
31
32 class FriendItemsHandler;
33 class GPSLocationItem;
34 class MapFetcher;
35 class MapScene;
36 class MapTile;
37 class OwnLocationItem;
38 class User;
39
40 /**
41 * @brief Map engine
42 *
43 * Logic for controlling map functionality. Does also include static methods for
44 * converting coordinates.
45 *
46 * @author Sami Rämö - sami.ramo (at) ixonos.com
47 * @author Jussi Laitinen - jussi.laitinen (at) ixonos.com
48 * @author Pekka Nissinen - pekka.nissinen (at) ixonos.com
49 * @author Ville Tiensuu - ville.tiensuu (at) ixonos.com
50 */
51 class MapEngine : public QObject
52 {
53     Q_OBJECT
54
55 public:
56     /**
57     * @brief Constructor
58     *
59     * @param parent Parent
60     */
61     MapEngine(QObject *parent = 0);
62
63     /**
64     * @brief Destructor
65     * Saves view of the map to settings file
66     */
67     ~MapEngine();
68
69 /*******************************************************************************
70  * MEMBER FUNCTIONS AND SLOTS
71  ******************************************************************************/
72 public:
73     /**
74       * @brief Coordinates  of the current center point
75       *
76       * @return Current coordinates (latitude & longitude)
77       */
78     QPointF centerGeoCoordinate();
79
80     /**
81     * @brief Convert latitude and longitude to scene coordinates.
82     *
83     * @param latLonCoordinate latitude and longitude values
84     * @return scene coordinate
85     */
86     static QPoint convertLatLonToSceneCoordinate(QPointF latLonCoordinate);
87
88     /**
89     * @brief converts scene coordinates to latitude and longitude
90     *
91     * @param zoomLevel current zoom level
92     * @param sceneCoordinate that will be converted
93     */
94     QPointF convertSceneCoordinateToLatLon(int zoomLevel, QPoint sceneCoordinate);
95
96     /**
97     * @brief Convert MapScene coordinate to tile x & y numbers.
98     *
99     * @param zoomLevel ZoomLevel
100     * @param sceneCoordinate MapScene coordinate
101     * @return QPoint tile x & y numbers
102     */
103     static QPoint convertSceneCoordinateToTileNumber(int zoomLevel, QPoint sceneCoordinate);
104
105     /**
106     * @brief Convert tile x & y numbers to MapScene coordinates
107     *
108     * @param zoomLevel Zoom level
109     * @param tileNumber x & y numbers of the tile
110     * @return QPoint MapScene coordinate
111     */
112     static QPoint convertTileNumberToSceneCoordinate(int zoomLevel, QPoint tileNumber);
113
114     /**
115      * @brief Calculate great-circle distance between two geographic coordinates
116      *
117      * Calculate great-circle distance between two given geographic locations using
118      * haversine formula
119      *
120      * @param firstLocation Coordinates of the first location
121      * @param secondLocation Coordinates of the second location
122      * @return qreal Distance in kilometers
123      */
124     qreal greatCircleDistance(QPointF firstLocation, QPointF secondLocation);
125
126     /**
127     * @brief MapEngine initializer
128     *
129     * Set initial location and zoom level for the engine. locationChanged and
130     * zoomLevelChanged signals are emitted, so init should be called after
131     * those signals are connected to MapView.
132     */
133     void init();
134
135     /**
136     * @brief Getter for scene
137     *
138     * @return QGraphicsScene
139     */
140     QGraphicsScene* scene();
141
142     /**
143     * @brief Sets new zoom level
144     *
145     * @return newZoomLevel value that is set to new zoom level
146     */
147     void setZoomLevel(const int newZoomLevel);
148
149     /**
150     * @brief Return tile path created from tile values.
151     *
152     * @param zoomLevel tile's zoom level
153     * @param x tile's x value
154     * @param y tile's y value
155     * @return QString tile path
156     */
157     static QString tilePath(int zoomLevel, int x, int y);
158
159 public slots:
160
161     /**
162     * @brief Slot to catch user own location data
163     *
164     * @param user User info
165     */
166     void receiveOwnLocation(User *user);
167
168     /**
169     * @brief Set auto centering.
170     *
171     * @param enabled true if enabled, false otherwise
172     */
173     void setAutoCentering(bool enabled);
174
175     /**
176       * @brief Slot for enabling / disabling GPS
177       *
178       * GPS location item is disabled or enabled based on GPS state
179       *
180       * @param enabled True is GPS is enabled, otherwise false
181       */
182     void setGPSEnabled(bool enabled);
183
184     /**
185     * @brief Slot for setting current view location
186     *
187     * Emits locationChanged signal.
188     * @param sceneCoordinate Scene coordinates for new position
189     */
190     void setLocation(QPoint sceneCoordinate);
191
192     /**
193     * @brief Helper for setting view location based on latitude and longitude
194     * coordinates
195     *
196     * @param latLonCoordinate Latitude & longitude coordinates for location
197     */
198     void setViewLocation(QPointF latLonCoordinate);    
199
200     /**
201     * @brief Slot for view resizing.
202     *
203     * @param size view size
204     */
205     void viewResized(const QSize &size);
206
207 private:
208     /**
209     * @brief Calculate grid of tile coordinates from current scene coordinate.
210     *
211     * Grid size is calculated from view size and scene's current center coordinate.
212     *
213     * @param sceneCoordinate scene's current center coordinate
214     * @return QRect grid of tile coordinates
215     */
216     QRect calculateTileGrid(QPoint sceneCoordinate);
217
218     /**
219     * @brief Check if auto centering should be disabled.
220     *
221     * @param sceneCoordinate scene's center coordinate
222     * @return bool true if auto centering should be disabled
223     */
224     bool disableAutoCentering(QPoint sceneCoordinate);
225
226     /**
227     * @brief Get new tiles.
228     *
229     * Calculates which tiles has to be fetched. Does emit fetchImage for tiles which
230     * aren't already in the scene.
231     * @param sceneCoordinate scene's center coordinate
232     */
233     void getTiles(QPoint sceneCoordinate);
234
235     /**
236     * @brief Check if auto centering is enabled
237     *
238     * @return true if enabled, false otherwise
239     */
240     bool isAutoCenteringEnabled();
241
242     /**
243     * @brief Check if center tile has changed.
244     *
245     * @param sceneCoordinate scene's center coordinate
246     * @return bool true if center tile changed, false otherwise
247     */
248     bool isCenterTileChanged(QPoint sceneCoordinate);
249
250     /**
251      * @brief Calculate scale at the map center of the map in meters/pixel
252      *
253      * @return qreal Scale of the map in meters/pixel
254      */
255     qreal sceneResolution();
256
257     /**
258     * @brief Calculate maximum value for tile in this zoom level.
259     *
260     * @param zoomLevel zoom level
261     * @return int tile's maximum value
262     */
263     int tileMaxValue(int zoomLevel);
264
265     /**
266     * @brief Updates the current view rect including margins
267     *
268     * Calculates tiles rect in scene based on m_viewTilesGrid and
269     * calls MapScene::viewRectUpdated()
270     */
271     void updateViewTilesSceneRect();
272
273 private slots:
274     /**
275       * @brief Slot for GPS position updates
276       *
277       * GPS location item is updated and map centered to new location (if automatic
278       * centering is enabled).
279       *
280       * @param position New coordinates from GPS
281       * @param accuracy Accuracy of the GPS fix
282       */
283     void gpsPositionUpdate(QPointF position, qreal accuracy);
284
285     /**
286     * @brief Slot for received map tile images
287     *
288     * Does add MapTile objects to MapScene.
289     * @param zoomLevel Zoom level
290     * @param x Tile x index
291     * @param y Tile y index
292     * @param image Received pixmap
293     */
294     void mapImageReceived(int zoomLevel, int x, int y, const QPixmap &image);    
295
296     /**
297     * @brief Slot for actions after view zoom is finished
298     *
299     * Does run removeOutOfViewTiles
300     */
301     void viewZoomFinished();
302
303     /**
304     * @brief Slot for zooming in
305     */
306     void zoomIn();
307
308     /**
309     * @brief Slot for zooming out
310     */
311     void zoomOut();
312
313 /*******************************************************************************
314  * SIGNALS
315  ******************************************************************************/
316 signals:
317     /**
318     * @brief Signals error
319     *
320     * @param error error code
321     */
322     void error(const int error);
323
324     /**
325     * @brief Signal for image fetching.
326     *
327     * @param zoomLevel Zoom level
328     * @param x Tile x index
329     * @param y Tile y index
330     */
331     void fetchImage(int zoomLevel, int x, int y);
332
333     /**
334     * @brief Signal when friend list locations are fetched
335     *
336     * @param friendsList Friends list data
337     */
338     void friendsLocationsReady(QList<User *> &friendsList);
339
340     /**
341     * @brief Request view centering to new locaiton
342     *
343     * @param sceneCoordinate New scene coordinates
344     */
345     void locationChanged(QPoint sceneCoordinate);
346
347     /**
348     * @brief Signal is emitted when location item is clicked.
349     *
350     * @param userIDs list of friends user IDs in the group
351     */
352     void locationItemClicked(const QList<QString> &userIDs);
353
354     /**
355     * @brief Signal to notify map scrolling.
356     */
357     void mapScrolledManually();
358
359     /**
360     * @brief Signal to notify when map is zoomed in to the maxmimum.
361     */
362     void maxZoomLevelReached();
363
364     /**
365     * @brief Signal to notify when map is zoomed out to the minimum.
366     */
367     void minZoomLevelReached();
368
369     /**
370      * @brief Signal to pass the scale of the map to map scale
371      */
372     void newMapResolution(qreal scale);
373
374     /**
375     * @brief Request view changing zoom level
376     *
377     * @param newZoomLevel New zoom level
378     */
379     void zoomLevelChanged(int newZoomLevel);
380
381 /*******************************************************************************
382  * DATA MEMBERS
383  ******************************************************************************/
384 private:
385     bool m_autoCenteringEnabled;   ///< Auto centering enabled
386     bool m_zoomedIn;               ///< Flag for checking if zoomed in when zoom is finished
387
388     int m_zoomLevel;               ///< Current zoom level
389
390     QPoint m_centerTile;           ///< Current center tile
391     QPoint m_lastManualPosition;   ///< Last manually set position in scene coordinate
392     QPoint m_sceneCoordinate;      ///< Current center coordinate
393
394     QRect m_viewTilesGrid;         ///< Current grid of tiles in view (includes margin)
395
396     QSize m_viewSize;              ///< Current view size
397
398     FriendItemsHandler *m_friendItemsHandler;   ///< Handler for friend and group items
399     GPSLocationItem *m_gpsLocationItem;         ///< Item pointing current location from GPS
400     MapFetcher *m_mapFetcher;                   ///< Fetcher for map tiles
401     MapScene *m_mapScene;                       ///< Scene for map tiles
402     OwnLocationItem *m_ownLocation;             ///< Item to show own location
403 };
404
405 #endif // MAPENGINE_H