summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--examples/location/mapviewer/main.cpp18
-rw-r--r--examples/location/places/main.cpp18
-rw-r--r--src/imports/location/location.cpp6
-rw-r--r--src/imports/location/location.pro6
-rw-r--r--src/imports/location/qdeclarativecirclemapitem.cpp9
-rw-r--r--src/imports/location/qdeclarativegeomap.cpp139
-rw-r--r--src/imports/location/qdeclarativegeomap_p.h12
-rw-r--r--src/imports/location/qdeclarativegeomapitemview_p_p.h4
-rw-r--r--src/imports/location/qdeclarativegeomapparameter.cpp125
-rw-r--r--src/imports/location/qdeclarativegeomapparameter_p.h89
-rw-r--r--src/imports/location/qdeclarativegeoroutemodel.cpp46
-rw-r--r--src/imports/location/qdeclarativegeoroutemodel_p.h3
-rw-r--r--src/imports/location/qdeclarativepolygonmapitem.cpp6
-rw-r--r--src/imports/location/qquickgeomapgesturearea.cpp1
-rw-r--r--src/imports/positioning/locationsingleton.cpp26
-rw-r--r--src/imports/positioning/locationsingleton.h4
-rw-r--r--src/imports/positioning/positioning.cpp3
-rw-r--r--src/location/maps/maps.pri4
-rw-r--r--src/location/maps/qgeocodereply.cpp1
-rw-r--r--src/location/maps/qgeocodereply.h1
-rw-r--r--src/location/maps/qgeomap.cpp36
-rw-r--r--src/location/maps/qgeomap_p.h6
-rw-r--r--src/location/maps/qgeomap_p_p.h7
-rw-r--r--src/location/maps/qgeomapparameter.cpp74
-rw-r--r--src/location/maps/qgeomapparameter_p.h84
-rw-r--r--src/location/maps/qgeoroutereply.cpp3
-rw-r--r--src/location/maps/qgeoroutereply.h1
-rw-r--r--src/location/maps/qgeotiledmap.cpp11
-rw-r--r--src/location/maps/qgeotiledmap_p.h12
-rw-r--r--src/location/maps/qgeotiledmap_p_p.h13
-rw-r--r--src/location/maps/qgeotiledmapreply.cpp1
-rw-r--r--src/location/maps/qgeotiledmapreply_p.h1
-rw-r--r--src/location/places/qplacereply.cpp1
-rw-r--r--src/location/places/qplacereply.h1
-rw-r--r--src/plugins/geoservices/esri/geocodereply_esri.cpp53
-rw-r--r--src/plugins/geoservices/esri/geocodereply_esri.h5
-rw-r--r--src/plugins/geoservices/esri/georoutereply_esri.cpp50
-rw-r--r--src/plugins/geoservices/esri/georoutereply_esri.h7
-rw-r--r--src/plugins/geoservices/esri/geotiledmapreply_esri.cpp62
-rw-r--r--src/plugins/geoservices/esri/geotiledmapreply_esri.h8
-rw-r--r--src/plugins/geoservices/mapbox/qgeomapreplymapbox.cpp55
-rw-r--r--src/plugins/geoservices/mapbox/qgeomapreplymapbox.h5
-rw-r--r--src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp53
-rw-r--r--src/plugins/geoservices/mapbox/qgeoroutereplymapbox.h5
-rw-r--r--src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp17
-rw-r--r--src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.cpp82
-rw-r--r--src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.h3
-rw-r--r--src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.cpp60
-rw-r--r--src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.h3
-rw-r--r--src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.cpp62
-rw-r--r--src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.h4
-rw-r--r--src/plugins/geoservices/nokia/placesv2/qplacesearchsuggestionreplyimpl.cpp48
-rw-r--r--src/plugins/geoservices/nokia/placesv2/qplacesearchsuggestionreplyimpl.h6
-rw-r--r--src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp51
-rw-r--r--src/plugins/geoservices/nokia/qgeocodereply_nokia.h3
-rw-r--r--src/plugins/geoservices/nokia/qgeomapreply_nokia.cpp51
-rw-r--r--src/plugins/geoservices/nokia/qgeomapreply_nokia.h7
-rw-r--r--src/plugins/geoservices/nokia/qgeoroutereply_nokia.cpp70
-rw-r--r--src/plugins/geoservices/nokia/qgeoroutereply_nokia.h3
-rw-r--r--src/plugins/geoservices/osm/qgeocodereplyosm.cpp48
-rw-r--r--src/plugins/geoservices/osm/qgeocodereplyosm.h5
-rw-r--r--src/plugins/geoservices/osm/qgeomapreplyosm.cpp57
-rw-r--r--src/plugins/geoservices/osm/qgeomapreplyosm.h11
-rw-r--r--src/plugins/geoservices/osm/qgeoroutereplyosm.cpp51
-rw-r--r--src/plugins/geoservices/osm/qgeoroutereplyosm.h5
-rw-r--r--src/plugins/geoservices/osm/qplacemanagerengineosm.cpp3
-rw-r--r--src/plugins/geoservices/osm/qplacesearchreplyosm.cpp41
-rw-r--r--src/plugins/geoservices/osm/qplacesearchreplyosm.h6
-rw-r--r--src/plugins/position/corelocation/corelocation.pro4
-rw-r--r--src/positioning/positioning.pro9
-rw-r--r--src/positioning/qgeocircle.cpp132
-rw-r--r--src/positioning/qgeocircle.h4
-rw-r--r--src/positioning/qgeocircle_p.h11
-rw-r--r--src/positioning/qgeocoordinate.cpp8
-rw-r--r--src/positioning/qgeopath.cpp679
-rw-r--r--src/positioning/qgeopath.h102
-rw-r--r--src/positioning/qgeopath_p.h111
-rw-r--r--src/positioning/qgeorectangle.cpp78
-rw-r--r--src/positioning/qgeorectangle.h86
-rw-r--r--src/positioning/qgeorectangle_p.h2
-rw-r--r--src/positioning/qgeoshape.cpp40
-rw-r--r--src/positioning/qgeoshape.h92
-rw-r--r--src/positioning/qgeoshape_p.h3
-rw-r--r--src/positioning/qlocationutils_p.h49
-rw-r--r--tests/auto/auto.pro1
-rw-r--r--tests/auto/declarative_ui/tst_map.qml53
-rw-r--r--tests/auto/geotestplugin/geotestplugin.pro3
-rw-r--r--tests/auto/geotestplugin/qgeocodingmanagerengine_test.h5
-rw-r--r--tests/auto/geotestplugin/qgeoroutingmanagerengine_test.h6
-rw-r--r--tests/auto/geotestplugin/qgeotiledmap_test.cpp88
-rw-r--r--tests/auto/geotestplugin/qgeotiledmap_test.h14
-rw-r--r--tests/auto/geotestplugin/qgeotiledmappingmanagerengine_test.h3
-rw-r--r--tests/auto/qgeocameracapabilities/tst_qgeocameracapabilities.cpp4
-rw-r--r--tests/auto/qgeocircle/tst_qgeocircle.cpp40
-rw-r--r--tests/auto/qgeopath/qgeopath.pro8
-rw-r--r--tests/auto/qgeopath/tst_qgeopath.cpp385
-rw-r--r--tests/auto/qgeorectangle/tst_qgeorectangle.cpp33
-rw-r--r--tests/auto/qgeoroutereply/tst_qgeoroutereply.cpp2
99 files changed, 2912 insertions, 917 deletions
diff --git a/.qmake.conf b/.qmake.conf
index aefa1e70..b1c22d3b 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,3 +1,3 @@
load(qt_build_config)
-MODULE_VERSION = 5.8.0
+MODULE_VERSION = 5.9.0
diff --git a/examples/location/mapviewer/main.cpp b/examples/location/mapviewer/main.cpp
index 1b526435..a58dcd44 100644
--- a/examples/location/mapviewer/main.cpp
+++ b/examples/location/mapviewer/main.cpp
@@ -89,6 +89,24 @@ int main(int argc, char *argv[])
QVariantMap parameters;
QStringList args(QCoreApplication::arguments());
+ // Fetch tokens from the environment, if present
+ const QByteArray mapboxMapID = qgetenv("MAPBOX_MAP_ID");
+ const QByteArray mapboxAccessToken = qgetenv("MAPBOX_ACCESS_TOKEN");
+ const QByteArray hereAppID = qgetenv("HERE_APP_ID");
+ const QByteArray hereToken = qgetenv("HERE_TOKEN");
+ const QByteArray esriToken = qgetenv("ESRI_TOKEN");
+
+ if (!mapboxMapID.isEmpty())
+ parameters["mapbox.map_id"] = QString::fromLocal8Bit(mapboxMapID);
+ if (!mapboxAccessToken.isEmpty())
+ parameters["mapbox.access_token"] = QString::fromLocal8Bit(mapboxAccessToken);
+ if (!hereAppID.isEmpty())
+ parameters["here.app_id"] = QString::fromLocal8Bit(hereAppID);
+ if (!hereToken.isEmpty())
+ parameters["here.token"] = QString::fromLocal8Bit(hereToken);
+ if (!esriToken.isEmpty())
+ parameters["esri.token"] = QString::fromLocal8Bit(esriToken);
+
if (parseArgs(args, parameters))
return 0;
if (!args.contains(QStringLiteral("osm.useragent")))
diff --git a/examples/location/places/main.cpp b/examples/location/places/main.cpp
index 8c3b64ed..a30fb857 100644
--- a/examples/location/places/main.cpp
+++ b/examples/location/places/main.cpp
@@ -90,6 +90,24 @@ int main(int argc, char *argv[])
QVariantMap parameters;
QStringList args(QCoreApplication::arguments());
+ // Fetch tokens from the environment, if present
+ const QByteArray mapboxMapID = qgetenv("MAPBOX_MAP_ID");
+ const QByteArray mapboxAccessToken = qgetenv("MAPBOX_ACCESS_TOKEN");
+ const QByteArray hereAppID = qgetenv("HERE_APP_ID");
+ const QByteArray hereToken = qgetenv("HERE_TOKEN");
+ const QByteArray esriToken = qgetenv("ESRI_TOKEN");
+
+ if (!mapboxMapID.isEmpty())
+ parameters["mapbox.map_id"] = QString::fromLocal8Bit(mapboxMapID);
+ if (!mapboxAccessToken.isEmpty())
+ parameters["mapbox.access_token"] = QString::fromLocal8Bit(mapboxAccessToken);
+ if (!hereAppID.isEmpty())
+ parameters["here.app_id"] = QString::fromLocal8Bit(hereAppID);
+ if (!hereToken.isEmpty())
+ parameters["here.token"] = QString::fromLocal8Bit(hereToken);
+ if (!esriToken.isEmpty())
+ parameters["esri.token"] = QString::fromLocal8Bit(esriToken);
+
if (parseArgs(args, parameters))
return 0;
diff --git a/src/imports/location/location.cpp b/src/imports/location/location.cpp
index 6405313b..f9b3545f 100644
--- a/src/imports/location/location.cpp
+++ b/src/imports/location/location.cpp
@@ -49,6 +49,7 @@
#include "qdeclarativeroutemapitem_p.h"
#include "qdeclarativepolylinemapitem_p.h"
#include "qdeclarativepolygonmapitem_p.h"
+#include "qdeclarativegeomapparameter_p.h"
//Place includes
#include "qdeclarativecategory_p.h"
@@ -166,6 +167,11 @@ public:
minor = 7;
qmlRegisterType<QDeclarativeGeoManeuver>(uri, major, minor, "RouteManeuver");
+ // Register the 5.9 types
+ minor = 9;
+ qmlRegisterType<QDeclarativeGeoMapParameter>(uri, major, minor, "MapParameter");
+
+
//registrations below are version independent
qRegisterMetaType<QPlaceCategory>();
qRegisterMetaType<QPlace>();
diff --git a/src/imports/location/location.pro b/src/imports/location/location.pro
index 57172ad8..e733a768 100644
--- a/src/imports/location/location.pro
+++ b/src/imports/location/location.pro
@@ -30,7 +30,8 @@ HEADERS += \
qquickgeomapgesturearea_p.h\
../positioning/qquickgeocoordinateanimation_p.h \
mapitemviewdelegateincubator.h \
- qdeclarativegeomapitemview_p_p.h
+ qdeclarativegeomapitemview_p_p.h \
+ qdeclarativegeomapparameter_p.h
SOURCES += \
location.cpp \
@@ -56,7 +57,8 @@ SOURCES += \
locationvaluetypehelper.cpp \
qquickgeomapgesturearea.cpp \
../positioning/qquickgeocoordinateanimation.cpp \
- mapitemviewdelegateincubator.cpp
+ mapitemviewdelegateincubator.cpp \
+ qdeclarativegeomapparameter.cpp
include(declarativeplaces/declarativeplaces.pri)
diff --git a/src/imports/location/qdeclarativecirclemapitem.cpp b/src/imports/location/qdeclarativecirclemapitem.cpp
index 6890703b..c440664c 100644
--- a/src/imports/location/qdeclarativecirclemapitem.cpp
+++ b/src/imports/location/qdeclarativecirclemapitem.cpp
@@ -46,6 +46,7 @@
#include <QPainter>
#include "qdoublevector2d_p.h"
+#include "qlocationutils_p.h"
/* poly2tri triangulator includes */
#include "../../3rdparty/poly2tri/common/shapes.h"
@@ -294,12 +295,8 @@ static void calculatePeripheralPoints(QList<QGeoCoordinate> &path,
qreal resultLonRad = lonRad + std::atan2(std::sin(azimuthRad) * cosLatRad_x_sinRatio,
cosRatio - sinLatRad * std::sin(resultLatRad));
qreal lat2 = qgeocoordinate_radToDeg(resultLatRad);
- qreal lon2 = qgeocoordinate_radToDeg(resultLonRad);
- if (lon2 < -180.0) {
- lon2 += 360.0;
- } else if (lon2 > 180.0) {
- lon2 -= 360.0;
- }
+ qreal lon2 = QLocationUtils::wrapLong(qgeocoordinate_radToDeg(resultLonRad));
+
path << QGeoCoordinate(lat2, lon2, center.altitude());
// Consider only points in the left half of the circle for the left bound.
if (azimuthRad > M_PI) {
diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp
index 0450bf56..d432e776 100644
--- a/src/imports/location/qdeclarativegeomap.cpp
+++ b/src/imports/location/qdeclarativegeomap.cpp
@@ -42,6 +42,7 @@
#include "qgeomappingmanager_p.h"
#include "qgeocameracapabilities_p.h"
#include "qgeomap_p.h"
+#include "qdeclarativegeomapparameter_p.h"
#include <QtPositioning/QGeoCircle>
#include <QtPositioning/QGeoRectangle>
#include <QtQuick/QQuickWindow>
@@ -158,7 +159,6 @@ static const qreal EARTH_MEAN_RADIUS = 6371007.2;
QDeclarativeGeoMap::QDeclarativeGeoMap(QQuickItem *parent)
: QQuickItem(parent),
m_plugin(0),
- m_serviceProvider(0),
m_mappingManager(0),
m_activeMapType(0),
m_gestureArea(new QQuickGeoMapGestureArea(this)),
@@ -331,11 +331,11 @@ void QDeclarativeGeoMap::initialize()
*/
void QDeclarativeGeoMap::pluginReady()
{
- m_serviceProvider = m_plugin->sharedGeoServiceProvider();
- m_mappingManager = m_serviceProvider->mappingManager();
+ QGeoServiceProvider *provider = m_plugin->sharedGeoServiceProvider();
+ m_mappingManager = provider->mappingManager();
- if (m_serviceProvider->error() != QGeoServiceProvider::NoError) {
- setError(m_serviceProvider->error(), m_serviceProvider->errorString());
+ if (provider->error() != QGeoServiceProvider::NoError) {
+ setError(provider->error(), provider->errorString());
return;
}
@@ -360,6 +360,7 @@ void QDeclarativeGeoMap::pluginReady()
void QDeclarativeGeoMap::componentComplete()
{
m_componentCompleted = true;
+ populateParameters();
populateMap();
QQuickItem::componentComplete();
}
@@ -455,6 +456,19 @@ void QDeclarativeGeoMap::populateMap()
}
}
+void QDeclarativeGeoMap::populateParameters()
+{
+ QObjectList kids = children();
+ QList<QQuickItem *> quickKids = childItems();
+ for (int i = 0; i < quickKids.count(); ++i)
+ kids.append(quickKids.at(i));
+ for (int i = 0; i < kids.size(); ++i) {
+ QDeclarativeGeoMapParameter *mapParameter = qobject_cast<QDeclarativeGeoMapParameter *>(kids.at(i));
+ if (mapParameter)
+ addMapParameter(mapParameter);
+ }
+}
+
/*!
\internal
*/
@@ -590,6 +604,11 @@ void QDeclarativeGeoMap::mappingManagerInitialized()
if (item)
item.data()->setMap(this, m_map);
}
+
+ // All map parameters that were added before the plugin was ready
+ // need to be added to m_map
+ for (QDeclarativeGeoMapParameter *p : m_mapParameters)
+ m_map->addParameter(p);
}
/*!
@@ -803,7 +822,7 @@ void QDeclarativeGeoMap::setVisibleRegion(const QGeoShape &shape)
return;
}
- if (!width() || !height()) {
+ if (!m_map || !width() || !height()) {
m_pendingFitViewport = true;
return;
}
@@ -1210,6 +1229,95 @@ void QDeclarativeGeoMap::addMapItem(QDeclarativeGeoMapItemBase *item)
}
/*!
+ \qmlmethod void QtLocation::Map::addMapParameter(MapParameter parameter)
+
+ Adds a MapParameter object to the map. The effect of this call is dependent
+ on the combination of the content of the MapParameter and the type of
+ underlying QGeoMap. If a MapParameter that is not supported by the underlying
+ QGeoMap gets added, the call has no effect.
+
+ The release of this API with Qt 5.9 is a Technology Preview.
+
+ \sa MapParameter, removeMapParameter, mapParameters, clearMapParameters
+
+ \since 5.9
+*/
+void QDeclarativeGeoMap::addMapParameter(QDeclarativeGeoMapParameter *parameter)
+{
+ if (!parameter->isComponentComplete()) {
+ connect(parameter, &QDeclarativeGeoMapParameter::completed, this, &QDeclarativeGeoMap::addMapParameter);
+ return;
+ }
+
+ disconnect(parameter);
+ if (m_mapParameters.contains(parameter))
+ return;
+ parameter->setParent(this);
+ m_mapParameters.insert(parameter); // parameter now owned by QDeclarativeGeoMap
+ if (m_map)
+ m_map->addParameter(parameter);
+}
+
+/*!
+ \qmlmethod void QtLocation::Map::removeMapParameter(MapParameter parameter)
+
+ Removes the given MapParameter object from the map.
+
+ The release of this API with Qt 5.9 is a Technology Preview.
+
+ \sa MapParameter, addMapParameter, mapParameters, clearMapParameters
+
+ \since 5.9
+*/
+void QDeclarativeGeoMap::removeMapParameter(QDeclarativeGeoMapParameter *parameter)
+{
+ if (!m_mapParameters.contains(parameter))
+ return;
+ if (m_map)
+ m_map->removeParameter(parameter);
+ m_mapParameters.remove(parameter);
+}
+
+/*!
+ \qmlmethod void QtLocation::Map::clearMapParameters()
+
+ Removes all map parameters from the map.
+
+ The release of this API with Qt 5.9 is a Technology Preview.
+
+ \sa MapParameter, mapParameters, addMapParameter, removeMapParameter, clearMapParameters
+
+ \since 5.9
+*/
+void QDeclarativeGeoMap::clearMapParameters()
+{
+ if (m_map)
+ m_map->clearParameters();
+ m_mapParameters.clear();
+}
+
+/*!
+ \qmlproperty list<MapParameters> QtLocation::Map::mapParameters
+
+ Returns the list of all map parameters in no particular order.
+ These items include map parameters that were declared statically as part of
+ the type declaration, as well as dynamical map parameters (\l addMapParameter).
+
+ The release of this API with Qt 5.9 is a Technology Preview.
+
+ \sa MapParameter, addMapParameter, removeMapParameter, clearMapParameters
+
+ \since 5.9
+*/
+QList<QObject *> QDeclarativeGeoMap::mapParameters()
+{
+ QList<QObject *> ret;
+ for (QDeclarativeGeoMapParameter *p : m_mapParameters)
+ ret << p;
+ return ret;
+}
+
+/*!
\qmlproperty list<MapItem> QtLocation::Map::mapItems
Returns the list of all map items in no particular order.
@@ -1312,11 +1420,26 @@ void QDeclarativeGeoMap::geometryChanged(const QRectF &newGeometry, const QRectF
m_map->setViewportSize(newGeometry.size().toSize());
- if (!m_initialized)
+ if (!m_initialized) {
initialize();
- else
+ } else {
setMinimumZoomLevel(m_map->minimumZoomAtViewportSize(newGeometry.width(), newGeometry.height()));
+ // Update the center latitudinal threshold
+ double maximumCenterLatitudeAtZoom = m_map->maximumCenterLatitudeAtZoom(m_cameraData.zoomLevel());
+ if (maximumCenterLatitudeAtZoom != m_maximumViewportLatitude) {
+ m_maximumViewportLatitude = maximumCenterLatitudeAtZoom;
+ QGeoCoordinate coord = m_cameraData.center();
+ coord.setLatitude(qBound(-m_maximumViewportLatitude, coord.latitude(), m_maximumViewportLatitude));
+
+ if (coord != m_cameraData.center()) {
+ m_cameraData.setCenter(coord);
+ m_map->setCameraData(m_cameraData);
+ emit centerChanged(m_cameraData.center());
+ }
+ }
+ }
+
/*!
The fitViewportTo*() functions depend on a valid map geometry.
If they were called prior to the first resize they cause
diff --git a/src/imports/location/qdeclarativegeomap_p.h b/src/imports/location/qdeclarativegeomap_p.h
index 262314ed..e0940f97 100644
--- a/src/imports/location/qdeclarativegeomap_p.h
+++ b/src/imports/location/qdeclarativegeomap_p.h
@@ -54,6 +54,7 @@
#include "qgeocameradata_p.h"
#include <QtQuick/QQuickItem>
#include <QtCore/QPointer>
+#include <QtCore/QSet>
#include <QtGui/QColor>
#include <QtPositioning/qgeoshape.h>
@@ -62,6 +63,7 @@ QT_BEGIN_NAMESPACE
class QDeclarativeGeoServiceProvider;
class QDeclarativeGeoMapType;
class QDeclarativeGeoMapCopyrightNotice;
+class QDeclarativeGeoMapParameter;
class QDeclarativeGeoMap : public QQuickItem
{
@@ -76,6 +78,7 @@ class QDeclarativeGeoMap : public QQuickItem
Q_PROPERTY(QQmlListProperty<QDeclarativeGeoMapType> supportedMapTypes READ supportedMapTypes NOTIFY supportedMapTypesChanged)
Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged)
Q_PROPERTY(QList<QObject *> mapItems READ mapItems NOTIFY mapItemsChanged)
+ Q_PROPERTY(QList<QObject *> mapParameters READ mapParameters)
Q_PROPERTY(QGeoServiceProvider::Error error READ error NOTIFY errorChanged)
Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged)
Q_PROPERTY(QGeoShape visibleRegion READ visibleRegion WRITE setVisibleRegion)
@@ -119,9 +122,15 @@ public:
Q_INVOKABLE void removeMapItem(QDeclarativeGeoMapItemBase *item);
Q_INVOKABLE void addMapItem(QDeclarativeGeoMapItemBase *item);
+
Q_INVOKABLE void clearMapItems();
QList<QObject *> mapItems();
+ Q_INVOKABLE void addMapParameter(QDeclarativeGeoMapParameter *parameter);
+ Q_INVOKABLE void removeMapParameter(QDeclarativeGeoMapParameter *parameter);
+ Q_INVOKABLE void clearMapParameters();
+ QList<QObject *> mapParameters();
+
Q_INVOKABLE QGeoCoordinate toCoordinate(const QPointF &position, bool clipToViewPort = true) const;
Q_INVOKABLE QPointF fromCoordinate(const QGeoCoordinate &coordinate, bool clipToViewPort = true) const;
@@ -177,13 +186,13 @@ private Q_SLOTS:
private:
void setupMapView(QDeclarativeGeoMapItemView *view);
void populateMap();
+ void populateParameters();
void fitViewportToMapItemsRefine(bool refine);
void fitViewportToGeoShape();
bool isInteractive();
private:
QDeclarativeGeoServiceProvider *m_plugin;
- QGeoServiceProvider *m_serviceProvider;
QGeoMappingManager *m_mappingManager;
QDeclarativeGeoMapType *m_activeMapType;
QList<QDeclarativeGeoMapType *> m_supportedMapTypes;
@@ -203,6 +212,7 @@ private:
double m_maximumViewportLatitude;
bool m_initialized;
bool m_validRegion;
+ QSet<QDeclarativeGeoMapParameter *> m_mapParameters;
friend class QDeclarativeGeoMapItem;
friend class QDeclarativeGeoMapItemView;
diff --git a/src/imports/location/qdeclarativegeomapitemview_p_p.h b/src/imports/location/qdeclarativegeomapitemview_p_p.h
index 5a4e3b25..3ad3ceb4 100644
--- a/src/imports/location/qdeclarativegeomapitemview_p_p.h
+++ b/src/imports/location/qdeclarativegeomapitemview_p_p.h
@@ -60,7 +60,9 @@ class MapItemViewDelegateIncubator;
class QDeclarativeGeoMapItemView;
class QDeclarativeGeoMapItemBase;
-struct QDeclarativeGeoMapItemViewItemData {
+class QDeclarativeGeoMapItemViewItemData
+{
+public:
QDeclarativeGeoMapItemViewItemData()
: incubator(0), item(0), context(0), modelData(0), modelDataMeta(0)
{
diff --git a/src/imports/location/qdeclarativegeomapparameter.cpp b/src/imports/location/qdeclarativegeomapparameter.cpp
new file mode 100644
index 00000000..88d609f4
--- /dev/null
+++ b/src/imports/location/qdeclarativegeomapparameter.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativegeomapparameter_p.h"
+
+#include <QByteArray>
+#include <QMetaObject>
+#include <QMetaProperty>
+#include <QSignalMapper>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype MapParameter
+ \instantiates QDeclarativeGeoMapParameter
+ \inqmlmodule QtLocation
+ \ingroup qml-QtLocation5-maps
+ \since Qt Location 5.9
+
+ \brief The MapParameter type represents a parameter for a Map element.
+ This type provides a mean to specify plugin-dependent optional parameters
+ for a map.
+
+ MapParameters by default contain only the \l type property, and
+ are highly plugin-dependent.
+ For this reason, additional properties have to be defined inside a
+ MapParameter at declaration time, using the QML syntax "property var foo".
+
+ What properties have to be put inside a particular MapParameter type for
+ a particular plugin can be found in the documentation of the plugin.
+ Note that MapProperties are \b optional.
+ By not specifying any of them, the Map will have the default behavior.
+
+ The release of this API with Qt 5.9 is a Technology Preview.
+*/
+
+/*!
+ \qmlproperty georectangle QtLocation::MapParameter::type
+
+ Set-once property which holds a string defining the type of the MapParameter
+*/
+
+QDeclarativeGeoMapParameter::QDeclarativeGeoMapParameter(QObject *parent)
+: QGeoMapParameter(parent), m_initialPropertyCount(metaObject()->propertyCount()), m_complete(false)
+{
+
+}
+
+QDeclarativeGeoMapParameter::~QDeclarativeGeoMapParameter()
+{
+}
+
+bool QDeclarativeGeoMapParameter::isComponentComplete() const
+{
+ return m_complete;
+}
+
+int QDeclarativeGeoMapParameter::initialPropertyCount() const
+{
+ return m_initialPropertyCount;
+}
+
+void QDeclarativeGeoMapParameter::classBegin()
+{
+}
+
+void QDeclarativeGeoMapParameter::componentComplete()
+{
+ for (int i = m_initialPropertyCount; i < metaObject()->propertyCount(); ++i) {
+ QMetaProperty property = metaObject()->property(i);
+
+ if (!property.hasNotifySignal()) {
+ return;
+ }
+
+ QSignalMapper *mapper = new QSignalMapper(this);
+ mapper->setMapping(this, i);
+
+ const QByteArray signalName = '2' + property.notifySignal().methodSignature(); // TODO: explain why '2'
+ QObject::connect(this, signalName, mapper, SLOT(map()));
+ QObject::connect(mapper, SIGNAL(mapped(int)), this, SLOT(onPropertyUpdated(int)));
+ }
+ m_complete = true;
+ emit completed(this);
+}
+
+void QDeclarativeGeoMapParameter::onPropertyUpdated(int index)
+{
+ emit propertyUpdated(this, metaObject()->property(index).name());
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/location/qdeclarativegeomapparameter_p.h b/src/imports/location/qdeclarativegeomapparameter_p.h
new file mode 100644
index 00000000..31ea5b04
--- /dev/null
+++ b/src/imports/location/qdeclarativegeomapparameter_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEGEOMAPPARAMETER_P_H
+#define QDECLARATIVEGEOMAPPARAMETER_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 <QtLocation/private/qgeomapparameter_p.h>
+#include <QQmlParserStatus>
+#include <qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeGeoMapParameter : public QGeoMapParameter, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+
+public:
+ explicit QDeclarativeGeoMapParameter(QObject *parent = 0);
+ virtual ~QDeclarativeGeoMapParameter();
+
+ bool isComponentComplete() const;
+
+Q_SIGNALS:
+ void completed(QDeclarativeGeoMapParameter *);
+
+protected:
+ int initialPropertyCount() const;
+ // QQmlParserStatus implementation
+ void classBegin() override;
+ void componentComplete() override;
+
+private slots:
+ void onPropertyUpdated(int index);
+
+private:
+ int m_initialPropertyCount;
+ bool m_complete;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativeGeoMapParameter)
+
+#endif // QDECLARATIVEGEOMAPPARAMETER_P_H
diff --git a/src/imports/location/qdeclarativegeoroutemodel.cpp b/src/imports/location/qdeclarativegeoroutemodel.cpp
index 0c64c23a..af01d25d 100644
--- a/src/imports/location/qdeclarativegeoroutemodel.cpp
+++ b/src/imports/location/qdeclarativegeoroutemodel.cpp
@@ -120,7 +120,6 @@ QDeclarativeGeoRouteModel::QDeclarativeGeoRouteModel(QObject *parent)
complete_(false),
plugin_(0),
routeQuery_(0),
- reply_(0),
autoUpdate_(false),
status_(QDeclarativeGeoRouteModel::Null),
error_(QDeclarativeGeoRouteModel::NoError)
@@ -133,7 +132,6 @@ QDeclarativeGeoRouteModel::~QDeclarativeGeoRouteModel()
qDeleteAll(routes_);
routes_.clear();
}
- delete reply_;
}
/*!
@@ -168,7 +166,7 @@ void QDeclarativeGeoRouteModel::reset()
endResetModel();
}
- abortRequest();
+ emit abortRequested();
setError(NoError, QString());
setStatus(QDeclarativeGeoRouteModel::Null);
}
@@ -181,25 +179,12 @@ void QDeclarativeGeoRouteModel::reset()
*/
void QDeclarativeGeoRouteModel::cancel()
{
- abortRequest();
+ emit abortRequested();
setError(NoError, QString());
setStatus(routes_.isEmpty() ? Null : Ready);
}
/*!
- \internal
-*/
-void QDeclarativeGeoRouteModel::abortRequest()
-{
- if (reply_) {
- reply_->abort();
- reply_->deleteLater();
- reply_ = 0;
- }
-}
-
-
-/*!
\qmlmethod void QtLocation::RouteModel::get(int)
Returns the Route at given index. Use \l count property to check the
@@ -589,7 +574,7 @@ void QDeclarativeGeoRouteModel::update()
setError(ParseError,"Cannot route, valid query not set.");
return;
}
- abortRequest(); // Clear previus requests
+ emit abortRequested(); // Clear previous requests
QGeoRouteRequest request = routeQuery_->routeRequest();
if (request.waypoints().count() < 2) {
setError(ParseError,tr("Not enough waypoints for routing."));
@@ -598,13 +583,15 @@ void QDeclarativeGeoRouteModel::update()
setError(NoError, QString());
- reply_ = routingManager->calculateRoute(request);
+ QGeoRouteReply *reply = routingManager->calculateRoute(request);
setStatus(QDeclarativeGeoRouteModel::Loading);
- if (reply_->isFinished()) {
- if (reply_->error() == QGeoRouteReply::NoError) {
- routingFinished(reply_);
+ if (!reply->isFinished()) {
+ connect(this, &QDeclarativeGeoRouteModel::abortRequested, reply, &QGeoRouteReply::abort);
+ } else {
+ if (reply->error() == QGeoRouteReply::NoError) {
+ routingFinished(reply);
} else {
- routingError(reply_, reply_->error(), reply_->errorString());
+ routingError(reply, reply->error(), reply->errorString());
}
}
}
@@ -614,7 +601,10 @@ void QDeclarativeGeoRouteModel::update()
*/
void QDeclarativeGeoRouteModel::routingFinished(QGeoRouteReply *reply)
{
- if (reply != reply_ || reply->error() != QGeoRouteReply::NoError)
+ if (!reply)
+ return;
+ reply->deleteLater();
+ if (reply->error() != QGeoRouteReply::NoError)
return;
beginResetModel();
@@ -632,9 +622,6 @@ void QDeclarativeGeoRouteModel::routingFinished(QGeoRouteReply *reply)
setError(NoError, QString());
setStatus(QDeclarativeGeoRouteModel::Ready);
- reply->deleteLater();
- reply_ = 0;
-
if (oldCount != 0 || routes_.count() != 0)
emit routesChanged();
if (oldCount != routes_.count())
@@ -648,12 +635,11 @@ void QDeclarativeGeoRouteModel::routingError(QGeoRouteReply *reply,
QGeoRouteReply::Error error,
const QString &errorString)
{
- if (reply != reply_)
+ if (!reply)
return;
+ reply->deleteLater();
setError(static_cast<QDeclarativeGeoRouteModel::RouteError>(error), errorString);
setStatus(QDeclarativeGeoRouteModel::Error);
- reply->deleteLater();
- reply_ = 0;
}
diff --git a/src/imports/location/qdeclarativegeoroutemodel_p.h b/src/imports/location/qdeclarativegeoroutemodel_p.h
index 66769ea7..30fc1ecc 100644
--- a/src/imports/location/qdeclarativegeoroutemodel_p.h
+++ b/src/imports/location/qdeclarativegeoroutemodel_p.h
@@ -155,6 +155,7 @@ Q_SIGNALS:
void errorChanged(); //emitted also for errorString notification
void routesChanged();
void measurementSystemChanged();
+ void abortRequested();
public Q_SLOTS:
void update();
@@ -170,13 +171,11 @@ private Q_SLOTS:
private:
void setStatus(Status status);
void setError(RouteError error, const QString &errorString);
- void abortRequest();
bool complete_;
QDeclarativeGeoServiceProvider *plugin_;
QDeclarativeGeoRouteQuery *routeQuery_;
- QGeoRouteReply *reply_;
QList<QDeclarativeGeoRoute *> routes_;
bool autoUpdate_;
diff --git a/src/imports/location/qdeclarativepolygonmapitem.cpp b/src/imports/location/qdeclarativepolygonmapitem.cpp
index 32dbb206..41196770 100644
--- a/src/imports/location/qdeclarativepolygonmapitem.cpp
+++ b/src/imports/location/qdeclarativepolygonmapitem.cpp
@@ -150,8 +150,6 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
if (!sourceDirty_)
return;
- double minX = -1.0;
-
// build the actual path
QDoubleVector2D origin;
QDoubleVector2D lastPoint;
@@ -182,13 +180,10 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
if (i == 0) {
origin = point;
- minX = point.x();
srcOrigin_ = coord;
srcPath_.moveTo(point.toPointF() - origin.toPointF());
lastPoint = point;
} else {
- if (point.x() <= minX)
- minX = point.x();
const QDoubleVector2D diff = (point - lastPoint);
if (diff.x() * diff.x() + diff.y() * diff.y() >= 3.0) {
srcPath_.lineTo(point.toPointF() - origin.toPointF());
@@ -203,7 +198,6 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
srcPath_ = srcPath_.simplified();
sourceBounds_ = srcPath_.boundingRect();
- geoLeftBound_ = map.itemPositionToCoordinate(QDoubleVector2D(minX, 0), false);
}
/*!
diff --git a/src/imports/location/qquickgeomapgesturearea.cpp b/src/imports/location/qquickgeomapgesturearea.cpp
index 0baaf98e..3d881ae2 100644
--- a/src/imports/location/qquickgeomapgesturearea.cpp
+++ b/src/imports/location/qquickgeomapgesturearea.cpp
@@ -1017,6 +1017,7 @@ void QQuickGeoMapGestureArea::updatePinch()
// Add to starting zoom level. Sign of (dist-pinchstartdist) takes care of zoom in / out
m_pinch.m_zoom.m_start;
}
+
m_pinch.m_event.setCenter(mapFromScene(m_sceneCenter));
m_pinch.m_event.setAngle(m_twoTouchAngle);
diff --git a/src/imports/positioning/locationsingleton.cpp b/src/imports/positioning/locationsingleton.cpp
index f12486b0..a48c1a96 100644
--- a/src/imports/positioning/locationsingleton.cpp
+++ b/src/imports/positioning/locationsingleton.cpp
@@ -179,6 +179,19 @@ QGeoCircle LocationSingleton::circle(const QGeoCoordinate &center, qreal radius)
}
/*!
+ \qmlmethod geopath QtPositioning::path() const
+
+ Constructs an empty geopath.
+
+ \sa {geopath}
+ \since 5.9
+*/
+QGeoPath LocationSingleton::path() const
+{
+ return QGeoPath();
+}
+
+/*!
\qmlmethod geocircle QtPositioning::shapeToCircle(geoshape shape) const
Converts \a shape to a geocircle.
@@ -204,3 +217,16 @@ QGeoRectangle LocationSingleton::shapeToRectangle(const QGeoShape &shape) const
return QGeoRectangle(shape);
}
+/*!
+ \qmlmethod geopath QtPositioning::shapeToPath(geoshape shape) const
+
+ Converts \a shape to a geopath.
+
+ \sa {geopath}
+ \since 5.9
+*/
+QGeoPath LocationSingleton::shapeToPath(const QGeoShape &shape) const
+{
+ return QGeoPath(shape);
+}
+
diff --git a/src/imports/positioning/locationsingleton.h b/src/imports/positioning/locationsingleton.h
index cc4ea5ce..9a5320e0 100644
--- a/src/imports/positioning/locationsingleton.h
+++ b/src/imports/positioning/locationsingleton.h
@@ -46,6 +46,7 @@
#include <QtPositioning/QGeoShape>
#include <QtPositioning/QGeoRectangle>
#include <QtPositioning/QGeoCircle>
+#include <QtPositioning/QGeoPath>
#include <QVariant>
class LocationSingleton : public QObject
@@ -71,8 +72,11 @@ public:
Q_INVOKABLE QGeoCircle circle() const;
Q_INVOKABLE QGeoCircle circle(const QGeoCoordinate &center, qreal radius = -1.0) const;
+ Q_INVOKABLE QGeoPath path() const;
+
Q_INVOKABLE QGeoCircle shapeToCircle(const QGeoShape &shape) const;
Q_INVOKABLE QGeoRectangle shapeToRectangle(const QGeoShape &shape) const;
+ Q_INVOKABLE QGeoPath shapeToPath(const QGeoShape &shape) const;
};
#endif // LOCATIONSINGLETON_H
diff --git a/src/imports/positioning/positioning.cpp b/src/imports/positioning/positioning.cpp
index 4c54c211..b7914e5d 100644
--- a/src/imports/positioning/positioning.cpp
+++ b/src/imports/positioning/positioning.cpp
@@ -55,6 +55,7 @@
#include <QtPositioning/QGeoRectangle>
#include <QtPositioning/QGeoCircle>
+#include <QtPositioning/QGeoPath>
#include <QtPositioning/QGeoLocation>
#include <QtCore/QDebug>
@@ -527,6 +528,8 @@ public:
QMetaType::registerEqualsComparator<QGeoRectangle>();
qRegisterMetaType<QGeoCircle>();
QMetaType::registerEqualsComparator<QGeoCircle>();
+ qRegisterMetaType<QGeoPath>();
+ QMetaType::registerEqualsComparator<QGeoPath>();
qRegisterMetaType<QGeoLocation>();
qRegisterMetaType<QGeoShape>();
QMetaType::registerEqualsComparator<QGeoShape>();
diff --git a/src/location/maps/maps.pri b/src/location/maps/maps.pri
index 1ea54208..3f76f737 100644
--- a/src/location/maps/maps.pri
+++ b/src/location/maps/maps.pri
@@ -18,6 +18,7 @@ PUBLIC_HEADERS += \
maps/qgeoserviceprovider.h
PRIVATE_HEADERS += \
+ maps/qgeomapparameter_p.h \
maps/qgeocameracapabilities_p.h \
maps/qgeocameradata_p.h \
maps/qgeocameratiles_p.h \
@@ -91,4 +92,5 @@ SOURCES += \
maps/qgeotiledmapscene.cpp \
maps/qgeorouteparser.cpp \
maps/qgeorouteparserosrmv5.cpp \
- maps/qgeorouteparserosrmv4.cpp
+ maps/qgeorouteparserosrmv4.cpp \
+ maps/qgeomapparameter.cpp
diff --git a/src/location/maps/qgeocodereply.cpp b/src/location/maps/qgeocodereply.cpp
index 47018217..d5112a69 100644
--- a/src/location/maps/qgeocodereply.cpp
+++ b/src/location/maps/qgeocodereply.cpp
@@ -233,6 +233,7 @@ void QGeoCodeReply::abort()
{
if (!isFinished())
setFinished(true);
+ emit aborted();
}
/*!
diff --git a/src/location/maps/qgeocodereply.h b/src/location/maps/qgeocodereply.h
index 048493b4..c92bc606 100644
--- a/src/location/maps/qgeocodereply.h
+++ b/src/location/maps/qgeocodereply.h
@@ -80,6 +80,7 @@ public:
Q_SIGNALS:
void finished();
+ void aborted();
void error(QGeoCodeReply::Error error, const QString &errorString = QString());
protected:
diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp
index 0e0a2007..ac6d661b 100644
--- a/src/location/maps/qgeomap.cpp
+++ b/src/location/maps/qgeomap.cpp
@@ -130,6 +130,32 @@ void QGeoMap::clearData()
}
+void QGeoMap::addParameter(QGeoMapParameter *param)
+{
+ Q_D(QGeoMap);
+ if (param && !d->m_mapParameters.contains(param)) {
+ d->m_mapParameters.insert(param);
+ d->addParameter(param);
+ }
+}
+
+void QGeoMap::removeParameter(QGeoMapParameter *param)
+{
+ Q_D(QGeoMap);
+ if (param && d->m_mapParameters.contains(param)) {
+ d->removeParameter(param);
+ d->m_mapParameters.remove(param);
+ }
+}
+
+void QGeoMap::clearParameters()
+{
+ Q_D(QGeoMap);
+ for (QGeoMapParameter *p : d->m_mapParameters)
+ d->removeParameter(p);
+ d->m_mapParameters.clear();
+}
+
QGeoMapPrivate::QGeoMapPrivate(QGeoMappingManagerEngine *engine)
: QObjectPrivate(),
m_engine(engine),
@@ -141,4 +167,14 @@ QGeoMapPrivate::~QGeoMapPrivate()
{
}
+void QGeoMapPrivate::addParameter(QGeoMapParameter *param)
+{
+ Q_UNUSED(param)
+}
+
+void QGeoMapPrivate::removeParameter(QGeoMapParameter *param)
+{
+ Q_UNUSED(param)
+}
+
QT_END_NAMESPACE
diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h
index ea4806c0..7a12820f 100644
--- a/src/location/maps/qgeomap_p.h
+++ b/src/location/maps/qgeomap_p.h
@@ -61,6 +61,7 @@ class QGeoCameraCapabilities;
class QGeoCoordinate;
class QSGNode;
class QQuickWindow;
+class QGeoMapParameter;
class Q_LOCATION_EXPORT QGeoMap : public QObject
{
@@ -94,6 +95,10 @@ public:
virtual void prefetchData();
virtual void clearData();
+ void addParameter(QGeoMapParameter *param);
+ void removeParameter(QGeoMapParameter *param);
+ void clearParameters();
+
protected:
QGeoMap(QGeoMapPrivate &dd, QObject *parent = 0);
void setCameraData(const QGeoCameraData &cameraData);
@@ -108,7 +113,6 @@ Q_SIGNALS:
private:
Q_DISABLE_COPY(QGeoMap)
- friend class QGeoMapController; //setCameraData
friend class QDeclarativeGeoMap; //updateSceneGraph
};
diff --git a/src/location/maps/qgeomap_p_p.h b/src/location/maps/qgeomap_p_p.h
index b95c1dc7..91938903 100644
--- a/src/location/maps/qgeomap_p_p.h
+++ b/src/location/maps/qgeomap_p_p.h
@@ -52,6 +52,7 @@
#include <QtLocation/private/qgeomaptype_p.h>
#include <QtCore/private/qobject_p.h>
#include <QtCore/QSize>
+#include <QtCore/QSet>
QT_BEGIN_NAMESPACE
@@ -59,6 +60,7 @@ QT_BEGIN_NAMESPACE
class QGeoMappingManagerEngine;
class QGeoMap;
class QGeoMapController;
+class QGeoMapParameter;
class Q_LOCATION_PRIVATE_EXPORT QGeoMapPrivate : public QObjectPrivate
{
@@ -69,6 +71,9 @@ public:
protected:
/* Hooks into the actual map implementations */
+ virtual void addParameter(QGeoMapParameter *param);
+ virtual void removeParameter(QGeoMapParameter *param);
+
virtual void changeViewportSize(const QSize &size) = 0; // called by QGeoMap::setSize()
virtual void changeCameraData(const QGeoCameraData &oldCameraData) = 0; // called by QGeoMap::setCameraData()
virtual void changeActiveMapType(const QGeoMapType mapType) = 0; // called by QGeoMap::setActiveMapType()
@@ -76,9 +81,9 @@ protected:
protected:
QSize m_viewportSize;
QPointer<QGeoMappingManagerEngine> m_engine;
- QGeoMapController *m_controller;
QGeoCameraData m_cameraData;
QGeoMapType m_activeMapType;
+ QSet<QGeoMapParameter *> m_mapParameters;
};
QT_END_NAMESPACE
diff --git a/src/location/maps/qgeomapparameter.cpp b/src/location/maps/qgeomapparameter.cpp
new file mode 100644
index 00000000..b8f9561f
--- /dev/null
+++ b/src/location/maps/qgeomapparameter.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qgeomapparameter_p.h"
+#include <QtCore/QVariant>
+
+QT_BEGIN_NAMESPACE
+
+QGeoMapParameter::QGeoMapParameter(QObject *parent) : QObject(parent)
+{
+
+}
+
+QGeoMapParameter::~QGeoMapParameter()
+{
+}
+
+QString QGeoMapParameter::type() const
+{
+ return m_type;
+}
+
+void QGeoMapParameter::setType(const QString &type)
+{
+ if (m_type.isEmpty())
+ m_type = type;
+}
+
+// DO NOT USE to set "type"
+void QGeoMapParameter::updateProperty(const char *propertyName, QVariant value)
+{
+ setProperty(propertyName, value);
+ // This should technically be emitted only for dynamically added properties.
+ // Since this object has only type defined as Q_PROPERTY() which is a set-once
+ // no check is really needed here.
+ emit propertyUpdated(this, propertyName);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/location/maps/qgeomapparameter_p.h b/src/location/maps/qgeomapparameter_p.h
new file mode 100644
index 00000000..c3bef4d8
--- /dev/null
+++ b/src/location/maps/qgeomapparameter_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QGEOMAPPARAMETER_P_H
+#define QGEOMAPPARAMETER_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 <QObject>
+#include <QString>
+#include <QtLocation/qlocationglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_LOCATION_EXPORT QGeoMapParameter : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString type READ type WRITE setType)
+public:
+ explicit QGeoMapParameter(QObject *parent = 0);
+ virtual ~QGeoMapParameter();
+
+ QString type() const;
+ void setType(const QString &type);
+
+ void updateProperty(const char *propertyName, QVariant value);
+
+Q_SIGNALS:
+ void propertyUpdated(QGeoMapParameter *param, const char *propertyName);
+
+protected:
+ QString m_type;
+
+ Q_DISABLE_COPY(QGeoMapParameter)
+ friend class QGeoMap;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGEOMAPPARAMETER_P_H
diff --git a/src/location/maps/qgeoroutereply.cpp b/src/location/maps/qgeoroutereply.cpp
index ab869d3c..b1c98349 100644
--- a/src/location/maps/qgeoroutereply.cpp
+++ b/src/location/maps/qgeoroutereply.cpp
@@ -218,8 +218,7 @@ void QGeoRouteReply::addRoutes(const QList<QGeoRoute> &routes)
*/
void QGeoRouteReply::abort()
{
- if (!isFinished())
- setFinished(true);
+ emit aborted();
}
/*!
diff --git a/src/location/maps/qgeoroutereply.h b/src/location/maps/qgeoroutereply.h
index 318d85f8..c1d6e8d1 100644
--- a/src/location/maps/qgeoroutereply.h
+++ b/src/location/maps/qgeoroutereply.h
@@ -74,6 +74,7 @@ public:
Q_SIGNALS:
void finished();
+ void aborted();
void error(QGeoRouteReply::Error error, const QString &errorString = QString());
protected:
diff --git a/src/location/maps/qgeotiledmap.cpp b/src/location/maps/qgeotiledmap.cpp
index 04f9ad21..a3cad550 100644
--- a/src/location/maps/qgeotiledmap.cpp
+++ b/src/location/maps/qgeotiledmap.cpp
@@ -60,6 +60,17 @@ QGeoTiledMap::QGeoTiledMap(QGeoTiledMappingManagerEngine *engine, QObject *paren
this,&QGeoTiledMap::handleTileVersionChanged);
}
+QGeoTiledMap::QGeoTiledMap(QGeoTiledMapPrivate &dd, QGeoTiledMappingManagerEngine *engine, QObject *parent)
+ : QGeoMap(dd, parent)
+{
+ Q_D(QGeoTiledMap);
+
+ d->m_tileRequests = new QGeoTileRequestManager(this, engine);
+
+ QObject::connect(engine,&QGeoTiledMappingManagerEngine::tileVersionChanged,
+ this,&QGeoTiledMap::handleTileVersionChanged);
+}
+
QGeoTiledMap::~QGeoTiledMap()
{
Q_D(QGeoTiledMap);
diff --git a/src/location/maps/qgeotiledmap_p.h b/src/location/maps/qgeotiledmap_p.h
index d00a1ed9..b148b59c 100644
--- a/src/location/maps/qgeotiledmap_p.h
+++ b/src/location/maps/qgeotiledmap_p.h
@@ -49,10 +49,10 @@
#include <QObject>
#include <QString>
-
-#include "qgeomap_p.h"
-#include "qgeocameradata_p.h"
-#include "qgeomaptype_p.h"
+#include <QtLocation/private/qlocationglobal_p.h>
+#include <QtLocation/private/qgeomap_p.h>
+#include <QtLocation/private/qgeocameradata_p.h>
+#include <QtLocation/private/qgeomaptype_p.h>
#include <QtPositioning/private/qdoublevector2d_p.h>
@@ -70,7 +70,7 @@ class QSGNode;
class QPointF;
-class Q_LOCATION_EXPORT QGeoTiledMap : public QGeoMap
+class Q_LOCATION_PRIVATE_EXPORT QGeoTiledMap : public QGeoMap
{
Q_OBJECT
Q_DECLARE_PRIVATE(QGeoTiledMap)
@@ -103,6 +103,8 @@ protected:
QSGNode *updateSceneGraph(QSGNode *, QQuickWindow *window) Q_DECL_OVERRIDE;
virtual void evaluateCopyrights(const QSet<QGeoTileSpec> &visibleTiles);
+ QGeoTiledMap(QGeoTiledMapPrivate &dd, QGeoTiledMappingManagerEngine *engine, QObject *parent);
+
private Q_SLOTS:
void handleTileVersionChanged();
diff --git a/src/location/maps/qgeotiledmap_p_p.h b/src/location/maps/qgeotiledmap_p_p.h
index 01646d66..72873d77 100644
--- a/src/location/maps/qgeotiledmap_p_p.h
+++ b/src/location/maps/qgeotiledmap_p_p.h
@@ -47,9 +47,10 @@
// We mean it.
//
-#include "qgeomap_p_p.h"
-#include "qgeocameradata_p.h"
-#include "qgeomaptype_p.h"
+#include <QtLocation/private/qlocationglobal_p.h>
+#include <QtLocation/private/qgeomap_p_p.h>
+#include <QtLocation/private/qgeocameradata_p.h>
+#include <QtLocation/private/qgeomaptype_p.h>
#include <QtPositioning/private/qdoublevector3d_p.h>
#include <QtPositioning/private/qdoublevector2d_p.h>
#include <QtCore/QPointer>
@@ -66,7 +67,7 @@ class QGeoTileSpec;
class QSGNode;
class QQuickWindow;
-class QGeoTiledMapPrivate : public QGeoMapPrivate
+class Q_LOCATION_PRIVATE_EXPORT QGeoTiledMapPrivate : public QGeoMapPrivate
{
Q_DECLARE_PUBLIC(QGeoTiledMap)
public:
@@ -89,10 +90,9 @@ protected:
void changeTileVersion(int version);
void clearScene();
-private:
void updateScene();
-private:
+protected:
QAbstractGeoTileCache *m_cache;
QGeoCameraTiles *m_visibleTiles;
QGeoCameraTiles *m_prefetchTiles;
@@ -101,7 +101,6 @@ private:
int m_maxZoomLevel;
int m_minZoomLevel;
QGeoTiledMap::PrefetchStyle m_prefetchStyle;
- bool m_geomoteryUpdated;
Q_DISABLE_COPY(QGeoTiledMapPrivate)
};
diff --git a/src/location/maps/qgeotiledmapreply.cpp b/src/location/maps/qgeotiledmapreply.cpp
index f2dfd9eb..34ca041f 100644
--- a/src/location/maps/qgeotiledmapreply.cpp
+++ b/src/location/maps/qgeotiledmapreply.cpp
@@ -242,6 +242,7 @@ void QGeoTiledMapReply::abort()
{
if (!isFinished())
setFinished(true);
+ emit aborted();
}
/*
diff --git a/src/location/maps/qgeotiledmapreply_p.h b/src/location/maps/qgeotiledmapreply_p.h
index 91852cc3..fc991bb7 100644
--- a/src/location/maps/qgeotiledmapreply_p.h
+++ b/src/location/maps/qgeotiledmapreply_p.h
@@ -88,6 +88,7 @@ public:
Q_SIGNALS:
void finished();
+ void aborted();
void error(QGeoTiledMapReply::Error error, const QString &errorString = QString());
protected:
diff --git a/src/location/places/qplacereply.cpp b/src/location/places/qplacereply.cpp
index 0590871d..582987b4 100644
--- a/src/location/places/qplacereply.cpp
+++ b/src/location/places/qplacereply.cpp
@@ -199,6 +199,7 @@ QPlaceReply::Error QPlaceReply::error() const
*/
void QPlaceReply::abort()
{
+ emit aborted();
}
/*!
diff --git a/src/location/places/qplacereply.h b/src/location/places/qplacereply.h
index 374c68b3..3eb3d6cc 100644
--- a/src/location/places/qplacereply.h
+++ b/src/location/places/qplacereply.h
@@ -86,6 +86,7 @@ public Q_SLOTS:
Q_SIGNALS:
void finished();
+ void aborted();
void error(QPlaceReply::Error error, const QString &errorString = QString());
protected:
diff --git a/src/plugins/geoservices/esri/geocodereply_esri.cpp b/src/plugins/geoservices/esri/geocodereply_esri.cpp
index a7ad9368..f1dac184 100644
--- a/src/plugins/geoservices/esri/geocodereply_esri.cpp
+++ b/src/plugins/geoservices/esri/geocodereply_esri.cpp
@@ -51,11 +51,17 @@ QT_BEGIN_NAMESPACE
GeoCodeReplyEsri::GeoCodeReplyEsri(QNetworkReply *reply, OperationType operationType,
QObject *parent) :
- QGeoCodeReply(parent), m_reply(reply), m_operationType(operationType)
+ QGeoCodeReply(parent), m_operationType(operationType)
{
- connect(m_reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
- connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
+ return;
+ }
+ connect(reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
+ connect(this, &QGeoCodeReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
setLimit(1);
setOffset(0);
@@ -63,49 +69,25 @@ GeoCodeReplyEsri::GeoCodeReplyEsri(QNetworkReply *reply, OperationType operation
GeoCodeReplyEsri::~GeoCodeReplyEsri()
{
- if (m_reply)
- m_reply->deleteLater();
-}
-
-void GeoCodeReplyEsri::abort()
-{
- if (!m_reply)
- return;
-
- m_reply->abort();
- QGeoCodeReply::abort();
-
- m_reply->deleteLater();
- m_reply = Q_NULLPTR;
}
void GeoCodeReplyEsri::networkReplyError(QNetworkReply::NetworkError error)
{
Q_UNUSED(error)
-
- if (!m_reply)
- return;
-
- setError(QGeoCodeReply::CommunicationError, m_reply->errorString());
-
- m_reply->deleteLater();
- m_reply = Q_NULLPTR;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ setError(QGeoCodeReply::CommunicationError, reply->errorString());
}
void GeoCodeReplyEsri::networkReplyFinished()
{
- if (!m_reply)
- return;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
- if (m_reply->error() != QNetworkReply::NoError)
- {
- setError(QGeoCodeReply::CommunicationError, m_reply->errorString());
- m_reply->deleteLater();
- m_reply = Q_NULLPTR;
+ if (reply->error() != QNetworkReply::NoError)
return;
- }
- QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());
+ QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
if (document.isObject()) {
QJsonObject object = document.object();
@@ -148,9 +130,6 @@ void GeoCodeReplyEsri::networkReplyFinished()
} else {
setError(QGeoCodeReply::CommunicationError, QStringLiteral("Unknown document"));
}
-
- m_reply->deleteLater();
- m_reply = Q_NULLPTR;
}
QGeoLocation GeoCodeReplyEsri::parseAddress(const QJsonObject& object)
diff --git a/src/plugins/geoservices/esri/geocodereply_esri.h b/src/plugins/geoservices/esri/geocodereply_esri.h
index 4434b7dc..a857599b 100644
--- a/src/plugins/geoservices/esri/geocodereply_esri.h
+++ b/src/plugins/geoservices/esri/geocodereply_esri.h
@@ -58,9 +58,7 @@ public:
public:
GeoCodeReplyEsri(QNetworkReply *reply, OperationType operationType, QObject *parent = Q_NULLPTR);
- virtual ~GeoCodeReplyEsri();
-
- void abort() Q_DECL_OVERRIDE;
+ ~GeoCodeReplyEsri();
inline OperationType operationType() const;
@@ -72,7 +70,6 @@ private Q_SLOTS:
QGeoLocation parseCandidate(const QJsonObject &candidate);
private:
- QNetworkReply *m_reply;
OperationType m_operationType;
};
diff --git a/src/plugins/geoservices/esri/georoutereply_esri.cpp b/src/plugins/geoservices/esri/georoutereply_esri.cpp
index 4a7d5c67..811ffd0d 100644
--- a/src/plugins/geoservices/esri/georoutereply_esri.cpp
+++ b/src/plugins/geoservices/esri/georoutereply_esri.cpp
@@ -48,43 +48,32 @@ QT_BEGIN_NAMESPACE
GeoRouteReplyEsri::GeoRouteReplyEsri(QNetworkReply *reply, const QGeoRouteRequest &request,
QObject *parent) :
- QGeoRouteReply(request, parent), m_reply(reply)
+ QGeoRouteReply(request, parent)
{
- connect(m_reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
- connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
+ return;
+ }
+ connect(reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
+ connect(this, &QGeoRouteReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
}
GeoRouteReplyEsri::~GeoRouteReplyEsri()
{
- if (m_reply)
- m_reply->deleteLater();
-}
-
-void GeoRouteReplyEsri::abort()
-{
- if (!m_reply)
- return;
-
- m_reply->abort();
- m_reply->deleteLater();
- m_reply = Q_NULLPTR;
}
void GeoRouteReplyEsri::networkReplyFinished()
{
- if (!m_reply)
- return;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
- if (m_reply->error() != QNetworkReply::NoError)
- {
- setError(QGeoRouteReply::CommunicationError, m_reply->errorString());
- m_reply->deleteLater();
- m_reply = Q_NULLPTR;
+ if (reply->error() != QNetworkReply::NoError)
return;
- }
- QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());
+ QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
GeoRouteJsonParserEsri parser(document);
if (parser.isValid())
@@ -94,21 +83,14 @@ void GeoRouteReplyEsri::networkReplyFinished()
} else {
setError(QGeoRouteReply::ParseError, parser.errorString());
}
-
- m_reply->deleteLater();
- m_reply = Q_NULLPTR;
}
void GeoRouteReplyEsri::networkReplyError(QNetworkReply::NetworkError error)
{
Q_UNUSED(error)
-
- if (!m_reply)
- return;
-
- setError(QGeoRouteReply::CommunicationError, m_reply->errorString());
- m_reply->deleteLater();
- m_reply = Q_NULLPTR;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ setError(QGeoRouteReply::CommunicationError, reply->errorString());
}
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/esri/georoutereply_esri.h b/src/plugins/geoservices/esri/georoutereply_esri.h
index 6e97ee9f..049dc3ba 100644
--- a/src/plugins/geoservices/esri/georoutereply_esri.h
+++ b/src/plugins/geoservices/esri/georoutereply_esri.h
@@ -51,16 +51,11 @@ class GeoRouteReplyEsri : public QGeoRouteReply
public:
GeoRouteReplyEsri(QNetworkReply *reply, const QGeoRouteRequest &request, QObject *parent = Q_NULLPTR);
- virtual ~GeoRouteReplyEsri();
-
- void abort() Q_DECL_OVERRIDE;
+ ~GeoRouteReplyEsri();
private Q_SLOTS:
void networkReplyFinished();
void networkReplyError(QNetworkReply::NetworkError error);
-
-private:
- QNetworkReply *m_reply;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/esri/geotiledmapreply_esri.cpp b/src/plugins/geoservices/esri/geotiledmapreply_esri.cpp
index e0816c15..f4431bf0 100644
--- a/src/plugins/geoservices/esri/geotiledmapreply_esri.cpp
+++ b/src/plugins/geoservices/esri/geotiledmapreply_esri.cpp
@@ -49,50 +49,32 @@ static const unsigned char gifSignature[] = {0x47, 0x49, 0x46, 0x38, 0x00};
GeoTiledMapReplyEsri::GeoTiledMapReplyEsri(QNetworkReply *reply, const QGeoTileSpec &spec,
QObject *parent) :
- QGeoTiledMapReply(spec, parent), m_reply(reply)
+ QGeoTiledMapReply(spec, parent)
{
- connect(m_reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
- connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
+ return;
+ }
+ connect(reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
- connect(m_reply, SIGNAL(destroyed()), this, SLOT(replyDestroyed()));
+ connect(this, &QGeoTiledMapReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
}
GeoTiledMapReplyEsri::~GeoTiledMapReplyEsri()
{
- if (m_reply) {
- m_reply->deleteLater();
- m_reply = Q_NULLPTR;
- }
-}
-
-void GeoTiledMapReplyEsri::abort()
-{
- if (!m_reply)
- return;
-
- m_reply->abort();
- QGeoTiledMapReply::abort();
-}
-
-void GeoTiledMapReplyEsri::replyDestroyed()
-{
- m_reply = Q_NULLPTR;
}
void GeoTiledMapReplyEsri::networkReplyFinished()
{
- if (!m_reply)
- return;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
- if (m_reply->error() != QNetworkReply::NoError)
- {
- setError(QGeoTiledMapReply::CommunicationError, m_reply->errorString());
- m_reply->deleteLater();
- m_reply = Q_NULLPTR;
+ if (reply->error() != QNetworkReply::NoError)
return;
- }
- QByteArray const& imageData = m_reply->readAll();
+ QByteArray const& imageData = reply->readAll();
bool validFormat = true;
if (imageData.startsWith(reinterpret_cast<const char*>(pngSignature)))
@@ -108,22 +90,16 @@ void GeoTiledMapReplyEsri::networkReplyFinished()
setMapImageData(imageData);
setFinished(true);
-
- m_reply->deleteLater();
- m_reply = Q_NULLPTR;
}
void GeoTiledMapReplyEsri::networkReplyError(QNetworkReply::NetworkError error)
{
- if (!m_reply)
- return;
-
- if (error != QNetworkReply::OperationCanceledError)
- setError(QGeoTiledMapReply::CommunicationError, m_reply->errorString());
-
- setFinished(true);
- m_reply->deleteLater();
- m_reply = Q_NULLPTR;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ if (error == QNetworkReply::OperationCanceledError)
+ setFinished(true);
+ else
+ setError(QGeoTiledMapReply::CommunicationError, reply->errorString());
}
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/esri/geotiledmapreply_esri.h b/src/plugins/geoservices/esri/geotiledmapreply_esri.h
index 32a35698..b459e943 100644
--- a/src/plugins/geoservices/esri/geotiledmapreply_esri.h
+++ b/src/plugins/geoservices/esri/geotiledmapreply_esri.h
@@ -52,17 +52,11 @@ class GeoTiledMapReplyEsri : public QGeoTiledMapReply
public:
GeoTiledMapReplyEsri(QNetworkReply *reply, const QGeoTileSpec &spec, QObject *parent = Q_NULLPTR);
- virtual ~GeoTiledMapReplyEsri();
-
- void abort() Q_DECL_OVERRIDE;
+ ~GeoTiledMapReplyEsri();
private Q_SLOTS:
- void replyDestroyed();
void networkReplyFinished();
void networkReplyError(QNetworkReply::NetworkError error);
-
-private:
- QNetworkReply *m_reply;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/mapbox/qgeomapreplymapbox.cpp b/src/plugins/geoservices/mapbox/qgeomapreplymapbox.cpp
index 5fe9caa8..4b60231d 100644
--- a/src/plugins/geoservices/mapbox/qgeomapreplymapbox.cpp
+++ b/src/plugins/geoservices/mapbox/qgeomapreplymapbox.cpp
@@ -39,59 +39,42 @@
#include <QtLocation/private/qgeotilespec_p.h>
QGeoMapReplyMapbox::QGeoMapReplyMapbox(QNetworkReply *reply, const QGeoTileSpec &spec, const QString &format, QObject *parent)
-: QGeoTiledMapReply(spec, parent), m_reply(reply), m_format (format)
+: QGeoTiledMapReply(spec, parent), m_format (format)
{
- connect(m_reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
- connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
+ return;
+ }
+ connect(reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
+ connect(this, &QGeoTiledMapReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
}
QGeoMapReplyMapbox::~QGeoMapReplyMapbox()
{
- if (m_reply) {
- m_reply->deleteLater();
- m_reply = 0;
- }
-}
-
-void QGeoMapReplyMapbox::abort()
-{
- if (!m_reply)
- return;
-
- m_reply->abort();
-}
-
-QNetworkReply *QGeoMapReplyMapbox::networkReply() const
-{
- return m_reply;
}
void QGeoMapReplyMapbox::networkReplyFinished()
{
- if (!m_reply)
- return;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
- if (m_reply->error() != QNetworkReply::NoError)
+ if (reply->error() != QNetworkReply::NoError)
return;
- setMapImageData(m_reply->readAll());
+ setMapImageData(reply->readAll());
setMapImageFormat(m_format);
setFinished(true);
-
- m_reply->deleteLater();
- m_reply = 0;
}
void QGeoMapReplyMapbox::networkReplyError(QNetworkReply::NetworkError error)
{
- if (!m_reply)
- return;
-
- if (error != QNetworkReply::OperationCanceledError)
- setError(QGeoTiledMapReply::CommunicationError, m_reply->errorString());
-
- setFinished(true);
- m_reply->deleteLater();
- m_reply = 0;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ if (error == QNetworkReply::OperationCanceledError)
+ setFinished(true);
+ else
+ setError(QGeoTiledMapReply::CommunicationError, reply->errorString());
}
diff --git a/src/plugins/geoservices/mapbox/qgeomapreplymapbox.h b/src/plugins/geoservices/mapbox/qgeomapreplymapbox.h
index 67ad61ad..c4a1dd82 100644
--- a/src/plugins/geoservices/mapbox/qgeomapreplymapbox.h
+++ b/src/plugins/geoservices/mapbox/qgeomapreplymapbox.h
@@ -51,16 +51,11 @@ public:
explicit QGeoMapReplyMapbox(QNetworkReply *reply, const QGeoTileSpec &spec, const QString &format, QObject *parent = 0);
~QGeoMapReplyMapbox();
- void abort();
-
- QNetworkReply *networkReply() const;
-
private Q_SLOTS:
void networkReplyFinished();
void networkReplyError(QNetworkReply::NetworkError error);
private:
- QPointer<QNetworkReply> m_reply;
QString m_format;
};
diff --git a/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp b/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp
index 4c98412b..8fc3386a 100644
--- a/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp
+++ b/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp
@@ -84,28 +84,21 @@ static QList<QGeoCoordinate> parseGeometry(const QJsonValue &geometry)
QGeoRouteReplyMapbox::QGeoRouteReplyMapbox(QNetworkReply *reply, const QGeoRouteRequest &request,
QObject *parent)
-: QGeoRouteReply(request, parent), m_reply(reply)
+: QGeoRouteReply(request, parent)
{
- connect(m_reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
- connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
+ return;
+ }
+ connect(reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
+ connect(this, &QGeoRouteReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
}
QGeoRouteReplyMapbox::~QGeoRouteReplyMapbox()
{
- if (m_reply)
- m_reply->deleteLater();
-}
-
-void QGeoRouteReplyMapbox::abort()
-{
- if (!m_reply)
- return;
-
- m_reply->abort();
-
- m_reply->deleteLater();
- m_reply = 0;
}
static QGeoRoute constructRoute(const QJsonObject &obj)
@@ -177,25 +170,19 @@ static QGeoRoute constructRoute(const QJsonObject &obj)
void QGeoRouteReplyMapbox::networkReplyFinished()
{
- if (!m_reply)
- return;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
- if (m_reply->error() != QNetworkReply::NoError) {
- setError(QGeoRouteReply::CommunicationError, m_reply->errorString());
- m_reply->deleteLater();
- m_reply = 0;
+ if (reply->error() != QNetworkReply::NoError)
return;
- }
- QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());
+ QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
if (document.isObject()) {
QJsonObject object = document.object();
QString status = object.value(QStringLiteral("code")).toString();
if (status != QStringLiteral("Ok")) {
setError(QGeoRouteReply::UnknownError, object.value(QStringLiteral("message")).toString());
- m_reply->deleteLater();
- m_reply = 0;
return;
}
@@ -210,22 +197,14 @@ void QGeoRouteReplyMapbox::networkReplyFinished()
} else {
setError(QGeoRouteReply::ParseError, QStringLiteral("Couldn't parse json."));
}
-
- m_reply->deleteLater();
- m_reply = 0;
}
void QGeoRouteReplyMapbox::networkReplyError(QNetworkReply::NetworkError error)
{
Q_UNUSED(error)
-
- if (!m_reply)
- return;
-
- setError(QGeoRouteReply::CommunicationError, m_reply->errorString());
-
- m_reply->deleteLater();
- m_reply = 0;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ setError(QGeoRouteReply::CommunicationError, reply->errorString());
}
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.h b/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.h
index 9df45ac4..f19faee7 100644
--- a/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.h
+++ b/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.h
@@ -55,14 +55,9 @@ public:
QGeoRouteReplyMapbox(QNetworkReply *reply, const QGeoRouteRequest &request, QObject *parent = 0);
~QGeoRouteReplyMapbox();
- void abort() Q_DECL_OVERRIDE;
-
private Q_SLOTS:
void networkReplyFinished();
void networkReplyError(QNetworkReply::NetworkError error);
-
-private:
- QNetworkReply *m_reply;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp
index d6ef8f0a..f5776852 100644
--- a/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp
+++ b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp
@@ -89,10 +89,19 @@ QGeoRouteReply* QGeoRoutingManagerEngineMapbox::calculateRoute(const QGeoRouteRe
foreach (const QGeoCoordinate &c, request.waypoints()) {
url += QString("%1,%2;").arg(c.longitude()).arg(c.latitude());
}
- if (url.right(1) == ";") url.chop(1);
- url += QString("?steps=true&overview=full&geometries=geojson&access_token=%1").arg(m_accessToken);
-
- networkRequest.setUrl(QUrl(url));
+ if (url.right(1) == ";")
+ url.chop(1);
+
+ QUrlQuery query;
+ query.addQueryItem(QStringLiteral("steps"), QStringLiteral("true"));
+ query.addQueryItem(QStringLiteral("alternatives"), QStringLiteral("true"));
+ query.addQueryItem(QStringLiteral("overview"), QStringLiteral("full"));
+ query.addQueryItem(QStringLiteral("geometries"), QStringLiteral("geojson"));
+ query.addQueryItem(QStringLiteral("access_token"), m_accessToken);
+
+ QUrl u(url);
+ u.setQuery(query);
+ networkRequest.setUrl(u);
QNetworkReply *reply = m_networkManager->get(networkRequest);
QGeoRouteReplyMapbox *routeReply = new QGeoRouteReplyMapbox(reply, request, this);
diff --git a/src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.cpp b/src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.cpp
index 9a5cbf48..f67fa5bb 100644
--- a/src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.cpp
+++ b/src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.cpp
@@ -48,30 +48,26 @@ QT_BEGIN_NAMESPACE
QPlaceContentReplyImpl::QPlaceContentReplyImpl(const QPlaceContentRequest &request,
QNetworkReply *reply,
QPlaceManagerEngineNokiaV2 *engine)
- : QPlaceContentReply(engine), m_reply(reply), m_engine(engine)
+ : QPlaceContentReply(engine), m_engine(engine)
{
Q_ASSERT(engine);
- setRequest(request);
-
- if (!m_reply)
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
return;
+ }
+ setRequest(request);
- m_reply->setParent(this);
- connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished()));
- connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ connect(reply, SIGNAL(finished()), this, SLOT(replyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(replyError(QNetworkReply::NetworkError)));
+ connect(this, &QPlaceReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
}
QPlaceContentReplyImpl::~QPlaceContentReplyImpl()
{
}
-void QPlaceContentReplyImpl::abort()
-{
- if (m_reply)
- m_reply->abort();
-}
-
void QPlaceContentReplyImpl::setError(QPlaceReply::Error error_, const QString &errorString)
{
QPlaceContentReply::setError(error_, errorString);
@@ -82,31 +78,32 @@ void QPlaceContentReplyImpl::setError(QPlaceReply::Error error_, const QString &
void QPlaceContentReplyImpl::replyFinished()
{
- if (m_reply->isOpen()) {
- QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());
- if (!document.isObject()) {
- setError(ParseError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, PARSE_ERROR));
- return;
- }
-
- QJsonObject object = document.object();
-
- QPlaceContent::Collection collection;
- int totalCount;
- QPlaceContentRequest previous;
- QPlaceContentRequest next;
-
- parseCollection(request().contentType(), object, &collection, &totalCount,
- &previous, &next, m_engine);
-
- setTotalCount(totalCount);
- setContent(collection);
- setPreviousPageRequest(previous);
- setNextPageRequest(next);
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+
+ if (reply->error() != QNetworkReply::NoError)
+ return;
+
+ QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
+ if (!document.isObject()) {
+ setError(ParseError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, PARSE_ERROR));
+ return;
}
- m_reply->deleteLater();
- m_reply = 0;
+ QJsonObject object = document.object();
+
+ QPlaceContent::Collection collection;
+ int totalCount;
+ QPlaceContentRequest previous;
+ QPlaceContentRequest next;
+
+ parseCollection(request().contentType(), object, &collection, &totalCount,
+ &previous, &next, m_engine);
+
+ setTotalCount(totalCount);
+ setContent(collection);
+ setPreviousPageRequest(previous);
+ setNextPageRequest(next);
setFinished(true);
emit finished();
@@ -114,13 +111,12 @@ void QPlaceContentReplyImpl::replyFinished()
void QPlaceContentReplyImpl::replyError(QNetworkReply::NetworkError error)
{
- switch (error) {
- case QNetworkReply::OperationCanceledError:
- setError(CancelError, "Request canceled.");
- break;
- default:
- setError(CommunicationError, "Network error.");
- }
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ if (error == QNetworkReply::OperationCanceledError)
+ setError(QPlaceReply::CancelError, QStringLiteral("Request cancelled"));
+ else
+ setError(QPlaceReply::CommunicationError, reply->errorString());
}
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.h b/src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.h
index c7ef7ee4..596b9a4c 100644
--- a/src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.h
+++ b/src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.h
@@ -54,15 +54,12 @@ public:
QPlaceManagerEngineNokiaV2 *engine);
~QPlaceContentReplyImpl();
- void abort();
-
private slots:
void setError(QPlaceReply::Error error_, const QString &errorString);
void replyFinished();
void replyError(QNetworkReply::NetworkError error);
private:
- QNetworkReply *m_reply;
QPlaceManagerEngineNokiaV2 *m_engine;
};
diff --git a/src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.cpp b/src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.cpp
index e85b9cc7..1e7f2d2f 100644
--- a/src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.cpp
+++ b/src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.cpp
@@ -88,27 +88,23 @@ static bool countryTableContains(const QString &countryCode)
QPlaceDetailsReplyImpl::QPlaceDetailsReplyImpl(QNetworkReply *reply,
QPlaceManagerEngineNokiaV2 *parent)
- : QPlaceDetailsReply(parent), m_reply(reply), m_engine(parent)
+: QPlaceDetailsReply(parent), m_engine(parent)
{
- Q_ASSERT(parent);
-
- if (!m_reply)
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
return;
-
- m_reply->setParent(this);
- connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished()));
+ }
+ connect(reply, SIGNAL(finished()), this, SLOT(replyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ this, SLOT(replyError(QNetworkReply::NetworkError)));
+ connect(this, &QPlaceReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
}
QPlaceDetailsReplyImpl::~QPlaceDetailsReplyImpl()
{
}
-void QPlaceDetailsReplyImpl::abort()
-{
- if (m_reply)
- m_reply->abort();
-}
-
void QPlaceDetailsReplyImpl::setError(QPlaceReply::Error error_, const QString &errorString)
{
QPlaceReply::setError(error_, errorString);
@@ -119,23 +115,13 @@ void QPlaceDetailsReplyImpl::setError(QPlaceReply::Error error_, const QString &
void QPlaceDetailsReplyImpl::replyFinished()
{
- if (m_reply->error() != QNetworkReply::NoError) {
- switch (m_reply->error()) {
- case QNetworkReply::OperationCanceledError:
- setError(CancelError, "Request canceled.");
- break;
- case QNetworkReply::ContentNotFoundError:
- setError(PlaceDoesNotExistError,
- QString::fromLatin1("The id, %1, does not reference an existing place")
- .arg(m_placeId));
- break;
- default:
- setError(CommunicationError, "Network error.");
- }
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+
+ if (reply->error() != QNetworkReply::NoError)
return;
- }
- QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());
+ QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
if (!document.isObject()) {
setError(ParseError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, PARSE_ERROR));
return;
@@ -337,11 +323,23 @@ void QPlaceDetailsReplyImpl::replyFinished()
place.setDetailsFetched(true);
setPlace(place);
- m_reply->deleteLater();
- m_reply = 0;
-
setFinished(true);
emit finished();
}
+void QPlaceDetailsReplyImpl::replyError(QNetworkReply::NetworkError error)
+{
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ if (error == QNetworkReply::OperationCanceledError) {
+ setError(QPlaceReply::CancelError, QStringLiteral("Request cancelled"));
+ } else if (error == QNetworkReply::ContentNotFoundError) {
+ setError(QPlaceReply::PlaceDoesNotExistError,
+ QString::fromLatin1("The id, %1, does not reference an existing place")
+ .arg(m_placeId));
+ } else {
+ setError(QPlaceReply::CommunicationError, reply->errorString());
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.h b/src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.h
index 2524d04a..dc537c80 100644
--- a/src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.h
+++ b/src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.h
@@ -53,15 +53,14 @@ public:
QPlaceDetailsReplyImpl(QNetworkReply *reply, QPlaceManagerEngineNokiaV2 *parent);
~QPlaceDetailsReplyImpl();
- void abort();
void setPlaceId(const QString &placeId) { m_placeId = placeId; }
private slots:
void setError(QPlaceReply::Error error_, const QString &errorString);
void replyFinished();
+ void replyError(QNetworkReply::NetworkError error);
private:
- QNetworkReply *m_reply;
QPlaceManagerEngineNokiaV2 *m_engine;
QString m_placeId;
};
diff --git a/src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.cpp b/src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.cpp
index 3a56c927..9808b539 100644
--- a/src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.cpp
+++ b/src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.cpp
@@ -54,29 +54,25 @@ QT_BEGIN_NAMESPACE
QPlaceSearchReplyHere::QPlaceSearchReplyHere(const QPlaceSearchRequest &request,
QNetworkReply *reply,
QPlaceManagerEngineNokiaV2 *parent)
- : QPlaceSearchReply(parent), m_reply(reply), m_engine(parent)
+ : QPlaceSearchReply(parent), m_engine(parent)
{
- Q_ASSERT(parent);
-
- setRequest(request);
-
- if (!m_reply)
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
return;
+ }
+ setRequest(request);
- m_reply->setParent(this);
- connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished()));
+ connect(reply, SIGNAL(finished()), this, SLOT(replyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ this, SLOT(replyError(QNetworkReply::NetworkError)));
+ connect(this, &QPlaceReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
}
QPlaceSearchReplyHere::~QPlaceSearchReplyHere()
{
}
-void QPlaceSearchReplyHere::abort()
-{
- if (m_reply)
- m_reply->abort();
-}
-
void QPlaceSearchReplyHere::setError(QPlaceReply::Error error_, const QString &errorString)
{
QPlaceReply::setError(error_, errorString);
@@ -87,23 +83,13 @@ void QPlaceSearchReplyHere::setError(QPlaceReply::Error error_, const QString &e
void QPlaceSearchReplyHere::replyFinished()
{
- if (m_reply->error() != QNetworkReply::NoError) {
- switch (m_reply->error()) {
- case QNetworkReply::OperationCanceledError:
- setError(CancelError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, CANCEL_ERROR));
- break;
- case QNetworkReply::ContentNotFoundError:
- setError(PlaceDoesNotExistError,
- QString::fromLatin1("The id, %1, does not reference an existing place")
- .arg(request().recommendationId()));
- break;
- default:
- setError(CommunicationError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, NETWORK_ERROR));
- }
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+
+ if (reply->error() != QNetworkReply::NoError)
return;
- }
- QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());
+ QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
if (!document.isObject()) {
setError(ParseError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, PARSE_ERROR));
return;
@@ -141,9 +127,6 @@ void QPlaceSearchReplyHere::replyFinished()
setResults(results);
- m_reply->deleteLater();
- m_reply = 0;
-
setFinished(true);
emit finished();
}
@@ -227,4 +210,19 @@ QPlaceProposedSearchResult QPlaceSearchReplyHere::parseSearchResult(const QJsonO
return result;
}
+void QPlaceSearchReplyHere::replyError(QNetworkReply::NetworkError error)
+{
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ if (error == QNetworkReply::OperationCanceledError) {
+ setError(QPlaceReply::CancelError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, CANCEL_ERROR));
+ } else if (error == QNetworkReply::ContentNotFoundError) {
+ setError(QPlaceReply::PlaceDoesNotExistError,
+ QString::fromLatin1("The id, %1, does not reference an existing place")
+ .arg(request().recommendationId()));
+ } else {
+ setError(QPlaceReply::CommunicationError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, NETWORK_ERROR));
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.h b/src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.h
index a712ab84..b3d97a3d 100644
--- a/src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.h
+++ b/src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.h
@@ -56,17 +56,15 @@ public:
QPlaceManagerEngineNokiaV2 *parent);
~QPlaceSearchReplyHere();
- void abort();
-
private slots:
void setError(QPlaceReply::Error error_, const QString &errorString);
void replyFinished();
+ void replyError(QNetworkReply::NetworkError error);
private:
QPlaceResult parsePlaceResult(const QJsonObject &item) const;
QPlaceProposedSearchResult parseSearchResult(const QJsonObject &item) const;
- QNetworkReply *m_reply;
QPlaceManagerEngineNokiaV2 *m_engine;
};
diff --git a/src/plugins/geoservices/nokia/placesv2/qplacesearchsuggestionreplyimpl.cpp b/src/plugins/geoservices/nokia/placesv2/qplacesearchsuggestionreplyimpl.cpp
index 6ed8b5a2..9882545d 100644
--- a/src/plugins/geoservices/nokia/placesv2/qplacesearchsuggestionreplyimpl.cpp
+++ b/src/plugins/geoservices/nokia/placesv2/qplacesearchsuggestionreplyimpl.cpp
@@ -46,25 +46,23 @@ QT_BEGIN_NAMESPACE
QPlaceSearchSuggestionReplyImpl::QPlaceSearchSuggestionReplyImpl(QNetworkReply *reply,
QObject *parent)
-: QPlaceSearchSuggestionReply(parent), m_reply(reply)
+: QPlaceSearchSuggestionReply(parent)
{
- if (!m_reply)
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
return;
-
- m_reply->setParent(this);
- connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished()));
+ }
+ connect(reply, SIGNAL(finished()), this, SLOT(replyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ this, SLOT(replyError(QNetworkReply::NetworkError)));
+ connect(this, &QPlaceReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
}
QPlaceSearchSuggestionReplyImpl::~QPlaceSearchSuggestionReplyImpl()
{
}
-void QPlaceSearchSuggestionReplyImpl::abort()
-{
- if (m_reply)
- m_reply->abort();
-}
-
void QPlaceSearchSuggestionReplyImpl::setError(QPlaceReply::Error error_,
const QString &errorString)
{
@@ -76,18 +74,13 @@ void QPlaceSearchSuggestionReplyImpl::setError(QPlaceReply::Error error_,
void QPlaceSearchSuggestionReplyImpl::replyFinished()
{
- if (m_reply->error() != QNetworkReply::NoError) {
- switch (m_reply->error()) {
- case QNetworkReply::OperationCanceledError:
- setError(CancelError, "Request canceled.");
- break;
- default:
- setError(CommunicationError, "Network error.");
- }
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+
+ if (reply->error() != QNetworkReply::NoError)
return;
- }
- QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());
+ QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
if (!document.isObject()) {
setError(ParseError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, PARSE_ERROR));
emit error(error(), errorString());
@@ -107,11 +100,18 @@ void QPlaceSearchSuggestionReplyImpl::replyFinished()
setSuggestions(s);
- m_reply->deleteLater();
- m_reply = 0;
-
setFinished(true);
emit finished();
}
+void QPlaceSearchSuggestionReplyImpl::replyError(QNetworkReply::NetworkError error)
+{
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ if (error == QNetworkReply::OperationCanceledError)
+ setError(QPlaceReply::CancelError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, CANCEL_ERROR));
+ else
+ setError(QPlaceReply::CommunicationError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, NETWORK_ERROR));
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/placesv2/qplacesearchsuggestionreplyimpl.h b/src/plugins/geoservices/nokia/placesv2/qplacesearchsuggestionreplyimpl.h
index dbcba3ab..97ae3e1e 100644
--- a/src/plugins/geoservices/nokia/placesv2/qplacesearchsuggestionreplyimpl.h
+++ b/src/plugins/geoservices/nokia/placesv2/qplacesearchsuggestionreplyimpl.h
@@ -50,14 +50,10 @@ public:
explicit QPlaceSearchSuggestionReplyImpl(QNetworkReply *reply, QObject *parent = 0);
~QPlaceSearchSuggestionReplyImpl();
- void abort();
-
private slots:
void setError(QPlaceReply::Error error_, const QString &errorString);
void replyFinished();
-
-private:
- QNetworkReply *m_reply;
+ void replyError(QNetworkReply::NetworkError error);
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp b/src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp
index e99b9815..0fb6eb2a 100644
--- a/src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp
+++ b/src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp
@@ -53,13 +53,21 @@ QT_BEGIN_NAMESPACE
QGeoCodeReplyNokia::QGeoCodeReplyNokia(QNetworkReply *reply, int limit, int offset,
const QGeoShape &viewport, bool manualBoundsRequired,
QObject *parent)
-: QGeoCodeReply(parent), m_reply(reply), m_parsing(false), m_manualBoundsRequired(manualBoundsRequired)
+: QGeoCodeReply(parent), m_parsing(false), m_manualBoundsRequired(manualBoundsRequired)
{
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
+ return;
+ }
qRegisterMetaType<QList<QGeoLocation> >();
- connect(m_reply, SIGNAL(finished()), this, SLOT(networkFinished()));
- connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ connect(reply, SIGNAL(finished()), this, SLOT(networkFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkError(QNetworkReply::NetworkError)));
+ connect(this, &QGeoCodeReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QGeoCodeReply::aborted, [this](){ m_parsing = false; });
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
+
setLimit(limit);
setOffset(offset);
@@ -68,29 +76,14 @@ QGeoCodeReplyNokia::QGeoCodeReplyNokia(QNetworkReply *reply, int limit, int offs
QGeoCodeReplyNokia::~QGeoCodeReplyNokia()
{
- abort();
-}
-
-void QGeoCodeReplyNokia::abort()
-{
- if (!m_reply) {
- m_parsing = false;
- return;
- }
-
- m_reply->abort();
-
- m_reply->deleteLater();
- m_reply = 0;
- m_parsing = false;
}
void QGeoCodeReplyNokia::networkFinished()
{
- if (!m_reply)
- return;
+ QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
- if (m_reply->error() != QNetworkReply::NoError)
+ if (reply->error() != QNetworkReply::NoError)
return;
QGeoCodeJsonParser *parser = new QGeoCodeJsonParser; // QRunnable, autoDelete = true.
@@ -101,23 +94,16 @@ void QGeoCodeReplyNokia::networkFinished()
connect(parser, SIGNAL(error(QString)), this, SLOT(parseError(QString)));
m_parsing = true;
- parser->parse(m_reply->readAll());
-
- m_reply->deleteLater();
- m_reply = 0;
+ parser->parse(reply->readAll());
}
void QGeoCodeReplyNokia::networkError(QNetworkReply::NetworkError error)
{
Q_UNUSED(error)
- if (!m_reply)
- return;
-
- setError(QGeoCodeReply::CommunicationError, m_reply->errorString());
-
- m_reply->deleteLater();
- m_reply = 0;
+ QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ setError(QGeoCodeReply::CommunicationError, reply->errorString());
}
void QGeoCodeReplyNokia::appendResults(const QList<QGeoLocation> &locations)
@@ -136,7 +122,6 @@ void QGeoCodeReplyNokia::parseError(const QString &errorString)
setError(QGeoCodeReply::ParseError,
QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, RESPONSE_NOT_RECOGNIZABLE));
- abort();
}
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/qgeocodereply_nokia.h b/src/plugins/geoservices/nokia/qgeocodereply_nokia.h
index 0d0c47d1..90443ebc 100644
--- a/src/plugins/geoservices/nokia/qgeocodereply_nokia.h
+++ b/src/plugins/geoservices/nokia/qgeocodereply_nokia.h
@@ -49,8 +49,6 @@ public:
QGeoCodeReplyNokia(QNetworkReply *reply, int limit, int offset, const QGeoShape &viewport, bool manualBoundsRequired, QObject *parent = 0);
~QGeoCodeReplyNokia();
- void abort();
-
private Q_SLOTS:
void networkFinished();
void networkError(QNetworkReply::NetworkError error);
@@ -58,7 +56,6 @@ private Q_SLOTS:
void parseError(const QString &errorString);
private:
- QNetworkReply *m_reply;
bool m_parsing;
bool m_manualBoundsRequired;
};
diff --git a/src/plugins/geoservices/nokia/qgeomapreply_nokia.cpp b/src/plugins/geoservices/nokia/qgeomapreply_nokia.cpp
index c95f8de3..6e1a1e85 100644
--- a/src/plugins/geoservices/nokia/qgeomapreply_nokia.cpp
+++ b/src/plugins/geoservices/nokia/qgeomapreply_nokia.cpp
@@ -42,63 +42,50 @@
QT_BEGIN_NAMESPACE
QGeoMapReplyNokia::QGeoMapReplyNokia(QNetworkReply *reply, const QGeoTileSpec &spec, QObject *parent)
- : QGeoTiledMapReply(spec, parent),
- m_reply(reply)
+ : QGeoTiledMapReply(spec, parent)
{
- connect(m_reply,
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
+ return;
+ }
+ connect(reply,
SIGNAL(finished()),
this,
SLOT(networkFinished()));
- connect(m_reply,
+ connect(reply,
SIGNAL(error(QNetworkReply::NetworkError)),
this,
SLOT(networkError(QNetworkReply::NetworkError)));
+ connect(this, &QGeoTiledMapReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
}
QGeoMapReplyNokia::~QGeoMapReplyNokia()
{
}
-QNetworkReply *QGeoMapReplyNokia::networkReply() const
-{
- return m_reply;
-}
-
-void QGeoMapReplyNokia::abort()
-{
- if (!m_reply)
- return;
-
- m_reply->abort();
-}
-
void QGeoMapReplyNokia::networkFinished()
{
- if (!m_reply)
- return;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
- if (m_reply->error() != QNetworkReply::NoError)
+ if (reply->error() != QNetworkReply::NoError)
return;
- setMapImageData(m_reply->readAll());
+ setMapImageData(reply->readAll());
setMapImageFormat("png");
setFinished(true);
-
- m_reply->deleteLater();
- m_reply = 0;
}
void QGeoMapReplyNokia::networkError(QNetworkReply::NetworkError error)
{
- if (!m_reply)
- return;
-
- if (error != QNetworkReply::OperationCanceledError)
- setError(QGeoTiledMapReply::CommunicationError, m_reply->errorString());
- setFinished(true);
- m_reply->deleteLater();
- m_reply = 0;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ if (error == QNetworkReply::OperationCanceledError)
+ setFinished(true);
+ else
+ setError(QGeoTiledMapReply::CommunicationError, reply->errorString());
}
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/qgeomapreply_nokia.h b/src/plugins/geoservices/nokia/qgeomapreply_nokia.h
index 55759914..d835757c 100644
--- a/src/plugins/geoservices/nokia/qgeomapreply_nokia.h
+++ b/src/plugins/geoservices/nokia/qgeomapreply_nokia.h
@@ -52,16 +52,9 @@ public:
QGeoMapReplyNokia(QNetworkReply *reply, const QGeoTileSpec &spec, QObject *parent = 0);
~QGeoMapReplyNokia();
- void abort();
-
- QNetworkReply *networkReply() const;
-
private Q_SLOTS:
void networkFinished();
void networkError(QNetworkReply::NetworkError error);
-
-private:
- QPointer<QNetworkReply> m_reply;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/qgeoroutereply_nokia.cpp b/src/plugins/geoservices/nokia/qgeoroutereply_nokia.cpp
index 45ea071f..b5fdfee1 100644
--- a/src/plugins/geoservices/nokia/qgeoroutereply_nokia.cpp
+++ b/src/plugins/geoservices/nokia/qgeoroutereply_nokia.cpp
@@ -49,43 +49,41 @@ QT_BEGIN_NAMESPACE
QGeoRouteReplyNokia::QGeoRouteReplyNokia(const QGeoRouteRequest &request,
const QList<QNetworkReply *> &replies,
QObject *parent)
-: QGeoRouteReply(request, parent), m_replies(replies), m_parsers(0)
+: QGeoRouteReply(request, parent), m_parsers(0)
{
qRegisterMetaType<QList<QGeoRoute> >();
- foreach (QNetworkReply *reply, m_replies) {
+ bool failure = false;
+ foreach (QNetworkReply *reply, replies) {
+ if (!reply) {
+ failure = true;
+ continue;
+ }
connect(reply, SIGNAL(finished()), this, SLOT(networkFinished()));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkError(QNetworkReply::NetworkError)));
+ connect(this, &QGeoRouteReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
}
+ if (failure)
+ setError(UnknownError, QStringLiteral("Null reply"));
+ else
+ connect(this, &QGeoRouteReply::aborted, [this](){ m_parsers = 0; });
}
QGeoRouteReplyNokia::~QGeoRouteReplyNokia()
{
- abort();
-}
-
-void QGeoRouteReplyNokia::abort()
-{
- if (m_replies.isEmpty() && !m_parsers)
- return;
-
- foreach (QNetworkReply *reply, m_replies) {
- reply->abort();
- reply->deleteLater();
- }
- m_replies.clear();
- m_parsers = 0;
}
void QGeoRouteReplyNokia::networkFinished()
{
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
- if (!reply)
- return;
+ reply->deleteLater();
- if (reply->error() != QNetworkReply::NoError)
+ if (reply->error() != QNetworkReply::NoError
+ && reply->error() != QNetworkReply::UnknownContentError) {
return;
+ }
QGeoRouteXmlParser *parser = new QGeoRouteXmlParser(request());
connect(parser, SIGNAL(results(QList<QGeoRoute>)),
@@ -94,32 +92,17 @@ void QGeoRouteReplyNokia::networkFinished()
++m_parsers;
parser->parse(reply->readAll());
-
- m_replies.removeOne(reply);
- reply->deleteLater();
}
void QGeoRouteReplyNokia::networkError(QNetworkReply::NetworkError error)
{
- QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
- if (!reply)
+ if (error == QNetworkReply::UnknownContentError)
return;
-
- if (error == QNetworkReply::UnknownContentError) {
- QGeoRouteXmlParser *parser = new QGeoRouteXmlParser(request());
- connect(parser, SIGNAL(results(QList<QGeoRoute>)),
- this, SLOT(appendResults(QList<QGeoRoute>)));
- connect(parser, SIGNAL(error(QString)), this, SLOT(parserError(QString)));
-
- ++m_parsers;
- parser->parse(reply->readAll());
-
- m_replies.removeOne(reply);
- reply->deleteLater();
- } else {
- setError(QGeoRouteReply::CommunicationError, reply->errorString());
- abort();
- }
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ setError(QGeoRouteReply::CommunicationError, reply->errorString());
+ if (error != QNetworkReply::OperationCanceledError) // Any error not caused by abort()
+ emit aborted(); // aborts all unfinished replies and sets m_parsers to 0
}
void QGeoRouteReplyNokia::appendResults(const QList<QGeoRoute> &routes)
@@ -130,19 +113,16 @@ void QGeoRouteReplyNokia::appendResults(const QList<QGeoRoute> &routes)
--m_parsers;
addRoutes(routes);
- if (!m_parsers && m_replies.isEmpty())
+ if (!m_parsers)
setFinished(true);
}
void QGeoRouteReplyNokia::parserError(const QString &errorString)
{
Q_UNUSED(errorString)
-
- --m_parsers;
-
+ emit aborted();
setError(QGeoRouteReply::ParseError,
QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, RESPONSE_NOT_RECOGNIZABLE));
- abort();
}
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/qgeoroutereply_nokia.h b/src/plugins/geoservices/nokia/qgeoroutereply_nokia.h
index 9d32bdb3..d38262a5 100644
--- a/src/plugins/geoservices/nokia/qgeoroutereply_nokia.h
+++ b/src/plugins/geoservices/nokia/qgeoroutereply_nokia.h
@@ -51,8 +51,6 @@ public:
QGeoRouteReplyNokia(const QGeoRouteRequest &request, const QList<QNetworkReply*> &replies, QObject *parent = 0);
~QGeoRouteReplyNokia();
- void abort();
-
private Q_SLOTS:
void networkFinished();
void networkError(QNetworkReply::NetworkError error);
@@ -60,7 +58,6 @@ private Q_SLOTS:
void parserError(const QString &errorString);
private:
- QList<QNetworkReply *> m_replies;
int m_parsers;
};
diff --git a/src/plugins/geoservices/osm/qgeocodereplyosm.cpp b/src/plugins/geoservices/osm/qgeocodereplyosm.cpp
index 15b1724e..a30601d0 100644
--- a/src/plugins/geoservices/osm/qgeocodereplyosm.cpp
+++ b/src/plugins/geoservices/osm/qgeocodereplyosm.cpp
@@ -50,31 +50,23 @@
QT_BEGIN_NAMESPACE
QGeoCodeReplyOsm::QGeoCodeReplyOsm(QNetworkReply *reply, QObject *parent)
-: QGeoCodeReply(parent), m_reply(reply)
+: QGeoCodeReply(parent)
{
- connect(m_reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
- connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
+ return;
+ }
+ connect(reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
-
+ connect(this, &QGeoCodeReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
setLimit(1);
setOffset(0);
}
QGeoCodeReplyOsm::~QGeoCodeReplyOsm()
{
- if (m_reply)
- m_reply->deleteLater();
-}
-
-void QGeoCodeReplyOsm::abort()
-{
- if (!m_reply)
- return;
-
- m_reply->abort();
-
- m_reply->deleteLater();
- m_reply = 0;
}
static QGeoAddress parseAddressObject(const QJsonObject &object)
@@ -108,14 +100,14 @@ static QGeoAddress parseAddressObject(const QJsonObject &object)
void QGeoCodeReplyOsm::networkReplyFinished()
{
- if (!m_reply)
- return;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
- if (m_reply->error() != QNetworkReply::NoError)
+ if (reply->error() != QNetworkReply::NoError)
return;
QList<QGeoLocation> locations;
- QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());
+ QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
if (document.isObject()) {
QJsonObject object = document.object();
@@ -169,22 +161,14 @@ void QGeoCodeReplyOsm::networkReplyFinished()
setLocations(locations);
setFinished(true);
-
- m_reply->deleteLater();
- m_reply = 0;
}
void QGeoCodeReplyOsm::networkReplyError(QNetworkReply::NetworkError error)
{
Q_UNUSED(error)
-
- if (!m_reply)
- return;
-
- setError(QGeoCodeReply::CommunicationError, m_reply->errorString());
-
- m_reply->deleteLater();
- m_reply = 0;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ setError(QGeoCodeReply::CommunicationError, reply->errorString());
}
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/osm/qgeocodereplyosm.h b/src/plugins/geoservices/osm/qgeocodereplyosm.h
index 2772910e..0847f58c 100644
--- a/src/plugins/geoservices/osm/qgeocodereplyosm.h
+++ b/src/plugins/geoservices/osm/qgeocodereplyosm.h
@@ -53,14 +53,9 @@ public:
explicit QGeoCodeReplyOsm(QNetworkReply *reply, QObject *parent = 0);
~QGeoCodeReplyOsm();
- void abort();
-
private Q_SLOTS:
void networkReplyFinished();
void networkReplyError(QNetworkReply::NetworkError error);
-
-private:
- QNetworkReply *m_reply;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/osm/qgeomapreplyosm.cpp b/src/plugins/geoservices/osm/qgeomapreplyosm.cpp
index 052ed351..a06f91f3 100644
--- a/src/plugins/geoservices/osm/qgeomapreplyosm.cpp
+++ b/src/plugins/geoservices/osm/qgeomapreplyosm.cpp
@@ -45,64 +45,45 @@ QGeoMapReplyOsm::QGeoMapReplyOsm(QNetworkReply *reply,
const QGeoTileSpec &spec,
const QString &imageFormat,
QObject *parent)
-: QGeoTiledMapReply(spec, parent), m_reply(reply)
+: QGeoTiledMapReply(spec, parent)
{
- connect(m_reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
- connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
+ return;
+ }
+ connect(reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
+ connect(this, &QGeoTiledMapReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
setMapImageFormat(imageFormat);
}
QGeoMapReplyOsm::~QGeoMapReplyOsm()
{
- if (m_reply) {
- m_reply->deleteLater();
- m_reply = 0;
- }
-}
-
-void QGeoMapReplyOsm::abort()
-{
- if (!m_reply)
- return;
-
- m_reply->abort();
-}
-
-QNetworkReply *QGeoMapReplyOsm::networkReply() const
-{
- return m_reply;
}
void QGeoMapReplyOsm::networkReplyFinished()
{
- if (!m_reply)
- return;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
- if (m_reply->error() != QNetworkReply::NoError) {
- m_reply->deleteLater();
- m_reply = 0;
+ if (reply->error() != QNetworkReply::NoError) // Already handled in networkReplyError
return;
- }
- QByteArray a = m_reply->readAll();
+ QByteArray a = reply->readAll();
setMapImageData(a);
setFinished(true);
-
- m_reply->deleteLater();
- m_reply = 0;
}
void QGeoMapReplyOsm::networkReplyError(QNetworkReply::NetworkError error)
{
- if (!m_reply)
- return;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ if (error == QNetworkReply::OperationCanceledError)
+ setFinished(true);
+ else
+ setError(QGeoTiledMapReply::CommunicationError, reply->errorString());
- if (error != QNetworkReply::OperationCanceledError)
- setError(QGeoTiledMapReply::CommunicationError, m_reply->errorString());
-
- setFinished(true);
- m_reply->deleteLater();
- m_reply = 0;
}
diff --git a/src/plugins/geoservices/osm/qgeomapreplyosm.h b/src/plugins/geoservices/osm/qgeomapreplyosm.h
index 804a0a24..ef0cbb15 100644
--- a/src/plugins/geoservices/osm/qgeomapreplyosm.h
+++ b/src/plugins/geoservices/osm/qgeomapreplyosm.h
@@ -40,12 +40,8 @@
#ifndef QGEOMAPREPLYOSM_H
#define QGEOMAPREPLYOSM_H
-#include "qgeotilefetcherosm.h"
-#include "qgeotileproviderosm.h"
-
#include <QtNetwork/QNetworkReply>
#include <QtLocation/private/qgeotiledmapreply_p.h>
-#include <QtCore/qpointer.h>
QT_BEGIN_NAMESPACE
@@ -57,16 +53,9 @@ public:
QGeoMapReplyOsm(QNetworkReply *reply, const QGeoTileSpec &spec, const QString &imageFormat, QObject *parent = 0);
~QGeoMapReplyOsm();
- void abort();
-
- QNetworkReply *networkReply() const;
-
private Q_SLOTS:
void networkReplyFinished();
void networkReplyError(QNetworkReply::NetworkError error);
-
-private:
- QPointer<QNetworkReply> m_reply;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp b/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp
index c640e595..6924fda7 100644
--- a/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp
+++ b/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp
@@ -44,48 +44,37 @@ QT_BEGIN_NAMESPACE
QGeoRouteReplyOsm::QGeoRouteReplyOsm(QNetworkReply *reply, const QGeoRouteRequest &request,
QObject *parent)
-: QGeoRouteReply(request, parent), m_reply(reply)
+: QGeoRouteReply(request, parent)
{
- connect(m_reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
- connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
+ return;
+ }
+ connect(reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
+ connect(this, &QGeoRouteReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
}
QGeoRouteReplyOsm::~QGeoRouteReplyOsm()
{
- if (m_reply)
- m_reply->deleteLater();
-}
-
-void QGeoRouteReplyOsm::abort()
-{
- if (!m_reply)
- return;
-
- m_reply->abort();
-
- m_reply->deleteLater();
- m_reply = 0;
}
void QGeoRouteReplyOsm::networkReplyFinished()
{
- if (!m_reply)
- return;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
- if (m_reply->error() != QNetworkReply::NoError) {
- setError(QGeoRouteReply::CommunicationError, m_reply->errorString());
- m_reply->deleteLater();
- m_reply = 0;
+ if (reply->error() != QNetworkReply::NoError)
return;
- }
QGeoRoutingManagerEngineOsm *engine = qobject_cast<QGeoRoutingManagerEngineOsm *>(parent());
const QGeoRouteParser *parser = engine->routeParser();
QList<QGeoRoute> routes;
QString errorString;
- QGeoRouteReply::Error error = parser->parseReply(routes, errorString, m_reply->readAll());
+ QGeoRouteReply::Error error = parser->parseReply(routes, errorString, reply->readAll());
if (error == QGeoRouteReply::NoError) {
setRoutes(routes.mid(0,1)); // TODO QTBUG-56426
@@ -94,22 +83,14 @@ void QGeoRouteReplyOsm::networkReplyFinished()
} else {
setError(error, errorString);
}
-
- m_reply->deleteLater();
- m_reply = 0;
}
void QGeoRouteReplyOsm::networkReplyError(QNetworkReply::NetworkError error)
{
Q_UNUSED(error)
-
- if (!m_reply)
- return;
-
- setError(QGeoRouteReply::CommunicationError, m_reply->errorString());
-
- m_reply->deleteLater();
- m_reply = 0;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ setError(QGeoRouteReply::CommunicationError, reply->errorString());
}
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/osm/qgeoroutereplyosm.h b/src/plugins/geoservices/osm/qgeoroutereplyosm.h
index 8733c154..feaae59c 100644
--- a/src/plugins/geoservices/osm/qgeoroutereplyosm.h
+++ b/src/plugins/geoservices/osm/qgeoroutereplyosm.h
@@ -54,14 +54,9 @@ public:
QGeoRouteReplyOsm(QNetworkReply *reply, const QGeoRouteRequest &request, QObject *parent = 0);
~QGeoRouteReplyOsm();
- void abort() Q_DECL_OVERRIDE;
-
private Q_SLOTS:
void networkReplyFinished();
void networkReplyError(QNetworkReply::NetworkError error);
-
-private:
- QNetworkReply *m_reply;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/osm/qplacemanagerengineosm.cpp b/src/plugins/geoservices/osm/qplacemanagerengineosm.cpp
index 719769f0..dcf02b13 100644
--- a/src/plugins/geoservices/osm/qplacemanagerengineosm.cpp
+++ b/src/plugins/geoservices/osm/qplacemanagerengineosm.cpp
@@ -260,9 +260,6 @@ void QPlaceManagerEngineOsm::setLocales(const QList<QLocale> &locales)
void QPlaceManagerEngineOsm::categoryReplyFinished()
{
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
- if (!reply)
- return;
-
reply->deleteLater();
QXmlStreamReader parser(reply);
diff --git a/src/plugins/geoservices/osm/qplacesearchreplyosm.cpp b/src/plugins/geoservices/osm/qplacesearchreplyosm.cpp
index 3cb0ab60..35b05d4d 100644
--- a/src/plugins/geoservices/osm/qplacesearchreplyosm.cpp
+++ b/src/plugins/geoservices/osm/qplacesearchreplyosm.cpp
@@ -53,32 +53,28 @@ QT_BEGIN_NAMESPACE
QPlaceSearchReplyOsm::QPlaceSearchReplyOsm(const QPlaceSearchRequest &request,
QNetworkReply *reply, QPlaceManagerEngineOsm *parent)
-: QPlaceSearchReply(parent), m_reply(reply)
+: QPlaceSearchReply(parent)
{
Q_ASSERT(parent);
-
- setRequest(request);
-
- if (!m_reply)
+ if (!reply) {
+ setError(UnknownError, QStringLiteral("Null reply"));
return;
+ }
+ setRequest(request);
- m_reply->setParent(this);
- connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished()));
+ connect(reply, SIGNAL(finished()), this, SLOT(replyFinished()));
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(networkError(QNetworkReply::NetworkError)));
+ connect(this, &QPlaceReply::aborted, reply, &QNetworkReply::abort);
+ connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
}
QPlaceSearchReplyOsm::~QPlaceSearchReplyOsm()
{
}
-void QPlaceSearchReplyOsm::abort()
-{
- if (m_reply)
- m_reply->abort();
-}
-
void QPlaceSearchReplyOsm::setError(QPlaceReply::Error errorCode, const QString &errorString)
{
- QPlaceReply::setError(errorCode, errorString);
+ setError(errorCode, errorString);
emit error(errorCode, errorString);
setFinished(true);
emit finished();
@@ -99,14 +95,11 @@ static QGeoRectangle parseBoundingBox(const QJsonArray &coordinates)
void QPlaceSearchReplyOsm::replyFinished()
{
- QNetworkReply *reply = m_reply;
- m_reply->deleteLater();
- m_reply = 0;
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
- if (reply->error() != QNetworkReply::NoError) {
- setError(CommunicationError, tr("Communication error"));
+ if (reply->error() != QNetworkReply::NoError)
return;
- }
QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
if (!document.isArray()) {
@@ -163,6 +156,14 @@ void QPlaceSearchReplyOsm::replyFinished()
emit finished();
}
+void QPlaceSearchReplyOsm::networkError(QNetworkReply::NetworkError error)
+{
+ Q_UNUSED(error)
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+ setError(QPlaceReply::CommunicationError, reply->errorString());
+}
+
QPlaceResult QPlaceSearchReplyOsm::parsePlaceResult(const QJsonObject &item) const
{
QPlace place;
diff --git a/src/plugins/geoservices/osm/qplacesearchreplyosm.h b/src/plugins/geoservices/osm/qplacesearchreplyosm.h
index e495d4fa..223e5f0c 100644
--- a/src/plugins/geoservices/osm/qplacesearchreplyosm.h
+++ b/src/plugins/geoservices/osm/qplacesearchreplyosm.h
@@ -41,6 +41,7 @@
#define QPLACESEARCHREPLYOSM_H
#include <QtLocation/QPlaceSearchReply>
+#include <QNetworkReply>
QT_BEGIN_NAMESPACE
@@ -57,16 +58,13 @@ public:
QPlaceManagerEngineOsm *parent);
~QPlaceSearchReplyOsm();
- void abort();
-
private slots:
void setError(QPlaceReply::Error errorCode, const QString &errorString);
void replyFinished();
+ void networkError(QNetworkReply::NetworkError error);
private:
QPlaceResult parsePlaceResult(const QJsonObject &item) const;
-
- QNetworkReply *m_reply;
};
QT_END_NAMESPACE
diff --git a/src/plugins/position/corelocation/corelocation.pro b/src/plugins/position/corelocation/corelocation.pro
index dbb5b6b3..947a1d0c 100644
--- a/src/plugins/position/corelocation/corelocation.pro
+++ b/src/plugins/position/corelocation/corelocation.pro
@@ -13,9 +13,7 @@ HEADERS += \
OTHER_FILES += \
plugin.json
-osx: LIBS += -framework Foundation
-else: ios|tvos: LIBS += -framework CoreFoundation
-LIBS += -framework CoreLocation
+LIBS += -framework Foundation -framework CoreLocation
PLUGIN_TYPE = position
PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryCL
diff --git a/src/positioning/positioning.pro b/src/positioning/positioning.pro
index 3cc059c0..a311e5e1 100644
--- a/src/positioning/positioning.pro
+++ b/src/positioning/positioning.pro
@@ -32,7 +32,8 @@ PUBLIC_HEADERS += \
qgeosatelliteinfosource.h \
qnmeapositioninfosource.h \
qgeopositioninfosourcefactory.h \
- qpositioningglobal.h
+ qpositioningglobal.h \
+ qgeopath.h \
PRIVATE_HEADERS += \
qgeoaddress_p.h \
@@ -50,7 +51,8 @@ PRIVATE_HEADERS += \
qdoublevector3d_p.h \
qgeoprojection_p.h \
qpositioningglobal_p.h \
- qlocationdata_simulator_p.h
+ qlocationdata_simulator_p.h \
+ qgeopath_p.h
SOURCES += \
qgeoaddress.cpp \
@@ -73,7 +75,8 @@ SOURCES += \
qdoublevector2d.cpp \
qdoublevector3d.cpp \
qgeoprojection.cpp \
- qlocationdata_simulator.cpp
+ qlocationdata_simulator.cpp \
+ qgeopath.cpp
HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS
diff --git a/src/positioning/qgeocircle.cpp b/src/positioning/qgeocircle.cpp
index 3f2707a4..17263a42 100644
--- a/src/positioning/qgeocircle.cpp
+++ b/src/positioning/qgeocircle.cpp
@@ -42,9 +42,11 @@
#include "qgeocoordinate.h"
#include "qnumeric.h"
+#include "qlocationutils_p.h"
#include "qdoublevector2d_p.h"
#include "qdoublevector3d_p.h"
+#include <cmath>
QT_BEGIN_NAMESPACE
/*!
@@ -191,12 +193,12 @@ bool QGeoCircle::operator!=(const QGeoCircle &other) const
bool QGeoCirclePrivate::isValid() const
{
- return m_center.isValid() && !qIsNaN(radius) && radius >= -1e-7;
+ return m_center.isValid() && !qIsNaN(m_radius) && m_radius >= -1e-7;
}
bool QGeoCirclePrivate::isEmpty() const
{
- return !isValid() || radius <= 1e-7;
+ return !isValid() || m_radius <= 1e-7;
}
/*!
@@ -206,7 +208,7 @@ void QGeoCircle::setCenter(const QGeoCoordinate &center)
{
Q_D(QGeoCircle);
- d->m_center = center;
+ d->setCenter(center);
}
/*!
@@ -226,7 +228,7 @@ void QGeoCircle::setRadius(qreal radius)
{
Q_D(QGeoCircle);
- d->radius = radius;
+ d->setRadius(radius);
}
/*!
@@ -236,7 +238,7 @@ qreal QGeoCircle::radius() const
{
Q_D(const QGeoCircle);
- return d->radius;
+ return d->m_radius;
}
bool QGeoCirclePrivate::contains(const QGeoCoordinate &coordinate) const
@@ -246,7 +248,7 @@ bool QGeoCirclePrivate::contains(const QGeoCoordinate &coordinate) const
// see QTBUG-41447 for details
qreal distance = m_center.distanceTo(coordinate);
- if (qFuzzyCompare(distance, radius) || distance <= radius)
+ if (qFuzzyCompare(distance, m_radius) || distance <= m_radius)
return true;
return false;
@@ -257,6 +259,103 @@ QGeoCoordinate QGeoCirclePrivate::center() const
return m_center;
}
+QGeoRectangle QGeoCirclePrivate::boundingGeoRectangle() const
+{
+ return m_bbox;
+}
+
+void QGeoCirclePrivate::updateBoundingBox()
+{
+ if (isEmpty()) {
+ if (m_center.isValid()) {
+ m_bbox.setTopLeft(m_center);
+ m_bbox.setBottomRight(m_center);
+ }
+ return;
+ }
+
+ bool crossNorth = crossNorthPole();
+ bool crossSouth = crossSouthPole();
+
+ if (crossNorth && crossSouth) {
+ // Circle crossing both poles fills the whole map
+ m_bbox = QGeoRectangle(QGeoCoordinate(90.0, -180.0), QGeoCoordinate(-90.0, 180.0));
+ } else if (crossNorth) {
+ // Circle crossing one pole fills the map in the longitudinal direction
+ m_bbox = QGeoRectangle(QGeoCoordinate(90.0, -180.0), QGeoCoordinate(m_center.atDistanceAndAzimuth(m_radius, 180.0).latitude(), 180.0));
+ } else if (crossSouth) {
+ m_bbox = QGeoRectangle(QGeoCoordinate(m_center.atDistanceAndAzimuth(m_radius, 0.0).latitude(), -180.0), QGeoCoordinate(-90, 180.0));
+ } else {
+ // Regular circle not crossing anything
+
+ // Calculate geo bounding box of the circle
+ //
+ // A circle tangential point with a meridian, together with pole and
+ // the circle center create a spherical triangle.
+ // Finding the tangential point with the spherical law of sines:
+ //
+ // * lon_delta_in_rad : delta between the circle center and a tangential
+ // point (absolute value).
+ // * r_in_rad : angular radius of the circle
+ // * lat_in_rad : latitude of the circle center
+ // * alpha_in_rad : angle between meridian and radius of the circle.
+ // At the tangential point, sin(alpha_in_rad) == 1.
+ // * lat_delta_in_rad - absolute delta of latitudes between the circle center and
+ // any of the two points where the great circle going through the circle
+ // center and the pole crosses the circle. In other words, the points
+ // on the circle with azimuth 0 or 180.
+ //
+ // Using:
+ // sin(lon_delta_in_rad)/sin(r_in_rad) = sin(alpha_in_rad)/sin(pi/2 - lat_in_rad)
+
+ double r_in_rad = m_radius / QLocationUtils::earthMeanRadius(); // angular r
+ double lat_delta_in_deg = QLocationUtils::degrees(r_in_rad);
+ double lon_delta_in_deg = QLocationUtils::degrees(std::asin(
+ std::sin(r_in_rad) /
+ std::cos(QLocationUtils::radians(m_center.latitude()))
+ ));
+
+ QGeoCoordinate topLeft;
+ topLeft.setLatitude(m_center.latitude() + lat_delta_in_deg);
+ topLeft.setLongitude(m_center.longitude() - lon_delta_in_deg);
+ QGeoCoordinate bottomRight;
+ bottomRight.setLatitude(m_center.latitude() - lat_delta_in_deg);
+ bottomRight.setLongitude(m_center.longitude() + lon_delta_in_deg);
+
+ m_bbox = QGeoRectangle(topLeft, bottomRight);
+ }
+}
+
+void QGeoCirclePrivate::setCenter(const QGeoCoordinate &c)
+{
+ m_center = c;
+ updateBoundingBox();
+}
+
+void QGeoCirclePrivate::setRadius(const qreal r)
+{
+ m_radius = r;
+ updateBoundingBox();
+}
+
+bool QGeoCirclePrivate::crossNorthPole() const
+{
+ const QGeoCoordinate northPole(90.0, m_center.longitude());
+ qreal distanceToPole = m_center.distanceTo(northPole);
+ if (distanceToPole < m_radius)
+ return true;
+ return false;
+}
+
+bool QGeoCirclePrivate::crossSouthPole() const
+{
+ const QGeoCoordinate southPole(-90.0, m_center.longitude());
+ qreal distanceToPole = m_center.distanceTo(southPole);
+ if (distanceToPole < m_radius)
+ return true;
+ return false;
+}
+
/*!
Extends the circle to include \a coordinate
*/
@@ -265,7 +364,7 @@ void QGeoCirclePrivate::extendShape(const QGeoCoordinate &coordinate)
if (!isValid() || !coordinate.isValid() || contains(coordinate))
return;
- radius = m_center.distanceTo(coordinate);
+ setRadius(m_center.distanceTo(coordinate));
}
/*!
@@ -285,12 +384,9 @@ void QGeoCircle::translate(double degreesLatitude, double degreesLongitude)
lat += degreesLatitude;
lon += degreesLongitude;
+ lon = QLocationUtils::wrapLong(lon);
- if (lon < -180.0)
- lon += 360.0;
- if (lon > 180.0)
- lon -= 360.0;
-
+ // TODO: remove this and simply clip latitude.
if (lat > 90.0) {
lat = 180.0 - lat;
if (lon < 0.0)
@@ -307,7 +403,7 @@ void QGeoCircle::translate(double degreesLatitude, double degreesLongitude)
lon -= 180;
}
- d->m_center = QGeoCoordinate(lat, lon);
+ d->setCenter(QGeoCoordinate(lat, lon));
}
/*!
@@ -349,18 +445,19 @@ QString QGeoCircle::toString() const
*******************************************************************************/
QGeoCirclePrivate::QGeoCirclePrivate()
-: QGeoShapePrivate(QGeoShape::CircleType), radius(-1.0)
+: QGeoShapePrivate(QGeoShape::CircleType), m_radius(-1.0)
{
}
QGeoCirclePrivate::QGeoCirclePrivate(const QGeoCoordinate &center, qreal radius)
-: QGeoShapePrivate(QGeoShape::CircleType), m_center(center), radius(radius)
+: QGeoShapePrivate(QGeoShape::CircleType), m_center(center), m_radius(radius)
{
+ updateBoundingBox();
}
QGeoCirclePrivate::QGeoCirclePrivate(const QGeoCirclePrivate &other)
: QGeoShapePrivate(QGeoShape::CircleType), m_center(other.m_center),
- radius(other.radius)
+ m_radius(other.m_radius), m_bbox(other.m_bbox)
{
}
@@ -378,8 +475,7 @@ bool QGeoCirclePrivate::operator==(const QGeoShapePrivate &other) const
const QGeoCirclePrivate &otherCircle = static_cast<const QGeoCirclePrivate &>(other);
- return radius == otherCircle.radius && m_center == otherCircle.m_center;
+ return m_radius == otherCircle.m_radius && m_center == otherCircle.m_center;
}
QT_END_NAMESPACE
-
diff --git a/src/positioning/qgeocircle.h b/src/positioning/qgeocircle.h
index b4b6c45e..e8632fe9 100644
--- a/src/positioning/qgeocircle.h
+++ b/src/positioning/qgeocircle.h
@@ -75,8 +75,8 @@ public:
void setRadius(qreal radius);
qreal radius() const;
- void translate(double degreesLatitude, double degreesLongitude);
- QGeoCircle translated(double degreesLatitude, double degreesLongitude) const;
+ Q_INVOKABLE void translate(double degreesLatitude, double degreesLongitude);
+ Q_INVOKABLE QGeoCircle translated(double degreesLatitude, double degreesLongitude) const;
Q_INVOKABLE QString toString() const;
diff --git a/src/positioning/qgeocircle_p.h b/src/positioning/qgeocircle_p.h
index 311aba8b..07d79db4 100644
--- a/src/positioning/qgeocircle_p.h
+++ b/src/positioning/qgeocircle_p.h
@@ -70,6 +70,14 @@ public:
QGeoCoordinate center() const Q_DECL_OVERRIDE;
+ QGeoRectangle boundingGeoRectangle() const Q_DECL_OVERRIDE;
+
+ bool crossNorthPole() const;
+ bool crossSouthPole() const;
+ void updateBoundingBox();
+ void setCenter(const QGeoCoordinate &c);
+ void setRadius(const qreal r);
+
void extendShape(const QGeoCoordinate &coordinate) Q_DECL_OVERRIDE;
QGeoShapePrivate *clone() const Q_DECL_OVERRIDE;
@@ -77,7 +85,8 @@ public:
bool operator==(const QGeoShapePrivate &other) const Q_DECL_OVERRIDE;
QGeoCoordinate m_center;
- qreal radius;
+ qreal m_radius;
+ QGeoRectangle m_bbox;
};
QT_END_NAMESPACE
diff --git a/src/positioning/qgeocoordinate.cpp b/src/positioning/qgeocoordinate.cpp
index 0386e859..8d39a62e 100644
--- a/src/positioning/qgeocoordinate.cpp
+++ b/src/positioning/qgeocoordinate.cpp
@@ -517,14 +517,8 @@ QGeoCoordinate QGeoCoordinate::atDistanceAndAzimuth(qreal distance, qreal azimut
double resultLon, resultLat;
QGeoCoordinatePrivate::atDistanceAndAzimuth(*this, distance, azimuth,
&resultLon, &resultLat);
-
- if (resultLon > 180.0)
- resultLon -= 360.0;
- else if (resultLon < -180.0)
- resultLon += 360.0;
-
double resultAlt = d->alt + distanceUp;
- return QGeoCoordinate(resultLat, resultLon, resultAlt);
+ return QGeoCoordinate(resultLat, QLocationUtils::wrapLong(resultLon), resultAlt);
}
/*!
diff --git a/src/positioning/qgeopath.cpp b/src/positioning/qgeopath.cpp
new file mode 100644
index 00000000..523a79fb
--- /dev/null
+++ b/src/positioning/qgeopath.cpp
@@ -0,0 +1,679 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 "qgeopath.h"
+#include "qgeopath_p.h"
+
+#include "qgeocoordinate.h"
+#include "qnumeric.h"
+#include "qlocationutils_p.h"
+#include "qgeoprojection_p.h"
+
+#include "qdoublevector2d_p.h"
+#include "qdoublevector3d_p.h"
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QGeoPath
+ \inmodule QtPositioning
+ \ingroup QtPositioning-positioning
+ \since 5.9
+
+ \brief The QGeoPath class defines a geographic path.
+
+ The path is defined by an ordered list of QGeoCoordinates.
+
+ Each two adjacent elements in the path are intended to be connected
+ together by the shortest line segment of constant bearing passing
+ through both elements.
+ This type of connection can cross the dateline in the longitudinal direction,
+ but never crosses the poles.
+
+ This is relevant for the calculation of the bounding box returned by
+ \l QGeoShape::geoBoundingBox() for this shape, which will have the latitude of
+ the top left corner set to the maximum latitude in the path point set.
+ Similarly, the latitude of the bottom right corner will be the minimum latitude
+ in the path point set.
+
+ This class is a \l Q_GADGET.
+ It can be \l{Cpp_value_integration_positioning}{directly used from C++ and QML}.
+*/
+
+/*!
+ \property QGeoPath::path
+ \brief This property holds the list of coordinates for the geo path.
+
+ The path is both invalid and empty if it contains no coordinate.
+
+ A default constructed QGeoPath is therefore invalid.
+*/
+
+inline QGeoPathPrivate *QGeoPath::d_func()
+{
+ return static_cast<QGeoPathPrivate *>(d_ptr.data());
+}
+
+inline const QGeoPathPrivate *QGeoPath::d_func() const
+{
+ return static_cast<const QGeoPathPrivate *>(d_ptr.constData());
+}
+
+struct PathVariantConversions
+{
+ PathVariantConversions()
+ {
+ QMetaType::registerConverter<QGeoShape, QGeoPath>();
+ QMetaType::registerConverter<QGeoPath, QGeoShape>();
+ }
+};
+
+Q_GLOBAL_STATIC(PathVariantConversions, initPathConversions)
+
+/*!
+ Constructs a new, empty geo path.
+*/
+QGeoPath::QGeoPath()
+: QGeoShape(new QGeoPathPrivate)
+{
+ initPathConversions();
+}
+
+/*!
+ Constructs a new geo path from a list of coordinates.
+*/
+QGeoPath::QGeoPath(const QList<QGeoCoordinate> &path, const qreal &width)
+: QGeoShape(new QGeoPathPrivate(path, width))
+{
+ initPathConversions();
+}
+
+/*!
+ Constructs a new geo path from the contents of \a other.
+*/
+QGeoPath::QGeoPath(const QGeoPath &other)
+: QGeoShape(other)
+{
+ initPathConversions();
+}
+
+/*!
+ Constructs a new geo path from the contents of \a other.
+*/
+QGeoPath::QGeoPath(const QGeoShape &other)
+: QGeoShape(other)
+{
+ initPathConversions();
+ if (type() != QGeoShape::PathType)
+ d_ptr = new QGeoPathPrivate;
+}
+
+/*!
+ Destroys this path.
+*/
+QGeoPath::~QGeoPath() {}
+
+/*!
+ Assigns \a other to this geo path and returns a reference to this geo path.
+*/
+QGeoPath &QGeoPath::operator=(const QGeoPath &other)
+{
+ QGeoShape::operator=(other);
+ return *this;
+}
+
+/*!
+ Returns whether this geo path is equal to \a other.
+*/
+bool QGeoPath::operator==(const QGeoPath &other) const
+{
+ Q_D(const QGeoPath);
+ return *d == *other.d_func();
+}
+
+/*!
+ Returns whether this geo path is not equal to \a other.
+*/
+bool QGeoPath::operator!=(const QGeoPath &other) const
+{
+ Q_D(const QGeoPath);
+ return !(*d == *other.d_func());
+}
+
+void QGeoPath::setPath(const QList<QGeoCoordinate> &path)
+{
+ Q_D(QGeoPath);
+ return d->setPath(path);
+}
+
+/*!
+ Returns all the elements. Equivalent to QGeoShape::center().
+ The center coordinate, in case of a QGeoPath, is the center of its bounding box.
+*/
+const QList<QGeoCoordinate> &QGeoPath::path() const
+{
+ Q_D(const QGeoPath);
+ return d->path();
+}
+
+void QGeoPath::setWidth(const qreal &width)
+{
+ Q_D(QGeoPath);
+ d->setWidth(width);
+}
+
+/*!
+ Returns the width of the path, in meters. This information is used in the \l contains method
+ The default value is 0.
+*/
+qreal QGeoPath::width() const
+{
+ Q_D(const QGeoPath);
+ return d->width();
+}
+
+/*!
+ Translates this geo path by \a degreesLatitude northwards and \a degreesLongitude eastwards.
+
+ Negative values of \a degreesLatitude and \a degreesLongitude correspond to
+ southward and westward translation respectively.
+*/
+void QGeoPath::translate(double degreesLatitude, double degreesLongitude)
+{
+ Q_D(QGeoPath);
+ d->translate(degreesLatitude, degreesLongitude);
+}
+
+/*!
+ Returns a copy of this geo path translated by \a degreesLatitude northwards and
+ \a degreesLongitude eastwards.
+
+ Negative values of \a degreesLatitude and \a degreesLongitude correspond to
+ southward and westward translation respectively.
+
+ \sa translate()
+*/
+QGeoPath QGeoPath::translated(double degreesLatitude, double degreesLongitude) const
+{
+ QGeoPath result(*this);
+ result.translate(degreesLatitude, degreesLongitude);
+ return result;
+}
+
+/*!
+ Returns the length of the path, in meters, from the element \a indexFrom to the element \a indexTo.
+ The length is intended to be the sum of the shortest distances for each pair of adjacent points.
+*/
+double QGeoPath::length(int indexFrom, int indexTo) const
+{
+ Q_D(const QGeoPath);
+ return d->length(indexFrom, indexTo);
+}
+
+/*!
+ Appends \a coordinate to the path.
+*/
+void QGeoPath::addCoordinate(const QGeoCoordinate &coordinate)
+{
+ Q_D(QGeoPath);
+ d->addCoordinate(coordinate);
+}
+
+/*!
+ Inserts \a coordinate at the specified \a index.
+*/
+void QGeoPath::insertCoordinate(int index, const QGeoCoordinate &coordinate)
+{
+ Q_D(QGeoPath);
+ d->insertCoordinate(index, coordinate);
+}
+
+/*!
+ Replaces the path element at the specified \a index with \a coordinate.
+*/
+void QGeoPath::replaceCoordinate(int index, const QGeoCoordinate &coordinate)
+{
+ Q_D(QGeoPath);
+ d->replaceCoordinate(index, coordinate);
+}
+
+/*!
+ Returns the coordinate at \a index .
+*/
+QGeoCoordinate QGeoPath::coordinateAt(int index) const
+{
+ Q_D(const QGeoPath);
+ return d->coordinateAt(index);
+}
+
+/*!
+ Returns true if the path contains \a coordinate as one of the elements.
+*/
+bool QGeoPath::containsCoordinate(const QGeoCoordinate &coordinate) const
+{
+ Q_D(const QGeoPath);
+ return d->containsCoordinate(coordinate);
+}
+
+/*!
+ Removes the last occurrence of \a coordinate from the path.
+*/
+void QGeoPath::removeCoordinate(const QGeoCoordinate &coordinate)
+{
+ Q_D(QGeoPath);
+ d->removeCoordinate(coordinate);
+}
+
+/*!
+ Removes element at position \a index from the path.
+*/
+void QGeoPath::removeCoordinate(int index)
+{
+ Q_D(QGeoPath);
+ d->removeCoordinate(index);
+}
+
+/*!
+ Returns the geo path properties as a string.
+*/
+QString QGeoPath::toString() const
+{
+ if (type() != QGeoShape::PathType) {
+ qWarning("Not a path");
+ return QStringLiteral("QGeoPath(not a path)");
+ }
+
+ QString pathString;
+ for (const auto &p : path())
+ pathString += p.toString() + QLatin1Char(',');
+
+ return QStringLiteral("QGeoPath([ %1 ])").arg(pathString);
+}
+
+/*******************************************************************************
+ * QGeoPathPrivate
+*******************************************************************************/
+
+QGeoPathPrivate::QGeoPathPrivate()
+: QGeoShapePrivate(QGeoShape::PathType), m_width(0)
+{
+}
+
+QGeoPathPrivate::QGeoPathPrivate(const QList<QGeoCoordinate> &path, const qreal width)
+: QGeoShapePrivate(QGeoShape::PathType), m_width(0)
+{
+ setPath(path);
+ setWidth(width);
+}
+
+QGeoPathPrivate::QGeoPathPrivate(const QGeoPathPrivate &other)
+: QGeoShapePrivate(QGeoShape::PathType), m_path(other.m_path),
+ m_deltaXs(other.m_deltaXs), m_minX(other.m_minX), m_maxX(other.m_maxX), m_minLati(other.m_minLati),
+ m_maxLati(other.m_maxLati), m_bbox(other.m_bbox), m_width(other.m_width)
+{
+}
+
+QGeoPathPrivate::~QGeoPathPrivate() {}
+
+QGeoShapePrivate *QGeoPathPrivate::clone() const
+{
+ return new QGeoPathPrivate(*this);
+}
+
+bool QGeoPathPrivate::operator==(const QGeoShapePrivate &other) const
+{
+ if (!QGeoShapePrivate::operator==(other))
+ return false;
+
+ const QGeoPathPrivate &otherPath = static_cast<const QGeoPathPrivate &>(other);
+ if (m_path.size() != otherPath.m_path.size())
+ return false;
+ return m_width == otherPath.m_width && m_path == otherPath.m_path;
+}
+
+bool QGeoPathPrivate::isValid() const
+{
+ return !isEmpty();
+}
+
+bool QGeoPathPrivate::isEmpty() const
+{
+ return m_path.isEmpty();
+}
+
+const QList<QGeoCoordinate> &QGeoPathPrivate::path() const
+{
+ return m_path;
+}
+
+void QGeoPathPrivate::setPath(const QList<QGeoCoordinate> &path)
+{
+ for (const QGeoCoordinate &c: path)
+ if (!c.isValid())
+ return;
+ m_path = path;
+ computeBoundingBox();
+}
+
+qreal QGeoPathPrivate::width() const
+{
+ return m_width;
+}
+
+void QGeoPathPrivate::setWidth(const qreal &width)
+{
+ if (qIsNaN(width) || width < 0.0)
+ return;
+ m_width = width;
+}
+
+double QGeoPathPrivate::length(int indexFrom, int indexTo) const
+{
+ if (indexTo < 0 || indexTo >= path().size())
+ indexTo = path().size() - 1;
+ double len = 0.0;
+ // TODO: consider calculating the length of the actual rhumb line segments
+ // instead of the shortest path from A to B.
+ for (int i = indexFrom; i < indexTo; i++)
+ len += m_path[i].distanceTo(m_path[i+1]);
+ return len;
+}
+
+/*!
+ Returns true if coordinate is present in m_path.
+*/
+bool QGeoPathPrivate::contains(const QGeoCoordinate &coordinate) const
+{
+ // Unoptimized approach:
+ // - consider each segment of the path
+ // - project it into mercator space (rhumb lines are straight in mercator space)
+ // - find closest point to coordinate
+ // - unproject the closest point
+ // - calculate coordinate to closest point distance with distanceTo()
+ // - if not within lineRadius, advance
+ //
+ // To keep wrapping into the equation:
+ // If the mercator x value of a coordinate of the line, or the coordinate parameter, is less
+ // than mercator(m_bbox).x, add that to the conversion.
+
+ double lineRadius = qMax(width() * 0.5, 0.2); // minimum radius: 20cm
+
+ if (!m_path.size())
+ return false;
+ else if (m_path.size() == 1)
+ return (m_path[0].distanceTo(coordinate) <= lineRadius);
+
+ double leftBoundMercator = QGeoProjection::coordToMercator(m_bbox.topLeft()).x();
+
+ QDoubleVector2D p = QGeoProjection::coordToMercator(coordinate);
+ if (p.x() < leftBoundMercator)
+ p.setX(p.x() + leftBoundMercator); // unwrap X
+
+ QDoubleVector2D a;
+ QDoubleVector2D b;
+ if (m_path.size()) {
+ a = QGeoProjection::coordToMercator(m_path[0]);
+ if (a.x() < leftBoundMercator)
+ a.setX(a.x() + leftBoundMercator); // unwrap X
+ }
+ for (int i = 1; i < m_path.size(); i++) {
+ b = QGeoProjection::coordToMercator(m_path[i]);
+ if (b.x() < leftBoundMercator)
+ b.setX(b.x() + leftBoundMercator); // unwrap X
+ if (b == a)
+ continue;
+
+ double u = ((p.x() - a.x()) * (b.x() - a.x()) + (p.y() - a.y()) * (b.y() - a.y()) ) / (b - a).lengthSquared();
+ QDoubleVector2D intersection(a.x() + u * (b.x() - a.x()) , a.y() + u * (b.y() - a.y()) );
+
+ QDoubleVector2D candidate = ( (p-a).length() < (p-b).length() ) ? a : b;
+
+ if (u < (b - a).length()
+ && (p-intersection).length() < (p-candidate).length() ) // And it falls in the segment
+ candidate = intersection;
+
+
+ if (candidate.x() > 1.0)
+ candidate.setX(candidate.x() - leftBoundMercator); // wrap X
+
+ QGeoCoordinate closest = QGeoProjection::mercatorToCoord(candidate);
+
+ double distanceMeters = coordinate.distanceTo(closest);
+ if (distanceMeters <= lineRadius)
+ return true;
+
+ // swap
+ a = b;
+ }
+
+ // Last check if the coordinate is on the left of leftBoundMercator, but close enough to
+ // m_path[0]
+ return (m_path[0].distanceTo(coordinate) <= lineRadius);
+}
+
+QGeoCoordinate QGeoPathPrivate::center() const
+{
+ return boundingGeoRectangle().center();
+}
+
+QGeoRectangle QGeoPathPrivate::boundingGeoRectangle() const
+{
+ return m_bbox;
+}
+
+void QGeoPathPrivate::extendShape(const QGeoCoordinate &coordinate)
+{
+ if (!coordinate.isValid() || contains(coordinate))
+ return;
+ addCoordinate(coordinate);
+}
+
+void QGeoPathPrivate::translate(double degreesLatitude, double degreesLongitude)
+{
+ if (degreesLatitude > 0.0)
+ degreesLatitude = qMin(degreesLatitude, 90.0 - m_maxLati);
+ else
+ degreesLatitude = qMax(degreesLatitude, -90.0 - m_minLati);
+ for (QGeoCoordinate &p: m_path) {
+ p.setLatitude(p.latitude() + degreesLatitude);
+ p.setLongitude(QLocationUtils::wrapLong(p.longitude() + degreesLongitude));
+ }
+ m_bbox.translate(degreesLatitude, degreesLongitude);
+ m_minLati += degreesLatitude;
+ m_maxLati += degreesLatitude;
+}
+
+void QGeoPathPrivate::addCoordinate(const QGeoCoordinate &coordinate)
+{
+ if (!coordinate.isValid())
+ return;
+ m_path.append(coordinate);
+ updateBoundingBox();
+}
+
+void QGeoPathPrivate::insertCoordinate(int index, const QGeoCoordinate &coordinate)
+{
+ if (index < 0 || index > m_path.size() || !coordinate.isValid())
+ return;
+
+ m_path.insert(index, coordinate);
+ computeBoundingBox();
+}
+
+void QGeoPathPrivate::replaceCoordinate(int index, const QGeoCoordinate &coordinate)
+{
+ if (index < 0 || index >= m_path.size() || !coordinate.isValid())
+ return;
+
+ m_path[index] = coordinate;
+ computeBoundingBox();
+}
+
+QGeoCoordinate QGeoPathPrivate::coordinateAt(int index) const
+{
+ if (index < 0 || index >= m_path.size())
+ return QGeoCoordinate();
+
+ return m_path.at(index);
+}
+
+bool QGeoPathPrivate::containsCoordinate(const QGeoCoordinate &coordinate) const
+{
+ return m_path.indexOf(coordinate) > -1;
+}
+
+void QGeoPathPrivate::removeCoordinate(const QGeoCoordinate &coordinate)
+{
+ int index = m_path.lastIndexOf(coordinate);
+ removeCoordinate(index);
+}
+
+void QGeoPathPrivate::removeCoordinate(int index)
+{
+ if (index < 0 || index >= m_path.size())
+ return;
+
+ m_path.removeAt(index);
+ computeBoundingBox();
+}
+
+void QGeoPathPrivate::computeBoundingBox()
+{
+ if (m_path.isEmpty()) {
+ m_deltaXs.clear();
+ m_minX = qInf();
+ m_maxX = -qInf();
+ m_minLati = qInf();
+ m_maxLati = -qInf();
+ m_bbox = QGeoRectangle();
+ return;
+ }
+
+ m_minLati = m_maxLati = m_path.at(0).latitude();
+ int minId = 0;
+ int maxId = 0;
+ m_deltaXs.resize(m_path.size());
+ m_deltaXs[0] = m_minX = m_maxX = 0.0;
+
+ for (int i = 1; i < m_path.size(); i++) {
+ const QGeoCoordinate &geoFrom = m_path.at(i-1);
+ const QGeoCoordinate &geoTo = m_path.at(i);
+ double longiFrom = geoFrom.longitude();
+ double longiTo = geoTo.longitude();
+ double deltaLongi = longiTo - longiFrom;
+ if (qAbs(deltaLongi) > 180.0) {
+ if (longiTo > 0.0)
+ longiTo -= 360.0;
+ else
+ longiTo += 360.0;
+ deltaLongi = longiTo - longiFrom;
+ }
+ m_deltaXs[i] = m_deltaXs[i-1] + deltaLongi;
+ if (m_deltaXs[i] < m_minX) {
+ m_minX = m_deltaXs[i];
+ minId = i;
+ }
+ if (m_deltaXs[i] > m_maxX) {
+ m_maxX = m_deltaXs[i];
+ maxId = i;
+ }
+ if (geoTo.latitude() > m_maxLati)
+ m_maxLati = geoTo.latitude();
+ if (geoTo.latitude() < m_minLati)
+ m_minLati = geoTo.latitude();
+ }
+
+ m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, m_path.at(minId).longitude()),
+ QGeoCoordinate(m_minLati, m_path.at(maxId).longitude()));
+}
+
+void QGeoPathPrivate::updateBoundingBox()
+{
+ if (m_path.isEmpty()) {
+ m_deltaXs.clear();
+ m_minX = qInf();
+ m_maxX = -qInf();
+ m_minLati = qInf();
+ m_maxLati = -qInf();
+ m_bbox = QGeoRectangle();
+ return;
+ } else if (m_path.size() == 1) { // was 0 now is 1
+ m_deltaXs.resize(1);
+ m_deltaXs[0] = m_minX = m_maxX = 0.0;
+ m_minLati = m_maxLati = m_path.at(0).latitude();
+ m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, m_path.at(0).longitude()),
+ QGeoCoordinate(m_minLati, m_path.at(0).longitude()));
+ return;
+ } else if ( m_path.size() != m_deltaXs.size() + 1 ) { // this case should not happen
+ computeBoundingBox(); // something went wrong
+ return;
+ }
+
+ const QGeoCoordinate &geoFrom = m_path.at(m_path.size()-2);
+ const QGeoCoordinate &geoTo = m_path.last();
+ double longiFrom = geoFrom.longitude();
+ double longiTo = geoTo.longitude();
+ double deltaLongi = longiTo - longiFrom;
+ if (qAbs(deltaLongi) > 180.0) {
+ if (longiTo > 0.0)
+ longiTo -= 360.0;
+ else
+ longiTo += 360.0;
+ deltaLongi = longiTo - longiFrom;
+ }
+
+ m_deltaXs.push_back(m_deltaXs.last() + deltaLongi);
+ double currentMinLongi = m_bbox.topLeft().longitude();
+ double currentMaxLongi = m_bbox.bottomRight().longitude();
+ if (m_deltaXs.last() < m_minX) {
+ m_minX = m_deltaXs.last();
+ currentMinLongi = geoTo.longitude();
+ }
+ if (m_deltaXs.last() > m_maxX) {
+ m_maxX = m_deltaXs.last();
+ currentMaxLongi = geoTo.longitude();
+ }
+ if (geoTo.latitude() > m_maxLati)
+ m_maxLati = geoTo.latitude();
+ if (geoTo.latitude() < m_minLati)
+ m_minLati = geoTo.latitude();
+ m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, currentMinLongi),
+ QGeoCoordinate(m_minLati, currentMaxLongi));
+}
+
+QT_END_NAMESPACE
diff --git a/src/positioning/qgeopath.h b/src/positioning/qgeopath.h
new file mode 100644
index 00000000..09a53a49
--- /dev/null
+++ b/src/positioning/qgeopath.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 QGEOPATH_H
+#define QGEOPATH_H
+
+#include <QtPositioning/QGeoShape>
+
+QT_BEGIN_NAMESPACE
+
+class QGeoCoordinate;
+class QGeoPathPrivate;
+
+class Q_POSITIONING_EXPORT QGeoPath : public QGeoShape
+{
+ Q_GADGET
+ Q_PROPERTY(QList<QGeoCoordinate> path READ path WRITE setPath)
+ Q_PROPERTY(qreal width READ width WRITE setWidth)
+
+public:
+ QGeoPath();
+ QGeoPath(const QList<QGeoCoordinate> &path, const qreal &width = 0.0);
+ QGeoPath(const QGeoPath &other);
+ QGeoPath(const QGeoShape &other);
+
+ ~QGeoPath();
+
+ QGeoPath &operator=(const QGeoPath &other);
+
+ using QGeoShape::operator==;
+ bool operator==(const QGeoPath &other) const;
+
+ using QGeoShape::operator!=;
+ bool operator!=(const QGeoPath &other) const;
+
+ void setPath(const QList<QGeoCoordinate> &path);
+ const QList<QGeoCoordinate> &path() const;
+
+ void setWidth(const qreal &width);
+ qreal width() const;
+
+ Q_INVOKABLE void translate(double degreesLatitude, double degreesLongitude);
+ Q_INVOKABLE QGeoPath translated(double degreesLatitude, double degreesLongitude) const;
+ Q_INVOKABLE double length(int indexFrom = 0, int indexTo = -1) const;
+ Q_INVOKABLE void addCoordinate(const QGeoCoordinate &coordinate);
+ Q_INVOKABLE void insertCoordinate(int index, const QGeoCoordinate &coordinate);
+ Q_INVOKABLE void replaceCoordinate(int index, const QGeoCoordinate &coordinate);
+ Q_INVOKABLE QGeoCoordinate coordinateAt(int index) const;
+ Q_INVOKABLE bool containsCoordinate(const QGeoCoordinate &coordinate) const;
+ Q_INVOKABLE void removeCoordinate(const QGeoCoordinate &coordinate);
+ Q_INVOKABLE void removeCoordinate(int index);
+
+ Q_INVOKABLE QString toString() const;
+
+private:
+ inline QGeoPathPrivate *d_func();
+ inline const QGeoPathPrivate *d_func() const;
+};
+
+Q_DECLARE_TYPEINFO(QGeoPath, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QGeoPath)
+
+#endif // QGEOPATH_H
diff --git a/src/positioning/qgeopath_p.h b/src/positioning/qgeopath_p.h
new file mode 100644
index 00000000..2256796d
--- /dev/null
+++ b/src/positioning/qgeopath_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 QGEOPATH_P_H
+#define QGEOPATH_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 "qgeoshape_p.h"
+#include "qgeocoordinate.h"
+#include "qlocationutils_p.h"
+
+#include <QtCore/QVector>
+
+QT_BEGIN_NAMESPACE
+
+class QGeoPathPrivate : public QGeoShapePrivate
+{
+public:
+ QGeoPathPrivate();
+ QGeoPathPrivate(const QList<QGeoCoordinate> &path, const qreal width = 0.0);
+ QGeoPathPrivate(const QGeoPathPrivate &other);
+ ~QGeoPathPrivate();
+
+ bool isValid() const Q_DECL_OVERRIDE;
+ bool isEmpty() const Q_DECL_OVERRIDE;
+ bool contains(const QGeoCoordinate &coordinate) const Q_DECL_OVERRIDE;
+
+ QGeoCoordinate center() const Q_DECL_OVERRIDE;
+ QGeoRectangle boundingGeoRectangle() const Q_DECL_OVERRIDE;
+ void extendShape(const QGeoCoordinate &coordinate) Q_DECL_OVERRIDE;
+ void translate(double degreesLatitude, double degreesLongitude);
+
+ QGeoShapePrivate *clone() const Q_DECL_OVERRIDE;
+
+ bool operator==(const QGeoShapePrivate &other) const Q_DECL_OVERRIDE;
+
+ const QList<QGeoCoordinate> &path() const;
+ void setPath(const QList<QGeoCoordinate> &path);
+ qreal width() const;
+ void setWidth(const qreal &width);
+ double length(int indexFrom, int indexTo) const;
+ void addCoordinate(const QGeoCoordinate &coordinate);
+ void insertCoordinate(int index, const QGeoCoordinate &coordinate);
+ void replaceCoordinate(int index, const QGeoCoordinate &coordinate);
+ QGeoCoordinate coordinateAt(int index) const;
+ bool containsCoordinate(const QGeoCoordinate &coordinate) const;
+ void removeCoordinate(const QGeoCoordinate &coordinate);
+ void removeCoordinate(int index);
+ void computeBoundingBox();
+ void updateBoundingBox();
+
+
+ QList<QGeoCoordinate> m_path;
+ QVector<double> m_deltaXs; // longitude deltas from m_path[0]
+ double m_minX; // minimum value inside deltaXs
+ double m_maxX; // maximum value inside deltaXs
+ double m_minLati; // minimum latitude. paths do not wrap around through the poles
+ double m_maxLati; // minimum latitude. paths do not wrap around through the poles
+ QGeoRectangle m_bbox;
+ qreal m_width;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGEOPATH_P_H
diff --git a/src/positioning/qgeorectangle.cpp b/src/positioning/qgeorectangle.cpp
index bbcafd6b..e74beee3 100644
--- a/src/positioning/qgeorectangle.cpp
+++ b/src/positioning/qgeorectangle.cpp
@@ -40,8 +40,11 @@
#include "qgeorectangle.h"
#include "qgeorectangle_p.h"
+#include "qgeoprojection_p.h"
+#include "qdoublevector2d_p.h"
#include "qgeocoordinate.h"
#include "qnumeric.h"
+#include "qlocationutils_p.h"
#include <QList>
QT_BEGIN_NAMESPACE
@@ -440,16 +443,8 @@ void QGeoRectangle::setCenter(const QGeoCoordinate &center)
double tlLon = center.longitude() - width / 2.0;
double brLat = center.latitude() - height / 2.0;
double brLon = center.longitude() + width / 2.0;
-
- if (tlLon < -180.0)
- tlLon += 360.0;
- if (tlLon > 180.0)
- tlLon -= 360.0;
-
- if (brLon < -180.0)
- brLon += 360.0;
- if (brLon > 180.0)
- brLon -= 360.0;
+ tlLon = QLocationUtils::wrapLong(tlLon);
+ brLon = QLocationUtils::wrapLong(brLon);
if (tlLat > 90.0) {
brLat = 2 * center.latitude() - 90.0;
@@ -515,18 +510,10 @@ void QGeoRectangle::setWidth(double degreesWidth)
QGeoCoordinate c = center();
double tlLon = c.longitude() - degreesWidth / 2.0;
-
- if (tlLon < -180.0)
- tlLon += 360.0;
- if (tlLon > 180.0)
- tlLon -= 360.0;
+ tlLon = QLocationUtils::wrapLong(tlLon);
double brLon = c.longitude() + degreesWidth / 2.0;
-
- if (brLon < -180.0)
- brLon += 360.0;
- if (brLon > 180.0)
- brLon -= 360.0;
+ brLon = QLocationUtils::wrapLong(brLon);
d->topLeft = QGeoCoordinate(tlLat, tlLon);
d->bottomRight = QGeoCoordinate(brLat, brLon);
@@ -614,10 +601,7 @@ double QGeoRectangle::height() const
Q_D(const QGeoRectangle);
- double result = d->topLeft.latitude() - d->bottomRight.latitude();
- if (result < 0.0)
- result = qQNaN();
- return result;
+ return d->topLeft.latitude() - d->bottomRight.latitude();
}
bool QGeoRectanglePrivate::contains(const QGeoCoordinate &coordinate) const
@@ -666,14 +650,15 @@ QGeoCoordinate QGeoRectanglePrivate::center() const
if (topLeft.longitude() > bottomRight.longitude())
cLon = cLon - 180.0;
- if (cLon < -180.0)
- cLon += 360.0;
- if (cLon > 180.0)
- cLon -= 360.0;
-
+ cLon = QLocationUtils::wrapLong(cLon);
return QGeoCoordinate(cLat, cLon);
}
+QGeoRectangle QGeoRectanglePrivate::boundingGeoRectangle() const
+{
+ return QGeoRectangle(topLeft, bottomRight);
+}
+
/*!
Returns whether the geo rectangle \a rectangle is contained within this
geo rectangle.
@@ -763,37 +748,18 @@ void QGeoRectangle::translate(double degreesLatitude, double degreesLongitude)
double brLat = d->bottomRight.latitude();
double brLon = d->bottomRight.longitude();
- if ((tlLat != 90.0) || (brLat != -90.0)) {
- tlLat += degreesLatitude;
- brLat += degreesLatitude;
- }
+ if (degreesLatitude >= 0.0)
+ degreesLatitude = qMin(degreesLatitude, 90.0 - tlLat);
+ else
+ degreesLatitude = qMax(degreesLatitude, -90.0 - brLat);
if ( (tlLon != -180.0) || (brLon != 180.0) ) {
- tlLon += degreesLongitude;
- brLon += degreesLongitude;
+ tlLon = QLocationUtils::wrapLong(tlLon + degreesLongitude);
+ brLon = QLocationUtils::wrapLong(brLon + degreesLongitude);
}
- if (tlLon < -180.0)
- tlLon += 360.0;
- if (tlLon > 180.0)
- tlLon -= 360.0;
-
- if (brLon < -180.0)
- brLon += 360.0;
- if (brLon > 180.0)
- brLon -= 360.0;
-
- if (tlLat > 90.0)
- tlLat = 90.0;
-
- if (tlLat < -90.0)
- tlLat = -90.0;
-
- if (brLat > 90.0)
- brLat = 90.0;
-
- if (brLat < -90.0)
- brLat = -90.0;
+ tlLat += degreesLatitude;
+ brLat += degreesLatitude;
d->topLeft = QGeoCoordinate(tlLat, tlLon);
d->bottomRight = QGeoCoordinate(brLat, brLon);
diff --git a/src/positioning/qgeorectangle.h b/src/positioning/qgeorectangle.h
index 7e921730..9e9acf91 100644
--- a/src/positioning/qgeorectangle.h
+++ b/src/positioning/qgeorectangle.h
@@ -42,89 +42,7 @@
#include <QtPositioning/QGeoShape>
-QT_BEGIN_NAMESPACE
-
-class QGeoCoordinate;
-class QGeoRectanglePrivate;
-
-class Q_POSITIONING_EXPORT QGeoRectangle : public QGeoShape
-{
- Q_GADGET
- Q_PROPERTY(QGeoCoordinate bottomLeft READ bottomLeft WRITE setBottomLeft)
- Q_PROPERTY(QGeoCoordinate bottomRight READ bottomRight WRITE setBottomRight)
- Q_PROPERTY(QGeoCoordinate topLeft READ topLeft WRITE setTopLeft)
- Q_PROPERTY(QGeoCoordinate topRight READ topRight WRITE setTopRight)
- Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter)
- Q_PROPERTY(double height READ height WRITE setHeight)
- Q_PROPERTY(double width READ width WRITE setWidth)
-
-public:
- QGeoRectangle();
- QGeoRectangle(const QGeoCoordinate &center, double degreesWidth, double degreesHeight);
- QGeoRectangle(const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight);
- QGeoRectangle(const QList<QGeoCoordinate> &coordinates);
- QGeoRectangle(const QGeoRectangle &other);
- QGeoRectangle(const QGeoShape &other);
-
- ~QGeoRectangle();
-
- QGeoRectangle &operator=(const QGeoRectangle &other);
-
- using QGeoShape::operator==;
- bool operator==(const QGeoRectangle &other) const;
-
- using QGeoShape::operator!=;
- bool operator!=(const QGeoRectangle &other) const;
-
- void setTopLeft(const QGeoCoordinate &topLeft);
- QGeoCoordinate topLeft() const;
-
- void setTopRight(const QGeoCoordinate &topRight);
- QGeoCoordinate topRight() const;
-
- void setBottomLeft(const QGeoCoordinate &bottomLeft);
- QGeoCoordinate bottomLeft() const;
-
- void setBottomRight(const QGeoCoordinate &bottomRight);
- QGeoCoordinate bottomRight() const;
-
- void setCenter(const QGeoCoordinate &center);
- QGeoCoordinate center() const;
-
- void setWidth(double degreesWidth);
- double width() const;
-
- void setHeight(double degreesHeight);
- double height() const;
-
- using QGeoShape::contains;
- bool contains(const QGeoRectangle &rectangle) const;
- bool intersects(const QGeoRectangle &rectangle) const;
-
- void translate(double degreesLatitude, double degreesLongitude);
- QGeoRectangle translated(double degreesLatitude, double degreesLongitude) const;
-
- QGeoRectangle united(const QGeoRectangle &rectangle) const;
- QGeoRectangle operator|(const QGeoRectangle &rectangle) const;
- QGeoRectangle &operator|=(const QGeoRectangle &rectangle);
-
- Q_INVOKABLE QString toString() const;
-
-private:
- inline QGeoRectanglePrivate *d_func();
- inline const QGeoRectanglePrivate *d_func() const;
-};
-
-Q_DECLARE_TYPEINFO(QGeoRectangle, Q_MOVABLE_TYPE);
-
-inline QGeoRectangle QGeoRectangle::operator|(const QGeoRectangle &rectangle) const
-{
- return united(rectangle);
-}
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QGeoRectangle)
+// QGeoRectangle declaration now in qgeoshape.h.
+// This file remains for compatibility.
#endif
-
diff --git a/src/positioning/qgeorectangle_p.h b/src/positioning/qgeorectangle_p.h
index 188e5548..ee1b1732 100644
--- a/src/positioning/qgeorectangle_p.h
+++ b/src/positioning/qgeorectangle_p.h
@@ -70,6 +70,8 @@ public:
QGeoCoordinate center() const Q_DECL_OVERRIDE;
+ QGeoRectangle boundingGeoRectangle() const Q_DECL_OVERRIDE;
+
void extendShape(const QGeoCoordinate &coordinate) Q_DECL_OVERRIDE;
QGeoShapePrivate *clone() const Q_DECL_OVERRIDE;
diff --git a/src/positioning/qgeoshape.cpp b/src/positioning/qgeoshape.cpp
index bac37605..c1f7bd9d 100644
--- a/src/positioning/qgeoshape.cpp
+++ b/src/positioning/qgeoshape.cpp
@@ -41,6 +41,8 @@
#include "qgeoshape_p.h"
#include "qgeorectangle.h"
#include "qgeocircle.h"
+#include "qgeopath.h"
+
#ifndef QT_NO_DEBUG_STREAM
#include <QtCore/QDebug>
@@ -227,6 +229,22 @@ bool QGeoShape::contains(const QGeoCoordinate &coordinate) const
}
/*!
+ Returns a \a QGeoRectangle representing the geographical bounding rectangle of the
+ geo shape, that defines the latitudinal/longitudinal bounds of the geo shape.
+
+ \since 5.9
+*/
+QGeoRectangle QGeoShape::boundingGeoRectangle() const
+{
+ Q_D(const QGeoShape);
+
+ if (d)
+ return d->boundingGeoRectangle();
+ else
+ return QGeoRectangle();
+}
+
+/*!
Returns the coordinate located at the geometric center of the geo shape.
\since 5.5
@@ -313,6 +331,9 @@ QDebug operator<<(QDebug dbg, const QGeoShape &shape)
case QGeoShape::RectangleType:
dbg << "Rectangle";
break;
+ case QGeoShape::PathType:
+ dbg << "Path";
+ break;
case QGeoShape::CircleType:
dbg << "Circle";
}
@@ -340,6 +361,13 @@ QDataStream &operator<<(QDataStream &stream, const QGeoShape &shape)
stream << c.center() << c.radius();
break;
}
+ case QGeoShape::PathType: {
+ QGeoPath p = shape;
+ stream << p.path().size();
+ for (const auto &c: p.path())
+ stream << c;
+ break;
+ }
}
return stream;
@@ -368,6 +396,18 @@ QDataStream &operator>>(QDataStream &stream, QGeoShape &shape)
shape = QGeoCircle(c, r);
break;
}
+ case QGeoShape::PathType: {
+ QList<QGeoCoordinate> l;
+ QGeoCoordinate c;
+ int sz;
+ stream >> sz;
+ for (int i = 0; i < sz; i++) {
+ stream >> c;
+ l.append(c);
+ }
+ shape = QGeoPath(l);
+ break;
+ }
}
return stream;
diff --git a/src/positioning/qgeoshape.h b/src/positioning/qgeoshape.h
index f8a30358..40123f88 100644
--- a/src/positioning/qgeoshape.h
+++ b/src/positioning/qgeoshape.h
@@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE
class QDebug;
class QGeoShapePrivate;
+class QGeoRectangle;
class Q_POSITIONING_EXPORT QGeoShape
{
@@ -64,7 +65,8 @@ public:
enum ShapeType {
UnknownType,
RectangleType,
- CircleType
+ CircleType,
+ PathType
};
ShapeType type() const;
@@ -72,10 +74,10 @@ public:
bool isValid() const;
bool isEmpty() const;
Q_INVOKABLE bool contains(const QGeoCoordinate &coordinate) const;
+ Q_INVOKABLE QGeoRectangle boundingGeoRectangle() const;
+ Q_INVOKABLE QGeoCoordinate center() const;
- QGeoCoordinate center() const;
-
- void extendShape(const QGeoCoordinate &coordinate);
+ Q_INVOKABLE void extendShape(const QGeoCoordinate &coordinate);
bool operator==(const QGeoShape &other) const;
bool operator!=(const QGeoShape &other) const;
@@ -104,9 +106,89 @@ Q_POSITIONING_EXPORT QDataStream &operator<<(QDataStream &stream, const QGeoShap
Q_POSITIONING_EXPORT QDataStream &operator>>(QDataStream &stream, QGeoShape &shape);
#endif
+
+
+// QGeoRectangle is declared here because of QGeoShape::boundingGeoRectangle
+class QGeoRectanglePrivate;
+
+class Q_POSITIONING_EXPORT QGeoRectangle : public QGeoShape
+{
+ Q_GADGET
+ Q_PROPERTY(QGeoCoordinate bottomLeft READ bottomLeft WRITE setBottomLeft)
+ Q_PROPERTY(QGeoCoordinate bottomRight READ bottomRight WRITE setBottomRight)
+ Q_PROPERTY(QGeoCoordinate topLeft READ topLeft WRITE setTopLeft)
+ Q_PROPERTY(QGeoCoordinate topRight READ topRight WRITE setTopRight)
+ Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter)
+ Q_PROPERTY(double height READ height WRITE setHeight)
+ Q_PROPERTY(double width READ width WRITE setWidth)
+
+public:
+ QGeoRectangle();
+ QGeoRectangle(const QGeoCoordinate &center, double degreesWidth, double degreesHeight);
+ QGeoRectangle(const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight);
+ QGeoRectangle(const QList<QGeoCoordinate> &coordinates);
+ QGeoRectangle(const QGeoRectangle &other);
+ QGeoRectangle(const QGeoShape &other);
+
+ ~QGeoRectangle();
+
+ QGeoRectangle &operator=(const QGeoRectangle &other);
+
+ using QGeoShape::operator==;
+ bool operator==(const QGeoRectangle &other) const;
+
+ using QGeoShape::operator!=;
+ bool operator!=(const QGeoRectangle &other) const;
+
+ void setTopLeft(const QGeoCoordinate &topLeft);
+ QGeoCoordinate topLeft() const;
+
+ void setTopRight(const QGeoCoordinate &topRight);
+ QGeoCoordinate topRight() const;
+
+ void setBottomLeft(const QGeoCoordinate &bottomLeft);
+ QGeoCoordinate bottomLeft() const;
+
+ void setBottomRight(const QGeoCoordinate &bottomRight);
+ QGeoCoordinate bottomRight() const;
+
+ void setCenter(const QGeoCoordinate &center);
+ QGeoCoordinate center() const;
+
+ void setWidth(double degreesWidth);
+ double width() const;
+
+ void setHeight(double degreesHeight);
+ double height() const;
+
+ using QGeoShape::contains;
+ bool contains(const QGeoRectangle &rectangle) const;
+ Q_INVOKABLE bool intersects(const QGeoRectangle &rectangle) const;
+
+ Q_INVOKABLE void translate(double degreesLatitude, double degreesLongitude);
+ Q_INVOKABLE QGeoRectangle translated(double degreesLatitude, double degreesLongitude) const;
+
+ Q_INVOKABLE QGeoRectangle united(const QGeoRectangle &rectangle) const;
+ QGeoRectangle operator|(const QGeoRectangle &rectangle) const;
+ QGeoRectangle &operator|=(const QGeoRectangle &rectangle);
+
+ Q_INVOKABLE QString toString() const;
+
+private:
+ inline QGeoRectanglePrivate *d_func();
+ inline const QGeoRectanglePrivate *d_func() const;
+};
+
+Q_DECLARE_TYPEINFO(QGeoRectangle, Q_MOVABLE_TYPE);
+
+inline QGeoRectangle QGeoRectangle::operator|(const QGeoRectangle &rectangle) const
+{
+ return united(rectangle);
+}
+
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QGeoShape)
+Q_DECLARE_METATYPE(QGeoRectangle)
#endif
-
diff --git a/src/positioning/qgeoshape_p.h b/src/positioning/qgeoshape_p.h
index 275886ff..251e872c 100644
--- a/src/positioning/qgeoshape_p.h
+++ b/src/positioning/qgeoshape_p.h
@@ -69,6 +69,8 @@ public:
virtual QGeoCoordinate center() const = 0;
+ virtual QGeoRectangle boundingGeoRectangle() const = 0;
+
virtual void extendShape(const QGeoCoordinate &coordinate) = 0;
virtual QGeoShapePrivate *clone() const = 0;
@@ -89,4 +91,3 @@ Q_INLINE_TEMPLATE QGeoShapePrivate *QSharedDataPointer<QGeoShapePrivate>::clone(
QT_END_NAMESPACE
#endif
-
diff --git a/src/positioning/qlocationutils_p.h b/src/positioning/qlocationutils_p.h
index 00c4d3e3..32addb63 100644
--- a/src/positioning/qlocationutils_p.h
+++ b/src/positioning/qlocationutils_p.h
@@ -53,6 +53,14 @@
#include <QtCore/QtGlobal>
#include <math.h>
+#ifndef M_1_180
+#define M_1_180 0.0055555555555555555555555555555555555555556
+#endif
+
+#ifndef M_1_PI
+#define M_1_PI 0.31830988618379067154
+#endif
+
QT_BEGIN_NAMESPACE
class QTime;
class QByteArray;
@@ -176,6 +184,47 @@ public:
return CardinalNNW;
}
+ // For values exceeding +- 720.0
+ inline static double wrapLongExt(double lng) {
+ double remainder = fmod(lng + 180.0, 360.0);
+ return fmod(remainder + 360.0, 360.0) - 180.0;
+ }
+
+ // Mirrors the azimuth against the X axis. Azimuth assumed to be in [0,360[
+ inline static double mirrorAzimuthX(double azimuth) {
+ if (azimuth <= 90.0)
+ return 180.0 - azimuth;
+ else
+ return 180.0 + (360.0 - azimuth);
+ }
+
+ // Mirrors the azimuth against the Y axis. Azimuth assumed to be in [0,360[
+ inline static double mirrorAzimuthY(double azimuth) {
+ if (azimuth == 0.0)
+ return 0.0;
+ return 360.0 - azimuth;
+ }
+
+ inline static double radians(double degrees)
+ {
+ return degrees * M_PI * M_1_180;
+ }
+
+ inline static double degrees(double radians)
+ {
+ return radians * 180.0 * M_1_PI;
+ }
+
+ inline static double earthMeanRadius()
+ {
+ return 6371007.2;
+ }
+
+ inline static double mercatorMaxLatitude()
+ {
+ return 85.05113;
+ }
+
/*
Creates a QGeoPositionInfo from a GGA, GLL, RMC, VTG or ZDA sentence.
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index e3236deb..ba7dc523 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -74,6 +74,7 @@ SUBDIRS += \
qgeoshape \
qgeorectangle \
qgeocircle \
+ qgeopath \
qgeocoordinate \
qgeolocation \
qgeopositioninfo \
diff --git a/tests/auto/declarative_ui/tst_map.qml b/tests/auto/declarative_ui/tst_map.qml
index 5f02962d..a81885fb 100644
--- a/tests/auto/declarative_ui/tst_map.qml
+++ b/tests/auto/declarative_ui/tst_map.qml
@@ -28,8 +28,8 @@
import QtQuick 2.0
import QtTest 1.0
-import QtLocation 5.6
import QtPositioning 5.5
+import QtLocation 5.9
Item {
width:100
@@ -82,7 +82,11 @@ Item {
Map {id: coordinateMap; plugin: herePlugin; center: coordinate3;
width: 1000; height: 1000; zoomLevel: 15 }
-
+ MapParameter {
+ id: testParameter
+ type: "cameraCenter_test"
+ property var center: QtPositioning.coordinate(-33.0, -47.0)
+ }
TestCase {
@@ -128,6 +132,51 @@ Item {
compare(map.center.latitude, 12)
}
+ function test_map_parameters()
+ {
+ // coordinate is set at map element declaration
+ var center = map.toCoordinate(Qt.point((map.width - 1) / 2.0, (map.height - 1) / 2.0))
+ fuzzyCompare(center.latitude, 10, 0.1)
+ fuzzyCompare(center.longitude, 11, 0.1)
+
+ compare(map.mapParameters.length, 0)
+
+ map.addMapParameter(testParameter)
+
+ compare(map.mapParameters.length, 1)
+
+ center = map.toCoordinate(Qt.point((map.width - 1) / 2.0, (map.height - 1) / 2.0))
+ fuzzyCompare(center.latitude, -33, 0.1)
+ fuzzyCompare(center.longitude, -47, 0.1)
+
+ map.addMapParameter(testParameter)
+ compare(map.mapParameters.length, 1)
+
+ map.removeMapParameter(testParameter)
+ compare(map.mapParameters.length, 0)
+
+ center = map.toCoordinate(Qt.point((map.width - 1) / 2.0, (map.height - 1) / 2.0))
+ fuzzyCompare(center.latitude, -33, 0.1)
+ fuzzyCompare(center.longitude, -47, 0.1)
+
+ testParameter.center = map.center
+ map.addMapParameter(testParameter)
+ compare(map.mapParameters.length, 1)
+
+ var center = map.toCoordinate(Qt.point((map.width - 1) / 2.0, (map.height - 1) / 2.0))
+ fuzzyCompare(center.latitude, 10, 0.1)
+ fuzzyCompare(center.longitude, 11, 0.1)
+
+ testParameter.center = QtPositioning.coordinate(-33.0, -47.0)
+
+ center = map.toCoordinate(Qt.point((map.width - 1) / 2.0, (map.height - 1) / 2.0))
+ fuzzyCompare(center.latitude, -33, 0.1)
+ fuzzyCompare(center.longitude, -47, 0.1)
+
+ map.removeMapParameter(testParameter)
+ compare(map.mapParameters.length, 0)
+ }
+
function test_map_clamp()
{
//valid
diff --git a/tests/auto/geotestplugin/geotestplugin.pro b/tests/auto/geotestplugin/geotestplugin.pro
index fb3f1b39..f4fe25b3 100644
--- a/tests/auto/geotestplugin/geotestplugin.pro
+++ b/tests/auto/geotestplugin/geotestplugin.pro
@@ -14,7 +14,8 @@ HEADERS += qgeocodingmanagerengine_test.h \
qgeotiledmap_test.h \
qgeotilefetcher_test.h
-SOURCES += qgeoserviceproviderplugin_test.cpp
+SOURCES += qgeoserviceproviderplugin_test.cpp \
+ qgeotiledmap_test.cpp
OTHER_FILES += \
geotestplugin.json \
diff --git a/tests/auto/geotestplugin/qgeocodingmanagerengine_test.h b/tests/auto/geotestplugin/qgeocodingmanagerengine_test.h
index 1d9f0792..ecbb60d1 100644
--- a/tests/auto/geotestplugin/qgeocodingmanagerengine_test.h
+++ b/tests/auto/geotestplugin/qgeocodingmanagerengine_test.h
@@ -57,11 +57,6 @@ public:
void callSetOffset ( int offset ) {setOffset(offset);}
void callSetLocations ( const QList<QGeoLocation> & locations ) {setLocations(locations);}
void callSetViewport ( const QGeoShape &viewport ) {setViewport(viewport);}
- void abort() {
- emit aborted();
- }
-Q_SIGNALS:
- void aborted();
};
class QGeoCodingManagerEngineTest: public QGeoCodingManagerEngine
diff --git a/tests/auto/geotestplugin/qgeoroutingmanagerengine_test.h b/tests/auto/geotestplugin/qgeoroutingmanagerengine_test.h
index 8ae58042..0a1e7ce6 100644
--- a/tests/auto/geotestplugin/qgeoroutingmanagerengine_test.h
+++ b/tests/auto/geotestplugin/qgeoroutingmanagerengine_test.h
@@ -52,12 +52,6 @@ public:
void callSetError ( Error error, const QString & errorString ) {setError(error, errorString);}
void callSetFinished ( bool finished ) {setFinished(finished);}
void callSetRoutes(const QList<QGeoRoute> &routes) {setRoutes(routes);}
-
- void abort() {
- emit aborted();
- }
-Q_SIGNALS:
- void aborted();
};
class QGeoRoutingManagerEngineTest: public QGeoRoutingManagerEngine
diff --git a/tests/auto/geotestplugin/qgeotiledmap_test.cpp b/tests/auto/geotestplugin/qgeotiledmap_test.cpp
new file mode 100644
index 00000000..ef2af7db
--- /dev/null
+++ b/tests/auto/geotestplugin/qgeotiledmap_test.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgeotiledmap_test.h"
+#include <QtLocation/private/qgeotiledmap_p_p.h>
+#include <QtLocation/private/qgeomapparameter_p.h>
+
+QT_USE_NAMESPACE
+
+class QGeoTiledMapTestPrivate: public QGeoTiledMapPrivate
+{
+ Q_DECLARE_PUBLIC(QGeoTiledMapTest)
+public:
+ QGeoTiledMapTestPrivate(QGeoTiledMappingManagerEngine *engine)
+ : QGeoTiledMapPrivate(engine)
+ {
+
+ }
+
+ ~QGeoTiledMapTestPrivate()
+ {
+
+ }
+
+ void addParameter(QGeoMapParameter *param) override
+ {
+ Q_Q(QGeoTiledMapTest);
+ if (param->type() == QStringLiteral("cameraCenter_test")) {
+ // We assume that cameraCenter_test parameters have a QGeoCoordinate property named "center"
+ // Handle the parameter
+ QGeoCameraData cameraData = m_cameraData;
+ QGeoCoordinate newCenter = param->property("center").value<QGeoCoordinate>();
+ cameraData.setCenter(newCenter);
+ q->setCameraData(cameraData);
+ // Connect for further changes handling
+ q->connect(param, SIGNAL(propertyUpdated(QGeoMapParameter *, const char *)),
+ q, SLOT(onCameraCenter_testChanged(QGeoMapParameter*, const char*)));
+
+ }
+ }
+ void removeParameter(QGeoMapParameter *param) override
+ {
+ Q_Q(QGeoTiledMapTest);
+ param->disconnect(q);
+ }
+};
+
+QGeoTiledMapTest::QGeoTiledMapTest(QGeoTiledMappingManagerEngine *engine, QObject *parent)
+: QGeoTiledMap(*new QGeoTiledMapTestPrivate(engine), engine, parent), m_engine(engine)
+{
+}
+
+void QGeoTiledMapTest::onCameraCenter_testChanged(QGeoMapParameter *param, const char *propertyName)
+{
+ Q_D(QGeoTiledMapTest);
+ if (strcmp(propertyName, "center") == 0) {
+ QGeoCameraData cameraData = d->m_cameraData;
+ // Not testing for propertyName as this param has only one allowed property
+ QGeoCoordinate newCenter = param->property(propertyName).value<QGeoCoordinate>();
+ cameraData.setCenter(newCenter);
+ setCameraData(cameraData);
+ }
+}
diff --git a/tests/auto/geotestplugin/qgeotiledmap_test.h b/tests/auto/geotestplugin/qgeotiledmap_test.h
index 27ff7164..19c7620e 100644
--- a/tests/auto/geotestplugin/qgeotiledmap_test.h
+++ b/tests/auto/geotestplugin/qgeotiledmap_test.h
@@ -33,17 +33,25 @@
#include <QtLocation/private/qgeotiledmap_p.h>
QT_USE_NAMESPACE
+
class QGeoTiledMappingManagerEngineTest;
+class QGeoTiledMapTestPrivate;
+
class QGeoTiledMapTest: public QGeoTiledMap
{
Q_OBJECT
+ Q_DECLARE_PRIVATE(QGeoTiledMapTest)
public:
- QGeoTiledMapTest(QGeoTiledMappingManagerEngine *engine, QObject *parent = 0):
- QGeoTiledMap(engine, parent),
- m_engine(engine){}
+ QGeoTiledMapTest(QGeoTiledMappingManagerEngine *engine, QObject *parent = 0);
+
+protected slots:
+ void onCameraCenter_testChanged(QGeoMapParameter *param, const char *propertyName);
+
public:
using QGeoTiledMap::setCameraData;
QGeoTiledMappingManagerEngine *m_engine;
};
#endif
+
+
diff --git a/tests/auto/geotestplugin/qgeotiledmappingmanagerengine_test.h b/tests/auto/geotestplugin/qgeotiledmappingmanagerengine_test.h
index 2765c268..015a203a 100644
--- a/tests/auto/geotestplugin/qgeotiledmappingmanagerengine_test.h
+++ b/tests/auto/geotestplugin/qgeotiledmappingmanagerengine_test.h
@@ -57,6 +57,9 @@ public:
capabilities.setMinimumZoomLevel(0.0);
capabilities.setMaximumZoomLevel(20.0);
capabilities.setSupportsBearing(true);
+ capabilities.setSupportsTilting(true);
+ capabilities.setMinimumTilt(0);
+ capabilities.setMaximumTilt(60);
setTileSize(QSize(256, 256));
QList<QGeoMapType> mapTypes;
diff --git a/tests/auto/qgeocameracapabilities/tst_qgeocameracapabilities.cpp b/tests/auto/qgeocameracapabilities/tst_qgeocameracapabilities.cpp
index 54755421..09d7293b 100644
--- a/tests/auto/qgeocameracapabilities/tst_qgeocameracapabilities.cpp
+++ b/tests/auto/qgeocameracapabilities/tst_qgeocameracapabilities.cpp
@@ -29,8 +29,8 @@
#include <QtCore/QString>
#include <QtTest/QtTest>
-#include "qgeocameracapabilities_p.h"
-#include "qgeotiledmap_p.h"
+#include <QtLocation/private/qgeocameracapabilities_p.h>
+#include <QtLocation/private/qgeotiledmap_p.h>
QT_USE_NAMESPACE
diff --git a/tests/auto/qgeocircle/tst_qgeocircle.cpp b/tests/auto/qgeocircle/tst_qgeocircle.cpp
index 01fbed6b..fb2f248b 100644
--- a/tests/auto/qgeocircle/tst_qgeocircle.cpp
+++ b/tests/auto/qgeocircle/tst_qgeocircle.cpp
@@ -60,6 +60,9 @@ private slots:
void contains_data();
void contains();
+ void boundingGeoRectangle_data();
+ void boundingGeoRectangle();
+
void extendShape();
void extendShape_data();
@@ -243,7 +246,7 @@ void tst_QGeoCircle::valid()
QCOMPARE(c.isValid(), valid);
QGeoShape area = c;
- QCOMPARE(c.isValid(), valid);
+ QCOMPARE(area.isValid(), valid);
}
void tst_QGeoCircle::empty_data()
@@ -281,7 +284,7 @@ void tst_QGeoCircle::contains_data()
QTest::addColumn<QGeoCoordinate>("probe");
QTest::addColumn<bool>("result");
- QTest::newRow("own centre") << QGeoCoordinate(1,1) << qreal(100.0) <<
+ QTest::newRow("own center") << QGeoCoordinate(1,1) << qreal(100.0) <<
QGeoCoordinate(1,1) << true;
QTest::newRow("over the hills") << QGeoCoordinate(1,1) << qreal(100.0) <<
QGeoCoordinate(30, 40) << false;
@@ -291,6 +294,7 @@ void tst_QGeoCircle::contains_data()
QGeoCoordinate(1.00077538, 0.99955527) << true;
QTest::newRow("at 1.01*radius") << QGeoCoordinate(1,1) << qreal(100.0) <<
QGeoCoordinate(1.00071413, 0.99943423) << false;
+ // TODO: add tests for edge circle cases: cross 1 pole, cross both poles
}
void tst_QGeoCircle::contains()
@@ -307,6 +311,38 @@ void tst_QGeoCircle::contains()
QCOMPARE(area.contains(probe), result);
}
+void tst_QGeoCircle::boundingGeoRectangle_data()
+{
+ QTest::addColumn<QGeoCoordinate>("center");
+ QTest::addColumn<qreal>("radius");
+ QTest::addColumn<QGeoCoordinate>("probe");
+ QTest::addColumn<bool>("result");
+
+ QTest::newRow("own center") << QGeoCoordinate(1,1) << qreal(100.0) <<
+ QGeoCoordinate(1,1) << true;
+ QTest::newRow("over the hills") << QGeoCoordinate(1,1) << qreal(100.0) <<
+ QGeoCoordinate(30, 40) << false;
+ QTest::newRow("at 0.5*radius") << QGeoCoordinate(1,1) << qreal(100.0) <<
+ QGeoCoordinate(1.00015374,1.00015274) << true;
+ QTest::newRow("at 0.99*radius") << QGeoCoordinate(1,1) << qreal(100.0) <<
+ QGeoCoordinate(1.00077538, 0.99955527) << true;
+ QTest::newRow("Outside the box") << QGeoCoordinate(1,1) << qreal(100.0) <<
+ QGeoCoordinate(1.00071413, 0.99903423) << false;
+ // TODO: add tests for edge circle cases: cross 1 pole, cross both poles
+}
+
+void tst_QGeoCircle::boundingGeoRectangle()
+{
+ QFETCH(QGeoCoordinate, center);
+ QFETCH(qreal, radius);
+ QFETCH(QGeoCoordinate, probe);
+ QFETCH(bool, result);
+
+ QGeoCircle c(center, radius);
+ QGeoRectangle box = c.boundingGeoRectangle();
+ QCOMPARE(box.contains(probe), result);
+}
+
void tst_QGeoCircle::extendShape()
{
QFETCH(QGeoCircle, circle);
diff --git a/tests/auto/qgeopath/qgeopath.pro b/tests/auto/qgeopath/qgeopath.pro
new file mode 100644
index 00000000..eec05974
--- /dev/null
+++ b/tests/auto/qgeopath/qgeopath.pro
@@ -0,0 +1,8 @@
+TEMPLATE = app
+CONFIG += testcase
+TARGET = tst_qgeopath
+
+SOURCES += \
+ tst_qgeopath.cpp
+
+QT += positioning testlib
diff --git a/tests/auto/qgeopath/tst_qgeopath.cpp b/tests/auto/qgeopath/tst_qgeopath.cpp
new file mode 100644
index 00000000..8c4ac767
--- /dev/null
+++ b/tests/auto/qgeopath/tst_qgeopath.cpp
@@ -0,0 +1,385 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtPositioning/QGeoCoordinate>
+#include <QtPositioning/QGeoRectangle>
+#include <QtPositioning/QGeoPath>
+
+QT_USE_NAMESPACE
+
+class tst_QGeoPath : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void defaultConstructor();
+ void listConstructor();
+ void assignment();
+
+ void comparison();
+ void type();
+
+ void path();
+ void width();
+
+ void translate_data();
+ void translate();
+
+ void valid_data();
+ void valid();
+
+ void contains_data();
+ void contains();
+
+ void boundingGeoRectangle_data();
+ void boundingGeoRectangle();
+
+ void extendShape();
+ void extendShape_data();
+};
+
+void tst_QGeoPath::defaultConstructor()
+{
+ QGeoPath p;
+ QVERIFY(!p.path().size());
+ QCOMPARE(p.width(), qreal(0.0));
+}
+
+void tst_QGeoPath::listConstructor()
+{
+ QList<QGeoCoordinate> coords;
+ coords.append(QGeoCoordinate(1,1));
+ coords.append(QGeoCoordinate(2,2));
+ coords.append(QGeoCoordinate(3,0));
+
+ QGeoPath p(coords, 1.0);
+ QCOMPARE(p.width(), qreal(1.0));
+ QCOMPARE(p.path().size(), 3);
+
+ for (const QGeoCoordinate &c : coords) {
+ QCOMPARE(p.path().contains(c), true);
+ }
+}
+
+void tst_QGeoPath::assignment()
+{
+ QGeoPath p1;
+ QList<QGeoCoordinate> coords;
+ coords.append(QGeoCoordinate(1,1));
+ coords.append(QGeoCoordinate(2,2));
+ coords.append(QGeoCoordinate(3,0));
+ QGeoPath p2(coords, 1.0);
+
+ QVERIFY(p1 != p2);
+
+ p1 = p2;
+ QCOMPARE(p1.path(), coords);
+ QCOMPARE(p1.width(), 1.0);
+ QCOMPARE(p1, p2);
+
+ // Assign c1 to an area
+ QGeoShape area = p1;
+ QCOMPARE(area.type(), p1.type());
+ QVERIFY(area == p1);
+
+ // Assign the area back to a bounding circle
+ QGeoPath p3 = area;
+ QCOMPARE(p3.path(), coords);
+ QCOMPARE(p3.width(), 1.0);
+
+ // Check that the copy is not modified when modifying the original.
+ p1.setWidth(2.0);
+ QVERIFY(p3.width() != p1.width());
+ QVERIFY(p3 != p1);
+}
+
+void tst_QGeoPath::comparison()
+{
+ QList<QGeoCoordinate> coords;
+ coords.append(QGeoCoordinate(1,1));
+ coords.append(QGeoCoordinate(2,2));
+ coords.append(QGeoCoordinate(3,0));
+ QList<QGeoCoordinate> coords2;
+ coords2.append(QGeoCoordinate(3,1));
+ coords2.append(QGeoCoordinate(4,2));
+ coords2.append(QGeoCoordinate(3,0));
+ QGeoPath c1(coords, qreal(50.0));
+ QGeoPath c2(coords, qreal(50.0));
+ QGeoPath c3(coords, qreal(35.0));
+ QGeoPath c4(coords2, qreal(50.0));
+
+ QVERIFY(c1 == c2);
+ QVERIFY(!(c1 != c2));
+
+ QVERIFY(!(c1 == c3));
+ QVERIFY(c1 != c3);
+
+ QVERIFY(!(c1 == c4));
+ QVERIFY(c1 != c4);
+
+ QVERIFY(!(c2 == c3));
+ QVERIFY(c2 != c3);
+
+ QGeoRectangle b1(QGeoCoordinate(20,20),QGeoCoordinate(10,30));
+ QVERIFY(!(c1 == b1));
+ QVERIFY(c1 != b1);
+
+ QGeoShape *c2Ptr = &c2;
+ QVERIFY(c1 == *c2Ptr);
+ QVERIFY(!(c1 != *c2Ptr));
+
+ QGeoShape *c3Ptr = &c3;
+ QVERIFY(!(c1 == *c3Ptr));
+ QVERIFY(c1 != *c3Ptr);
+}
+
+void tst_QGeoPath::type()
+{
+ QGeoPath c;
+ QCOMPARE(c.type(), QGeoShape::PathType);
+}
+
+void tst_QGeoPath::path()
+{
+ QList<QGeoCoordinate> coords;
+ coords.append(QGeoCoordinate(1,1));
+ coords.append(QGeoCoordinate(2,2));
+ coords.append(QGeoCoordinate(3,0));
+
+ QGeoPath p;
+ p.setPath(coords);
+ QCOMPARE(p.path().size(), 3);
+
+ for (const QGeoCoordinate &c : coords) {
+ QCOMPARE(p.path().contains(c), true);
+ }
+}
+
+void tst_QGeoPath::width()
+{
+ QGeoPath p;
+ p.setWidth(10.0);
+ QCOMPARE(p.width(), qreal(10.0));
+}
+
+void tst_QGeoPath::translate_data()
+{
+ QTest::addColumn<QGeoCoordinate>("c1");
+ QTest::addColumn<QGeoCoordinate>("c2");
+ QTest::addColumn<QGeoCoordinate>("c3");
+ QTest::addColumn<double>("lat");
+ QTest::addColumn<double>("lon");
+
+ QTest::newRow("Simple") << QGeoCoordinate(1,1) << QGeoCoordinate(2,2) <<
+ QGeoCoordinate(3,0) << 5.0 << 4.0;
+ QTest::newRow("Backward") << QGeoCoordinate(1,1) << QGeoCoordinate(2,2) <<
+ QGeoCoordinate(3,0) << -5.0 << -4.0;
+}
+
+void tst_QGeoPath::translate()
+{
+ QFETCH(QGeoCoordinate, c1);
+ QFETCH(QGeoCoordinate, c2);
+ QFETCH(QGeoCoordinate, c3);
+ QFETCH(double, lat);
+ QFETCH(double, lon);
+
+ QList<QGeoCoordinate> coords;
+ coords.append(c1);
+ coords.append(c2);
+ coords.append(c3);
+ QGeoPath p(coords);
+
+ p.translate(lat, lon);
+
+ for (int i = 0; i < p.path().size(); i++) {
+ QCOMPARE(coords[i].latitude(), p.path()[i].latitude() - lat );
+ QCOMPARE(coords[i].longitude(), p.path()[i].longitude() - lon );
+ }
+}
+
+void tst_QGeoPath::valid_data()
+{
+ QTest::addColumn<QGeoCoordinate>("c1");
+ QTest::addColumn<QGeoCoordinate>("c2");
+ QTest::addColumn<QGeoCoordinate>("c3");
+ QTest::addColumn<qreal>("width");
+ QTest::addColumn<bool>("valid");
+
+ QTest::newRow("empty coords") << QGeoCoordinate() << QGeoCoordinate() << QGeoCoordinate() << qreal(5.0) << false;
+ QTest::newRow("invalid coord") << QGeoCoordinate(50, 50) << QGeoCoordinate(60, 60) << QGeoCoordinate(700, 700) << qreal(5.0) << false;
+ QTest::newRow("bad width") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << qreal(-5.0) << true;
+ QTest::newRow("NaN width") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << qreal(qQNaN()) << true;
+ QTest::newRow("zero width") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << qreal(0) << true;
+ QTest::newRow("good") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << qreal(5) << true;
+}
+
+void tst_QGeoPath::valid()
+{
+ QFETCH(QGeoCoordinate, c1);
+ QFETCH(QGeoCoordinate, c2);
+ QFETCH(QGeoCoordinate, c3);
+ QFETCH(qreal, width);
+ QFETCH(bool, valid);
+
+ QList<QGeoCoordinate> coords;
+ coords.append(c1);
+ coords.append(c2);
+ coords.append(c3);
+ QGeoPath p(coords, width);
+
+ QCOMPARE(p.isValid(), valid);
+
+ QGeoShape area = p;
+ QCOMPARE(area.isValid(), valid);
+}
+
+void tst_QGeoPath::contains_data()
+{
+ QTest::addColumn<QGeoCoordinate>("c1");
+ QTest::addColumn<QGeoCoordinate>("c2");
+ QTest::addColumn<QGeoCoordinate>("c3");
+ QTest::addColumn<qreal>("width");
+ QTest::addColumn<QGeoCoordinate>("probe");
+ QTest::addColumn<bool>("result");
+
+ QList<QGeoCoordinate> c;
+ c.append(QGeoCoordinate(1,1));
+ c.append(QGeoCoordinate(2,2));
+ c.append(QGeoCoordinate(3,0));
+
+ QTest::newRow("One of the points") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(2, 2) << true;
+ QTest::newRow("Not so far away") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(0, 0) << false;
+ QTest::newRow("Not so far away and large line") << c[0] << c[1] << c[2] << 100000.0 << QGeoCoordinate(0, 0) << true;
+}
+
+void tst_QGeoPath::contains()
+{
+ QFETCH(QGeoCoordinate, c1);
+ QFETCH(QGeoCoordinate, c2);
+ QFETCH(QGeoCoordinate, c3);
+ QFETCH(qreal, width);
+ QFETCH(QGeoCoordinate, probe);
+ QFETCH(bool, result);
+
+ QList<QGeoCoordinate> coords;
+ coords.append(c1);
+ coords.append(c2);
+ coords.append(c3);
+ QGeoPath p(coords, width);
+
+ QCOMPARE(p.contains(probe), result);
+
+ QGeoShape area = p;
+ QCOMPARE(area.contains(probe), result);
+}
+
+void tst_QGeoPath::boundingGeoRectangle_data()
+{
+ QTest::addColumn<QGeoCoordinate>("c1");
+ QTest::addColumn<QGeoCoordinate>("c2");
+ QTest::addColumn<QGeoCoordinate>("c3");
+ QTest::addColumn<qreal>("width");
+ QTest::addColumn<QGeoCoordinate>("probe");
+ QTest::addColumn<bool>("result");
+
+ QList<QGeoCoordinate> c;
+ c.append(QGeoCoordinate(1,1));
+ c.append(QGeoCoordinate(2,2));
+ c.append(QGeoCoordinate(3,0));
+
+ QTest::newRow("One of the points") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(2, 2) << true;
+ QTest::newRow("Not so far away") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(0, 0) << false;
+ QTest::newRow("Inside the bounds") << c[0] << c[1] << c[2] << 100.0 << QGeoCoordinate(1, 0) << true;
+ QTest::newRow("Inside the bounds") << c[0] << c[1] << c[2] << 100.0 << QGeoCoordinate(1.1, 0.1) << true;
+}
+
+void tst_QGeoPath::boundingGeoRectangle()
+{
+ QFETCH(QGeoCoordinate, c1);
+ QFETCH(QGeoCoordinate, c2);
+ QFETCH(QGeoCoordinate, c3);
+ QFETCH(qreal, width);
+ QFETCH(QGeoCoordinate, probe);
+ QFETCH(bool, result);
+
+ QList<QGeoCoordinate> coords;
+ coords.append(c1);
+ coords.append(c2);
+ coords.append(c3);
+ QGeoPath p(coords, width);
+
+ QGeoRectangle box = p.boundingGeoRectangle();
+ QCOMPARE(box.contains(probe), result);
+}
+
+void tst_QGeoPath::extendShape()
+{
+ QFETCH(QGeoCoordinate, c1);
+ QFETCH(QGeoCoordinate, c2);
+ QFETCH(QGeoCoordinate, c3);
+ QFETCH(qreal, width);
+ QFETCH(QGeoCoordinate, probe);
+ QFETCH(bool, before);
+ QFETCH(bool, after);
+
+ QList<QGeoCoordinate> coords;
+ coords.append(c1);
+ coords.append(c2);
+ coords.append(c3);
+ QGeoPath p(coords, width);
+
+
+ QCOMPARE(p.contains(probe), before);
+ p.extendShape(probe);
+ QCOMPARE(p.contains(probe), after);
+}
+
+void tst_QGeoPath::extendShape_data()
+{
+ QTest::addColumn<QGeoCoordinate>("c1");
+ QTest::addColumn<QGeoCoordinate>("c2");
+ QTest::addColumn<QGeoCoordinate>("c3");
+ QTest::addColumn<qreal>("width");
+ QTest::addColumn<QGeoCoordinate>("probe");
+ QTest::addColumn<bool>("before");
+ QTest::addColumn<bool>("after");
+
+ QList<QGeoCoordinate> c;
+ c.append(QGeoCoordinate(1,1));
+ c.append(QGeoCoordinate(2,2));
+ c.append(QGeoCoordinate(3,0));
+
+ QTest::newRow("One of the points") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(2, 2) << true << true;
+ QTest::newRow("Not so far away") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(0, 0) << false << true;
+ QTest::newRow("Not so far away and large line") << c[0] << c[1] << c[2] << 100000.0 << QGeoCoordinate(0, 0) << true << true;
+}
+
+QTEST_MAIN(tst_QGeoPath)
+#include "tst_qgeopath.moc"
diff --git a/tests/auto/qgeorectangle/tst_qgeorectangle.cpp b/tests/auto/qgeorectangle/tst_qgeorectangle.cpp
index 71a3765a..06b65e86 100644
--- a/tests/auto/qgeorectangle/tst_qgeorectangle.cpp
+++ b/tests/auto/qgeorectangle/tst_qgeorectangle.cpp
@@ -71,6 +71,9 @@ private slots:
void center();
void center_data();
+ void boundingGeoRectangle();
+ void boundingGeoRectangle_data();
+
void containsCoord();
void containsCoord_data();
@@ -957,6 +960,28 @@ void tst_QGeoRectangle::center_data()
QGeoCoordinate(-90.0, -170.0));
}
+void tst_QGeoRectangle::boundingGeoRectangle_data()
+{
+ QTest::addColumn<QGeoRectangle>("rectangle");
+
+ QGeoRectangle b1(QGeoCoordinate(70, 30), QGeoCoordinate(30, 70));
+ QGeoRectangle b2(QGeoCoordinate(70, 150), QGeoCoordinate(30, -170));
+ QGeoRectangle b3(QGeoCoordinate(90, 30), QGeoCoordinate(50, 70));
+ QGeoRectangle b4(QGeoCoordinate(-50, 30), QGeoCoordinate(-90, 70));
+
+ QTest::newRow("Box 1") << b1;
+ QTest::newRow("Box 2") << b2;
+ QTest::newRow("Box 3") << b3;
+ QTest::newRow("Box 4") << b4;
+}
+
+void tst_QGeoRectangle::boundingGeoRectangle()
+{
+ QFETCH(QGeoRectangle, rectangle);
+
+ QGeoRectangle box = rectangle.boundingGeoRectangle();
+ QCOMPARE(box, rectangle);
+}
void tst_QGeoRectangle::containsCoord()
{
@@ -1769,14 +1794,14 @@ void tst_QGeoRectangle::translate_data()
<< 20.0
<< 20.0
<< QGeoRectangle(QGeoCoordinate(90.0, -10.0),
- QGeoCoordinate(40.0, 50.0));
+ QGeoCoordinate(30.0, 50.0));
QTest::newRow("non wrapping -> south clip")
<< QGeoRectangle(QGeoCoordinate(-20.0, -30.0),
QGeoCoordinate(-80.0, 30.0))
<< -20.0
<< 20.0
- << QGeoRectangle(QGeoCoordinate(-40.0, -10.0),
+ << QGeoRectangle(QGeoCoordinate(-30.0, -10.0),
QGeoCoordinate(-90.0, 50.0));
QTest::newRow("wrapping -> non wrapping")
@@ -1801,14 +1826,14 @@ void tst_QGeoRectangle::translate_data()
<< 20.0
<< 20.0
<< QGeoRectangle(QGeoCoordinate(90.0, 150.0),
- QGeoCoordinate(40.0, -150.0));
+ QGeoCoordinate(30.0, -150.0));
QTest::newRow("wrapping -> south clip")
<< QGeoRectangle(QGeoCoordinate(-20.0, 130.0),
QGeoCoordinate(-80.0, -170.0))
<< -20.0
<< 20.0
- << QGeoRectangle(QGeoCoordinate(-40.0, 150.0),
+ << QGeoRectangle(QGeoCoordinate(-30.0, 150.0),
QGeoCoordinate(-90.0, -150.0));
}
diff --git a/tests/auto/qgeoroutereply/tst_qgeoroutereply.cpp b/tests/auto/qgeoroutereply/tst_qgeoroutereply.cpp
index 447181f2..de406b40 100644
--- a/tests/auto/qgeoroutereply/tst_qgeoroutereply.cpp
+++ b/tests/auto/qgeoroutereply/tst_qgeoroutereply.cpp
@@ -197,7 +197,7 @@ void tst_QGeoRouteReply::abort()
reply->abort();
QCOMPARE(signalerror->count(), 0);
- QCOMPARE(signalfinished->count(), 1);
+ QCOMPARE(signalfinished->count(), 0);
}
void tst_QGeoRouteReply::error()