1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
5 \page location-places-qml.html
10 The Places API lets users discover places of interest and view details
11 about them, such as address and contact information. Some places may have
12 additional content associated with them, such as images and reviews. The
13 Places API also lets you manage places and categories, allowing
14 you to to save and remove them. Places may also include paths, roads, or
15 forms of transport, enabling navigation optimization and assistance. For
16 more information about navigation, see \l {route}s.
18 \section1 Introductory Concepts
21 A \l Plugin is an abstraction for a backend. One \l Plugin might access places from a
22 REST server while another may access places from a local database. The following
23 instantiates a \l Plugin object by providing a name of "osm". The \l Plugin name
24 identifies which backend to choose from. Plugins may also be provided with a set of
25 \l {PluginParameter} {parameters}, which essentially takes the form of a set of
26 key-value pairs. The \l {PluginParameter} {parameters} that can be specified vary
27 among the different \l Plugin backends. For documentation on the possible \l
28 {PluginParameter} {parameters} and nuances of each \l Plugin, see the \l {Plugin
29 references and parameters}{Plugin References}.
31 \snippet places_list/places_list.qml Initialize Plugin
33 \section2 Models, Views and Delegates
34 The QML Places API is built around the notion of models, views and delegates.
39 \li A model holds data items and maintains their structure.
40 The model is also responsible for retrieving the items from a data source.
43 \li A view is a visual container that displays the data and manages how visual
44 items are shown such as in a list or a grid. The view may also
45 be responsible for navigating the data, for example, scrolling through
46 the visual items during a flicking motion.
49 \li A delegate defines how individual data elements should appear
50 as visual items in the view. The models expose a set of data roles
51 and the delegate uses them to construct a visual item. The delegate
52 may also define behaviour such as an operation to invoke when a visual
56 The Common Use Cases section below demonstrates concrete examples of how
57 these concepts fit together.
59 \section1 Common Use Cases
61 \section2 Searching for Places
62 Searching is accomplished via the \l PlaceSearchModel. The \l
63 {PlaceSearchModel::plugin} {plugin} property specifies which backend to
64 perform search operations against. Search parameters may be provided
65 through properties such as the \l {PlaceSearchModel::searchTerm}
66 {searchTerm} and \l {PlaceSearchModel::searchArea} {searchArea}. A search
67 operation can then be started by invoking the \l {PlaceSearchModel::update}
68 {update()} method. For simplicity, the snippet below invokes \l
69 {PlaceSearchModel::update} {update()} once construction of the model as
70 been completed, typically \l {PlaceSearchModel::update} {update()} would be
71 invoked in response to a user action such as a button click. While the
72 search operation is underway the \l {PlaceSearchModel::status} property
73 transitions into the \c Loading state and when successfully completed moves
74 into the \c Ready state.
76 \snippet places_list/places_list.qml PlaceSearchModel
78 \section2 Display Search Results using a ListView
79 A \l ListView can be used to show the search results found by the model.
80 It defines the visual region for where the results are shown, and in the
81 case below fills the entirety of its parent. The \l ListView has built in
82 behavior that enables the region to respond to flicking events and to
85 In the snippet below, the search model has been assigned to the ListView's
86 \l {ListView::model} {model} property. When the model is updated with new
87 results, the \l ListView is automatically updated to reflect the model's new
90 A simple delegate has been bound to the \l {ListView}'s \l
91 {ListView::delegate} {delegate} property. The \l PlaceSearchModel exposes
92 a set of \l {PlaceSearchModel Roles} {roles} of which the \e title and \e
93 place roles have been used below, these are of type string and \l Place
94 respectively. Essentially for each data item that should be visible in the
95 view, the view invokes the delegate to create a visual representation of
101 \snippet places_list/places_list.qml Places ListView
103 \inlineimage places_list.png
106 \note For simplicty's sake we have assumed that every search result is of
107 \l {Search Result Types} {type} \c PlaceSearchResult and so always have
108 access to the \e place role, other search result types may not have a
111 See the \l {Places List(QML)} {Places List} example for full source code.
113 \section2 Display Search Results using a MapItemView
114 Instead of a \l ListView, the \l PlaceSearchModel can be used in
115 conjunction with a \l MapItemView to display markers on a map. Firstly a
116 \l Map is used to define the visual region occupied by the map, in this
117 case it fills the entirety of its parent. Other properties are specified
118 such as the \l {Map::plugin} {plugin} providing the maps, and the map's \l
119 {Map::center} {center} and \l {Map::zoomLevel} {zoomLevel}.
121 Inside the \l Map, a \l MapItemView is declared, where the \l
122 {MapItemView::model} {model} property has been set to the search model and
123 a \l {MapItemView::delegate} {delegate} consisting of a \l MapQuickItem is
124 used to display a marker image. A marker is shown for every place that
125 was found by the search model. The delegate uses the \e place role
126 to position the marker.
131 \snippet places_map/places_map.qml Places MapItemView
133 \inlineimage places_map.png
136 \note For simplicty's sake we have assumed that every search result is of
137 \l {Search Result Types} {type} \c PlaceSearchResult and so always have
138 access to the \e place role, other search result types may not have a
141 See the \l {Places Map(QML)} {Places Map} example for full source code.
143 \section2 Fetching Place Details
144 In order to save bandwidth, sometimes a backend will only return places which
145 are partially populated with details. This can be checked with the
146 Place::detailsFetched property which indicates whether all availalable details
147 have been fetched or not. If not, the Place::getDetails() method can be invoked
148 to fetch the remaining details.
150 \snippet declarative/places.qml Place fetchDetails
152 \section2 Saving and Removing Places
153 Some backends may support saving and removing places. This can be done by
154 calling the Place::save() and Place::remove() methods respectively. Note
155 that in order to save a \l Place, a \l Plugin must be assigned to specify
156 which backend we are saving to. The \l {Place::status} {status} property will
157 transition into the \c Saving state while the save operation is happening and on
158 successful completion will move to the \c Ready state. The following
159 snippet shows how to save and remove a place using javascript.
161 \snippet declarative/places.qml Place createAndSavePlace
163 \snippet declarative/places.qml Place removePlace
166 The above snippets only exhibit a small subset of Places functionality.
167 Refer to the \l {Places Types} shown below for richer content such as \l {ImageModel} {images}, \l {ReviewModel} {reviews} etc, as well as more indepth descriptions and explanations.
169 See also the \l {Places (QML)}{Places (QML)} example for a more comprehensive demonstration on
172 \section1 Places Types
174 \annotatedlist qml-QtLocation5-places-data
177 \annotatedlist qml-QtLocation5-places-models
181 \page location-places-cpp.html
186 The Places API allows users to discover places/points of interest
187 and view details about them such as address and contact information;
188 some places may even have rich content such as images and reviews.
189 The Places API also facilitates management of places and
190 categories, allowing users to save and remove them.
192 \section1 Place Definition
193 \include place-definition.qdocinc
195 \section1 Common Operations
197 \section2 Initializing a Manager
198 All places functionality is facilitated by a QPlaceManager instance. One must specify
199 a QGeoServiceProvider in order to create the QPlaceManager
201 \snippet places/requesthandler.h Initialize Manager
203 \section2 Discovery/Search
205 In order to perform a search operation we simply create a QPlaceSearchRequest
206 and set the desired search parameters, such as a search term and search center.
208 \snippet places/requesthandler.h Search for places cpp
210 The request is an asynchronous operation so we need a slot to handle the
211 completion of the request. In the handler we check that there are no errors and that our search result
212 type is a place. If so we can then retrieve some of the core details of the
213 place. At the end of the slot, we delete the reply since they are for single use only.
215 \snippet places/requesthandler.h Search for places handler cpp
217 \b {Note:} Depending upon the plugin backend that was chosen, the search results may contain places
218 which have further details that can be fetched on a place by place basis. To fetch these other details
219 see \l {Fetching Place Details}.
221 \section3 Recommendations
222 Recommendations can be retrieved by supplying a place id via QPlaceSearchRequest::setRecommendationId().
223 Any places similar to the given place are retrieved.
226 If the plugin supports paging, the limit parameter may be provided to the search request.
227 \snippet places/requesthandler.h Search paging
229 \section2 Fetching Place Details
230 A place that has been returned from a search request may have more details
231 that can be fetched. The following demonstrates how to check if there
232 are further details and if so how to request them.
234 \snippet places/requesthandler.h Details check
237 \snippet places/requesthandler.h Details handler cpp
239 \section2 Fetching Rich Content
240 Rich content such as images and reviews is retrieved through the manager and then if required assigned to a place.
241 \snippet places/requesthandler.h Image request
243 We can handle the content request as shown below.
244 \snippet places/requesthandler.h Image handler
246 It is important to note that the results in the QPlaceContentReply,
247 is a QPlaceContent::Collection which is essentially a QMap<int, QPlaceContent>. The key \c {int} in this case is the
248 index of the content, and the value is the content itself. Due to the way Content is implemented
249 it is possible to convert a content type as follows
251 QPlaceImage image = content; //provided that 'content' has a type QPlace::ImageType
254 The usage of the QPlaceContent::Collection and the conversion between content and its subtypes means
255 that code for handling the mechanics of paging reviews, images and editorials can be easily shared.
257 \section2 Search Suggestions
258 The retrieval of search term suggestions is very similar to performing a place search. A QPlaceSearchRequest
259 is used just like a place search, the only difference being that the search term is set to a
260 partially completed string.
262 \snippet places/requesthandler.h Suggestion request
263 And when the request is done, we can use the reply to show the suggestions.
264 \snippet places/requesthandler.h Suggestion handler
266 \target Saving a place cpp
267 \section2 Saving a Place
268 The saving of a new place is performed as follows, we create a QPlace instance
269 and populate it with information such as a name, address and coordinate. Once
270 done we can invoke QPlaceManager::savePlace() to begin a save operation.
271 \snippet places/requesthandler.h Save place pt1
273 \snippet places/requesthandler.h Save place pt2
275 Once a place is saved the reply contains the new identifier for that place.
276 \snippet places/requesthandler.h Save place handler
278 Note that to save an already \e existing place, the QPlace::placeId() must
279 be filled in with the correct identifier. Otherwise a new place will be created if empty or the
280 wrong place overwritten if the identifier is incorrect.
282 When a place is saved, the QPlaceManager may emit QPlaceManager::placedAdded() or QPlaceManager::placeUpdated()
283 signals. However whether a manager does so or not is provider specific, managers accessing places
284 from a web service will typically not emit these signals while managers accessing places locally stored generally will.
287 \input place-caveats.qdocinc
289 \section3 Saving Between Managers
290 When saving places between managers, there are a few things to be aware of.
291 Some fields of a place such as the id, categories and icons are manager specific entities
292 for example the categories in one manager may not be recognized in another.
293 Therefore trying to save a place directly from one manager to another is not possible.
295 The typical approach is to use the QPlaceManager::compatiblePlace() function,
296 it creates a copy of a place, but only copies data that the manager supports.
297 Manager specific data such as the place identifier is not copied over. The new
298 copy is now suitable for saving into the manager. If the manager supports matching by alternative
299 identifiers, an alternative identifier attribute is assigned to the copy (see \l {Matching places between managers})
301 \snippet places/requesthandler.h Save to different manager
303 \target Removing a place cpp
304 \section2 Removing a Place
305 The removal of a place is performed as follows:
306 \snippet places/requesthandler.h Remove place
309 \snippet places/requesthandler.h Remove place handler
311 When a place is removed, the QPlaceManager may emit the QPlaceManager::placeRemoved() signal. Whether a
312 manager does so is provider specific. Managers accessing places from a web service will typically not emit
313 these signals, while managers accessing places stored locally generally will.
315 \section2 Using Categories
317 Categories are keywords that can describe a place. For example, 'park', 'theater',
318 'restaurant'. A place could be described by many categories, it could be a park and a music venue and a ferry or bus stop.
320 To use categories they must first be initialized.
321 \snippet places/requesthandler.h Initialize categories
324 \snippet places/requesthandler.h Initialize categories reply
326 After the categories have been initialized we can then use these category functions.
328 \li QPlaceManager::childCategories()
329 \li QPlaceManager::category()
330 \li QPlaceManager::parentCategoryId()
331 \li QPlaceManager::childCategoryIds();
334 To retrieve the top level categories
335 we use the QPlaceManager::childCategories() function but do not provide
336 a category identifier.
338 \snippet places/requesthandler.h Top level categories
340 If we did provide an identifier then we could retrieve a category's children.
342 \snippet places/requesthandler.h Child categories
344 \section2 Saving a Category
345 The following shows how to save a category
346 \snippet places/requesthandler.h Save category
349 \snippet places/requesthandler.h Save category handler
351 When a category is saved, the QPlaceManager may emit QPlaceManager::categoryAdded() or QPlaceManager::categoryUpdated()
352 signals. However whether a manager does so or not is provider specific, managers accessing places
353 from a web service will typically not emit these signals while managers accessing places locally stored generally will.
356 \section2 Removing a Category
357 Category removal is very similar to removing a place
358 \snippet places/requesthandler.h Remove category
361 \snippet places/requesthandler.h Remove category handler
363 When a category is removed, the QPlaceManager may emit the QPlaceManager::categoryRemoved() signal. Whether a
364 manager does so is provider specific. Managers accessing places from a web service will typically not emit
365 these signals, while managers accessing places stored locally generally will.
367 \section2 Matching Places Between Managers
368 Sometimes you may want to cross reference whether places from one manager match those from another manager.
369 Such a situation may arise where one manager provides read-only access to places (origin manager) while another second r/w
370 manager (destination manager) is used to save selected favorites from the first. During a search
371 of the origin manager we may want to know which ones have been 'favorited' into the destination manager and perhaps display
372 a customized favorite name rather than the original name.
374 The matching mechanism can vary between managers, but is typically accomplished through an alternative identifier.
375 As part of the save process, the place identifier from the origin manager is saved as an alternative identifier attribute in the destination manager
376 (which can have its own place identifier scheme). In the following example, the origin manager is from the 'here' QGeoServiceProider, therefore
377 as part of the saving process an alternative identifier attribute, x_id_here, is set for the place saved into the destination manager
378 (when QPlaceManager::compatiblePlace() is called)
380 \input place-crossref.qdocinc
382 In order to perform the matching, we create a QPlaceMatchRequest and assign it the search results from the origin manager.
383 The QPlaceMatchRequest will be used on the destination manager to return corresponding places. We also specify
384 matching parameters which are key value pairs. As mentioned previously, this can vary depending on the manager but typically
385 the key is QPlaceMatchRequest::AlternativeId to indicate we are matching by alternative id, the value in this case would be
386 x_id_here which specifies which alternative identifier attribute we are using to do the matching.
388 \snippet places/requesthandler.h Match places
391 \snippet places/requesthandler.h Match places handler
393 \section1 Classes in Places
395 \section2 Data Classes
396 \annotatedlist QtLocation-places-data
398 \section2 Request Classes
399 \annotatedlist QtLocation-places-requests
401 \target Places Reply Classes
402 \section2 Reply classes
403 \annotatedlist QtLocation-places-replies
405 \section2 Manager Classes
406 \annotatedlist QtLocation-places-manager