1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtPositioning module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
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 https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "locationsingleton.h"
41#include <QtPositioning/private/qwebmercator_p.h>
42#include <QtPositioning/private/qdoublevector2d_p.h>
43#include <QDebug>
44
45static QGeoCoordinate parseCoordinate(const QJSValue &value, bool *ok)
46{
47 QGeoCoordinate c;
48
49 if (value.isObject()) {
50 if (value.hasProperty(QStringLiteral("latitude")))
51 c.setLatitude(value.property(QStringLiteral("latitude")).toNumber());
52 if (value.hasProperty(QStringLiteral("longitude")))
53 c.setLongitude(value.property(QStringLiteral("longitude")).toNumber());
54 if (value.hasProperty(QStringLiteral("altitude")))
55 c.setAltitude(value.property(QStringLiteral("altitude")).toNumber());
56
57 if (ok)
58 *ok = true;
59 }
60
61 return c;
62}
63
64
65/*!
66 \qmltype QtPositioning
67 \instantiates LocationSingleton
68 \inqmlmodule QtPositioning
69 \since 5.2
70
71 \brief The QtPositioning global object provides useful functions for working with location-based
72 types in QML.
73
74 \qml
75 import QtPositioning 5.2
76
77 Item {
78 property variant coordinate: QtPositioning.coordinate(-27.5, 153.1)
79 }
80 \endqml
81*/
82
83LocationSingleton::LocationSingleton(QObject *parent)
84: QObject(parent)
85{
86}
87
88/*!
89 \qmlmethod coordinate ::QtPositioning::coordinate()
90
91 Constructs an invalid coordinate.
92
93*/
94QGeoCoordinate LocationSingleton::coordinate() const
95{
96 return QGeoCoordinate();
97}
98
99/*!
100 \qmlmethod coordinate QtPositioning::coordinate(real latitude, real longitude, real altitude) const
101
102 Constructs a coordinate with the specified \a latitude, \a longitude and optional \a altitude.
103 Both \a latitude and \a longitude must be valid, otherwise an invalid coordinate is returned.
104
105 \sa {coordinate}
106*/
107QGeoCoordinate LocationSingleton::coordinate(double latitude, double longitude, double altitude) const
108{
109 return QGeoCoordinate(latitude, longitude, altitude);
110}
111
112/*!
113 \qmlmethod geoshape QtPositioning::shape() const
114
115 Constructs an invalid geoshape.
116
117 \sa {geoshape}
118*/
119QGeoShape LocationSingleton::shape() const
120{
121 return QGeoShape();
122}
123
124/*!
125 \qmlmethod georectangle QtPositioning::rectangle() const
126
127 Constructs an invalid georectangle.
128
129 \sa {georectangle}
130*/
131QGeoRectangle LocationSingleton::rectangle() const
132{
133 return QGeoRectangle();
134}
135
136/*!
137 \qmlmethod georectangle QtPositioning::rectangle(coordinate center, real width, real height) const
138
139 Constructs a georectangle centered at \a center with a width of \a width degrees and a hight of
140 \a height degrees.
141
142 \sa {georectangle}
143*/
144QGeoRectangle LocationSingleton::rectangle(const QGeoCoordinate &center,
145 double width, double height) const
146{
147 return QGeoRectangle(center, width, height);
148}
149
150/*!
151 \qmlmethod georectangle QtPositioning::rectangle(coordinate topLeft, coordinate bottomRight) const
152
153 Constructs a georectangle with its top left corner positioned at \a topLeft and its bottom
154 right corner positioned at \a {bottomRight}.
155
156 \sa {georectangle}
157*/
158QGeoRectangle LocationSingleton::rectangle(const QGeoCoordinate &topLeft,
159 const QGeoCoordinate &bottomRight) const
160{
161 return QGeoRectangle(topLeft, bottomRight);
162}
163
164/*!
165 \qmlmethod georectangle QtLocation5::QtLocation::rectangle(list<coordinate> coordinates) const
166
167 Constructs a georectangle from the list of coordinates, the returned list is the smallest possible
168 containing all the coordinates.
169
170 \sa {georectangle}
171*/
172QGeoRectangle LocationSingleton::rectangle(const QVariantList &coordinates) const
173{
174 QList<QGeoCoordinate> internalCoordinates;
175 for (int i = 0; i < coordinates.size(); i++) {
176 if (coordinates.at(i).canConvert<QGeoCoordinate>())
177 internalCoordinates << coordinates.at(i).value<QGeoCoordinate>();
178 }
179 return QGeoRectangle(internalCoordinates);
180}
181
182/*!
183 \qmlmethod geocircle QtPositioning::circle() const
184
185 Constructs an invalid geocircle.
186
187 \sa {geocircle}
188*/
189QGeoCircle LocationSingleton::circle() const
190{
191 return QGeoCircle();
192}
193
194/*!
195 \qmlmethod geocircle QtPositioning::circle(coordinate center, real radius) const
196
197 Constructs a geocircle centered at \a center with a radius of \a radius meters.
198*/
199QGeoCircle LocationSingleton::circle(const QGeoCoordinate &center, qreal radius) const
200{
201 return QGeoCircle(center, radius);
202}
203
204/*!
205 \qmlmethod geopath QtPositioning::path() const
206
207 Constructs an empty geopath.
208
209 \sa {geopath}
210 \since 5.9
211*/
212QGeoPath LocationSingleton::path() const
213{
214 return QGeoPath();
215}
216
217/*!
218 \qmlmethod geopath QtPositioning::path(list<coordinate> coordinates, real width) const
219
220 Constructs a geopath from coordinates and width.
221
222 \sa {geopath}
223 \since 5.9
224*/
225QGeoPath LocationSingleton::path(const QJSValue &value, qreal width) const
226{
227 QList<QGeoCoordinate> pathList;
228
229 if (value.isArray()) {
230 quint32 length = value.property(QStringLiteral("length")).toUInt();
231 for (quint32 i = 0; i < length; ++i) {
232 bool ok;
233 QGeoCoordinate c = parseCoordinate(value: value.property(arrayIndex: i), ok: &ok);
234
235 if (!ok || !c.isValid()) {
236 pathList.clear(); // aborting
237 break;
238 }
239
240 pathList.append(t: c);
241 }
242 }
243
244 return QGeoPath(pathList, width);
245}
246
247/*!
248 \qmlmethod geopolygon QtPositioning::polygon() const
249
250 Constructs an empty polygon.
251
252 \sa {geopolygon}
253 \since 5.10
254*/
255QGeoPolygon LocationSingleton::polygon() const
256{
257 return QGeoPolygon();
258}
259
260/*!
261 \qmlmethod geopolygon QtPositioning::polygon(list<coordinate> coordinates) const
262
263 Constructs a polygon from coordinates.
264
265 \sa {geopolygon}
266 \since 5.10
267*/
268QGeoPolygon LocationSingleton::polygon(const QVariantList &coordinates) const
269{
270 QList<QGeoCoordinate> internalCoordinates;
271 for (int i = 0; i < coordinates.size(); i++) {
272 if (coordinates.at(i).canConvert<QGeoCoordinate>())
273 internalCoordinates << coordinates.at(i).value<QGeoCoordinate>();
274 }
275 return QGeoPolygon(internalCoordinates);
276}
277
278/*!
279 \qmlmethod geopolygon QtPositioning::polygon(list<coordinate> perimeter, list<list<coordinate>> holes) const
280
281 Constructs a polygon from coordinates for perimeter and inner holes.
282
283 \sa {geopolygon}
284 \since 5.12
285*/
286QGeoPolygon LocationSingleton::polygon(const QVariantList &perimeter, const QVariantList &holes) const
287{
288 QList<QGeoCoordinate> internalCoordinates;
289 for (int i = 0; i < perimeter.size(); i++) {
290 if (perimeter.at(i).canConvert<QGeoCoordinate>())
291 internalCoordinates << perimeter.at(i).value<QGeoCoordinate>();
292 }
293 QGeoPolygon poly(internalCoordinates);
294
295 for (int i = 0; i < holes.size(); i++) {
296 if (holes.at(i).type() == QVariant::List) {
297 QList<QGeoCoordinate> hole;
298 const QVariantList &holeData = holes.at(i).toList();
299 for (int j = 0; j < holeData.size(); j++) {
300 if (holeData.at(i: j).canConvert<QGeoCoordinate>())
301 hole << holeData.at(i: j).value<QGeoCoordinate>();
302 }
303 if (hole.size())
304 poly.addHole(holePath: hole);
305 }
306 }
307
308 return poly;
309}
310
311/*!
312 \qmlmethod geocircle QtPositioning::shapeToCircle(geoshape shape) const
313
314 Converts \a shape to a geocircle.
315
316 \sa {geocircle}
317 \since 5.5
318*/
319QGeoCircle LocationSingleton::shapeToCircle(const QGeoShape &shape) const
320{
321 return QGeoCircle(shape);
322}
323
324/*!
325 \qmlmethod georectangle QtPositioning::shapeToRectangle(geoshape shape) const
326
327 Converts \a shape to a georectangle.
328
329 \sa {georectangle}
330 \since 5.5
331*/
332QGeoRectangle LocationSingleton::shapeToRectangle(const QGeoShape &shape) const
333{
334 return QGeoRectangle(shape);
335}
336
337/*!
338 \qmlmethod geopath QtPositioning::shapeToPath(geoshape shape) const
339
340 Converts \a shape to a geopath.
341
342 \sa {geopath}
343 \since 5.9
344*/
345QGeoPath LocationSingleton::shapeToPath(const QGeoShape &shape) const
346{
347 return QGeoPath(shape);
348}
349
350/*!
351 \qmlmethod geopolygon QtPositioning::shapeToPolygon(geoshape shape) const
352
353 Converts \a shape to a polygon.
354
355 \sa {geopolygon}
356 \since 5.10
357*/
358QGeoPolygon LocationSingleton::shapeToPolygon(const QGeoShape &shape) const
359{
360 return QGeoPolygon(shape);
361}
362
363/*!
364 \qmlmethod coordinate QtPositioning::mercatorToCoord(point mercator) const
365
366 Converts a \a mercator coordinate into a latitude-longitude coordinate.
367
368 \sa {coordToMercator}
369 \since 5.12
370*/
371QGeoCoordinate LocationSingleton::mercatorToCoord(const QPointF &mercator) const
372{
373 return QWebMercator::mercatorToCoord(mercator: QDoubleVector2D(mercator.x(), mercator.y()));
374}
375
376/*!
377 \qmlmethod point QtPositioning::coordToMercator(coordinate coord) const
378
379 Converts a coordinate \a coord into a mercator coordinate and returns it.
380 \sa {mercatorToCoord}
381 \since 5.12
382*/
383QPointF LocationSingleton::coordToMercator(const QGeoCoordinate &coord) const
384{
385 return QWebMercator::coordToMercator(coord).toPointF();
386}
387

source code of qtlocation/src/imports/positioning/locationsingleton.cpp