Friend filtering redone
[situare] / src / qmlui / geomap.cpp
1 #include "geomap.h"
2 #include <QDebug>
3 #include <QGeoMapPixmapObject>
4 #include "../user/friendmodel.h"
5 #include "../coordinates/geocoordinate.h"
6 #include <QGraphicsSceneMouseEvent>
7
8 using namespace QtMobility;
9
10 class GeoMapPrivate
11 {
12 public:
13     GeoMapPrivate()
14         : friendModel(0),
15           friendFilterModel(0),
16           gpsLocationMapObject(0)
17     {}
18
19     FriendModel* friendModel;
20     FilteredFriendModel* friendFilterModel;
21
22     QGeoMapPixmapObject* gpsLocationMapObject;
23
24     QList<QGeoMapPixmapObject*> friendMapObjects;
25 };
26
27 GeoMap::GeoMap(QGraphicsItem* parent)
28     : QGraphicsGeoMap(parent),
29       d_ptr(new GeoMapPrivate),
30       source(0),
31       prevGpsLocation(0,0),
32       initialized(false)
33 {
34     qDebug() << __PRETTY_FUNCTION__;
35     connect(this, SIGNAL(panned(QPoint)), this, SLOT(panned()));
36
37     setCenter(prevGpsLocation);
38
39     goToGpsLocation();
40
41     setObjectName("geoMap");
42 }
43
44 GeoMap::~GeoMap()
45 {
46     qDebug() << __PRETTY_FUNCTION__;
47 }
48
49 qreal GeoMap::angleToGpsLocation() const
50 {
51     const qreal result = prevGpsLocation.isValid() ? center().azimuthTo(prevGpsLocation) : 0.0;
52     qDebug() << "QmlMap::angleToGpsLocation: " << result;
53     return result;
54 }
55
56 qreal GeoMap::distanceToGpsLocation() const
57 {
58     const qreal result = prevGpsLocation.isValid() ? center().distanceTo(prevGpsLocation) : 0.0;
59     const int km = result * 0.001;
60     qDebug() << "QmlMap::distanceToGpsLocation: " << km;
61     return km;
62 }
63
64 double GeoMap::centerLatitude() const {
65     return center().latitude();
66 }
67
68 void GeoMap::setCenterLatitude(const double latitude) {
69     QGeoCoordinate newCenter = center();
70     newCenter.setLatitude(latitude);
71     setCenter(newCenter);
72     emit positionChanged();
73 }
74
75 double GeoMap::centerLongitude() const
76 {
77     return center().longitude();
78 }
79
80 void GeoMap::setCenterLongitude(const double longitude) {
81     QGeoCoordinate newCenter = center();
82     newCenter.setLongitude(longitude);
83     setCenter(newCenter);
84     emit positionChanged();
85
86 }
87
88 double GeoMap::gpsLocationLatitude() const
89 {
90     return prevGpsLocation.latitude();
91 }
92
93 double GeoMap::gpsLocationLongitude() const
94 {
95     return prevGpsLocation.longitude();
96 }
97
98 void GeoMap::setFriendModels(FriendModel* friendModel, FilteredFriendModel* friendFilterModel)
99 {
100     Q_D(GeoMap);
101     Q_ASSERT(friendModel && friendFilterModel);
102     if (friendModel && friendFilterModel) {
103         d->friendModel = friendModel;
104         d->friendFilterModel = friendFilterModel;
105         connect(d->friendModel, SIGNAL(modelReset()), this, SLOT(onFriendModelReset()));
106     }
107 }
108
109 void GeoMap::panned()
110 {
111     emit positionChanged();
112 }
113
114 void GeoMap::onFriendModelReset()
115 {
116     Q_D(GeoMap);
117     Q_ASSERT(d->friendModel);
118
119     foreach(QGeoMapPixmapObject* mapObject, d->friendMapObjects)
120         removeMapObject(mapObject);
121
122     for (int i=0; i < d->friendModel->rowCount(); ++i) {
123         const QModelIndex index = d->friendModel->index(i);
124         QPixmap pixmap = d->friendModel->data(index, FriendModel::ImageRole).value<QPixmap>();
125         GeoCoordinate coordinate = d->friendModel->data(index, FriendModel::CoordinateRole).value<GeoCoordinate>();
126
127         if (pixmap.isNull())
128             pixmap = QPixmap(":/res/images/user_info.png");
129
130         Q_ASSERT(!pixmap.isNull());
131
132         if (!pixmap.isNull() && coordinate.isValid()) {
133             QPoint offset(-pixmap.width()/2, -pixmap.height()/2);
134             QGeoMapPixmapObject* object = new QGeoMapPixmapObject(QGeoCoordinate(coordinate.latitude(), coordinate.longitude()),
135                                                                   offset,
136                                                                   pixmap,
137                                                                   0);
138             object->setProperty("user", d->friendModel->data(index, FriendModel::UserRole));
139             addMapObject(object);
140             d->friendMapObjects << object;
141         }
142     }
143 }
144
145 void GeoMap::goToGpsLocation()
146 {
147     qDebug() << "QmlMap::goToGpsLocation";
148     if (!source)
149         source = QGeoPositionInfoSource::createDefaultSource(this);
150
151     if (source) {
152         source->requestUpdate();
153         connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo)));
154         source->setUpdateInterval(10000);
155         source->startUpdates();
156     }
157 }
158
159 void GeoMap::onClicked(qreal mouseX, qreal mouseY)
160 {
161     Q_D(GeoMap);
162     QList<QGeoMapObject*> mapObjects = mapObjectsAtScreenPosition(QPointF(mouseX, mouseY));
163     QList<User*> filter;
164     foreach(QGeoMapObject* mapObject, mapObjects) {
165         User* user = static_cast<User*>(mapObject->property("user").value<void*>());
166         Q_ASSERT(user);
167         filter << user;
168     }
169     // TODO: reset filter only if it contains at least one entry
170     //if (!filter.isEmpty())
171         d->friendFilterModel->setFilter(filter);
172 }
173
174 void GeoMap::positionUpdated(const QGeoPositionInfo& positionInfo)
175 {
176     qDebug() << "QmlMap::positionUpdated: " << positionInfo.coordinate();
177     prevGpsLocation = positionInfo.coordinate();
178     Q_D(GeoMap);
179
180     if (!d->gpsLocationMapObject) {
181         QPixmap image(":/res/gps_position.png");
182         Q_ASSERT(!image.isNull());
183         d->gpsLocationMapObject = new QGeoMapPixmapObject(prevGpsLocation, QPoint(-image.width()/2, -image.height()/2), image);
184         addMapObject(d->gpsLocationMapObject);
185         setCenter(prevGpsLocation);
186         emit positionChanged();
187     }
188     else {
189         d->gpsLocationMapObject->setCoordinate(prevGpsLocation);
190     }
191     emit gpsLocationChanged();
192 }