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 "qgeocameracapabilities_p.h"
38
39#include <QSharedData>
40#include <cmath>
41
42static const double invLog2 = 1.0 / std::log(x: 2.0);
43
44static double zoomLevelTo256(double zoomLevelForTileSize, double tileSize)
45{
46 return std::log( x: std::pow(x: 2.0, y: zoomLevelForTileSize) * tileSize / 256.0 ) * invLog2;
47}
48
49QT_BEGIN_NAMESPACE
50
51class QGeoCameraCapabilitiesPrivate : public QSharedData
52{
53public:
54 QGeoCameraCapabilitiesPrivate();
55 QGeoCameraCapabilitiesPrivate(const QGeoCameraCapabilitiesPrivate &other);
56 ~QGeoCameraCapabilitiesPrivate();
57
58 QGeoCameraCapabilitiesPrivate &operator = (const QGeoCameraCapabilitiesPrivate &other);
59
60 bool operator == (const QGeoCameraCapabilitiesPrivate &rhs) const;
61
62 bool supportsBearing_;
63 bool supportsRolling_;
64 bool supportsTilting_;
65
66 // this is mutable so that it can be set from accessor functions that are const
67 // TODO: remove the mutable here
68 mutable bool valid_;
69
70 double minZoom_;
71 double maxZoom_;
72 double minTilt_;
73 double maxTilt_;
74 int tileSize_;
75 double minimumFieldOfView_;
76 double maximumFieldOfView_;
77 bool overzoomEnabled_;
78};
79
80QGeoCameraCapabilitiesPrivate::QGeoCameraCapabilitiesPrivate()
81 : supportsBearing_(false),
82 supportsRolling_(false),
83 supportsTilting_(false),
84 valid_(false),
85 minZoom_(0.0),
86 maxZoom_(0.0),
87 minTilt_(0.0),
88 maxTilt_(0.0),
89 tileSize_(256),
90 minimumFieldOfView_(45.0), // Defaulting to a fixed FOV of 45 degrees. Too large FOVs cause the loading of too many tiles
91 maximumFieldOfView_(45.0),
92 overzoomEnabled_(false) {}
93
94
95QGeoCameraCapabilitiesPrivate::QGeoCameraCapabilitiesPrivate(const QGeoCameraCapabilitiesPrivate &other)
96 : QSharedData(other),
97 supportsBearing_(other.supportsBearing_),
98 supportsRolling_(other.supportsRolling_),
99 supportsTilting_(other.supportsTilting_),
100 valid_(other.valid_),
101 minZoom_(other.minZoom_),
102 maxZoom_(other.maxZoom_),
103 minTilt_(other.minTilt_),
104 maxTilt_(other.maxTilt_),
105 tileSize_(other.tileSize_),
106 minimumFieldOfView_(other.minimumFieldOfView_),
107 maximumFieldOfView_(other.maximumFieldOfView_),
108 overzoomEnabled_(other.overzoomEnabled_){}
109
110
111QGeoCameraCapabilitiesPrivate::~QGeoCameraCapabilitiesPrivate() {}
112
113QGeoCameraCapabilitiesPrivate &QGeoCameraCapabilitiesPrivate::operator = (const QGeoCameraCapabilitiesPrivate &other)
114{
115 if (this == &other)
116 return *this;
117
118 supportsBearing_ = other.supportsBearing_;
119 supportsRolling_ = other.supportsRolling_;
120 supportsTilting_ = other.supportsTilting_;
121 valid_ = other.valid_;
122 minZoom_ = other.minZoom_;
123 maxZoom_ = other.maxZoom_;
124 minTilt_ = other.minTilt_;
125 maxTilt_ = other.maxTilt_;
126 tileSize_ = other.tileSize_;
127 minimumFieldOfView_ = other.minimumFieldOfView_;
128 maximumFieldOfView_ = other.maximumFieldOfView_;
129 overzoomEnabled_ = other.overzoomEnabled_;
130
131 return *this;
132}
133
134bool QGeoCameraCapabilitiesPrivate::operator == (const QGeoCameraCapabilitiesPrivate &rhs) const
135{
136 return ((supportsBearing_ == rhs.supportsBearing_)
137 && (supportsRolling_ == rhs.supportsRolling_)
138 && (supportsTilting_ == rhs.supportsTilting_)
139 && (valid_ == rhs.valid_)
140 && (minZoom_ == rhs.minZoom_)
141 && (maxZoom_ == rhs.maxZoom_)
142 && (minTilt_ == rhs.minTilt_)
143 && (maxTilt_ == rhs.maxTilt_)
144 && (tileSize_ == rhs.tileSize_)
145 && (minimumFieldOfView_ == rhs.minimumFieldOfView_)
146 && (maximumFieldOfView_ == rhs.maximumFieldOfView_)
147 && (overzoomEnabled_ == rhs.overzoomEnabled_));
148}
149
150/*!
151 \class QGeoCameraCapabilities
152 \inmodule QtLocation
153 \ingroup QtLocation-impl
154 \since 5.6
155 \internal
156
157 \brief The QGeoCameraCapabilities class describes the limitations on camera settings imposed by a mapping plugin.
158
159 Different mapping plugins will support different ranges of zoom levels, and not all mapping plugins will
160 be able to support, bearing, tilting and rolling of the camera.
161
162 This class describes what the plugin supports, and is used to restrict changes to the camera information
163 associated with a \l QGeoMap such that the camera information stays within these limits.
164*/
165
166/*!
167 Constructs a camera capabilities object.
168*/
169QGeoCameraCapabilities::QGeoCameraCapabilities()
170 : d(new QGeoCameraCapabilitiesPrivate()) {}
171
172/*!
173 Constructs a camera capabilities object from the contents of \a other.
174*/
175QGeoCameraCapabilities::QGeoCameraCapabilities(const QGeoCameraCapabilities &other)
176 : d(other.d) {}
177
178/*!
179 Destroys this camera capabilities object.
180*/
181QGeoCameraCapabilities::~QGeoCameraCapabilities() {}
182
183/*!
184 Assigns the contents of \a other to this camera capabilities object and
185 returns a reference to this camera capabilities object.
186*/
187QGeoCameraCapabilities &QGeoCameraCapabilities::operator = (const QGeoCameraCapabilities &other)
188{
189 if (this == &other)
190 return *this;
191
192 d = other.d;
193 return *this;
194}
195
196bool QGeoCameraCapabilities::operator == (const QGeoCameraCapabilities &rhs) const
197{
198 return (*(d.constData()) == *(rhs.d.constData()));
199}
200
201bool QGeoCameraCapabilities::operator != (const QGeoCameraCapabilities &other) const
202{
203 return !(operator==(rhs: other));
204}
205
206void QGeoCameraCapabilities::setTileSize(int tileSize)
207{
208 if (tileSize < 1)
209 return;
210 d->tileSize_ = tileSize;
211}
212
213int QGeoCameraCapabilities::tileSize() const
214{
215 return d->tileSize_;
216}
217
218/*!
219 Returns whether this instance of the class is considered "valid". To be
220 valid, the instance must have had at least one capability set (to either
221 true or false) using a set method, or copied from another instance
222 (such as by the assignment operator).
223*/
224bool QGeoCameraCapabilities::isValid() const
225{
226 return d->valid_;
227}
228
229/*!
230 Sets the minimum zoom level supported by the associated plugin to \a maximumZoomLevel.
231
232 Larger values of the zoom level correspond to more detailed views of the
233 map.
234*/
235void QGeoCameraCapabilities::setMinimumZoomLevel(double minimumZoomLevel)
236{
237 d->minZoom_ = minimumZoomLevel;
238 d->valid_ = true;
239}
240
241/*!
242 Returns the minimum zoom level supported by the associated plugin.
243
244 Larger values of the zoom level correspond to more detailed views of the
245 map.
246*/
247double QGeoCameraCapabilities::minimumZoomLevel() const
248{
249 return d->minZoom_;
250}
251
252double QGeoCameraCapabilities::minimumZoomLevelAt256() const
253{
254 if (d->tileSize_ == 256)
255 return d->minZoom_;
256 return qMax<double>(a: 0, b: zoomLevelTo256(zoomLevelForTileSize: d->minZoom_, tileSize: d->tileSize_));
257}
258
259/*!
260 Sets the maximum zoom level supported by the associated plugin to \a maximumZoomLevel.
261
262 Larger values of the zoom level correspond to more detailed views of the
263 map.
264*/
265void QGeoCameraCapabilities::setMaximumZoomLevel(double maximumZoomLevel)
266{
267 d->maxZoom_ = maximumZoomLevel;
268 d->valid_ = true;
269}
270
271/*!
272 Returns the maximum zoom level supported by the associated plugin.
273
274 Larger values of the zoom level correspond to more detailed views of the
275 map.
276*/
277double QGeoCameraCapabilities::maximumZoomLevel() const
278{
279 return d->maxZoom_;
280}
281
282double QGeoCameraCapabilities::maximumZoomLevelAt256() const
283{
284 if (d->tileSize_ == 256)
285 return d->maxZoom_;
286 return qMax<double>(a: 0, b: zoomLevelTo256(zoomLevelForTileSize: d->maxZoom_, tileSize: d->tileSize_));
287}
288
289/*!
290 Sets whether the associated plugin can render a map when the camera
291 has an arbitrary bearing to \a supportsBearing.
292*/
293void QGeoCameraCapabilities::setSupportsBearing(bool supportsBearing)
294{
295 d->supportsBearing_ = supportsBearing;
296 d->valid_ = true;
297}
298
299/*!
300 Returns whether the associated plugin can render a map when the camera
301 has an arbitrary bearing.
302*/
303bool QGeoCameraCapabilities::supportsBearing() const
304{
305 return d->supportsBearing_;
306}
307
308/*!
309 Sets whether the associated plugin can render a map when the
310 camera is rolled to \a supportsRolling.
311*/
312void QGeoCameraCapabilities::setSupportsRolling(bool supportsRolling)
313{
314 d->supportsRolling_ = supportsRolling;
315 d->valid_ = true;
316}
317
318/*!
319 Returns whether the associated plugin can render a map when the
320 camera is rolled.
321*/
322bool QGeoCameraCapabilities::supportsRolling() const
323{
324 return d->supportsRolling_;
325}
326
327/*!
328 Sets whether the associated plugin can render a map when the
329 camera is tilted to \a supportsTilting.
330*/
331void QGeoCameraCapabilities::setSupportsTilting(bool supportsTilting)
332{
333 d->supportsTilting_ = supportsTilting;
334 d->valid_ = true;
335}
336
337/*!
338 Returns whether the associated plugin can render a map when the
339 camera is tilted.
340*/
341bool QGeoCameraCapabilities::supportsTilting() const
342{
343 return d->supportsTilting_;
344}
345
346/*!
347 Sets the minimum tilt supported by the associated plugin to \a minimumTilt.
348
349 The value is in degrees where 0 is equivalent to 90 degrees between
350 the line of view and earth's surface, that is, looking straight down to earth.
351*/
352void QGeoCameraCapabilities::setMinimumTilt(double minimumTilt)
353{
354 d->minTilt_ = minimumTilt;
355 d->valid_ = true;
356}
357
358/*!
359 Returns the minimum tilt supported by the associated plugin.
360
361 The value is in degrees where 0 is equivalent to 90 degrees between
362 the line of view and earth's surface, that is, looking straight down to earth.
363*/
364double QGeoCameraCapabilities::minimumTilt() const
365{
366 return d->minTilt_;
367}
368
369/*!
370 Sets the maximum tilt supported by the associated plugin to \a maximumTilt.
371
372 The value is in degrees where 0 is equivalent to 90 degrees between
373 the line of view and earth's surface, that is, looking straight down to earth.
374*/
375void QGeoCameraCapabilities::setMaximumTilt(double maximumTilt)
376{
377 d->maxTilt_ = maximumTilt;
378 d->valid_ = true;
379}
380
381/*!
382 Returns the maximum tilt supported by the associated plugin.
383
384 The value is in degrees where 0 is equivalent to 90 degrees between
385 the line of view and earth's surface, that is, looking straight down to earth.
386*/
387double QGeoCameraCapabilities::maximumTilt() const
388{
389 return d->maxTilt_;
390}
391
392/*!
393 Sets the minimum field of view supported by the associated plugin to \a minimumFieldOfView.
394 The value is in degrees and is clamped against a [1, 179] range.
395
396 \since 5.9
397*/
398void QGeoCameraCapabilities::setMinimumFieldOfView(double minimumFieldOfView)
399{
400 d->minimumFieldOfView_ = qBound(min: 1.0, val: minimumFieldOfView, max: 179.0);
401 d->valid_ = true;
402}
403
404/*!
405 Returns the minimum field of view supported by the associated plugin.
406 The value is in degrees.
407
408 \since 5.9
409*/
410double QGeoCameraCapabilities::minimumFieldOfView() const
411{
412 return d->minimumFieldOfView_;
413}
414
415/*!
416 Sets the maximum field of view supported by the associated plugin to \a maximumFieldOfView.
417 The value is in degrees and is clamped against a [1, 179] range.
418
419 \since 5.9
420*/
421void QGeoCameraCapabilities::setMaximumFieldOfView(double maximumFieldOfView)
422{
423 d->maximumFieldOfView_ = qBound(min: 1.0, val: maximumFieldOfView, max: 179.0);
424 d->valid_ = true;
425}
426
427/*!
428 Returns the maximum field of view supported by the associated plugin.
429 The value is in degrees.
430
431 \since 5.9
432*/
433double QGeoCameraCapabilities::maximumFieldOfView() const
434{
435 return d->maximumFieldOfView_;
436}
437
438/*!
439 Sets whether overzooming is supported by the associated plugin.
440
441 Overzooming means that zoom levels outside the [minimumZL, maximumZL] range can be set,
442 and if tiles aren't available for those zoom levels, either tiles from other zoom levels
443 will be used, or nothing will be shown.
444
445 Set this value to false if the plugin is not capable of that. For example if using
446 a mapping engine that always clamp the zoomLevel value, which may cause misalignment in case
447 of stacked map elements.
448
449 \since 5.9
450*/
451void QGeoCameraCapabilities::setOverzoomEnabled(bool overzoomEnabled)
452{
453 d->overzoomEnabled_ = overzoomEnabled;
454 d->valid_ = true;
455}
456
457/*!
458 Returns whether overzooming is supported by the associated plugin.
459
460 \since 5.9
461*/
462bool QGeoCameraCapabilities::overzoomEnabled() const
463{
464 return d->overzoomEnabled_;
465}
466
467
468QT_END_NAMESPACE
469

source code of qtlocation/src/location/maps/qgeocameracapabilities.cpp