diff options
author | Paolo Angelelli <paolo.angelelli@qt.io> | 2019-01-30 20:59:59 +0100 |
---|---|---|
committer | Paolo Angelelli <paolo.angelelli@qt.io> | 2019-03-11 12:10:54 +0000 |
commit | a52dae6a79c1c19ee2391037cfdc6d557381bb88 (patch) | |
tree | 0308df23ee4097132a8dc34a05ea326bb9adda58 | |
parent | b1f6028c2aba51b898ce380f7b584ae603a06382 (diff) | |
download | qtlocation-a52dae6a79c1c19ee2391037cfdc6d557381bb88.tar.gz |
Introduce Qt.labs.location QtLocationLabs singleton type
This singleton is meant to offer tech-preview map-related API.
It starts with a mapObjectsAt invokable, that can be used to probe
MapObjects at a specific coordinate of a map.
Reference implementation for Q*ObjectQSG, based on QGeoShape::contains,
included.
Change-Id: Ief692eb5a43115ca02d4642c82023d1b2e217400
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r-- | src/imports/location/location.cpp | 1 | ||||
-rw-r--r-- | src/imports/locationlabs/locationlabs.cpp | 10 | ||||
-rw-r--r-- | src/imports/locationlabs/locationlabs.pro | 6 | ||||
-rw-r--r-- | src/imports/locationlabs/locationlabssingleton.cpp | 81 | ||||
-rw-r--r-- | src/imports/locationlabs/locationlabssingleton_p.h | 68 | ||||
-rw-r--r-- | src/imports/positioning/locationsingleton.h | 11 | ||||
-rw-r--r-- | src/location/declarativemaps/qgeomapobject_p.h | 4 | ||||
-rw-r--r-- | src/location/labs/qgeotiledmaplabs.cpp | 37 | ||||
-rw-r--r-- | src/location/labs/qgeotiledmaplabs_p.h | 1 | ||||
-rw-r--r-- | src/location/labs/qsg/qgeomapobjectqsgsupport.cpp | 6 | ||||
-rw-r--r-- | src/location/labs/qsg/qmaprouteobjectqsg.cpp | 5 | ||||
-rw-r--r-- | src/location/labs/qsg/qmaprouteobjectqsg_p_p.h | 1 | ||||
-rw-r--r-- | src/location/maps/qgeomap.cpp | 5 | ||||
-rw-r--r-- | src/location/maps/qgeomap_p.h | 1 | ||||
-rw-r--r-- | src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp | 39 | ||||
-rw-r--r-- | src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h | 1 | ||||
-rw-r--r-- | src/positioning/qlocationutils_p.h | 8 |
17 files changed, 281 insertions, 4 deletions
diff --git a/src/imports/location/location.cpp b/src/imports/location/location.cpp index 049d52c0..5d1b6e23 100644 --- a/src/imports/location/location.cpp +++ b/src/imports/location/location.cpp @@ -176,6 +176,7 @@ public: // Register the 5.11 types minor = 11; + qmlRegisterType<QGeoMapObject>(); qmlRegisterType<QDeclarativeGeoManeuver, 11>(uri, major, minor, "RouteManeuver"); qmlRegisterType<QDeclarativeGeoMap, 11>(uri, major, minor, "Map"); qmlRegisterUncreatableType<QDeclarativeGeoMapItemBase, 11>(uri, major, minor, "GeoMapItemBase", diff --git a/src/imports/locationlabs/locationlabs.cpp b/src/imports/locationlabs/locationlabs.cpp index c90993eb..09fba284 100644 --- a/src/imports/locationlabs/locationlabs.cpp +++ b/src/imports/locationlabs/locationlabs.cpp @@ -43,13 +43,20 @@ #include <QtLocation/private/qdeclarativenavigator_p.h> #include <QtLocation/private/qdeclarativenavigator_p_p.h> #include <QtLocation/private/qnavigationmanagerengine_p.h> - #include <QtQml/qqmlextensionplugin.h> #include <QtQml/qqml.h> #include <QtCore/QDebug> +#include "locationlabssingleton_p.h" QT_BEGIN_NAMESPACE +static QObject *singleton_type_factory(QQmlEngine *engine, QJSEngine *jsEngine) +{ + Q_UNUSED(engine); + Q_UNUSED(jsEngine); + + return new LocationLabsSingleton; +} class QtLocationLabsDeclarativeModule: public QQmlExtensionPlugin { @@ -78,6 +85,7 @@ public: qmlRegisterType<QDeclarativeNavigationBasicDirections>(); qmlRegisterType<QDeclarativeNavigator>(uri, major, minor, "Navigator"); qmlRegisterType<QAbstractNavigator>(); + qmlRegisterSingletonType<LocationLabsSingleton>(uri, major, minor, "QtLocationLabs", singleton_type_factory); } else { qDebug() << "Unsupported URI given to load location QML plugin: " << QLatin1String(uri); } diff --git a/src/imports/locationlabs/locationlabs.pro b/src/imports/locationlabs/locationlabs.pro index 2fcc1adc..c55b09b8 100644 --- a/src/imports/locationlabs/locationlabs.pro +++ b/src/imports/locationlabs/locationlabs.pro @@ -5,8 +5,12 @@ CXX_MODULE = $$TARGET TARGETPATH = Qt/labs/location IMPORT_VERSION = 1.0 +HEADERS += \ + locationlabssingleton_p.h + SOURCES += \ - locationlabs.cpp + locationlabs.cpp \ + locationlabssingleton.cpp #CONFIG += no_cxx_module load(qml_plugin) diff --git a/src/imports/locationlabs/locationlabssingleton.cpp b/src/imports/locationlabs/locationlabssingleton.cpp new file mode 100644 index 00000000..c053da9e --- /dev/null +++ b/src/imports/locationlabs/locationlabssingleton.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtPositioning module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "locationlabssingleton_p.h" + +/*! + \qmltype QtLocationLabs + \instantiates LocationLabsSingleton + \inqmlmodule Qt.labs.location + \since 5.13 + + \brief The QtLocationLabs global object provides experimental, tech-preview functions for working with + location-based types in QML. + + \qml + import Qt.labs.location 1.0 + + Map { + id: map + MouseArea { + anchors.fill: parent + onClicked: { + var mapObjects = QtLocationLabs.mapObjectsAt(map.toCoordinate(Qt.point(mouseX,mouseY)), map) + } + } + } + \endqml +*/ + +LocationLabsSingleton::LocationLabsSingleton(QObject *parent) +: QObject(parent) +{ +} + +/*! + \qmlmethod coordinate ::QtLocationLabs::mapObjectsAt(coordinate, map) + + Returns the map objects in \a map covering \a coordinate. +*/ +QList<QObject *> LocationLabsSingleton::mapObjectsAt(const QGeoCoordinate &coordinate, QDeclarativeGeoMap *map) const +{ + if (!map) + return QList<QObject *>(); + return map->map()->mapObjectsAt(coordinate); +} diff --git a/src/imports/locationlabs/locationlabssingleton_p.h b/src/imports/locationlabs/locationlabssingleton_p.h new file mode 100644 index 00000000..42f4a21c --- /dev/null +++ b/src/imports/locationlabs/locationlabssingleton_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtPositioning module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef LOCATIONLABSSINGLETON_P_H +#define LOCATIONLABSSINGLETON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QObject> +#include <QtPositioning/QGeoCoordinate> +#include <QtLocation/private/qdeclarativegeomap_p.h> + +class LocationLabsSingleton : public QObject +{ + Q_OBJECT + +public: + explicit LocationLabsSingleton(QObject *parent = 0); + + Q_INVOKABLE QList<QObject *> mapObjectsAt(const QGeoCoordinate &coordinate, QDeclarativeGeoMap *map) const; +}; + +#endif // LOCATIONLABSSINGLETON_P_H diff --git a/src/imports/positioning/locationsingleton.h b/src/imports/positioning/locationsingleton.h index 9372b8f1..16d838e6 100644 --- a/src/imports/positioning/locationsingleton.h +++ b/src/imports/positioning/locationsingleton.h @@ -40,6 +40,17 @@ #ifndef LOCATIONSINGLETON_H #define LOCATIONSINGLETON_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include <QtCore/QObject> #include <QtCore/qnumeric.h> #include <QtPositioning/QGeoCoordinate> diff --git a/src/location/declarativemaps/qgeomapobject_p.h b/src/location/declarativemaps/qgeomapobject_p.h index bc63e0a6..000d8320 100644 --- a/src/location/declarativemaps/qgeomapobject_p.h +++ b/src/location/declarativemaps/qgeomapobject_p.h @@ -51,6 +51,7 @@ #include <QtLocation/private/qparameterizableobject_p.h> #include <QExplicitlySharedDataPointer> #include <QtPositioning/qgeoshape.h> +#include <qqml.h> QT_BEGIN_NAMESPACE @@ -133,6 +134,9 @@ protected: friend class QGeoMapLayer; friend class QDeclarativeNavigator; }; + QT_END_NAMESPACE +QML_DECLARE_TYPE(QGeoMapObject) + #endif // QGEOMAPOBJECTBASE_H diff --git a/src/location/labs/qgeotiledmaplabs.cpp b/src/location/labs/qgeotiledmaplabs.cpp index 22d582c0..7d8d7108 100644 --- a/src/location/labs/qgeotiledmaplabs.cpp +++ b/src/location/labs/qgeotiledmaplabs.cpp @@ -44,6 +44,8 @@ #include <QtLocation/private/qmapiconobjectqsg_p_p.h> #include <QtLocation/private/qdeclarativepolylinemapitem_p.h> #include <QtLocation/private/qgeomapobjectqsgsupport_p.h> +#include <QtPositioning/private/qlocationutils_p.h> +#include <math.h> QT_BEGIN_NAMESPACE @@ -57,6 +59,7 @@ public: QGeoMapObjectPrivate *createMapObjectImplementation(QGeoMapObject *obj) override; virtual QList<QGeoMapObject *> mapObjects() const override; void removeMapObject(QGeoMapObject *obj); + QList<QObject *>mapObjectsAt(const QGeoCoordinate &coordinate) const; void updateMapObjects(QSGNode *root, QQuickWindow *window); void updateObjectsGeometry(); @@ -95,6 +98,34 @@ void QGeoTiledMapLabsPrivate::removeMapObject(QGeoMapObject *obj) m_qsgSupport.removeMapObject(obj); } +QList<QObject *> QGeoTiledMapLabsPrivate::mapObjectsAt(const QGeoCoordinate &coordinate) const +{ + // ToDo: use a space partitioning strategy + QList<QObject *> res; + for (const auto o: mapObjects()) { + // explicitly handle lines + bool contains = false; + if (o->type() == QGeoMapObject::PolylineType ) { + QMapPolylineObject *mpo = static_cast<QMapPolylineObject *>(o); + qreal mpp = QLocationUtils::metersPerPixel(m_cameraData.zoomLevel(), coordinate); + QGeoPath path = o->geoShape(); + path.setWidth(mpp * mpo->border()->width()); + contains = path.contains(coordinate); + } else if (o->type() == QGeoMapObject::RouteType) { + qreal mpp = QLocationUtils::metersPerPixel(m_cameraData.zoomLevel(), coordinate); + QGeoPath path = o->geoShape(); + path.setWidth(mpp * 4); // MapRouteObjectQSG has a hardcoded 4 pixels width; + contains = path.contains(coordinate); + } else { + contains = o->geoShape().contains(coordinate); + } + + if (contains) + res.append(o); + } + return res; +} + void QGeoTiledMapLabsPrivate::updateMapObjects(QSGNode *root, QQuickWindow *window) { m_qsgSupport.updateMapObjects(root, window); @@ -161,6 +192,12 @@ void QGeoTiledMapLabs::removeMapObject(QGeoMapObject *obj) d->removeMapObject(obj); } +QList<QObject *> QGeoTiledMapLabs::mapObjectsAt(const QGeoCoordinate &coordinate) const +{ + Q_D(const QGeoTiledMapLabs); + return d->mapObjectsAt(coordinate); +} + QGeoTiledMapLabs::QGeoTiledMapLabs(QGeoTiledMapLabsPrivate &dd, QGeoTiledMappingManagerEngine *engine, QObject *parent) : QGeoTiledMap(dd, engine, parent) { diff --git a/src/location/labs/qgeotiledmaplabs_p.h b/src/location/labs/qgeotiledmaplabs_p.h index 4f179028..d10ec633 100644 --- a/src/location/labs/qgeotiledmaplabs_p.h +++ b/src/location/labs/qgeotiledmaplabs_p.h @@ -72,6 +72,7 @@ public: bool createMapObjectImplementation(QGeoMapObject *obj) override; void removeMapObject(QGeoMapObject *obj) override; + QList<QObject *> mapObjectsAt(const QGeoCoordinate &coordinate) const override; protected: QSGNode *updateSceneGraph(QSGNode *node, QQuickWindow *window) override; diff --git a/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp b/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp index e0e3a6d7..1a1b102b 100644 --- a/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp +++ b/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp @@ -126,7 +126,11 @@ QGeoMapObjectPrivate *QGeoMapObjectQSGSupport::createMapObjectImplementationPriv QList<QGeoMapObject *> QGeoMapObjectQSGSupport::mapObjects() const { - return QList<QGeoMapObject *>(); + QList<QGeoMapObject *> res; + for (int i = 0; i < m_mapObjects.size(); ++i) { + res.append(m_mapObjects.at(i).object.data()); + } + return res; } void QGeoMapObjectQSGSupport::removeMapObject(QGeoMapObject *obj) diff --git a/src/location/labs/qsg/qmaprouteobjectqsg.cpp b/src/location/labs/qsg/qmaprouteobjectqsg.cpp index eaea64f3..8f347f88 100644 --- a/src/location/labs/qsg/qmaprouteobjectqsg.cpp +++ b/src/location/labs/qsg/qmaprouteobjectqsg.cpp @@ -100,4 +100,9 @@ void QMapRouteObjectPrivateQSG::setVisible(bool visible) m_polyline->setVisible(visible); } +QGeoShape QMapRouteObjectPrivateQSG::geoShape() const +{ + return m_polyline->geoShape(); +} + QT_END_NAMESPACE diff --git a/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h b/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h index 0c946259..2ade5d53 100644 --- a/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h +++ b/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h @@ -80,6 +80,7 @@ public: QGeoMapObjectPrivate *clone() override; void setMap(QGeoMap *map) override; void setVisible(bool visible) override; + virtual QGeoShape geoShape() const override; // Data Members QScopedPointer<QMapPolylineObjectPrivateQSG> m_polyline; diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp index 80edac1a..dc8aa2c8 100644 --- a/src/location/maps/qgeomap.cpp +++ b/src/location/maps/qgeomap.cpp @@ -305,6 +305,11 @@ void QGeoMap::removeMapObject(QGeoMapObject * /*obj*/) { } +QList<QObject *> QGeoMap::mapObjectsAt(const QGeoCoordinate &/*coordinate*/) const +{ + return QList<QObject *>(); +} + void QGeoMap::setVisibleArea(const QRectF &visibleArea) { Q_D(QGeoMap); diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h index c0af9e10..216c8b64 100644 --- a/src/location/maps/qgeomap_p.h +++ b/src/location/maps/qgeomap_p.h @@ -154,6 +154,7 @@ public: virtual void setCopyrightVisible(bool visible); virtual void removeMapObject(QGeoMapObject *obj); + virtual QList<QObject *> mapObjectsAt(const QGeoCoordinate &coordinate) const; void setVisibleArea(const QRectF &visibleArea); QRectF visibleArea() const; diff --git a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp index f6520484..1ebad08d 100644 --- a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp +++ b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp @@ -65,6 +65,7 @@ public: virtual QList<QGeoMapObject *> mapObjects() const override; void removeMapObject(QGeoMapObject *obj); void updateMapObjects(QSGNode *root, QQuickWindow *window); + QList<QObject *>mapObjectsAt(const QGeoCoordinate &coordinate) const; QGeoMapObjectQSGSupport m_qsgSupport; #endif @@ -137,6 +138,16 @@ void QGeoMapItemsOverlay::removeMapObject(QGeoMapObject *obj) #endif } +QList<QObject *> QGeoMapItemsOverlay::mapObjectsAt(const QGeoCoordinate &coordinate) const +{ +#ifdef LOCATIONLABS + Q_D(const QGeoMapItemsOverlay); + return d->mapObjectsAt(coordinate); +#else + return QGeoMap::mapObjectsAt(coordinate); +#endif +} + void QGeoMapItemsOverlayPrivate::setVisibleArea(const QRectF &visibleArea) { Q_Q(QGeoMapItemsOverlay); @@ -185,6 +196,34 @@ void QGeoMapItemsOverlayPrivate::updateMapObjects(QSGNode *root, QQuickWindow *w { m_qsgSupport.updateMapObjects(root, window); } + +QList<QObject *> QGeoMapItemsOverlayPrivate::mapObjectsAt(const QGeoCoordinate &coordinate) const +{ + // ToDo: use a space partitioning strategy + QList<QObject *> res; + for (const auto o: mapObjects()) { + // explicitly handle lines + bool contains = false; + if (o->type() == QGeoMapObject::PolylineType ) { + QMapPolylineObject *mpo = static_cast<QMapPolylineObject *>(o); + qreal mpp = QLocationUtils::metersPerPixel(m_cameraData.zoomLevel(), coordinate); + QGeoPath path = o->geoShape(); + path.setWidth(mpp * mpo->border()->width()); + contains = path.contains(coordinate); + } else if (o->type() == QGeoMapObject::RouteType) { + qreal mpp = QLocationUtils::metersPerPixel(m_cameraData.zoomLevel(), coordinate); + QGeoPath path = o->geoShape(); + path.setWidth(mpp * 4); // MapRouteObjectQSG has a hardcoded 4 pixels width; + contains = path.contains(coordinate); + } else { + contains = o->geoShape().contains(coordinate); + } + + if (contains) + res.append(o); + } + return res; +} #endif void QGeoMapItemsOverlayPrivate::updateObjectsGeometry() diff --git a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h index 1594ffb3..c287345c 100644 --- a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h +++ b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h @@ -56,6 +56,7 @@ public: QGeoMap::Capabilities capabilities() const override; bool createMapObjectImplementation(QGeoMapObject *obj) override; void removeMapObject(QGeoMapObject *obj) override; + QList<QObject *> mapObjectsAt(const QGeoCoordinate &coordinate) const override; protected: QSGNode *updateSceneGraph(QSGNode *node, QQuickWindow *window) override; diff --git a/src/positioning/qlocationutils_p.h b/src/positioning/qlocationutils_p.h index d9e6524a..e3881f6f 100644 --- a/src/positioning/qlocationutils_p.h +++ b/src/positioning/qlocationutils_p.h @@ -229,7 +229,7 @@ public: return 6371007.2; } - inline static double earthMeanDiameter() + inline static double earthMeanCircumference() { return earthMeanRadius() * 2.0 * M_PI; } @@ -256,6 +256,12 @@ public: return wrapLong(centerLongitude - leftOffset); } + static qreal metersPerPixel(qreal zoomLevel, const QGeoCoordinate &coordinate) + { + const qreal metersPerTile = earthMeanCircumference() * std::cos(radians(coordinate.latitude())) / std::pow(2, zoomLevel); + return metersPerTile / 256.0; + } + /* returns the NMEA sentence type. */ |