3 #include <QGeoMapPixmapObject>
4 #include <QGeoMapPolylineObject>
5 #include "../user/friendmodel.h"
6 #include "../coordinates/geocoordinate.h"
7 #include "../routing/routemodel.h"
8 #include <QGraphicsSceneMouseEvent>
9 #include "../ui/avatarimage.h"
11 using namespace QtMobility;
20 gpsLocationMapObject(0),
25 * Filter geometry points.
28 void filterCoordinatePoints(QList<QGeoCoordinate>* geometryPoints)
30 // Rough guess for maximum point count for smooth use
31 // Produces max 500+n items to result array (rounding error in division)...
32 static const int MAX_POINT_COUNT = 500;
34 if (geometryPoints->count() > MAX_POINT_COUNT) {
35 const int skip = geometryPoints->count() / MAX_POINT_COUNT;
37 QList<QGeoCoordinate> filtered;
38 for (int i = 0; i < geometryPoints->count(); i += skip)
39 filtered << geometryPoints->at(i);
40 filtered << geometryPoints->last();
41 *geometryPoints = filtered;
45 FriendModel* friendModel;
46 FilteredFriendModel* friendFilterModel;
48 RouteModel* routeModel;
50 QGeoMapPixmapObject* gpsLocationMapObject;
51 QGeoMapPolylineObject* routeMapObject;
53 QList<QGeoMapPixmapObject*> friendMapObjects;
56 GeoMap::GeoMap(QGraphicsItem* parent)
57 : QGraphicsGeoMap(parent),
58 d_ptr(new GeoMapPrivate),
63 qDebug() << __PRETTY_FUNCTION__;
64 connect(this, SIGNAL(panned(QPoint)), this, SLOT(panned()));
66 setCenter(prevGpsLocation);
70 setObjectName("geoMap");
75 qDebug() << __PRETTY_FUNCTION__;
78 qreal GeoMap::angleToGpsLocation() const
80 const qreal result = prevGpsLocation.isValid() ? center().azimuthTo(prevGpsLocation) : 0.0;
81 qDebug() << "QmlMap::angleToGpsLocation: " << result;
85 qreal GeoMap::distanceToGpsLocation() const
87 const qreal result = prevGpsLocation.isValid() ? center().distanceTo(prevGpsLocation) : 0.0;
88 qDebug() << "QmlMap::distanceToGpsLocation: " << result << " meters";
92 QString GeoMap::distanceToGpsLocationText() const
94 const qreal distance = distanceToGpsLocation();
95 // copy/paste from: IndicatorButtonPanel::updateValues
96 const int MAX_TO_METERS = 999.5;
97 const int MAX_TO_KM_WITH_DESIMAL = 99950;
98 const int MIN_TO_METERS = 10;
99 const int M_TO_KM = 1000; ///< Meters to kilometers conversion
100 const QString UNIT_KILOMETER = " km";
101 const QString UNIT_METER = " m";
103 QString distanceText;
104 if (distance < MIN_TO_METERS) {
105 distanceText.setNum(10);
106 distanceText.prepend("< ");
107 distanceText.append(UNIT_METER);
108 } else if (distance < MAX_TO_METERS) {
109 distanceText.setNum(distance, 'f', 0);
110 distanceText.append(UNIT_METER);
111 } else if (distance < MAX_TO_KM_WITH_DESIMAL) {
112 distanceText.setNum(distance / M_TO_KM, 'f', 1);
113 distanceText.append(UNIT_KILOMETER);
115 distanceText.setNum(distance / M_TO_KM, 'f', 0);
116 distanceText.append(UNIT_KILOMETER);
121 double GeoMap::centerLatitude() const {
122 return center().latitude();
125 void GeoMap::setCenterLatitude(const double latitude) {
126 QGeoCoordinate newCenter = center();
127 newCenter.setLatitude(latitude);
128 setCenter(newCenter);
129 emit positionChanged();
132 double GeoMap::centerLongitude() const
134 return center().longitude();
137 void GeoMap::setCenterLongitude(const double longitude) {
138 QGeoCoordinate newCenter = center();
139 newCenter.setLongitude(longitude);
140 setCenter(newCenter);
141 emit positionChanged();
145 double GeoMap::gpsLocationLatitude() const
147 return prevGpsLocation.latitude();
150 double GeoMap::gpsLocationLongitude() const
152 return prevGpsLocation.longitude();
155 void GeoMap::setFriendModels(FriendModel* friendModel, FilteredFriendModel* friendFilterModel)
158 Q_ASSERT(friendModel && friendFilterModel);
159 if (friendModel && friendFilterModel) {
160 d->friendModel = friendModel;
161 d->friendFilterModel = friendFilterModel;
162 connect(d->friendModel, SIGNAL(modelReset()), this, SLOT(onFriendModelReset()));
166 void GeoMap::setRouteModel(RouteModel* routeModel)
169 Q_ASSERT(routeModel);
170 d->routeModel = routeModel;
171 connect(d->routeModel, SIGNAL(modelReset()), this, SLOT(onRouteModelReset()));
174 void GeoMap::panned()
176 emit positionChanged();
179 void GeoMap::onFriendModelReset()
182 Q_ASSERT(d->friendModel);
184 foreach(QGeoMapPixmapObject* mapObject, d->friendMapObjects) {
185 removeMapObject(mapObject);
188 d->friendMapObjects.clear();
190 for (int i=0; i < d->friendModel->rowCount(); ++i) {
191 const QModelIndex index = d->friendModel->index(i);
192 QPixmap pixmap = d->friendModel->data(index, FriendModel::ImageRole).value<QPixmap>();
193 GeoCoordinate coordinate = d->friendModel->data(index, FriendModel::CoordinateRole).value<GeoCoordinate>();
196 pixmap = QPixmap(":/res/images/user_info.png");
198 Q_ASSERT(!pixmap.isNull());
200 pixmap = AvatarImage::create(pixmap, AvatarImage::Small);
202 if (!pixmap.isNull() && coordinate.isValid()) {
203 QPoint offset(-pixmap.width()/2, -pixmap.height()/2);
204 QGeoMapPixmapObject* object = new QGeoMapPixmapObject(QGeoCoordinate(coordinate.latitude(), coordinate.longitude()),
208 object->setProperty("user", d->friendModel->data(index, FriendModel::UserRole));
209 addMapObject(object);
210 d->friendMapObjects << object;
215 void GeoMap::onRouteModelReset()
217 qDebug() << __PRETTY_FUNCTION__;
219 Q_ASSERT(d->routeModel);
221 const QList<GeoCoordinate>& geometryPoints = d->routeModel->geometryPoints();
223 QList<QGeoCoordinate> path;
224 foreach(GeoCoordinate c, geometryPoints)
225 path << QGeoCoordinate(c.latitude(), c.longitude());
227 if (!d->routeMapObject) {
228 d->routeMapObject = new QGeoMapPolylineObject();
231 removeMapObject(d->routeMapObject);
233 if (!path.isEmpty()) {
234 qDebug() << "PATH BEFORE: " << path.count();
235 d->filterCoordinatePoints(&path);
236 qDebug() << "PATH AFTER: " << path.count();
238 d->routeMapObject->setPath(path);
241 d->routeMapObject->setPen(pen);
242 addMapObject(d->routeMapObject);
246 void GeoMap::goToGpsLocation()
248 qDebug() << "QmlMap::goToGpsLocation";
250 source = QGeoPositionInfoSource::createDefaultSource(this);
253 source->requestUpdate();
254 connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo)));
255 source->setUpdateInterval(10000);
256 source->startUpdates();
260 void GeoMap::onClicked(qreal mouseX, qreal mouseY)
263 QList<QGeoMapObject*> mapObjects = mapObjectsAtScreenPosition(QPointF(mouseX, mouseY));
265 foreach(QGeoMapObject* mapObject, mapObjects) {
266 User* user = static_cast<User*>(mapObject->property("user").value<void*>());
270 // TODO: reset filter only if it contains at least one entry
271 //if (!filter.isEmpty())
272 d->friendFilterModel->setFilter(filter);
275 void GeoMap::zoomIn()
277 setZoomLevel(zoomLevel() + 1.0);
280 void GeoMap::zoomOut()
282 if (zoomLevel() > 1.0)
283 setZoomLevel(zoomLevel() - 1.0);
287 void GeoMap::positionUpdated(const QGeoPositionInfo& positionInfo)
289 qDebug() << "QmlMap::positionUpdated: " << positionInfo.coordinate();
290 prevGpsLocation = positionInfo.coordinate();
293 if (!d->gpsLocationMapObject) {
294 QPixmap image(":/res/gps_position.png");
295 Q_ASSERT(!image.isNull());
296 d->gpsLocationMapObject = new QGeoMapPixmapObject(prevGpsLocation, QPoint(-image.width()/2, -image.height()/2), image);
297 addMapObject(d->gpsLocationMapObject);
298 setCenter(prevGpsLocation);
299 emit positionChanged();
302 d->gpsLocationMapObject->setCoordinate(prevGpsLocation);
304 emit gpsLocationChanged();