1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtLocation module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL3$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or later as published by the Free
28 ** Software Foundation and appearing in the file LICENSE.GPL included in
29 ** the packaging of this file. Please review the following information to
30 ** ensure the GNU General Public License version 2.0 requirements will be
31 ** met: http://www.gnu.org/licenses/gpl-2.0.html.
32 **
33 ** $QT_END_LICENSE$
34 **
35 ****************************************************************************/
36 
37 #include "qgeocodingmanager.h"
38 #include "qgeocodingmanager_p.h"
39 #include "qgeocodingmanagerengine.h"
40 
41 #include "qgeorectangle.h"
42 #include "qgeocircle.h"
43 
44 #include <QLocale>
45 
46 QT_BEGIN_NAMESPACE
47 
48 /*!
49     \class QGeoCodingManager
50     \inmodule QtLocation
51     \ingroup QtLocation-geocoding
52     \since 5.6
53 
54     \brief The QGeoCodingManager class provides support for geocoding
55     operations.
56 
57     The geocode() and reverseGeocode() functions return
58     QGeoCodeReply objects, which manage these operations and report on the
59     result of the operations and any errors which may have occurred.
60 
61     The geocode() and reverseGeocode() functions can be used to convert
62     QGeoAddress instances to QGeoCoordinate instances and vice-versa.
63 
64     The geocode() function is also overloaded to allow a user to perform a free text
65     geocoding operation, if the string provided can be interpreted as
66     an address it can be geocoded to coordinate information.
67 
68     Instances of QGeoCodingManager can be accessed with
69     QGeoServiceProvider::geocodingManager().
70 */
71 
72 /*!
73     Constructs a new manager with the specified \a parent and with the
74     implementation provided by \a engine.
75 
76     This constructor is used interally by QGeoServiceProviderFactory. Regular
77     users should acquire instances of QGeoCodingManager with
78     QGeoServiceProvider::geocodingManager();
79 */
QGeoCodingManager(QGeoCodingManagerEngine * engine,QObject * parent)80 QGeoCodingManager::QGeoCodingManager(QGeoCodingManagerEngine *engine, QObject *parent)
81     : QObject(parent),
82       d_ptr(new QGeoCodingManagerPrivate())
83 {
84     d_ptr->engine = engine;
85     if (d_ptr->engine) {
86         d_ptr->engine->setParent(this);
87 
88         connect(d_ptr->engine,
89                 SIGNAL(finished(QGeoCodeReply*)),
90                 this,
91                 SIGNAL(finished(QGeoCodeReply*)));
92 
93         connect(d_ptr->engine,
94                 SIGNAL(error(QGeoCodeReply*,QGeoCodeReply::Error,QString)),
95                 this,
96                 SIGNAL(error(QGeoCodeReply*,QGeoCodeReply::Error,QString)));
97     } else {
98         qFatal("The geocoding manager engine that was set for this geocoding manager was NULL.");
99     }
100 }
101 
102 /*!
103     Destroys this manager.
104 */
~QGeoCodingManager()105 QGeoCodingManager::~QGeoCodingManager()
106 {
107     delete d_ptr;
108 }
109 
110 /*!
111     Returns the name of the engine which implements the behaviour of this
112     geocoding manager.
113 
114     The combination of managerName() and managerVersion() should be unique
115     amongst the plugin implementations.
116 */
managerName() const117 QString QGeoCodingManager::managerName() const
118 {
119 //    if (!d_ptr->engine)
120 //        return QString();
121 
122     return d_ptr->engine->managerName();
123 }
124 
125 /*!
126     Returns the version of the engine which implements the behaviour of this
127     geocoding manager.
128 
129     The combination of managerName() and managerVersion() should be unique
130     amongst the plugin implementations.
131 */
managerVersion() const132 int QGeoCodingManager::managerVersion() const
133 {
134 //    if (!d_ptr->engine)
135 //        return -1;
136 
137     return d_ptr->engine->managerVersion();
138 }
139 
140 /*!
141     Begins the geocoding of \a address. Geocoding is the process of finding a
142     coordinate that corresponds to a given address.
143 
144     A QGeoCodeReply object will be returned, which can be used to manage the
145     geocoding operation and to return the results of the operation.
146 
147     This manager and the returned QGeoCodeReply object will emit signals
148     indicating if the operation completes or if errors occur.
149 
150     If supportsGeocoding() returns false an
151     QGeoCodeReply::UnsupportedOptionError will occur.
152 
153     Once the operation has completed, QGeoCodeReply::locations() can be used to
154     retrieve the results, which will consist of a list of QGeoLocation objects.
155     These objects represent a combination of coordinate and address data.
156 
157     The address data returned in the results may be different from \a address.
158     This will usually occur if the geocoding service backend uses a different
159     canonical form of addresses or if \a address was only partially filled out.
160 
161     If \a bounds is non-null and is a valid QGeoShape it will be used to
162     limit the results to those that are contained within \a bounds. This is
163     particularly useful if \a address is only partially filled out, as the
164     service will attempt to geocode all matches for the specified data.
165 
166     The user is responsible for deleting the returned reply object, although
167     this can be done in the slot connected to QGeoCodingManager::finished(),
168     QGeoCodingManager::error(), QGeoCodeReply::finished() or
169     QGeoCodeReply::error() with deleteLater().
170 */
geocode(const QGeoAddress & address,const QGeoShape & bounds)171 QGeoCodeReply *QGeoCodingManager::geocode(const QGeoAddress &address, const QGeoShape &bounds)
172 {
173     return d_ptr->engine->geocode(address, bounds);
174 }
175 
176 
177 /*!
178     Begins the reverse geocoding of \a coordinate. Reverse geocoding is the
179     process of finding an address that corresponds to a given coordinate.
180 
181     A QGeoCodeReply object will be returned, which can be used to manage the
182     reverse geocoding operation and to return the results of the operation.
183 
184     This manager and the returned QGeoCodeReply object will emit signals
185     indicating if the operation completes or if errors occur.
186 
187     If supportsReverseGeocoding() returns false an
188     QGeoCodeReply::UnsupportedOptionError will occur.
189 
190     At that point QGeoCodeReply::locations() can be used to retrieve the
191     results, which will consist of a list of QGeoLocation objects. These objects
192     represent a combination of coordinate and address data.
193 
194     The coordinate data returned in the results may be different from \a
195     coordinate. This will usually occur if the reverse geocoding service
196     backend shifts the coordinates to be closer to the matching addresses, or
197     if the backend returns results at multiple levels of detail.
198 
199     If multiple results are returned by the reverse geocoding service backend
200     they will be provided in order of specificity. This normally occurs if the
201     backend is configured to reverse geocode across multiple levels of detail.
202     As an example, some services will return address and coordinate pairs for
203     the street address, the city, the state and the country.
204 
205     If \a bounds is non-null and a valid QGeoRectangle it will be used to
206     limit the results to those that are contained within \a bounds.
207 
208     The user is responsible for deleting the returned reply object, although
209     this can be done in the slot connected to QGeoCodingManager::finished(),
210     QGeoCodingManager::error(), QGeoCodeReply::finished() or
211     QGeoCodeReply::error() with deleteLater().
212 */
reverseGeocode(const QGeoCoordinate & coordinate,const QGeoShape & bounds)213 QGeoCodeReply *QGeoCodingManager::reverseGeocode(const QGeoCoordinate &coordinate, const QGeoShape &bounds)
214 {
215     return d_ptr->engine->reverseGeocode(coordinate, bounds);
216 }
217 
218 /*!
219     Begins geocoding for a location matching \a address.
220 
221     A QGeoCodeReply object will be returned, which can be used to manage the
222     geocoding operation and to return the results of the operation.
223 
224     This manager and the returned QGeoCodeReply object will emit signals
225     indicating if the operation completes or if errors occur.
226 
227     Once the operation has completed, QGeoCodeReply::locations() can be used to
228     retrieve the results, which will consist of a list of QGeoLocation objects.
229     These objects represent a combination of coordinate and address data.
230 
231     If \a limit is -1 the entire result set will be returned, otherwise at most
232     \a limit results will be returned.
233 
234     The \a offset parameter is used to ask the geocoding service to not return the
235     first \a offset results.
236 
237     The \a limit and \a offset results are used together to implement paging.
238 
239     If \a bounds is non-null and a valid QGeoShape it will be used to
240     limit the results to those that are contained within \a bounds.
241 
242     The user is responsible for deleting the returned reply object, although
243     this can be done in the slot connected to QGeoCodingManager::finished(),
244     QGeoCodingManager::error(), QGeoCodeReply::finished() or
245     QGeoCodeReply::error() with deleteLater().
246 */
geocode(const QString & address,int limit,int offset,const QGeoShape & bounds)247 QGeoCodeReply *QGeoCodingManager::geocode(const QString &address,
248         int limit,
249         int offset,
250         const QGeoShape &bounds)
251 {
252     QGeoCodeReply *reply = d_ptr->engine->geocode(address,
253                              limit,
254                              offset,
255                              bounds);
256     return reply;
257 }
258 
259 /*!
260     Sets the locale to be used by this manager to \a locale.
261 
262     If this geocoding manager supports returning the results
263     in different languages, they will be returned in the language of \a locale.
264 
265     The locale used defaults to the system locale if this is not set.
266 */
setLocale(const QLocale & locale)267 void QGeoCodingManager::setLocale(const QLocale &locale)
268 {
269     d_ptr->engine->setLocale(locale);
270 }
271 
272 /*!
273     Returns the locale used to hint to this geocoding manager about what
274     language to use for the results.
275 */
locale() const276 QLocale QGeoCodingManager::locale() const
277 {
278     return d_ptr->engine->locale();
279 }
280 
281 /*!
282 \fn void QGeoCodingManager::finished(QGeoCodeReply *reply)
283 
284     This signal is emitted when \a reply has finished processing.
285 
286     If reply::error() equals QGeoCodeReply::NoError then the processing
287     finished successfully.
288 
289     This signal and QGeoCodeReply::finished() will be emitted at the same
290     time.
291 
292     \note Do not delete the \a reply object in the slot connected to this
293     signal. Use deleteLater() instead.
294 */
295 
296 /*!
297 \fn void QGeoCodingManager::error(QGeoCodeReply *reply, QGeoCodeReply::Error error, QString errorString)
298 
299     This signal is emitted when an error has been detected in the processing of
300     \a reply. The QGeoCodingManager::finished() signal will probably follow.
301 
302     The error will be described by the error code \a error. If \a errorString is
303     not empty it will contain a textual description of the error.
304 
305     This signal and QGeoCodeReply::error() will be emitted at the same time.
306 
307     \note Do not delete the \a reply object in the slot connected to this
308     signal. Use deleteLater() instead.
309 */
310 
311 /*******************************************************************************
312 *******************************************************************************/
313 
QGeoCodingManagerPrivate()314 QGeoCodingManagerPrivate::QGeoCodingManagerPrivate()
315     : engine(0) {}
316 
~QGeoCodingManagerPrivate()317 QGeoCodingManagerPrivate::~QGeoCodingManagerPrivate()
318 {
319     delete engine;
320 }
321 
322 /*******************************************************************************
323 *******************************************************************************/
324 
325 QT_END_NAMESPACE
326