Modified MapEngine's setLocation and imageReceived methods.
[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 "common.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 */
40 class MapEngine : public QObject
41 {
42     Q_OBJECT
43 public:
44     /**
45     * @brief Constructor
46     *
47     * @param parent Parent
48     */
49     MapEngine(QObject *parent = 0);
50     
51     /**
52     * @brief Convert tile x & y numbers to MapScene coordinates
53     *
54     * @param zoomLevel Zoom level
55     * @param tileNumber x & y numbers of the tile
56     * @return QPoint MapScene coordinate
57     */
58
59     static QPoint convertTileNumberToSceneCoordinate(int zoomLevel, QPoint tileNumber)
60     {
61         int pow = 1 << (MAX_ZOOM_LEVEL - zoomLevel);
62         int x = tileNumber.x() * TILE_SIZE_X * pow;
63         int y = tileNumber.y() * TILE_SIZE_Y * pow;
64
65         return QPoint(x, y);
66     }
67
68     static QPoint convertSceneCoordinateToTileNumber(int zoomLevel, QPointF sceneCoordinate)
69     {
70         int pow = 1 << (MAX_ZOOM_LEVEL - zoomLevel);
71         int x = static_cast<int>(sceneCoordinate.x()) / (TILE_SIZE_X*pow);
72         int y = static_cast<int>(sceneCoordinate.y()) / (TILE_SIZE_Y*pow);
73
74         return QPoint(x, y);
75     }
76
77     /**
78     * @brief Getter for scene
79     *
80     * @return QGraphicsScene
81     */
82     QGraphicsScene* scene();
83
84     /**
85     * @brief Set view location
86     *
87     * @param latLonCoordinate Latitude & longitude coordinates for location
88     */
89     void setViewLocation(QPointF latLonCoordinate);
90
91     /**
92     * @brief Converts latitude, longitude and zoom to tile x, y values.
93     *
94     * @param zoomLevel zoom level
95     * @param latLonCoordinate latitude and longitude values
96     * @return QPoint tile x,y value
97     */
98     static QPoint convertLatLonToTile(int zoomLevel, QPointF latLonCoordinate)
99     {
100         qDebug() << __PRETTY_FUNCTION__;
101
102         qreal longitude = latLonCoordinate.x();
103         qreal latitude = latLonCoordinate.y();
104
105         if ((zoomLevel > MAX_ZOOM_LEVEL) || (zoomLevel < MIN_ZOOM_LEVEL))
106             return QPoint(UNDEFINED, UNDEFINED);
107         if ((longitude > MAX_LONGITUDE) || (longitude < MIN_LONGITUDE))
108             return QPoint(UNDEFINED, UNDEFINED);
109         if ((latitude > MAX_LATITUDE) || (latitude < MIN_LATITUDE))
110             return QPoint(UNDEFINED, UNDEFINED);
111
112         qreal z = static_cast<qreal>(1 << zoomLevel);
113
114         qreal x = static_cast<qreal>((longitude + 180.0) / 360.0);
115         qreal y = static_cast<qreal>((1.0 - log(tan(latitude * M_PI / 180.0) + 1.0
116                                     / cos(latitude * M_PI / 180.0)) / M_PI) / 2.0);
117
118         return QPoint(qFloor(x*z), qFloor(y*z));
119     }
120
121     QRect calculateGrid(QPointF sceneCenterCoordinate);
122
123 public slots:
124     void setLocation(QPointF sceneCenterCoordinate);
125
126 private:
127     /**
128     * @brief Build URL for donwloading single map tile from OpenStreetMap tile server
129     *
130     * @param zoomLevel Zoom level
131     * @param tileNumbers Tile x & y numbers
132     * @return URL for the required tile
133     */
134     QUrl buildURL(int zoomLevel, QPoint tileNumbers);
135
136     /**
137     * @brief Parses given URL to zoom, x and y values. Parsed values are
138     * placed in variables given as parameters.
139     *
140     * @param url url to parse
141     * @param [out] zoom zoom variable
142     * @param [out] x x variable
143     * @param [out] y y variable
144     */
145     void parseURL(const QUrl &url, int &zoom, int &x, int &y);
146
147     int tileMaxValue(int zoomLevel);
148
149
150 private slots:
151     /**
152     * @brief Slot for received map tile images
153     *
154     * Does add MapTile objects to MapScene. Zoom level and location is parsed from URL.
155     * @param url URL of the received image
156     * @param pixmap Received pixmap
157     */
158     void mapImageReceived(const QUrl &url, const QPixmap &pixmap);
159
160 signals:
161     /**
162     * @brief Signal for zoom level change
163     *
164     * @param newZoomLevel New zoom level
165     */
166     void zoomLevelChanged(int newZoomLevel);
167
168     void fetchImage(const QUrl &url);
169
170     void centerToSceneCoordinates(QPointF sceneCoordinate);
171
172 private:
173     MapScene *m_mapScene; ///< Scene for map tiles
174     MapFetcher *m_mapFetcher; ///< Fetcher for map tiles
175     int m_zoomLevel; ///< Current zoom level
176     QHash<QString, MapTile *> mapTilesInScene;  ///< List of map tiles in map scene
177 };
178
179 #endif // MAPENGINE_H