df0914098ee8e3341a785af10e11314319d00b4e
[harmattan/cameraplus] / src / geocode.cpp
1 #include "geocode.h"
2 #include <QDebug>
3 #include <QStringList>
4
5 Geocode::Geocode(QObject *parent) :
6   QObject(parent),
7   m_provider(0),
8   m_manager(0),
9   m_reply(0),
10   m_active(false) {
11
12   QStringList providers = QGeoServiceProvider::availableServiceProviders();
13
14   if (!providers.isEmpty()) {
15     m_provider = new QGeoServiceProvider(providers.at(0));
16   }
17   else {
18     qCritical() << "Cannot find any geo-service providers";
19     return;
20   }
21
22   m_manager = m_provider->searchManager();
23   if (!m_manager) {
24     qCritical() << "Cannot get hold of the geo-search manager" << m_provider->errorString();
25     return;
26   }
27
28   if (!m_manager->supportsReverseGeocoding()) {
29     qCritical() << "geo-search manager does not support reverse geocoding";
30
31     delete m_provider; m_provider = 0;
32     m_manager = 0;
33     return;
34   }
35
36   QObject::connect(m_manager, SIGNAL(finished(QGeoSearchReply *)),
37                    this, SLOT(finished(QGeoSearchReply *)));
38   QObject::connect(m_manager, SIGNAL(error(QGeoSearchReply *, const QGeoSearchReply::Error&,
39                                            const QString&)),
40                    this, SLOT(error(QGeoSearchReply *, const QGeoSearchReply::Error&,
41                                     const QString&)));
42 }
43
44 Geocode::~Geocode() {
45   setActive(false);
46
47   delete m_provider; m_provider = 0;
48 }
49
50 bool Geocode::isActive() const {
51   return m_active;
52 }
53
54 void Geocode::setActive(bool active) {
55   if (active != m_active) {
56     m_active = active;
57
58     if (!m_active && m_reply) {
59       m_reply->deleteLater(); m_reply = 0;
60     }
61
62     clear();
63
64     emit activeChanged();
65   }
66 }
67
68 QString Geocode::country() const {
69   return m_country;
70 }
71
72 QString Geocode::city() const {
73   return m_city;
74 }
75
76 QString Geocode::suburb() const {
77   return m_suburb;
78 }
79
80 void Geocode::search(double longitude, double latitude) {
81   if (!m_active || !m_provider) {
82     return;
83   }
84
85   if (m_reply) {
86     m_reply->abort();
87     delete m_reply;
88   }
89
90   m_reply = m_manager->reverseGeocode(QGeoCoordinate(latitude, longitude));
91   if (!m_reply) {
92     qCritical() << "geo-search manager provided a null reply!";
93     return;
94   }
95 }
96
97 void Geocode::clear() {
98   if (!m_country.isEmpty()) {
99     m_country.clear();
100     emit countryChanged();
101   }
102
103   if (!m_city.isEmpty()) {
104     m_city.clear();
105     emit cityChanged();
106   }
107
108   if (!m_suburb.isEmpty()) {
109     m_suburb.clear();
110     emit suburbChanged();
111   }
112 }
113
114 void Geocode::finished(QGeoSearchReply *reply) {
115   if (reply->error() != QGeoSearchReply::NoError) {
116     qWarning() << "Error while geocoding" << reply->error() << reply->errorString();
117
118     reply->deleteLater();
119
120     if (reply == m_reply) {
121       m_reply = 0;
122     }
123
124     clear();
125
126     return;
127   }
128
129   QList<QGeoPlace> places = reply->places();
130   if (!places.isEmpty()) {
131     QGeoAddress address = places.at(0).address();
132     if (m_country != address.country()) {
133       m_country = address.country();
134       emit countryChanged();
135     }
136
137     if (m_city != address.city()) {
138       m_city = address.city();
139       emit cityChanged();
140     }
141
142     if (m_suburb != address.district()) {
143       m_suburb = address.district();
144       emit suburbChanged();
145     }
146   }
147   else {
148     qWarning() << "No places found";
149     clear();
150   }
151
152   reply->deleteLater();
153
154   if (reply == m_reply) {
155     m_reply = 0;
156   }
157 }
158
159 void Geocode::error(QGeoSearchReply *reply, const QGeoSearchReply::Error& error,
160                     const QString& errorString) {
161
162   qWarning() << "Error while geocoding" << error << reply->errorString() << errorString;
163
164   reply->deleteLater();
165
166   if (reply == m_reply) {
167     m_reply = 0;
168     clear();
169   }
170 }